xref: /freebsd/sys/dev/nvmf/host/nvmf_cmd.c (revision a1eda74167b5edb99fd31d507d8a3f7d7e14ae2b)
1*a1eda741SJohn Baldwin /*-
2*a1eda741SJohn Baldwin  * SPDX-License-Identifier: BSD-2-Clause
3*a1eda741SJohn Baldwin  *
4*a1eda741SJohn Baldwin  * Copyright (c) 2023-2024 Chelsio Communications, Inc.
5*a1eda741SJohn Baldwin  * Written by: John Baldwin <jhb@FreeBSD.org>
6*a1eda741SJohn Baldwin  */
7*a1eda741SJohn Baldwin 
8*a1eda741SJohn Baldwin #include <sys/types.h>
9*a1eda741SJohn Baldwin #include <sys/memdesc.h>
10*a1eda741SJohn Baldwin #include <sys/systm.h>
11*a1eda741SJohn Baldwin #include <dev/nvme/nvme.h>
12*a1eda741SJohn Baldwin #include <dev/nvmf/nvmf.h>
13*a1eda741SJohn Baldwin #include <dev/nvmf/nvmf_proto.h>
14*a1eda741SJohn Baldwin #include <dev/nvmf/host/nvmf_var.h>
15*a1eda741SJohn Baldwin 
16*a1eda741SJohn Baldwin bool
17*a1eda741SJohn Baldwin nvmf_cmd_get_property(struct nvmf_softc *sc, uint32_t offset, uint8_t size,
18*a1eda741SJohn Baldwin     nvmf_request_complete_t *cb, void *cb_arg, int how)
19*a1eda741SJohn Baldwin {
20*a1eda741SJohn Baldwin 	struct nvmf_fabric_prop_get_cmd cmd;
21*a1eda741SJohn Baldwin 	struct nvmf_request *req;
22*a1eda741SJohn Baldwin 
23*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
24*a1eda741SJohn Baldwin 	cmd.opcode = NVME_OPC_FABRICS_COMMANDS;
25*a1eda741SJohn Baldwin 	cmd.fctype = NVMF_FABRIC_COMMAND_PROPERTY_GET;
26*a1eda741SJohn Baldwin 	switch (size) {
27*a1eda741SJohn Baldwin 	case 4:
28*a1eda741SJohn Baldwin 		cmd.attrib.size = NVMF_PROP_SIZE_4;
29*a1eda741SJohn Baldwin 		break;
30*a1eda741SJohn Baldwin 	case 8:
31*a1eda741SJohn Baldwin 		cmd.attrib.size = NVMF_PROP_SIZE_8;
32*a1eda741SJohn Baldwin 		break;
33*a1eda741SJohn Baldwin 	default:
34*a1eda741SJohn Baldwin 		panic("Invalid property size");
35*a1eda741SJohn Baldwin 	}
36*a1eda741SJohn Baldwin 	cmd.ofst = htole32(offset);
37*a1eda741SJohn Baldwin 
38*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, cb, cb_arg, how);
39*a1eda741SJohn Baldwin 	if (req != NULL)
40*a1eda741SJohn Baldwin 		nvmf_submit_request(req);
41*a1eda741SJohn Baldwin 	return (req != NULL);
42*a1eda741SJohn Baldwin }
43*a1eda741SJohn Baldwin 
44*a1eda741SJohn Baldwin bool
45*a1eda741SJohn Baldwin nvmf_cmd_set_property(struct nvmf_softc *sc, uint32_t offset, uint8_t size,
46*a1eda741SJohn Baldwin     uint64_t value, nvmf_request_complete_t *cb, void *cb_arg, int how)
47*a1eda741SJohn Baldwin {
48*a1eda741SJohn Baldwin 	struct nvmf_fabric_prop_set_cmd cmd;
49*a1eda741SJohn Baldwin 	struct nvmf_request *req;
50*a1eda741SJohn Baldwin 
51*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
52*a1eda741SJohn Baldwin 	cmd.opcode = NVME_OPC_FABRICS_COMMANDS;
53*a1eda741SJohn Baldwin 	cmd.fctype = NVMF_FABRIC_COMMAND_PROPERTY_SET;
54*a1eda741SJohn Baldwin 	switch (size) {
55*a1eda741SJohn Baldwin 	case 4:
56*a1eda741SJohn Baldwin 		cmd.attrib.size = NVMF_PROP_SIZE_4;
57*a1eda741SJohn Baldwin 		cmd.value.u32.low = htole32(value);
58*a1eda741SJohn Baldwin 		break;
59*a1eda741SJohn Baldwin 	case 8:
60*a1eda741SJohn Baldwin 		cmd.attrib.size = NVMF_PROP_SIZE_8;
61*a1eda741SJohn Baldwin 		cmd.value.u64 = htole64(value);
62*a1eda741SJohn Baldwin 		break;
63*a1eda741SJohn Baldwin 	default:
64*a1eda741SJohn Baldwin 		panic("Invalid property size");
65*a1eda741SJohn Baldwin 	}
66*a1eda741SJohn Baldwin 	cmd.ofst = htole32(offset);
67*a1eda741SJohn Baldwin 
68*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, cb, cb_arg, how);
69*a1eda741SJohn Baldwin 	if (req != NULL)
70*a1eda741SJohn Baldwin 		nvmf_submit_request(req);
71*a1eda741SJohn Baldwin 	return (req != NULL);
72*a1eda741SJohn Baldwin }
73*a1eda741SJohn Baldwin 
74*a1eda741SJohn Baldwin bool
75*a1eda741SJohn Baldwin nvmf_cmd_keep_alive(struct nvmf_softc *sc, nvmf_request_complete_t *cb,
76*a1eda741SJohn Baldwin     void *cb_arg, int how)
77*a1eda741SJohn Baldwin {
78*a1eda741SJohn Baldwin 	struct nvme_command cmd;
79*a1eda741SJohn Baldwin 	struct nvmf_request *req;
80*a1eda741SJohn Baldwin 
81*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
82*a1eda741SJohn Baldwin 	cmd.opc = NVME_OPC_KEEP_ALIVE;
83*a1eda741SJohn Baldwin 
84*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, cb, cb_arg, how);
85*a1eda741SJohn Baldwin 	if (req != NULL)
86*a1eda741SJohn Baldwin 		nvmf_submit_request(req);
87*a1eda741SJohn Baldwin 	return (req != NULL);
88*a1eda741SJohn Baldwin }
89*a1eda741SJohn Baldwin 
90*a1eda741SJohn Baldwin bool
91*a1eda741SJohn Baldwin nvmf_cmd_identify_active_namespaces(struct nvmf_softc *sc, uint32_t id,
92*a1eda741SJohn Baldwin     struct nvme_ns_list *nslist, nvmf_request_complete_t *req_cb,
93*a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how)
94*a1eda741SJohn Baldwin {
95*a1eda741SJohn Baldwin 	struct nvme_command cmd;
96*a1eda741SJohn Baldwin 	struct memdesc mem;
97*a1eda741SJohn Baldwin 	struct nvmf_request *req;
98*a1eda741SJohn Baldwin 
99*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
100*a1eda741SJohn Baldwin 	cmd.opc = NVME_OPC_IDENTIFY;
101*a1eda741SJohn Baldwin 
102*a1eda741SJohn Baldwin 	/* 5.15.1 Use CNS of 0x02 for namespace data. */
103*a1eda741SJohn Baldwin 	cmd.cdw10 = htole32(2);
104*a1eda741SJohn Baldwin 	cmd.nsid = htole32(id);
105*a1eda741SJohn Baldwin 
106*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, req_cb, req_cb_arg, how);
107*a1eda741SJohn Baldwin 	if (req == NULL)
108*a1eda741SJohn Baldwin 		return (false);
109*a1eda741SJohn Baldwin 	mem = memdesc_vaddr(nslist, sizeof(*nslist));
110*a1eda741SJohn Baldwin 	nvmf_capsule_append_data(req->nc, &mem, sizeof(*nslist), false,
111*a1eda741SJohn Baldwin 	    io_cb, io_cb_arg);
112*a1eda741SJohn Baldwin 	nvmf_submit_request(req);
113*a1eda741SJohn Baldwin 	return (true);
114*a1eda741SJohn Baldwin }
115*a1eda741SJohn Baldwin 
116*a1eda741SJohn Baldwin bool
117*a1eda741SJohn Baldwin nvmf_cmd_identify_namespace(struct nvmf_softc *sc, uint32_t id,
118*a1eda741SJohn Baldwin     struct nvme_namespace_data *nsdata, nvmf_request_complete_t *req_cb,
119*a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how)
120*a1eda741SJohn Baldwin {
121*a1eda741SJohn Baldwin 	struct nvme_command cmd;
122*a1eda741SJohn Baldwin 	struct memdesc mem;
123*a1eda741SJohn Baldwin 	struct nvmf_request *req;
124*a1eda741SJohn Baldwin 
125*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
126*a1eda741SJohn Baldwin 	cmd.opc = NVME_OPC_IDENTIFY;
127*a1eda741SJohn Baldwin 
128*a1eda741SJohn Baldwin 	/* 5.15.1 Use CNS of 0x00 for namespace data. */
129*a1eda741SJohn Baldwin 	cmd.cdw10 = htole32(0);
130*a1eda741SJohn Baldwin 	cmd.nsid = htole32(id);
131*a1eda741SJohn Baldwin 
132*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, req_cb, req_cb_arg, how);
133*a1eda741SJohn Baldwin 	if (req == NULL)
134*a1eda741SJohn Baldwin 		return (false);
135*a1eda741SJohn Baldwin 	mem = memdesc_vaddr(nsdata, sizeof(*nsdata));
136*a1eda741SJohn Baldwin 	nvmf_capsule_append_data(req->nc, &mem, sizeof(*nsdata), false,
137*a1eda741SJohn Baldwin 	    io_cb, io_cb_arg);
138*a1eda741SJohn Baldwin 	nvmf_submit_request(req);
139*a1eda741SJohn Baldwin 	return (true);
140*a1eda741SJohn Baldwin }
141*a1eda741SJohn Baldwin 
142*a1eda741SJohn Baldwin bool
143*a1eda741SJohn Baldwin nvmf_cmd_get_log_page(struct nvmf_softc *sc, uint32_t nsid, uint8_t lid,
144*a1eda741SJohn Baldwin     uint64_t offset, void *buf, size_t len, nvmf_request_complete_t *req_cb,
145*a1eda741SJohn Baldwin     void *req_cb_arg, nvmf_io_complete_t *io_cb, void *io_cb_arg, int how)
146*a1eda741SJohn Baldwin {
147*a1eda741SJohn Baldwin 	struct nvme_command cmd;
148*a1eda741SJohn Baldwin 	struct memdesc mem;
149*a1eda741SJohn Baldwin 	struct nvmf_request *req;
150*a1eda741SJohn Baldwin 	size_t numd;
151*a1eda741SJohn Baldwin 
152*a1eda741SJohn Baldwin 	MPASS(len != 0 && len % 4 == 0);
153*a1eda741SJohn Baldwin 	MPASS(offset % 4 == 0);
154*a1eda741SJohn Baldwin 
155*a1eda741SJohn Baldwin 	numd = (len / 4) - 1;
156*a1eda741SJohn Baldwin 	memset(&cmd, 0, sizeof(cmd));
157*a1eda741SJohn Baldwin 	cmd.opc = NVME_OPC_GET_LOG_PAGE;
158*a1eda741SJohn Baldwin 	cmd.nsid = htole32(nsid);
159*a1eda741SJohn Baldwin 	cmd.cdw10 = htole32(numd << 16 | lid);
160*a1eda741SJohn Baldwin 	cmd.cdw11 = htole32(numd >> 16);
161*a1eda741SJohn Baldwin 	cmd.cdw12 = htole32(offset);
162*a1eda741SJohn Baldwin 	cmd.cdw13 = htole32(offset >> 32);
163*a1eda741SJohn Baldwin 
164*a1eda741SJohn Baldwin 	req = nvmf_allocate_request(sc->admin, &cmd, req_cb, req_cb_arg, how);
165*a1eda741SJohn Baldwin 	if (req == NULL)
166*a1eda741SJohn Baldwin 		return (false);
167*a1eda741SJohn Baldwin 	mem = memdesc_vaddr(buf, len);
168*a1eda741SJohn Baldwin 	nvmf_capsule_append_data(req->nc, &mem, len, false, io_cb, io_cb_arg);
169*a1eda741SJohn Baldwin 	nvmf_submit_request(req);
170*a1eda741SJohn Baldwin 	return (true);
171*a1eda741SJohn Baldwin }
172