Skip to content

Commit 9237ba8

Browse files
authored
Merge pull request #391 from CodeConstruct/mi
MI: tests and fixes
2 parents e1e659f + 0cb6a0c commit 9237ba8

3 files changed

Lines changed: 134 additions & 22 deletions

File tree

src/nvme/mi.c

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,16 @@ int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl,
163163
return -EINVAL;
164164

165165
nvme_mi_admin_init_req(&req, &req_hdr, ctrl->id, nvme_admin_identify);
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;
166+
req_hdr.cdw1 = cpu_to_le32(args->nsid);
167+
req_hdr.cdw10 = cpu_to_le32(args->cntid << 16 | args->cns);
168+
req_hdr.cdw11 = cpu_to_le32((args->csi & 0xff) << 24 |
169+
args->cns_specific_id);
170+
req_hdr.cdw14 = cpu_to_le32(args->uuidx);
169171
req_hdr.dlen = cpu_to_le32(size & 0xffffffff);
170172
req_hdr.flags = 0x1;
171173
if (offset) {
172174
req_hdr.flags |= 0x2;
173-
req_hdr.doff = offset;
175+
req_hdr.doff = cpu_to_le32(offset);
174176
}
175177

176178
nvme_mi_calc_req_mic(&req);
@@ -194,20 +196,6 @@ int nvme_mi_admin_identify_partial(nvme_mi_ctrl_t ctrl,
194196
return 0;
195197
}
196198

197-
int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl,
198-
struct nvme_id_ctrl *id)
199-
{
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);
209-
}
210-
211199
static int nvme_mi_read_data(nvme_mi_ep_t ep, __u32 cdw0,
212200
void *data, size_t *data_len)
213201
{

src/nvme/mi.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,15 +155,16 @@ static inline int nvme_mi_admin_identify_cns_nsid(nvme_mi_ctrl_t ctrl,
155155
return nvme_mi_admin_identify(ctrl, &args);
156156
}
157157

158-
static inline int nvme_mi_identify_ctrl(nvme_mi_ctrl_t ctrl,
159-
struct nvme_id_ctrl *id)
158+
static inline int nvme_mi_admin_identify_ctrl(nvme_mi_ctrl_t ctrl,
159+
struct nvme_id_ctrl *id)
160160
{
161161
return nvme_mi_admin_identify_cns_nsid(ctrl, NVME_IDENTIFY_CNS_CTRL,
162162
NVME_NSID_NONE, id);
163163
}
164164

165-
static inline int nvme_mi_identify_ctrl_list(nvme_mi_ctrl_t ctrl, __u16 cntid,
166-
struct nvme_ctrl_list *list)
165+
static inline int nvme_mi_admin_identify_ctrl_list(nvme_mi_ctrl_t ctrl,
166+
__u16 cntid,
167+
struct nvme_ctrl_list *list)
167168
{
168169
struct nvme_identify_args args = {
169170
.result = NULL,

test/mi.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,127 @@ static void test_invalid_crc(nvme_mi_ep_t ep)
193193
assert(rc != 0);
194194
}
195195

196+
/* test: simple NVMe admin request/response */
197+
static int test_admin_id_cb(struct nvme_mi_ep *ep,
198+
struct nvme_mi_req *req,
199+
struct nvme_mi_resp *resp,
200+
void *data)
201+
{
202+
__u8 ror, mt, *hdr;
203+
__u32 dlen, cdw10;
204+
__u16 ctrl_id;
205+
__u8 flags;
206+
207+
assert(req->hdr->type == NVME_MI_MSGTYPE_NVME);
208+
209+
ror = req->hdr->nmp >> 7;
210+
mt = req->hdr->nmp >> 3 & 0x7;
211+
assert(ror == NVME_MI_ROR_REQ);
212+
assert(mt == NVME_MI_MT_ADMIN);
213+
214+
/* do we have enough for a mi header? */
215+
assert(req->hdr_len == sizeof(struct nvme_mi_admin_req_hdr));
216+
217+
/* inspect response as raw bytes */
218+
hdr = (__u8 *)req->hdr;
219+
assert(hdr[4] == nvme_admin_identify);
220+
flags = hdr[5];
221+
222+
ctrl_id = hdr[7] << 8 | hdr[6];
223+
assert(ctrl_id == 0x5); /* controller id */
224+
225+
/* we requested a full id; if we've set the length flag,
226+
* ensure the length matches */
227+
dlen = hdr[35] << 24 | hdr[34] << 16 | hdr[33] << 8 | hdr[32];
228+
if (flags & 0x1) {
229+
assert(dlen == sizeof(struct nvme_id_ctrl));
230+
}
231+
assert(!(flags & 0x2));
232+
233+
/* CNS value of 1 in cdw10 field */
234+
cdw10 = hdr[47] << 24 | hdr[46] << 16 | hdr[45] << 8 | hdr[44];
235+
assert(cdw10 == 0x1);
236+
237+
/* create valid (but somewhat empty) response */
238+
hdr = (__u8 *)resp->hdr;
239+
memset(resp->hdr, 0, resp->hdr_len);
240+
memset(resp->data, 0, resp->data_len);
241+
hdr[4] = 0x00; /* status: success */
242+
243+
test_transport_resp_calc_mic(resp);
244+
245+
return 0;
246+
}
247+
248+
static void test_admin_id(nvme_mi_ep_t ep)
249+
{
250+
struct nvme_id_ctrl id;
251+
nvme_mi_ctrl_t ctrl;
252+
int rc;
253+
254+
test_set_transport_callback(ep, test_admin_id_cb, NULL);
255+
256+
ctrl = nvme_mi_init_ctrl(ep, 5);
257+
assert(ctrl);
258+
259+
rc = nvme_mi_admin_identify_ctrl(ctrl, &id);
260+
assert(rc == 0);
261+
}
262+
263+
/* test: simple NVMe error response */
264+
static int test_admin_err_resp_cb(struct nvme_mi_ep *ep,
265+
struct nvme_mi_req *req,
266+
struct nvme_mi_resp *resp,
267+
void *data)
268+
{
269+
__u8 ror, mt, *hdr;
270+
271+
assert(req->hdr->type == NVME_MI_MSGTYPE_NVME);
272+
273+
ror = req->hdr->nmp >> 7;
274+
mt = req->hdr->nmp >> 3 & 0x7;
275+
assert(ror == NVME_MI_ROR_REQ);
276+
assert(mt == NVME_MI_MT_ADMIN);
277+
278+
/* do we have enough for a mi header? */
279+
assert(req->hdr_len == sizeof(struct nvme_mi_admin_req_hdr));
280+
281+
/* inspect response as raw bytes */
282+
hdr = (__u8 *)req->hdr;
283+
assert(hdr[4] == nvme_admin_identify);
284+
285+
/* we need at least 8 bytes for error information */
286+
assert(resp->hdr_len >= 8);
287+
288+
/* create error response */
289+
hdr = (__u8 *)resp->hdr;
290+
hdr[4] = 0x02; /* status: internal error */
291+
hdr[5] = 0;
292+
hdr[6] = 0;
293+
hdr[7] = 0;
294+
resp->hdr_len = 8;
295+
resp->data_len = 0;
296+
297+
test_transport_resp_calc_mic(resp);
298+
299+
return 0;
300+
}
301+
302+
static void test_admin_err_resp(nvme_mi_ep_t ep)
303+
{
304+
struct nvme_id_ctrl id;
305+
nvme_mi_ctrl_t ctrl;
306+
int rc;
307+
308+
test_set_transport_callback(ep, test_admin_err_resp_cb, NULL);
309+
310+
ctrl = nvme_mi_init_ctrl(ep, 1);
311+
assert(ctrl);
312+
313+
rc = nvme_mi_admin_identify_ctrl(ctrl, &id);
314+
assert(rc != 0);
315+
}
316+
196317
#define DEFINE_TEST(name) { #name, test_ ## name }
197318
struct test {
198319
const char *name;
@@ -201,6 +322,8 @@ struct test {
201322
DEFINE_TEST(read_mi_data),
202323
DEFINE_TEST(transport_fail),
203324
DEFINE_TEST(invalid_crc),
325+
DEFINE_TEST(admin_id),
326+
DEFINE_TEST(admin_err_resp),
204327
};
205328

206329
static void print_log_buf(FILE *logfd)

0 commit comments

Comments
 (0)