summaryrefslogtreecommitdiffstats
path: root/nvme-print-json.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--nvme-print-json.c358
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,