]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme-print-json: Add single_property printf function
authorTokunori Ikegami <ikegami.t@gmail.com>
Fri, 13 Oct 2023 06:58:33 +0000 (15:58 +0900)
committerDaniel Wagner <wagi@monom.org>
Thu, 16 Nov 2023 10:05:54 +0000 (11:05 +0100)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme-print-json.c
nvme-print-stdout.c
nvme-print.h

index c0fbbbd90ab641d4686165f867d63047a715e6c0..07a6463dd1a10b9f2bd67fcac497d3772591063c 100644 (file)
 #include "common.h"
 
 #define ERROR_MSG_LEN 100
-#define STR_LEN 40
+#define STR_LEN 100
 #define BUF_LEN 320
 #define VAL_LEN 4096
 #define BYTE_TO_BIT(byte) ((byte) * 8)
+#define POWER_OF_TWO(exponent) (1 << (exponent))
+#define MS500_TO_SEC(time) ((time) / 2)
+
+#define array_add_obj(o, k) json_array_add_value_object(o, k);
+#define obj_add_str(o, k, v) json_object_add_value_string(o, k, v)
+#define root_add_array(k, v) json_object_add_value_array(root, k, v)
+#define root_add_int_secs(k, v) obj_add_int_secs(root, k, v)
+#define root_add_prix64(k, v) obj_add_prix64(root, k, v)
+#define root_add_str(k, v) json_object_add_value_string(root, k, v)
+#define root_add_uint(k, v) json_object_add_value_uint(root, k, v)
+#define root_add_uint_0x(k, v) obj_add_uint_0x(root, k, v)
+#define root_add_uint_x(k, v) obj_add_uint_x(root, k, v)
 
 static const uint8_t zero_uuid[16] = { 0 };
 static struct print_ops json_print_ops;
 
+static const char *supported = "Supported";
+static const char *not_supported = "Not Supported";
+static const char *yes = "Yes";
+static const char *no = "No";
+static const char *enabled = "Enabled";
+static const char *disabled = "Disabled";
+static const char *reserved = "Reserved";
+static const char *true_str = "True";
+static const char *false_str = "False";
+
+static void obj_add_uint_x(struct json_object *o, const char *k, __u32 v)
+{
+       char str[STR_LEN];
+
+       sprintf(str, "%x", v);
+       obj_add_str(o, k, str);
+}
+
+static void obj_add_uint_0x(struct json_object *o, const char *k, __u32 v)
+{
+       char str[STR_LEN];
+
+       sprintf(str, "0x%02x", v);
+       obj_add_str(o, k, str);
+}
+
+static void obj_add_prix64(struct json_object *o, const char *k, uint64_t v)
+{
+       char str[STR_LEN];
+
+       sprintf(str, "%"PRIx64"", v);
+       obj_add_str(o, k, str);
+}
+
+static void obj_add_int_secs(struct json_object *o, const char *k, int v)
+{
+       char str[STR_LEN];
+
+       sprintf(str, "%d secs", v);
+       obj_add_str(o, k, str);
+}
+
 static void json_print(struct json_object *root)
 {
        json_print_object(root, NULL);
@@ -693,6 +747,255 @@ add:
        json_print(root);
 }
 
+static void json_registers_cap(struct nvme_bar_cap *cap, struct json_object *root)
+{
+       char json_str[STR_LEN];
+       struct json_object *cssa = json_create_array();
+       struct json_object *csso = json_create_object();
+       struct json_object *amsa = json_create_array();
+       struct json_object *amso = json_create_object();
+
+       sprintf(json_str, "%"PRIx64"", *(uint64_t *)cap);
+       json_object_add_value_string(root, "cap", json_str);
+
+       root_add_str("Controller Ready With Media Support (CRWMS)",
+                    cap->crwms ? supported : not_supported);
+       root_add_str("Controller Ready Independent of Media Support (CRIMS)",
+                    cap->crims ? supported : not_supported);
+       root_add_str("NVM Subsystem Shutdown Supported (NSSS)",
+                    cap->nsss ? supported : not_supported);
+       root_add_str("Controller Memory Buffer Supported (CMBS):",
+                    cap->cmbs ? supported : not_supported);
+       root_add_str("Persistent Memory Region Supported (PMRS)",
+                    cap->pmrs ? supported : not_supported);
+
+       sprintf(json_str, "%u bytes", 1 << (12 + cap->mpsmax));
+       root_add_str("Memory Page Size Maximum (MPSMAX)", json_str);
+
+       sprintf(json_str, "%u bytes", 1 << (12 + cap->mpsmin));
+       root_add_str("Memory Page Size Minimum (MPSMIN)", json_str);
+
+       root_add_str("Controller Power Scope (CPS)", !cap->cps ? "Not Reported" : cap->cps == 1 ?
+                    "Controller scope" : cap->cps == 2 ? "Domain scope" : "NVM subsystem scope");
+       root_add_str("Boot Partition Support (BPS)", cap->bps ? yes : no);
+
+       root_add_array("Command Sets Supported (CSS)", cssa);
+       obj_add_str(csso, "NVM command set is %s", cap->css & 1 ? supported : not_supported);
+       obj_add_str(csso, "One or more I/O Command Sets are %s",
+                   cap->css & 0x40 ? supported : not_supported);
+       obj_add_str(csso, cap->css & 0x80 ? "Only Admin Command Set" : "I/O Command Set",
+                   supported);
+       array_add_obj(cssa, csso);
+
+       root_add_str("NVM Subsystem Reset Supported (NSSRS): %s", cap->nssrs ? yes : no);
+
+       sprintf(json_str, "%u bytes", 1 << (2 + cap->dstrd));
+       root_add_str("Doorbell Stride (DSTRD)", json_str);
+
+       root_add_uint("Timeout (TO): %u ms", cap->to * 500);
+
+       root_add_array("Arbitration Mechanism Supported (AMS)", amsa);
+       obj_add_str(amso, "Weighted Round Robin with Urgent Priority Class",
+                   cap->ams & 2 ? supported : not_supported);
+       array_add_obj(amsa, amso);
+
+       root_add_str("Contiguous Queues Required (CQR)", cap->cqr ? yes : no);
+       root_add_uint("Maximum Queue Entries Supported (MQES)", cap->mqes + 1);
+}
+
+static void json_registers_version(__u32 vs, struct json_object *root)
+{
+       char json_str[STR_LEN];
+
+       sprintf(json_str, "%x", vs);
+       root_add_str("version", json_str);
+
+       sprintf(json_str, "%d.%d", (vs & 0xffff0000) >> 16, (vs & 0x0000ff00) >> 8);
+       root_add_str("NVMe specification", json_str);
+}
+
+static void json_registers_cc_ams (__u8 ams, struct json_object *root)
+{
+       char json_str[STR_LEN];
+
+       switch (ams) {
+       case 0:
+               sprintf(json_str, "Round Robin");
+               break;
+       case 1:
+               sprintf(json_str, "Weighted Round Robin with Urgent Priority Class");
+               break;
+       case 7:
+               sprintf(json_str, "Vendor Specific");
+               break;
+       default:
+               sprintf(json_str, "Reserved");
+               break;
+       }
+
+       root_add_str("Arbitration Mechanism Selected (AMS)", json_str);
+}
+
+static void json_registers_cc_shn (__u8 shn, struct json_object *root)
+{
+       char json_str[STR_LEN];
+
+       switch (shn) {
+       case 0:
+               sprintf(json_str, "No notification; no effect");
+               break;
+       case 1:
+               sprintf(json_str, "Normal shutdown notification");
+               break;
+       case 2:
+               sprintf(json_str, "Abrupt shutdown notification");
+               break;
+       default:
+               sprintf(json_str, "Reserved");
+               break;
+       }
+
+       root_add_str("Shutdown Notification (SHN)", json_str);
+}
+
+static void json_registers_cc(__u32 cc, struct json_object *root)
+{
+       char json_str[STR_LEN];
+
+       sprintf(json_str, "%x", cc);
+       root_add_str("cc", json_str);
+
+       root_add_str("Controller Ready Independent of Media Enable (CRIME)",
+                    NVME_CC_CRIME(cc) ? enabled : disabled);
+
+       sprintf(json_str, "%u bytes", POWER_OF_TWO(NVME_GET(cc, CC_IOCQES)));
+       root_add_str("I/O Completion Queue Entry Size (IOCQES): ", json_str);
+
+       sprintf(json_str, "%u bytes", POWER_OF_TWO(NVME_GET(cc, CC_IOSQES)));
+       root_add_str("I/O Submission Queue Entry Size (IOSQES)", json_str);
+
+       json_registers_cc_shn((cc & 0xc000) >> NVME_CC_SHN_SHIFT, root);
+       json_registers_cc_ams((cc & 0x3800) >> NVME_CC_AMS_SHIFT, root);
+
+       sprintf(json_str, "%u bytes", POWER_OF_TWO(12 + NVME_GET(cc, CC_MPS)));
+       root_add_str("Memory Page Size (MPS)", json_str);
+
+       root_add_str("I/O Command Set Selected (CSS)", (cc & 0x70) == 0x00 ? "NVM Command Set" :
+                    (cc & 0x70) == 0x60 ? "All supported I/O Command Sets" :
+                    (cc & 0x70) == 0x70 ? "Admin Command Set only" : reserved);
+       root_add_str("Enable (EN)", cc & 1 ? yes : no);
+}
+
+static void json_registers_csts_shst(__u8 shst, struct json_object *root)
+{
+       char json_str[STR_LEN];
+
+       switch (shst) {
+       case 0:
+               sprintf(json_str, "Normal operation (no shutdown has been requested)");
+               break;
+       case 1:
+               sprintf(json_str, "Shutdown processing occurring");
+               break;
+       case 2:
+               sprintf(json_str, "Shutdown processing complete");
+               break;
+       default:
+               sprintf(json_str, "Reserved");
+               break;
+       }
+       root_add_str("Shutdown Status (SHST)", json_str);
+}
+
+static void json_registers_csts(__u32 csts, struct json_object *root)
+{
+       root_add_uint_x("csts", csts);
+
+       root_add_str("Processing Paused (PP)", csts & 0x20 ? yes : no);
+       root_add_str("NVM Subsystem Reset Occurred (NSSRO)", csts & 0x10 ? yes : no);
+
+       json_registers_csts_shst((csts & 0xc) >> 2, root);
+
+       root_add_str("Controller Fatal Status (CFS)", csts & 2 ? true_str : false_str);
+       root_add_str("Ready (RDY)", csts & 1 ? yes : no);
+}
+
+static void json_registers_nssr(__u32 nssr, struct json_object *root)
+{
+       root_add_uint_x("nssr", nssr);
+       root_add_uint("NVM Subsystem Reset Control (NSSRC)", nssr);
+}
+
+static void json_registers_crto(__u32 crto, struct json_object *root)
+{
+       root_add_uint_x("crto", crto);
+
+       root_add_int_secs("CRIMT", MS500_TO_SEC(NVME_CRTO_CRIMT(crto)));
+       root_add_int_secs("CRWMT", MS500_TO_SEC(NVME_CRTO_CRWMT(crto)));
+}
+
+static void json_registers_unknown(int offset, uint64_t value64, struct json_object *root)
+{
+       root_add_uint_0x("unknown property", offset);
+       root_add_str("name", nvme_register_to_string(offset));
+       root_add_prix64("value", value64);
+}
+
+static void json_single_property_human(int offset, uint64_t value64, struct json_object *root)
+{
+       uint32_t value32 = (uint32_t)value64;
+
+       switch (offset) {
+       case NVME_REG_CAP:
+               json_registers_cap((struct nvme_bar_cap *)&value64, root);
+               break;
+       case NVME_REG_VS:
+               json_registers_version(value32, root);
+               break;
+       case NVME_REG_CC:
+               json_registers_cc(value32, root);
+               break;
+       case NVME_REG_CSTS:
+               json_registers_csts(value32, root);
+               break;
+       case NVME_REG_NSSR:
+               json_registers_nssr(value32, root);
+               break;
+       case NVME_REG_CRTO:
+               json_registers_crto(value32, root);
+               break;
+       default:
+               json_registers_unknown(offset, value64, root);
+               break;
+       }
+}
+
+static void json_single_property(int offset, uint64_t value64)
+{
+       struct json_object *root = json_create_object();
+       char json_str[STR_LEN];
+       int human = json_print_ops.flags & VERBOSE;
+       uint32_t value32 = (uint32_t)value64;
+
+       if (human) {
+               json_single_property_human(offset, value64, root);
+       } else {
+               sprintf(json_str, "0x%02x", offset);
+               json_object_add_value_string(root, "property", json_str);
+
+               json_object_add_value_string(root, "name", nvme_register_to_string(offset));
+
+               if (nvme_is_64bit_reg(offset))
+                       sprintf(json_str, "%"PRIx64"", value64);
+               else
+                       sprintf(json_str, "%x", value32);
+
+               json_object_add_value_string(root, "value", json_str);
+       }
+
+       json_print(root);
+}
+
 struct json_object* json_effects_log(enum nvme_csi csi,
                             struct nvme_cmd_effects_log *effects_log)
 {
@@ -3820,7 +4123,7 @@ static struct print_ops json_print_ops = {
        .secondary_ctrl_list            = json_nvme_list_secondary_ctrl,
        .select_result                  = json_select_result,
        .self_test_log                  = json_self_test_log,
-       .single_property                = NULL,
+       .single_property                = json_single_property,
        .smart_log                      = json_smart_log,
        .supported_cap_config_list_log  = json_supported_cap_config_log,
        .supported_log_pages            = json_support_log,
index 2f0c8a4bbdda426c455a677d30f20661235f59a4..39a5923790c84a1ebab455fdba5da937183bbff0 100644 (file)
@@ -26,27 +26,6 @@ static const char dash[100] = {[0 ... 99] = '-'};
 
 static struct print_ops stdout_print_ops;
 
-struct nvme_bar_cap {
-       __u16   mqes;
-       __u8    cqr:1;
-       __u8    ams:2;
-       __u8    rsvd19:5;
-       __u8    to;
-       __u16   dstrd:4;
-       __u16   nssrs:1;
-       __u16   css:8;
-       __u16   bps:1;
-       __u8    cps:2;
-       __u8    mpsmin:4;
-       __u8    mpsmax:4;
-       __u8    pmrs:1;
-       __u8    cmbs:1;
-       __u8    nsss:1;
-       __u8    crwms:1;
-       __u8    crims:1;
-       __u8    rsvd61:3;
-};
-
 static const char *subsys_key(const struct nvme_subsystem *s)
 {
        return nvme_subsystem_get_name((nvme_subsystem_t)s);
@@ -1246,10 +1225,8 @@ static void stdout_registers_csts(__u32 csts)
 
 static void stdout_registers_crto(__u32 crto)
 {
-       printf("\tCRIMT                               : %d secs\n",
-               NVME_CRTO_CRIMT(crto)/2 );
-       printf("\tCRWMT                               : %d secs\n",
-               NVME_CRTO_CRWMT(crto)/2 );
+       printf("\tCRIMT                               : %d secs\n", NVME_CRTO_CRIMT(crto) / 2);
+       printf("\tCRWMT                               : %d secs\n", NVME_CRTO_CRWMT(crto) / 2);
 }
 
 static void stdout_registers_aqa(__u32 aqa)
@@ -1612,24 +1589,18 @@ void stdout_ctrl_registers(void *bar, bool fabrics)
 static void stdout_single_property(int offset, uint64_t value64)
 {
        int human = stdout_print_ops.flags & VERBOSE;
-
-       uint32_t value32;
+       uint32_t value32 = (uint32_t)value64;
 
        if (!human) {
                if (nvme_is_64bit_reg(offset))
                        printf("property: 0x%02x (%s), value: %"PRIx64"\n",
-                               offset, nvme_register_to_string(offset),
-                               value64);
+                              offset, nvme_register_to_string(offset), value64);
                else
                        printf("property: 0x%02x (%s), value: %x\n", offset,
-                                  nvme_register_to_string(offset),
-                                  (uint32_t) value64);
-
+                              nvme_register_to_string(offset), value32);
                return;
        }
 
-       value32 = (uint32_t) value64;
-
        switch (offset) {
        case NVME_REG_CAP:
                printf("cap : %"PRIx64"\n", value64);
@@ -1649,8 +1620,7 @@ static void stdout_single_property(int offset, uint64_t value64)
                break;
        case NVME_REG_NSSR:
                printf("nssr : %x\n", value32);
-               printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
-                       value32);
+               printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n", value32);
                break;
        case NVME_REG_CRTO:
                printf("crto : %x\n", value32);
@@ -1658,7 +1628,7 @@ static void stdout_single_property(int offset, uint64_t value64)
                break;
        default:
                printf("unknown property: 0x%02x (%s), value: %"PRIx64"\n",
-                       offset, nvme_register_to_string(offset), value64);
+                      offset, nvme_register_to_string(offset), value64);
                break;
        }
 }
index c05576b786c9f26dfc07718d3bd67f6f152e011a..1eee46b2cad78b1e0d0bbf76b6ae9153286a4d8a 100644 (file)
@@ -100,6 +100,27 @@ struct print_ops {
        enum nvme_print_flags flags;
 };
 
+struct nvme_bar_cap {
+       __u16   mqes;
+       __u8    cqr:1;
+       __u8    ams:2;
+       __u8    rsvd19:5;
+       __u8    to;
+       __u16   dstrd:4;
+       __u16   nssrs:1;
+       __u16   css:8;
+       __u16   bps:1;
+       __u8    cps:2;
+       __u8    mpsmin:4;
+       __u8    mpsmax:4;
+       __u8    pmrs:1;
+       __u8    cmbs:1;
+       __u8    nsss:1;
+       __u8    crwms:1;
+       __u8    crims:1;
+       __u8    rsvd61:3;
+};
+
 #ifdef CONFIG_JSONC
 
 struct print_ops *nvme_get_json_print_ops(enum nvme_print_flags flags);