Skip to content

Commit a779efa

Browse files
authored
Merge pull request #386 from CodeConstruct/mi
MI: Update MI Admin API to suit core
2 parents 677c586 + aa3d6a7 commit a779efa

4 files changed

Lines changed: 107 additions & 52 deletions

File tree

examples/mi-mctp.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,15 @@ static const char *__copy_id_str(const void *field, size_t size,
177177

178178
int do_identify(nvme_mi_ep_t ep, int argc, char **argv)
179179
{
180+
struct nvme_identify_args id_args = { 0 };
180181
struct nvme_mi_ctrl *ctrl;
181182
struct nvme_id_ctrl id;
182183
uint16_t ctrl_id;
183184
char buf[41];
185+
bool partial;
184186
int rc, tmp;
185187

186-
if (argc != 2) {
188+
if (argc < 2) {
187189
fprintf(stderr, "no controller ID specified\n");
188190
return -1;
189191
}
@@ -196,15 +198,33 @@ int do_identify(nvme_mi_ep_t ep, int argc, char **argv)
196198

197199
ctrl_id = tmp & 0xffff;
198200

201+
partial = argc > 2 && !strcmp(argv[2], "--partial");
202+
199203
ctrl = nvme_mi_init_ctrl(ep, tmp);
200204
if (!ctrl) {
201205
warn("can't create controller");
202206
return -1;
203207
}
204208

205-
/* we only use the fields before rab; just request partial ID data */
206-
rc = nvme_mi_admin_identify_ctrl_partial(ctrl, &id, 0,
207-
offsetof(struct nvme_id_ctrl, rab));
209+
id_args.data = &id;
210+
id_args.args_size = sizeof(id_args);
211+
id_args.cns = NVME_IDENTIFY_CNS_CTRL;
212+
id_args.nsid = NVME_NSID_NONE;
213+
id_args.cntid = ctrl_id;
214+
id_args.csi = NVME_CSI_NVM;
215+
216+
/* for this example code, we can either do a full or partial identify;
217+
* since we're only printing the fields before the 'rab' member,
218+
* these will be equivalent, aside from the size of the MI
219+
* response.
220+
*/
221+
if (partial) {
222+
rc = nvme_mi_admin_identify_partial(ctrl, &id_args, 0,
223+
offsetof(struct nvme_id_ctrl, rab));
224+
} else {
225+
rc = nvme_mi_admin_identify(ctrl, &id_args);
226+
}
227+
208228
if (rc) {
209229
warn("can't perform Admin Identify command");
210230
return -1;
@@ -241,7 +261,7 @@ int main(int argc, char **argv)
241261
fprintf(stderr, "where action is:\n"
242262
" info\n"
243263
" controllers\n"
244-
" identify <controller-id>\n");
264+
" identify <controller-id> [--partial]\n");
245265
return EXIT_FAILURE;
246266
}
247267

src/libnvme-mi.map

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ LIBNVME_MI_1_1 {
1010
nvme_mi_mi_read_mi_data_ctrl_list;
1111
nvme_mi_mi_read_mi_data_ctrl;
1212
nvme_mi_mi_subsystem_health_status_poll;
13-
nvme_mi_admin_identify_ctrl;
14-
nvme_mi_admin_identify_ctrl_partial;
15-
nvme_mi_admin_identify_ctrl_list;
13+
nvme_mi_admin_identify_partial;
1614
nvme_mi_open_mctp;
1715
local:
1816
*;

src/nvme/mi.c

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -146,23 +146,26 @@ static void nvme_mi_admin_init_resp(struct nvme_mi_resp *resp,
146146
resp->hdr_len = sizeof(*hdr);
147147
}
148148

149-
static int nvme_mi_admin_identify(nvme_mi_ctrl_t ctrl,
150-
enum nvme_identify_cns cns,
151-
__u16 cid, __u16 nsid, void *id,
152-
off_t offset, size_t size)
149+
int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl,
150+
struct nvme_identify_args *args,
151+
off_t offset, size_t size)
153152
{
154153
struct nvme_mi_admin_resp_hdr resp_hdr;
155154
struct nvme_mi_admin_req_hdr req_hdr;
156155
struct nvme_mi_resp resp;
157156
struct nvme_mi_req req;
158157
int rc;
159158

159+
if (args->args_size < sizeof(*args))
160+
return -EINVAL;
161+
160162
if (!size || size > 0xffffffff)
161163
return -EINVAL;
162164

163165
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_identify);
164-
req_hdr.cdw10 = cpu_to_le16(cid) << 16 | cpu_to_le16(cns);
165-
req_hdr.cdw11 = cpu_to_le16(nsid);
166+
req_hdr.cdw10 = cpu_to_le16(args->cntid) << 16 | cpu_to_le16(args->cns);
167+
req_hdr.cdw11 = cpu_to_le16(args->nsid);
168+
req_hdr.cdw14 = args->uuidx & 0xff;
166169
req_hdr.dlen = cpu_to_le32(size & 0xffffffff);
167170
req_hdr.flags = 0x1;
168171
if (offset) {
@@ -173,50 +176,36 @@ static int nvme_mi_admin_identify(nvme_mi_ctrl_t ctrl,
173176
nvme_mi_calc_req_mic(&req);
174177

175178
nvme_mi_admin_init_resp(&resp, &resp_hdr);
176-
resp.data = id;
179+
resp.data = args->data;
177180
resp.data_len = size;
178181

179182
rc = nvme_mi_submit(ctrl->ep, &req, &resp);
180183
if (rc)
181184
return rc;
182185

183-
/* check status, map to return value */
186+
if (args->result)
187+
*args->result = le32_to_cpu(resp_hdr.cdw0);
188+
189+
/* callers will expect a full response; if the data buffer isn't
190+
* fully valid, return an error */
191+
if (resp.data_len != size)
192+
return -EPROTO;
184193

185194
return 0;
186195
}
187196

188197
int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl,
189198
struct nvme_id_ctrl *id)
190199
{
191-
return nvme_mi_admin_identify(ctrl, NVME_IDENTIFY_CNS_CTRL,
192-
0, 0, id, 0, sizeof(*id));
193-
}
194-
195-
int nvme_mi_admin_identify_ctrl_partial(nvme_mi_ctrl_t ctrl,
196-
struct nvme_id_ctrl *id,
197-
off_t offset, size_t size)
198-
{
199-
void *buf;
200-
201-
if (offset > sizeof(*id))
202-
return -EINVAL;
203-
if (size > sizeof(*id))
204-
return -EINVAL;
205-
if (offset + size > sizeof(*id))
206-
return -EINVAL;
207-
208-
buf = id;
209-
buf += offset;
210-
211-
return nvme_mi_admin_identify(ctrl, NVME_IDENTIFY_CNS_CTRL,
212-
0, 0, buf, offset, size);
213-
}
214-
215-
int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl,
216-
struct nvme_ctrl_list *ctrllist)
217-
{
218-
return nvme_mi_admin_identify(ctrl, NVME_IDENTIFY_CNS_CTRL_LIST,
219-
0, 0, ctrllist, 0, sizeof(*ctrllist));
200+
struct nvme_identify_args id_args = {
201+
.args_size = sizeof(id_args),
202+
.data = id,
203+
.cns = NVME_IDENTIFY_CNS_CTRL,
204+
.nsid = NVME_NSID_NONE,
205+
.cntid = ctrl->id,
206+
};
207+
208+
return nvme_mi_admin_identify(ctrl, &id_args);
220209
}
221210

222211
static int nvme_mi_read_data(nvme_mi_ep_t ep, __u32 cdw0,

src/nvme/mi.h

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,12 +124,60 @@ int nvme_mi_mi_subsystem_health_status_poll(nvme_mi_ep_t ep, bool clear,
124124
struct nvme_mi_nvm_ss_health_status *nshds);
125125

126126
/* Admin channel functions */
127-
int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl,
128-
struct nvme_id_ctrl *id);
129-
int nvme_mi_admin_identify_ctrl_partial(nvme_mi_ctrl_t ctrl,
130-
struct nvme_id_ctrl *id,
131-
off_t offset, size_t size);
132-
int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl,
133-
struct nvme_ctrl_list *ctrllist);
127+
int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl,
128+
struct nvme_identify_args *args,
129+
off_t offset, size_t size);
130+
131+
/* Helpers for identify commands */
132+
static inline int nvme_mi_admin_identify(nvme_mi_ctrl_t ctrl,
133+
struct nvme_identify_args *args)
134+
{
135+
return nvme_mi_admin_identify_partial(ctrl, args,
136+
0, NVME_IDENTIFY_DATA_SIZE);
137+
}
138+
139+
static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl,
140+
enum nvme_identify_cns cns,
141+
__u32 nsid, void *data)
142+
{
143+
struct nvme_identify_args args = {
144+
.result = NULL,
145+
.data = data,
146+
.args_size = sizeof(args),
147+
.cns = cns,
148+
.csi = NVME_CSI_NVM,
149+
.nsid = nsid,
150+
.cntid = NVME_CNTLID_NONE,
151+
.cns_specific_id = NVME_CNSSPECID_NONE,
152+
.uuidx = NVME_UUID_NONE,
153+
};
154+
155+
return nvme_mi_admin_identify(ctrl, &args);
156+
}
157+
158+
static inline int nvme_mi_identify_ctrl(nvme_mi_ctrl_t ctrl,
159+
struct nvme_id_ctrl *id)
160+
{
161+
return nvme_mi_admin_identify_cns_nsid(ctrl, NVME_IDENTIFY_CNS_CTRL,
162+
NVME_NSID_NONE, id);
163+
}
164+
165+
static inline int nvme_mi_identify_ctrl_list(nvme_mi_ctrl_t ctrl, __u16 cntid,
166+
struct nvme_ctrl_list *list)
167+
{
168+
struct nvme_identify_args args = {
169+
.result = NULL,
170+
.data = list,
171+
.args_size = sizeof(args),
172+
.cns = NVME_IDENTIFY_CNS_CTRL_LIST,
173+
.csi = NVME_CSI_NVM,
174+
.nsid = NVME_NSID_NONE,
175+
.cntid = cntid,
176+
.cns_specific_id = NVME_CNSSPECID_NONE,
177+
.uuidx = NVME_UUID_NONE,
178+
};
179+
180+
return nvme_mi_admin_identify(ctrl, &args);
181+
}
134182

135183
#endif /* _LIBNVME_MI_MI_H */

0 commit comments

Comments
 (0)