diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:11:05 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 11:11:05 +0000 |
commit | 81d6a5ded50a26338e1b36462b3e0a6e45beb9a6 (patch) | |
tree | 364371981040c3dc6e97bb289bda0d33933ebfac /nvme-print-json.c | |
parent | Adding upstream version 2.8. (diff) | |
download | nvme-cli-upstream/2.9.1.tar.xz nvme-cli-upstream/2.9.1.zip |
Adding upstream version 2.9.1.upstream/2.9.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | nvme-print-json.c | 358 |
1 files changed, 290 insertions, 68 deletions
diff --git a/nvme-print-json.c b/nvme-print-json.c index 27f5c7c..fc3ba77 100644 --- a/nvme-print-json.c +++ b/nvme-print-json.c @@ -16,7 +16,6 @@ #define BUF_LEN 320 #define VAL_LEN 4096 #define BYTE_TO_BIT(byte) ((byte) * 8) -#define POWER_OF_TWO(exponent) (1 << (exponent)) #define MS_TO_SEC(time) ((time) / 1000) #define MS500_TO_MS(time) ((time) * 500) #define MS500_TO_SEC(time) (MS_TO_SEC(MS500_TO_MS(time))) @@ -36,6 +35,9 @@ static const uint8_t zero_uuid[16] = { 0 }; static struct print_ops json_print_ops; static struct json_object *json_r = NULL; +static void json_feature_show_fields(enum nvme_features_id fid, unsigned int result, + unsigned char *buf); + static void d_json(unsigned char *buf, int len, int width, int group, struct json_object *array) { int i; @@ -57,6 +59,15 @@ static void d_json(unsigned char *buf, int len, int width, int group, struct jso } } +static void obj_d(struct json_object *o, const char *k, unsigned char *buf, int len, int width, + int group) +{ + struct json_object *data = json_create_array(); + + d_json(buf, len, width, group, data); + obj_add_array(o, k, data); +} + static void obj_add_uint_x(struct json_object *o, const char *k, __u32 v) { char str[STR_LEN]; @@ -73,7 +84,7 @@ static void obj_add_uint_0x(struct json_object *o, const char *k, __u32 v) obj_add_str(o, k, str); } -static void obj_add_uint_02x(struct json_object *o, const char *k, __u32 v) +static void obj_add_uint_0nx(struct json_object *o, const char *k, __u32 v, int width) { char str[STR_LEN]; @@ -81,6 +92,11 @@ static void obj_add_uint_02x(struct json_object *o, const char *k, __u32 v) obj_add_str(o, k, str); } +static void obj_add_uint_02x(struct json_object *o, const char *k, __u32 v) +{ + obj_add_uint_0nx(o, k, v, 2); +} + static void obj_add_uint_nx(struct json_object *o, const char *k, __u32 v) { char str[STR_LEN]; @@ -179,6 +195,12 @@ static void json_print(struct json_object *r) json_free_object(r); } +static void obj_print(struct json_object *o) +{ + if (!json_r) + json_print(o); +} + static bool human(void) { return json_print_ops.flags & VERBOSE; @@ -759,7 +781,7 @@ static void json_select_result(enum nvme_features_id fid, __u32 result) sprintf(json_str, "Feature: %#0*x: select", fid ? 4 : 2, fid); obj_add_array(r, json_str, feature); - json_print(r); + obj_print(r); } static void json_self_test_log(struct nvme_self_test_log *self_test, __u8 dst_entries, @@ -880,7 +902,7 @@ static void json_registers_version(__u32 vs, struct json_object *r) sprintf(json_str, "%x", vs); obj_add_str(r, "Version", json_str); - sprintf(json_str, "%d.%d", (vs & 0xffff0000) >> 16, (vs & 0x0000ff00) >> 8); + sprintf(json_str, "%d.%d.%d", NVME_MAJOR(vs), NVME_MINOR(vs), NVME_TERTIARY(vs)); obj_add_str(r, "NVMe specification", json_str); } @@ -903,13 +925,13 @@ static void json_registers_cc_ams(__u8 ams, struct json_object *r) char json_str[STR_LEN]; switch (ams) { - case 0: + case NVME_CC_AMS_RR: sprintf(json_str, "Round Robin"); break; - case 1: + case NVME_CC_AMS_WRRU: sprintf(json_str, "Weighted Round Robin with Urgent Priority Class"); break; - case 7: + case NVME_CC_AMS_VS: sprintf(json_str, "Vendor Specific"); break; default: @@ -925,13 +947,13 @@ static void json_registers_cc_shn(__u8 shn, struct json_object *r) char json_str[STR_LEN]; switch (shn) { - case 0: + case NVME_CC_SHN_NONE: sprintf(json_str, "No notification; no effect"); break; - case 1: + case NVME_CC_SHN_NORMAL: sprintf(json_str, "Normal shutdown notification"); break; - case 2: + case NVME_CC_SHN_ABRUPT: sprintf(json_str, "Abrupt shutdown notification"); break; default: @@ -952,22 +974,23 @@ static void json_registers_cc(__u32 cc, struct json_object *r) obj_add_str(r, "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))); + sprintf(json_str, "%u bytes", POWER_OF_TWO(NVME_CC_IOCQES(cc))); obj_add_str(r, "I/O Completion Queue Entry Size (IOCQES): ", json_str); - sprintf(json_str, "%u bytes", POWER_OF_TWO(NVME_GET(cc, CC_IOSQES))); + sprintf(json_str, "%u bytes", POWER_OF_TWO(NVME_CC_IOSQES(cc))); obj_add_str(r, "I/O Submission Queue Entry Size (IOSQES)", json_str); - json_registers_cc_shn((cc & 0xc000) >> NVME_CC_SHN_SHIFT, r); - json_registers_cc_ams((cc & 0x3800) >> NVME_CC_AMS_SHIFT, r); + json_registers_cc_shn(NVME_CC_SHN(cc), r); + json_registers_cc_ams(NVME_CC_AMS(cc), r); - sprintf(json_str, "%u bytes", POWER_OF_TWO(12 + NVME_GET(cc, CC_MPS))); + sprintf(json_str, "%u bytes", POWER_OF_TWO(12 + NVME_CC_MPS(cc))); obj_add_str(r, "Memory Page Size (MPS)", json_str); - obj_add_str(r, "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"); - obj_add_str(r, "Enable (EN)", cc & 1 ? "Yes" : "No"); + obj_add_str(r, "I/O Command Set Selected (CSS)", + NVME_CC_CSS(cc) == NVME_CC_CSS_NVM ? "NVM Command Set" : + NVME_CC_CSS(cc) == NVME_CC_CSS_CSI ? "All supported I/O Command Sets" : + NVME_CC_CSS(cc) == NVME_CC_CSS_ADMIN ? "Admin Command Set only" : "Reserved"); + obj_add_str(r, "Enable (EN)", NVME_CC_EN(cc) ? "Yes" : "No"); } static void json_registers_csts_shst(__u8 shst, struct json_object *r) @@ -975,13 +998,13 @@ static void json_registers_csts_shst(__u8 shst, struct json_object *r) char json_str[STR_LEN]; switch (shst) { - case 0: + case NVME_CSTS_SHST_NORMAL: sprintf(json_str, "Normal operation (no shutdown has been requested)"); break; - case 1: + case NVME_CSTS_SHST_OCCUR: sprintf(json_str, "Shutdown processing occurring"); break; - case 2: + case NVME_CSTS_SHST_CMPLT: sprintf(json_str, "Shutdown processing complete"); break; default: @@ -996,13 +1019,15 @@ static void json_registers_csts(__u32 csts, struct json_object *r) { obj_add_uint_x(r, "csts", csts); - obj_add_str(r, "Processing Paused (PP)", csts & 0x20 ? "Yes" : "No"); - obj_add_str(r, "NVM Subsystem Reset Occurred (NSSRO)", csts & 0x10 ? "Yes" : "No"); + obj_add_str(r, "Shutdown Type (ST)", NVME_CSTS_ST(csts) ? "Subsystem" : "Controller"); + obj_add_str(r, "Processing Paused (PP)", NVME_CSTS_PP(csts) ? "Yes" : "No"); + obj_add_str(r, "NVM Subsystem Reset Occurred (NSSRO)", + NVME_CSTS_NSSRO(csts) ? "Yes" : "No"); - json_registers_csts_shst((csts & 0xc) >> 2, r); + json_registers_csts_shst(NVME_CSTS_SHST(csts), r); - obj_add_str(r, "Controller Fatal Status (CFS)", csts & 2 ? "True" : "False"); - obj_add_str(r, "Ready (RDY)", csts & 1 ? "Yes" : "No"); + obj_add_str(r, "Controller Fatal Status (CFS)", NVME_CSTS_CFS(csts) ? "True" : "False"); + obj_add_str(r, "Ready (RDY)", NVME_CSTS_RDY(csts) ? "Yes" : "No"); } static void json_registers_nssr(__u32 nssr, struct json_object *r) @@ -1011,6 +1036,11 @@ static void json_registers_nssr(__u32 nssr, struct json_object *r) obj_add_uint(r, "NVM Subsystem Reset Control (NSSRC)", nssr); } +static void json_registers_nssd(__u32 nssd, struct json_object *r) +{ + obj_add_uint_nx(r, "NVM Subsystem Shutdown Control (NSSC)", nssd); +} + static void json_registers_crto(__u32 crto, struct json_object *r) { obj_add_uint_x(r, "crto", crto); @@ -1022,8 +1052,8 @@ static void json_registers_crto(__u32 crto, struct json_object *r) static void json_registers_aqa(uint32_t aqa, struct json_object *r) { obj_add_uint_x(r, "aqa", aqa); - obj_add_uint(r, "Admin Completion Queue Size (ACQS)", ((aqa & 0xfff0000) >> 16) + 1); - obj_add_uint(r, "Admin Submission Queue Size (ASQS)", (aqa & 0xfff) + 1); + obj_add_uint(r, "Admin Completion Queue Size (ACQS)", NVME_AQA_ACQS(aqa) + 1); + obj_add_uint(r, "Admin Submission Queue Size (ASQS)", NVME_AQA_ASQS(aqa) + 1); } static void json_registers_asq(uint64_t asq, struct json_object *r) @@ -1038,13 +1068,11 @@ static void json_registers_acq(uint64_t acq, struct json_object *r) obj_add_prix64(r, "Admin Completion Queue Base (ACQB)", acq); } -static void json_registers_cmbloc(uint32_t cmbloc, void *bar, struct json_object *r) +static void json_registers_cmbloc(uint32_t cmbloc, bool support, struct json_object *r) { - uint32_t cmbsz = mmio_read32(bar + NVME_REG_CMBSZ); - obj_add_uint_x(r, "cmbloc", cmbloc); - if (!cmbsz) { + if (!support) { obj_add_result(r, "Controller Memory Buffer feature is not supported"); return; } @@ -1173,17 +1201,15 @@ static void json_registers_pmrctl(uint32_t pmrctl, struct json_object *r) obj_add_str(r, "Enable (EN)", pmrctl & 1 ? "Ready" : "Disabled"); } -static void json_registers_pmrsts(uint32_t pmrsts, void *bar, struct json_object *r) +static void json_registers_pmrsts(uint32_t pmrsts, bool ready, struct json_object *r) { - uint32_t pmrctl = mmio_read32(bar + NVME_REG_PMRCTL); - obj_add_uint_x(r, "pmrsts", pmrsts); obj_add_uint_x(r, "Controller Base Address Invalid (CBAI)", (pmrsts & 0x1000) >> 12); obj_add_str(r, "Health Status (HSTS)", - nvme_register_pmr_hsts_to_string((pmrsts & 0xe00) >> 9)); + nvme_register_pmr_hsts_to_string((pmrsts & 0xe00) >> 9)); obj_add_str(r, "Not Ready (NRDY)", - !(pmrsts & 0x100) && (pmrctl & 1) ? "Ready" : "Not ready"); + !(pmrsts & 0x100) && ready ? "Ready" : "Not ready"); obj_add_uint_x(r, "Error (ERR)", pmrsts & 0xff); } @@ -1194,7 +1220,7 @@ static void json_registers_pmrebs(uint32_t pmrebs, struct json_object *r) obj_add_uint_x(r, "PMR Elasticity Buffer Size Base (PMRWBZ)", (pmrebs & 0xffffff00) >> 8); obj_add_str(r, "Read Bypass Behavior", pmrebs & 0x10 ? "Shall" : "May"); obj_add_str(r, "PMR Elasticity Buffer Size Units (PMRSZU)", - nvme_register_pmr_pmrszu_to_string(pmrebs & 0xf)); + nvme_register_unit_to_string(pmrebs & 0xf)); } static void json_registers_pmrswtp(uint32_t pmrswtp, struct json_object *r) @@ -1203,7 +1229,7 @@ static void json_registers_pmrswtp(uint32_t pmrswtp, struct json_object *r) obj_add_uint_x(r, "PMR Sustained Write Throughput (PMRSWTV)", (pmrswtp & 0xffffff00) >> 8); obj_add_key(r, "PMR Sustained Write Throughput Units (PMRSWTU)", "%s/second", - nvme_register_pmr_pmrszu_to_string(pmrswtp & 0xf)); + nvme_register_unit_to_string(pmrswtp & 0xf)); } static void json_registers_pmrmscl(uint32_t pmrmscl, struct json_object *r) @@ -1248,6 +1274,9 @@ static void json_single_property_human(int offset, uint64_t value64, struct json case NVME_REG_NSSR: json_registers_nssr(value32, r); break; + case NVME_REG_NSSD: + json_registers_nssd(value32, r); + break; case NVME_REG_CRTO: json_registers_crto(value32, r); break; @@ -1321,7 +1350,7 @@ struct json_object* json_effects_log(enum nvme_csi csi, static void json_effects_log_list(struct list_head *list) { struct json_object *r = json_create_array(); - nvme_effects_log_node_t *node; + nvme_effects_log_node_t *node = NULL; list_for_each(list, node, node) { struct json_object *json_page = @@ -1351,7 +1380,7 @@ static void json_sanitize_log(struct nvme_sanitize_log_page *sanitize_log, status_str = nvme_sstat_status_to_string(status); sprintf(str, "(%d) %s", status & NVME_SANITIZE_SSTAT_STATUS_MASK, status_str); - obj_add_str(sstat, status_str, str); + obj_add_str(sstat, "status", str); obj_add_obj(dev, "sstat", sstat); obj_add_uint(dev, "cdw10_info", le32_to_cpu(sanitize_log->scdw10)); @@ -1416,12 +1445,12 @@ static void json_add_bitmap(int i, __u8 seb, struct json_object *r) char evt_str[50]; char key[128]; - for (int bit = 0; bit < 8; bit++) { - if (nvme_pel_event_to_string(bit + i * 8)) { - sprintf(key, "bitmap_%x", (bit + i * 8)); + for (int bit = 0; bit < CHAR_BIT; bit++) { + if (nvme_pel_event_to_string(bit + i * CHAR_BIT)) { + sprintf(key, "bitmap_%x", (bit + i * CHAR_BIT)); if ((seb >> bit) & 0x1) snprintf(evt_str, sizeof(evt_str), "Support %s", - nvme_pel_event_to_string(bit + i * 8)); + nvme_pel_event_to_string(bit + i * CHAR_BIT)); obj_add_str(r, key, evt_str); } } @@ -1644,6 +1673,31 @@ static void json_pel_sanitize_completion(void *pevent_log_info, __u32 offset, obj_add_uint(valid_attrs, "cmpln_info", le16_to_cpu(sanitize_cmpln_event->cmpln_info)); } +static void json_pel_set_feature(void *pevent_log_info, __u32 offset, + struct json_object *valid_attrs) +{ + struct nvme_set_feature_event *set_feat_event = pevent_log_info + offset; + int fid = NVME_GET(le32_to_cpu(set_feat_event->cdw_mem[0]), FEATURES_CDW10_FID); + int cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]); + int dword_cnt = NVME_SET_FEAT_EVENT_DW_COUNT(set_feat_event->layout); + unsigned char *mem_buf; + + obj_add_uint_02x(valid_attrs, "feature", fid); + obj_add_str(valid_attrs, "name", nvme_feature_to_string(fid)); + obj_add_uint_0nx(valid_attrs, "value", cdw11, 8); + + if (NVME_SET_FEAT_EVENT_MB_COUNT(set_feat_event->layout)) { + mem_buf = (unsigned char *)(set_feat_event + 4 + dword_cnt * 4); + json_feature_show_fields(fid, cdw11, mem_buf); + } +} + +static void json_pel_telemetry_crt(void *pevent_log_info, __u32 offset, + struct json_object *valid_attrs) +{ + obj_d(valid_attrs, "create", pevent_log_info + offset, 512, 16, 1); +} + static void json_pel_thermal_excursion(void *pevent_log_info, __u32 offset, struct json_object *valid_attrs) { @@ -1720,6 +1774,12 @@ static void json_pevent_entry(void *pevent_log_info, __u8 action, __u32 size, co case NVME_PEL_SANITIZE_COMPLETION_EVENT: json_pel_sanitize_completion(pevent_log_info, offset, valid_attrs); break; + case NVME_PEL_SET_FEATURE_EVENT: + json_pel_set_feature(pevent_log_info, offset, valid_attrs); + break; + case NVME_PEL_TELEMETRY_CRT: + json_pel_telemetry_crt(pevent_log_info, offset, valid_attrs); + break; case NVME_PEL_THERMAL_EXCURSION_EVENT: json_pel_thermal_excursion(pevent_log_info, offset, valid_attrs); break; @@ -1942,8 +2002,8 @@ static void json_boot_part_log(void *bp_log, const char *devname, struct json_object *r = json_create_object(); obj_add_uint(r, "count", hdr->lid); - obj_add_uint(r, "abpid", (le32_to_cpu(hdr->bpinfo) >> 31) & 0x1); - obj_add_uint(r, "bpsz", le32_to_cpu(hdr->bpinfo) & 0x7fff); + obj_add_uint(r, "abpid", NVME_BOOT_PARTITION_INFO_ABPID(le32_to_cpu(hdr->bpinfo))); + obj_add_uint(r, "bpsz", NVME_BOOT_PARTITION_INFO_BPSZ(le32_to_cpu(hdr->bpinfo))); json_print(r); } @@ -1997,7 +2057,7 @@ static void json_phy_rx_eom_descs(struct nvme_phy_rx_eom_log *log, obj_add_uint(jdesc, "ncols", le16_to_cpu(desc->ncols)); obj_add_uint(jdesc, "edlen", le16_to_cpu(desc->edlen)); - if (log->odp & NVME_EOM_PRINTABLE_EYE_PRESENT) + if (NVME_EOM_ODP_PEFP(log->odp)) allocated_eyes[i] = json_eom_printable_eye(desc, r); /* Eye Data field is vendor specific, doesn't map to JSON */ @@ -2476,6 +2536,16 @@ static void json_ctrl_registers_nssr(void *bar, struct json_object *r) obj_add_int(r, "nssr", nssr); } +static void json_ctrl_registers_nssd(void *bar, struct json_object *r) +{ + uint32_t nssd = mmio_read32(bar + NVME_REG_NSSD); + + if (human()) + json_registers_nssd(nssd, obj_create_array_obj(r, "nssd")); + else + obj_add_int(r, "nssd", nssd); +} + static void json_ctrl_registers_crto(void *bar, struct json_object *r) { uint32_t crto = mmio_read32(bar + NVME_REG_CRTO); @@ -2519,11 +2589,16 @@ static void json_ctrl_registers_acq(void *bar, struct json_object *r) static void json_ctrl_registers_cmbloc(void *bar, struct json_object *r) { uint32_t cmbloc = mmio_read32(bar + NVME_REG_CMBLOC); + uint32_t cmbsz; + bool support; - if (human()) - json_registers_cmbloc(cmbloc, bar, obj_create_array_obj(r, "cmbloc")); - else + if (human()) { + cmbsz = mmio_read32(bar + NVME_REG_CMBSZ); + support = nvme_registers_cmbloc_support(cmbsz); + json_registers_cmbloc(cmbloc, support, obj_create_array_obj(r, "cmbloc")); + } else { obj_add_int(r, "cmbloc", cmbloc); + } } static void json_ctrl_registers_cmbsz(void *bar, struct json_object *r) @@ -2609,11 +2684,16 @@ static void json_ctrl_registers_pmrctl(void *bar, struct json_object *r) static void json_ctrl_registers_pmrsts(void *bar, struct json_object *r) { uint32_t pmrsts = mmio_read32(bar + NVME_REG_PMRSTS); + uint32_t pmrctl; + bool ready; - if (human()) - json_registers_pmrsts(pmrsts, bar, obj_create_array_obj(r, "pmrsts")); - else + if (human()) { + pmrctl = mmio_read32(bar + NVME_REG_PMRCTL); + ready = nvme_registers_pmrctl_ready(pmrctl); + json_registers_pmrsts(pmrsts, ready, obj_create_array_obj(r, "pmrsts")); + } else { obj_add_int(r, "pmrsts", pmrsts); + } } static void json_ctrl_registers_pmrebs(void *bar, struct json_object *r) @@ -2667,6 +2747,7 @@ static void json_ctrl_registers(void *bar, bool fabrics) json_ctrl_registers_cc(bar, r); json_ctrl_registers_csts(bar, r); json_ctrl_registers_nssr(bar, r); + json_ctrl_registers_nssd(bar, r); json_ctrl_registers_crto(bar, r); json_ctrl_registers_aqa(bar, r); json_ctrl_registers_asq(bar, r); @@ -2689,6 +2770,149 @@ static void json_ctrl_registers(void *bar, bool fabrics) json_print(r); } +static void json_registers_cmbebs(__u32 cmbebs, struct json_object *r) +{ + char buffer[BUF_LEN]; + + obj_add_uint_nx(r, "cmbebs", cmbebs); + + obj_add_uint_nx(r, "CMB Elasticity Buffer Size Base (CMBWBZ)", cmbebs >> 8); + sprintf(buffer, "%s", cmbebs & 0x10 ? "shall" : "may"); + obj_add_str(r, "Read Bypass Behavior", buffer); + obj_add_str(r, "CMB Elasticity Buffer Size Units (CMBSZU)", + nvme_register_unit_to_string(cmbebs & 0xf)); +} + +static void json_registers_cmbswtp(__u32 cmbswtp, struct json_object *r) +{ + char str[STR_LEN]; + + obj_add_uint_nx(r, "cmbswtp", cmbswtp); + + obj_add_uint_nx(r, "CMB Sustained Write Throughput (CMBSWTV)", cmbswtp >> 8); + sprintf(str, "%s", nvme_register_unit_to_string(cmbswtp & 0xf)); + obj_add_str(r, "CMB Sustained Write Throughput Units (CMBSWTU)", str); +} + +static void json_ctrl_register_human(int offset, uint64_t value, struct json_object *r) +{ + char buffer[BUF_LEN]; + struct json_object *array_obj = NULL; + + switch (offset) { + case NVME_REG_CAP: + array_obj = obj_create_array_obj(r, "cap"); + break; + case NVME_REG_VS: + array_obj = obj_create_array_obj(r, "vs"); + break; + case NVME_REG_INTMS: + obj_add_nprix64(r, "Interrupt Vector Mask Set (IVMS)", value); + break; + case NVME_REG_INTMC: + obj_add_nprix64(r, "Interrupt Vector Mask Clear (IVMC)", value); + break; + case NVME_REG_CC: + array_obj = obj_create_array_obj(r, "cc"); + break; + case NVME_REG_CSTS: + array_obj = obj_create_array_obj(r, "csts"); + break; + case NVME_REG_NSSR: + obj_add_uint64(r, "NVM Subsystem Reset Control (NSSRC)", value); + break; + case NVME_REG_AQA: + json_registers_aqa(value, obj_create_array_obj(r, "aqa")); + break; + case NVME_REG_ASQ: + obj_add_nprix64(r, "Admin Submission Queue Base (ASQB)", value); + break; + case NVME_REG_ACQ: + obj_add_nprix64(r, "Admin Completion Queue Base (ACQB)", value); + break; + case NVME_REG_CMBLOC: + json_registers_cmbloc(value, true, obj_create_array_obj(r, "cmbloc")); + break; + case NVME_REG_CMBSZ: + json_registers_cmbsz(value, obj_create_array_obj(r, "cmbsz")); + break; + case NVME_REG_BPINFO: + json_registers_bpinfo(value, obj_create_array_obj(r, "bpinfo")); + break; + case NVME_REG_BPRSEL: + json_registers_bprsel(value, obj_create_array_obj(r, "bprsel")); + break; + case NVME_REG_BPMBL: + json_registers_bpmbl(value, obj_create_array_obj(r, "bpmbl")); + break; + case NVME_REG_CMBMSC: + json_registers_cmbmsc(value, obj_create_array_obj(r, "cmbmsc")); + break; + case NVME_REG_CMBSTS: + json_registers_cmbsts(value, obj_create_array_obj(r, "cmbsts")); + break; + case NVME_REG_CMBEBS: + json_registers_cmbebs(value, obj_create_array_obj(r, "cmbebs")); + break; + case NVME_REG_CMBSWTP: + json_registers_cmbswtp(value, obj_create_array_obj(r, "cmbswtp")); + break; + case NVME_REG_NSSD: + json_registers_nssd(value, obj_create_array_obj(r, "nssd")); + break; + case NVME_REG_CRTO: + array_obj = obj_create_array_obj(r, "crto"); + break; + case NVME_REG_PMRCAP: + json_registers_pmrcap(value, obj_create_array_obj(r, "pmrcap")); + break; + case NVME_REG_PMRCTL: + json_registers_pmrctl(value, obj_create_array_obj(r, "pmrctl")); + break; + case NVME_REG_PMRSTS: + json_registers_pmrsts(value, true, obj_create_array_obj(r, "pmrsts")); + break; + case NVME_REG_PMREBS: + json_registers_pmrebs(value, obj_create_array_obj(r, "pmrebs")); + break; + case NVME_REG_PMRSWTP: + json_registers_pmrswtp(value, obj_create_array_obj(r, "pmrswtp")); + break; + case NVME_REG_PMRMSCL: + json_registers_pmrmscl(value, obj_create_array_obj(r, "pmrmscl")); + break; + case NVME_REG_PMRMSCU: + json_registers_pmrmscu(value, obj_create_array_obj(r, "pmrmscu")); + break; + default: + sprintf(buffer, "%#04x (%s)", offset, nvme_register_to_string(offset)); + obj_add_str(r, "register", buffer); + obj_add_nprix64(r, "value", value); + break; + } + + if (array_obj) + json_single_property_human(offset, value, array_obj); +} + +static void json_ctrl_register(int offset, uint64_t value) +{ + bool human = json_print_ops.flags & VERBOSE; + struct json_object *r; + char json_str[STR_LEN]; + + sprintf(json_str, "register: %#04x", offset); + r = obj_create(json_str); + + if (human) { + obj_add_uint64(r, nvme_register_to_string(offset), value); + json_ctrl_register_human(offset, value, r); + } else { + obj_add_str(r, "name", nvme_register_symbol_to_string(offset)); + obj_add_uint64(r, "value", value); + } +} + static void json_nvme_cmd_set_independent_id_ns(struct nvme_id_independent_id_ns *ns, unsigned int nsid) { @@ -3433,7 +3657,7 @@ static void json_feature_show(enum nvme_features_id fid, int sel, unsigned int r sprintf(json_str, "%#0*x", result ? 10 : 8, result); obj_add_str(r, nvme_select_to_string(sel), json_str); - json_print(r); + obj_print(r); } static void json_feature_show_fields(enum nvme_features_id fid, unsigned int result, @@ -3525,9 +3749,7 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res json_feature_show_fields_spinup_control(r, result); break; case NVME_FEAT_FID_ENH_CTRL_METADATA: - fallthrough; case NVME_FEAT_FID_CTRL_METADATA: - fallthrough; case NVME_FEAT_FID_NS_METADATA: json_feature_show_fields_ns_metadata(r, fid, buf); break; @@ -3556,7 +3778,7 @@ static void json_feature_show_fields(enum nvme_features_id fid, unsigned int res break; } - json_print(r); + obj_print(r); } void json_id_ctrl_rpmbs(__le32 ctrl_rpmbs) @@ -3604,13 +3826,11 @@ void json_d(unsigned char *buf, int len, int width, int group) { struct json_object *r = json_r ? json_r : json_create_object(); char json_str[STR_LEN]; - struct json_object *data = json_create_array(); sprintf(json_str, "data: buf=%p len=%d width=%d group=%d", buf, len, width, group); - d_json(buf, len, width, group, data); - obj_add_array(r, json_str, data); + obj_d(r, json_str, buf, len, width, group); - json_print(r); + obj_print(r); } static void json_nvme_list_ctrl(struct nvme_ctrl_list *ctrl_list) @@ -3876,6 +4096,7 @@ static void json_detail_list(nvme_root_t t) struct json_object *jpaths = json_create_array(); obj_add_str(jctrl, "Controller", nvme_ctrl_get_name(c)); + obj_add_str(jctrl, "Cntlid", nvme_ctrl_get_cntlid(c)); obj_add_str(jctrl, "SerialNumber", nvme_ctrl_get_serial(c)); obj_add_str(jctrl, "ModelNumber", nvme_ctrl_get_model(c)); obj_add_str(jctrl, "Firmware", nvme_ctrl_get_firmware(c)); @@ -4311,7 +4532,7 @@ static void json_output_status(int status) if (status < 0) { obj_add_str(r, "error", nvme_strerror(errno)); - json_print(r); + obj_print(r); return; } @@ -4332,7 +4553,7 @@ static void json_output_status(int status) break; } - json_print(r); + obj_print(r); } static void json_output_error_status(int status, const char *msg, va_list ap) @@ -4353,7 +4574,7 @@ static void json_output_error_status(int status, const char *msg, va_list ap) if (status < 0) { obj_add_str(r, "error", nvme_strerror(errno)); - json_print(r); + obj_print(r); return; } @@ -4376,7 +4597,7 @@ static void json_output_error_status(int status, const char *msg, va_list ap) obj_add_int(r, "value", val); - json_print(r); + obj_print(r); } static void json_output_message(bool error, const char *msg, va_list ap) @@ -4391,7 +4612,7 @@ static void json_output_message(bool error, const char *msg, va_list ap) free(value); - json_print(r); + obj_print(r); } static void json_output_perror(const char *msg) @@ -4432,6 +4653,7 @@ static struct print_ops json_print_ops = { .phy_rx_eom_log = json_phy_rx_eom_log, .ctrl_list = json_nvme_list_ctrl, .ctrl_registers = json_ctrl_registers, + .ctrl_register = json_ctrl_register, .directive = json_directive_show, .discovery_log = json_discovery_log, .effects_log_list = json_effects_log_list, |