]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
mi: Add simple Admin command test
authorJeremy Kerr <jk@codeconstruct.com.au>
Mon, 20 Jun 2022 04:51:33 +0000 (12:51 +0800)
committerJeremy Kerr <jk@codeconstruct.com.au>
Mon, 20 Jun 2022 07:56:31 +0000 (15:56 +0800)
Add a little test for the MI Admin path, using Identify as a sample
admin function.

Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
test/mi.c

index dbf6374aaf2f399e8e60f6dc706ea42d5c49e36c..0340caf4d8afdc917c8caf132c5f5d94d747cd57 100644 (file)
--- a/test/mi.c
+++ b/test/mi.c
@@ -193,6 +193,73 @@ static void test_invalid_crc(nvme_mi_ep_t ep)
        assert(rc != 0);
 }
 
+/* test: simple NVMe admin request/response */
+static int test_admin_id_cb(struct nvme_mi_ep *ep,
+                                 struct nvme_mi_req *req,
+                                 struct nvme_mi_resp *resp,
+                                 void *data)
+{
+       __u8 ror, mt, *hdr;
+       __u32 dlen, cdw10;
+       __u16 ctrl_id;
+       __u8 flags;
+
+       assert(req->hdr->type == NVME_MI_MSGTYPE_NVME);
+
+       ror = req->hdr->nmp >> 7;
+       mt = req->hdr->nmp >> 3 & 0x7;
+       assert(ror == NVME_MI_ROR_REQ);
+       assert(mt == NVME_MI_MT_ADMIN);
+
+       /* do we have enough for a mi header? */
+       assert(req->hdr_len == sizeof(struct nvme_mi_admin_req_hdr));
+
+       /* inspect response as raw bytes */
+       hdr = (__u8 *)req->hdr;
+       assert(hdr[4] == nvme_admin_identify);
+       flags = hdr[5];
+
+       ctrl_id = hdr[7] << 8 | hdr[6];
+       assert(ctrl_id == 0x5); /* controller id */
+
+       /* we requested a full id; if we've set the length flag,
+        * ensure the length matches */
+       dlen = hdr[35] << 24 | hdr[34] << 16 | hdr[33] << 8 | hdr[32];
+       if (flags & 0x1) {
+               assert(dlen == sizeof(struct nvme_id_ctrl));
+       }
+       assert(!(flags & 0x2));
+
+       /* CNS value of 1 in cdw10 field */
+       cdw10 = hdr[47] << 24 | hdr[46] << 16 | hdr[45] << 8 | hdr[44];
+       assert(cdw10 == 0x1);
+
+       /* create valid (but somewhat empty) response */
+       hdr = (__u8 *)resp->hdr;
+       memset(resp->hdr, 0, resp->hdr_len);
+       memset(resp->data, 0, resp->data_len);
+       hdr[4] = 0x00; /* status: success */
+
+       test_transport_resp_calc_mic(resp);
+
+       return 0;
+}
+
+static void test_admin_id(nvme_mi_ep_t ep)
+{
+       struct nvme_id_ctrl id;
+       nvme_mi_ctrl_t ctrl;
+       int rc;
+
+       test_set_transport_callback(ep, test_admin_id_cb, NULL);
+
+       ctrl = nvme_mi_init_ctrl(ep, 5);
+       assert(ctrl);
+
+       rc = nvme_mi_admin_identify_ctrl(ctrl, &id);
+       assert(rc == 0);
+}
+
 #define DEFINE_TEST(name) { #name, test_ ## name }
 struct test {
        const char *name;
@@ -201,6 +268,7 @@ struct test {
        DEFINE_TEST(read_mi_data),
        DEFINE_TEST(transport_fail),
        DEFINE_TEST(invalid_crc),
+       DEFINE_TEST(admin_id),
 };
 
 static void print_log_buf(FILE *logfd)