summaryrefslogtreecommitdiffstats
path: root/nvme-print.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--nvme-print.c397
1 files changed, 237 insertions, 160 deletions
diff --git a/nvme-print.c b/nvme-print.c
index d0ddb53..696f192 100644
--- a/nvme-print.c
+++ b/nvme-print.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
#include <assert.h>
#include <errno.h>
#include <stdio.h>
@@ -31,7 +32,7 @@ struct nvme_bar_cap {
__u8 to;
__u16 bps_css_nssrs_dstrd;
__u8 mpsmax_mpsmin;
- __u8 rsvd_cmbs_pmrs;
+ __u8 rsvd_crms_nsss_cmbs_pmrs;
};
static long double int128_to_double(__u8 *data)
@@ -86,8 +87,8 @@ const char *nvme_cmd_to_string(int admin, __u8 opcode)
case nvme_admin_directive_send: return "Directive Send";
case nvme_admin_directive_recv: return "Directive Receive";
case nvme_admin_virtual_mgmt: return "Virtualization Management";
- case nvme_admin_nvme_mi_send: return "NVMEe-MI Send";
- case nvme_admin_nvme_mi_recv: return "NVMEe-MI Receive";
+ case nvme_admin_nvme_mi_send: return "NVMe-MI Send";
+ case nvme_admin_nvme_mi_recv: return "NVMe-MI Receive";
case nvme_admin_dbbuf: return "Doorbell Buffer Config";
case nvme_admin_format_nvm: return "Format NVM";
case nvme_admin_security_send: return "Security Send";
@@ -185,7 +186,7 @@ static void json_nvme_id_ns(struct nvme_id_ns *ns, bool cap_only)
json_object_add_value_int(root, "nabo", le16_to_cpu(ns->nabo));
json_object_add_value_int(root, "nabspf", le16_to_cpu(ns->nabspf));
json_object_add_value_int(root, "noiob", le16_to_cpu(ns->noiob));
- json_object_add_value_float(root, "nvmcap", nvmcap);
+ json_object_add_value_double(root, "nvmcap", nvmcap);
json_object_add_value_int(root, "nsattr", ns->nsattr);
json_object_add_value_int(root, "nvmsetid", le16_to_cpu(ns->nvmsetid));
@@ -298,8 +299,8 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "mtfa", le16_to_cpu(ctrl->mtfa));
json_object_add_value_uint(root, "hmpre", le32_to_cpu(ctrl->hmpre));
json_object_add_value_uint(root, "hmmin", le32_to_cpu(ctrl->hmmin));
- json_object_add_value_float(root, "tnvmcap", tnvmcap);
- json_object_add_value_float(root, "unvmcap", unvmcap);
+ json_object_add_value_double(root, "tnvmcap", tnvmcap);
+ json_object_add_value_double(root, "unvmcap", unvmcap);
json_object_add_value_uint(root, "rpmbs", le32_to_cpu(ctrl->rpmbs));
json_object_add_value_int(root, "edstt", le16_to_cpu(ctrl->edstt));
json_object_add_value_int(root, "dsto", ctrl->dsto);
@@ -321,7 +322,7 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "nanagrpid",
le32_to_cpu(ctrl->nanagrpid));
json_object_add_value_int(root, "domainid", le16_to_cpu(ctrl->domainid));
- json_object_add_value_float(root, "megcap", megcap);
+ json_object_add_value_double(root, "megcap", megcap);
json_object_add_value_int(root, "sqes", ctrl->sqes);
json_object_add_value_int(root, "cqes", ctrl->cqes);
json_object_add_value_int(root, "maxcmd", le16_to_cpu(ctrl->maxcmd));
@@ -337,7 +338,7 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(root, "acwu", le16_to_cpu(ctrl->acwu));
json_object_add_value_int(root, "ocfs", le16_to_cpu(ctrl->ocfs));
json_object_add_value_int(root, "sgls", le32_to_cpu(ctrl->sgls));
- json_object_add_value_float(root, "maxdna", maxdna);
+ json_object_add_value_double(root, "maxdna", maxdna);
json_object_add_value_int(root, "maxcna", le32_to_cpu(ctrl->maxcna));
if (strlen(subnqn))
@@ -374,10 +375,12 @@ static void json_nvme_id_ctrl(struct nvme_id_ctrl *ctrl,
json_object_add_value_int(psd, "idle_power",
le16_to_cpu(ctrl->psd[i].idlp));
json_object_add_value_int(psd, "idle_scale",
- ctrl->psd[i].ips);
+ nvme_psd_power_scale(ctrl->psd[i].ips));
json_object_add_value_int(psd, "active_power",
le16_to_cpu(ctrl->psd[i].actp));
- json_object_add_value_int(psd, "active_work_scale",
+ json_object_add_value_int(psd, "active_power_work",
+ ctrl->psd[i].apws & 0x7);
+ json_object_add_value_int(psd, "active_scale",
nvme_psd_power_scale(ctrl->psd[i].apws));
json_array_add_value_object(psds, psd);
@@ -609,18 +612,18 @@ static void json_endurance_log(struct nvme_endurance_group_log *endurance_group,
endurance_group->avl_spare_threshold);
json_object_add_value_int(root, "percent_used",
endurance_group->percent_used);
- json_object_add_value_float(root, "endurance_estimate",
+ json_object_add_value_double(root, "endurance_estimate",
endurance_estimate);
- json_object_add_value_float(root, "data_units_read", data_units_read);
- json_object_add_value_float(root, "data_units_written",
+ json_object_add_value_double(root, "data_units_read", data_units_read);
+ json_object_add_value_double(root, "data_units_written",
data_units_written);
- json_object_add_value_float(root, "mediate_write_commands",
+ json_object_add_value_double(root, "mediate_write_commands",
media_units_written);
- json_object_add_value_float(root, "host_read_cmds", host_read_cmds);
- json_object_add_value_float(root, "host_write_cmds", host_write_cmds);
- json_object_add_value_float(root, "media_data_integrity_err",
+ json_object_add_value_double(root, "host_read_cmds", host_read_cmds);
+ json_object_add_value_double(root, "host_write_cmds", host_write_cmds);
+ json_object_add_value_double(root, "media_data_integrity_err",
media_data_integrity_err);
- json_object_add_value_float(root, "num_err_info_log_entries",
+ json_object_add_value_double(root, "num_err_info_log_entries",
num_err_info_log_entries);
json_print_object(root, NULL);
@@ -673,20 +676,20 @@ static void json_smart_log(struct nvme_smart_log *smart, unsigned int nsid,
json_object_add_value_int(root, "percent_used", smart->percent_used);
json_object_add_value_int(root, "endurance_grp_critical_warning_summary",
smart->endu_grp_crit_warn_sumry);
- json_object_add_value_float(root, "data_units_read", data_units_read);
- json_object_add_value_float(root, "data_units_written",
+ json_object_add_value_double(root, "data_units_read", data_units_read);
+ json_object_add_value_double(root, "data_units_written",
data_units_written);
- json_object_add_value_float(root, "host_read_commands",
+ json_object_add_value_double(root, "host_read_commands",
host_read_commands);
- json_object_add_value_float(root, "host_write_commands",
+ json_object_add_value_double(root, "host_write_commands",
host_write_commands);
- json_object_add_value_float(root, "controller_busy_time",
+ json_object_add_value_double(root, "controller_busy_time",
controller_busy_time);
- json_object_add_value_float(root, "power_cycles", power_cycles);
- json_object_add_value_float(root, "power_on_hours", power_on_hours);
- json_object_add_value_float(root, "unsafe_shutdowns", unsafe_shutdowns);
- json_object_add_value_float(root, "media_errors", media_errors);
- json_object_add_value_float(root, "num_err_log_entries",
+ json_object_add_value_double(root, "power_cycles", power_cycles);
+ json_object_add_value_double(root, "power_on_hours", power_on_hours);
+ json_object_add_value_double(root, "unsafe_shutdowns", unsafe_shutdowns);
+ json_object_add_value_double(root, "media_errors", media_errors);
+ json_object_add_value_double(root, "num_err_log_entries",
num_err_log_entries);
json_object_add_value_uint(root, "warning_temp_time",
le32_to_cpu(smart->warning_temp_time));
@@ -1188,7 +1191,7 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
le16_to_cpu(pevent_log_head->lhl));
json_object_add_value_uint64(root, "timestamp",
le64_to_cpu(pevent_log_head->ts));
- json_object_add_value_float(root, "power_on_hours",
+ json_object_add_value_double(root, "power_on_hours",
int128_to_double(pevent_log_head->poh));
json_object_add_value_uint64(root, "power_cycle_count",
le64_to_cpu(pevent_log_head->pcc));
@@ -1277,25 +1280,25 @@ static void json_persistent_event_log(void *pevent_log_info, __u32 size)
json_object_add_value_int(valid_attrs,
"endurance_grp_critical_warning_summary",
smart_event->endu_grp_crit_warn_sumry);
- json_object_add_value_float(valid_attrs, "data_units_read",
+ json_object_add_value_double(valid_attrs, "data_units_read",
data_units_read);
- json_object_add_value_float(valid_attrs, "data_units_written",
+ json_object_add_value_double(valid_attrs, "data_units_written",
data_units_written);
- json_object_add_value_float(valid_attrs, "host_read_commands",
+ json_object_add_value_double(valid_attrs, "host_read_commands",
host_read_commands);
- json_object_add_value_float(valid_attrs, "host_write_commands",
+ json_object_add_value_double(valid_attrs, "host_write_commands",
host_write_commands);
- json_object_add_value_float(valid_attrs, "controller_busy_time",
+ json_object_add_value_double(valid_attrs, "controller_busy_time",
controller_busy_time);
- json_object_add_value_float(valid_attrs, "power_cycles",
+ json_object_add_value_double(valid_attrs, "power_cycles",
power_cycles);
- json_object_add_value_float(valid_attrs, "power_on_hours",
+ json_object_add_value_double(valid_attrs, "power_on_hours",
power_on_hours);
- json_object_add_value_float(valid_attrs, "unsafe_shutdowns",
+ json_object_add_value_double(valid_attrs, "unsafe_shutdowns",
unsafe_shutdowns);
- json_object_add_value_float(valid_attrs, "media_errors",
+ json_object_add_value_double(valid_attrs, "media_errors",
media_errors);
- json_object_add_value_float(valid_attrs, "num_err_log_entries",
+ json_object_add_value_double(valid_attrs, "num_err_log_entries",
num_err_log_entries);
json_object_add_value_uint(valid_attrs, "warning_temp_time",
le32_to_cpu(smart_event->warning_temp_time));
@@ -1477,7 +1480,7 @@ static void nvme_show_persistent_event_log_rci(__le32 pel_header_rci)
printf("\tReporting Context Port Identifier Type (RCPIT): %u(%s)\n", rcpit,
(rcpit == 0x00) ? "Does not already exist" :
(rcpit == 0x01) ? "NVM subsystem port" :
- (rcpit == 0x10) ? "NVMe-MI port" : "Reserved");
+ (rcpit == 0x02) ? "NVMe-MI port" : "Reserved");
printf("\tReporting Context Port Identifier (RCPID): %#x\n\n", rcpid);
}
@@ -1490,8 +1493,8 @@ static void nvme_show_persistent_event_entry_ehai(__u8 ehai)
printf("\tPort Identifier Type (PIT): %u(%s)\n", pit,
(pit == 0x00) ? "PIT not reported and PELPID does not apply" :
(pit == 0x01) ? "NVM subsystem port" :
- (pit == 0x10) ? "NVMe-MI port" :
- (pit == 0x11) ? "Event not associated with any port and PELPID does not apply" : "Reserved");
+ (pit == 0x02) ? "NVMe-MI port" :
+ "Event not associated with any port and PELPID does not apply");
}
void nvme_show_persistent_event_log(void *pevent_log_info,
@@ -1737,13 +1740,12 @@ void nvme_show_persistent_event_log(void *pevent_log_info,
fid = le32_to_cpu(set_feat_event->cdw_mem[0]) & 0x000f;
cdw11 = le32_to_cpu(set_feat_event->cdw_mem[1]);
- if (((set_feat_event->layout & 0xff) >> 2) != 0)
- mem_buf = (unsigned char *)(set_feat_event + 4 + dword_cnt * 4);
-
printf("Set Feature ID :%#02x (%s), value:%#08x\n", fid,
nvme_feature_to_string(fid), cdw11);
-
- nvme_feature_show_fields(fid, cdw11, mem_buf);
+ if (((set_feat_event->layout & 0xff) >> 2) != 0) {
+ mem_buf = (unsigned char *)(set_feat_event + 4 + dword_cnt * 4);
+ nvme_feature_show_fields(fid, cdw11, mem_buf);
+ }
break;
case NVME_PEL_TELEMETRY_CRT:
d(pevent_log_info + offset, 512, 16, 1);
@@ -2261,9 +2263,9 @@ static void json_supported_cap_config_log(
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].endgid));
json_object_add_value_uint(endurance, "cap_adj_factor",
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].cap_adj_factor));
- json_object_add_value_float(endurance, "tegcap",
+ json_object_add_value_double(endurance, "tegcap",
int128_to_double(cap_log->cap_config_desc[i].egcd[j].tegcap));
- json_object_add_value_float(endurance, "segcap",
+ json_object_add_value_double(endurance, "segcap",
int128_to_double(cap_log->cap_config_desc[i].egcd[j].segcap));
json_object_add_value_uint(endurance, "egsets",
le16_to_cpu(cap_log->cap_config_desc[i].egcd[j].egsets));
@@ -2373,25 +2375,31 @@ void nvme_show_supported_cap_config_log(
}
}
-static unsigned int nvme_show_subsystem_multipath(nvme_subsystem_t s)
+static unsigned int nvme_show_subsystem_multipath(nvme_subsystem_t s,
+ bool show_ana)
{
nvme_ns_t n;
+ nvme_path_t p;
unsigned int i = 0;
- nvme_subsystem_for_each_ns(s, n) {
- nvme_path_t p;
+ n = nvme_subsystem_first_ns(s);
+ if (!n)
+ return 0;
- nvme_namespace_for_each_path(n, p) {
- nvme_ctrl_t c = nvme_path_get_ctrl(p);
+ nvme_namespace_for_each_path(n, p) {
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+ const char *ana_state = "";
- printf(" +- %s %s %s %s %s\n",
- nvme_ctrl_get_name(c),
- nvme_ctrl_get_transport(c),
- nvme_ctrl_get_address(c),
- nvme_ctrl_get_state(c),
- nvme_path_get_ana_state(p));
- i++;
- }
+ if (show_ana)
+ ana_state = nvme_path_get_ana_state(p);
+
+ printf(" +- %s %s %s %s %s\n",
+ nvme_ctrl_get_name(c),
+ nvme_ctrl_get_transport(c),
+ nvme_ctrl_get_address(c),
+ nvme_ctrl_get_state(c),
+ ana_state);
+ i++;
}
return i;
@@ -2410,7 +2418,7 @@ static void nvme_show_subsystem_ctrls(nvme_subsystem_t s)
}
}
-static void nvme_show_subsystem(nvme_root_t r)
+static void nvme_show_subsystem(nvme_root_t r, bool show_ana)
{
nvme_host_t h;
@@ -2422,39 +2430,42 @@ static void nvme_show_subsystem(nvme_root_t r)
nvme_subsystem_get_nqn(s));
printf("\\\n");
- if (!nvme_show_subsystem_multipath(s))
+ if (!nvme_show_subsystem_multipath(s, show_ana))
nvme_show_subsystem_ctrls(s);
}
}
}
static unsigned int json_print_nvme_subsystem_multipath(nvme_subsystem_t s,
+ bool show_ana,
json_object *paths)
{
nvme_ns_t n;
+ nvme_path_t p;
unsigned int i = 0;
- nvme_subsystem_for_each_ns(s, n) {
- nvme_path_t p;
-
- nvme_namespace_for_each_path(n, p) {
- struct json_object *path_attrs;
- nvme_ctrl_t c = nvme_path_get_ctrl(p);
-
- path_attrs = json_create_object();
- json_object_add_value_string(path_attrs, "Name",
- nvme_ctrl_get_name(c));
- json_object_add_value_string(path_attrs, "Transport",
- nvme_ctrl_get_transport(c));
- json_object_add_value_string(path_attrs, "Address",
- nvme_ctrl_get_address(c));
- json_object_add_value_string(path_attrs, "State",
- nvme_ctrl_get_state(c));
+ n = nvme_subsystem_first_ns(s);
+ if (!n)
+ return 0;
+
+ nvme_namespace_for_each_path(n, p) {
+ struct json_object *path_attrs;
+ nvme_ctrl_t c = nvme_path_get_ctrl(p);
+
+ path_attrs = json_create_object();
+ json_object_add_value_string(path_attrs, "Name",
+ nvme_ctrl_get_name(c));
+ json_object_add_value_string(path_attrs, "Transport",
+ nvme_ctrl_get_transport(c));
+ json_object_add_value_string(path_attrs, "Address",
+ nvme_ctrl_get_address(c));
+ json_object_add_value_string(path_attrs, "State",
+ nvme_ctrl_get_state(c));
+ if (show_ana)
json_object_add_value_string(path_attrs, "ANAState",
nvme_path_get_ana_state(p));
- json_array_add_value_object(paths, path_attrs);
- i++;
- }
+ json_array_add_value_object(paths, path_attrs);
+ i++;
}
return i;
@@ -2481,7 +2492,7 @@ static void json_print_nvme_subsystem_ctrls(nvme_subsystem_t s,
}
}
-static void json_print_nvme_subsystem_list(nvme_root_t r)
+static void json_print_nvme_subsystem_list(nvme_root_t r, bool show_ana)
{
struct json_object *host_attrs, *subsystem_attrs;
struct json_object *subsystems, *paths;
@@ -2509,7 +2520,7 @@ static void json_print_nvme_subsystem_list(nvme_root_t r)
json_array_add_value_object(subsystems, subsystem_attrs);
paths = json_create_array();
- if (!json_print_nvme_subsystem_multipath(s, paths))
+ if (!json_print_nvme_subsystem_multipath(s, show_ana, paths))
json_print_nvme_subsystem_ctrls(s, paths);
json_object_add_value_array(subsystem_attrs, "Paths",
@@ -2523,20 +2534,25 @@ static void json_print_nvme_subsystem_list(nvme_root_t r)
json_free_object(root);
}
-void nvme_show_subsystem_list(nvme_root_t r, enum nvme_print_flags flags)
+void nvme_show_subsystem_list(nvme_root_t r, bool show_ana,
+ enum nvme_print_flags flags)
{
if (flags & JSON)
- return json_print_nvme_subsystem_list(r);
- nvme_show_subsystem(r);
+ return json_print_nvme_subsystem_list(r, show_ana);
+ nvme_show_subsystem(r, show_ana);
}
static void nvme_show_registers_cap(struct nvme_bar_cap *cap)
{
+ printf("\tController Ready With Media Support (CRWMS): %s\n",
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x08) >> 3) ? "Supported" : "Not Supported");
+ printf("\tController Ready Independent of Media Support (CRIMS): %s\n",
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x10) >> 4) ? "Supported" : "Not Supported");
printf("\tController Memory Buffer Supported (CMBS): The Controller Memory Buffer is %s\n",
- ((cap->rsvd_cmbs_pmrs & 0x02) >> 1) ? "Supported" :
+ ((cap->rsvd_crms_nsss_cmbs_pmrs & 0x02) >> 1) ? "Supported" :
"Not Supported");
printf("\tPersistent Memory Region Supported (PMRS): The Persistent Memory Region is %s\n",
- (cap->rsvd_cmbs_pmrs & 0x01) ? "Supported" : "Not Supported");
+ (cap->rsvd_crms_nsss_cmbs_pmrs & 0x01) ? "Supported" : "Not Supported");
printf("\tMemory Page Size Maximum (MPSMAX): %u bytes\n",
1 << (12 + ((cap->mpsmax_mpsmin & 0xf0) >> 4)));
printf("\tMemory Page Size Minimum (MPSMIN): %u bytes\n",
@@ -2608,6 +2624,9 @@ static void nvme_show_registers_cc_shn (__u8 shn)
static void nvme_show_registers_cc(__u32 cc)
{
+ printf("\tController Ready Independent of Media Enable (CRIME): %s\n",
+ NVME_CC_CRIME(cc) ? "Enabled":"Disabled");
+
printf("\tI/O Completion Queue Entry Size (IOCQES): %u bytes\n",
1 << ((cc & 0x00f00000) >> NVME_CC_IOCQES_SHIFT));
printf("\tI/O Submission Queue Entry Size (IOSQES): %u bytes\n",
@@ -2656,6 +2675,14 @@ static void nvme_show_registers_csts(__u32 csts)
}
+static void nvme_show_registers_crto(__u32 crto)
+{
+ printf("\tCRIMT : %d secs\n",
+ NVME_CRTO_CRIMT(crto)/2 );
+ printf("\tCRWMT : %d secs\n",
+ NVME_CRTO_CRWMT(crto)/2 );
+}
+
static void nvme_show_registers_aqa(__u32 aqa)
{
printf("\tAdmin Completion Queue Size (ACQS): %u\n",
@@ -2894,7 +2921,7 @@ static void nvme_show_registers_pmrmscu(uint32_t pmrmscu)
static void json_ctrl_registers(void *bar)
{
uint64_t cap, asq, acq, bpmbl, cmbmsc;
- uint32_t vs, intms, intmc, cc, csts, nssr, aqa, cmbsz, cmbloc,
+ uint32_t vs, intms, intmc, cc, csts, nssr, crto, aqa, cmbsz, cmbloc,
bpinfo, bprsel, cmbsts, pmrcap, pmrctl, pmrsts, pmrebs, pmrswtp,
pmrmscl, pmrmscu;
struct json_object *root;
@@ -2906,6 +2933,7 @@ static void json_ctrl_registers(void *bar)
cc = mmio_read32(bar + NVME_REG_CC);
csts = mmio_read32(bar + NVME_REG_CSTS);
nssr = mmio_read32(bar + NVME_REG_NSSR);
+ crto = mmio_read32(bar + NVME_REG_CRTO);
aqa = mmio_read32(bar + NVME_REG_AQA);
asq = mmio_read64(bar + NVME_REG_ASQ);
acq = mmio_read64(bar + NVME_REG_ACQ);
@@ -2925,22 +2953,23 @@ static void json_ctrl_registers(void *bar)
pmrmscu = mmio_read32(bar + NVME_REG_PMRMSCU);
root = json_create_object();
- json_object_add_value_uint(root, "cap", cap);
+ json_object_add_value_uint64(root, "cap", cap);
json_object_add_value_int(root, "vs", vs);
json_object_add_value_int(root, "intms", intms);
json_object_add_value_int(root, "intmc", intmc);
json_object_add_value_int(root, "cc", cc);
json_object_add_value_int(root, "csts", csts);
json_object_add_value_int(root, "nssr", nssr);
+ json_object_add_value_int(root, "crto", crto);
json_object_add_value_int(root, "aqa", aqa);
- json_object_add_value_uint(root, "asq", asq);
- json_object_add_value_uint(root, "acq", acq);
+ json_object_add_value_uint64(root, "asq", asq);
+ json_object_add_value_uint64(root, "acq", acq);
json_object_add_value_int(root, "cmbloc", cmbloc);
json_object_add_value_int(root, "cmbsz", cmbsz);
json_object_add_value_int(root, "bpinfo", bpinfo);
json_object_add_value_int(root, "bprsel", bprsel);
- json_object_add_value_uint(root, "bpmbl", bpmbl);
- json_object_add_value_uint(root, "cmbmsc", cmbmsc);
+ json_object_add_value_uint64(root, "bpmbl", bpmbl);
+ json_object_add_value_uint64(root, "cmbmsc", cmbmsc);
json_object_add_value_int(root, "cmbsts", cmbsts);
json_object_add_value_int(root, "pmrcap", pmrcap);
json_object_add_value_int(root, "pmrctl", pmrctl);
@@ -2958,7 +2987,7 @@ void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags fla
{
const unsigned int reg_size = 0x0e1c; /* 0x0000 to 0x0e1b */
uint64_t cap, asq, acq, bpmbl, cmbmsc;
- uint32_t vs, intms, intmc, cc, csts, nssr, aqa, cmbsz, cmbloc, bpinfo,
+ uint32_t vs, intms, intmc, cc, csts, nssr, crto, aqa, cmbsz, cmbloc, bpinfo,
bprsel, cmbsts, pmrcap, pmrctl, pmrsts, pmrebs, pmrswtp,
pmrmscl, pmrmscu;
int human = flags & VERBOSE;
@@ -2975,6 +3004,7 @@ void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags fla
cc = mmio_read32(bar + NVME_REG_CC);
csts = mmio_read32(bar + NVME_REG_CSTS);
nssr = mmio_read32(bar + NVME_REG_NSSR);
+ crto = mmio_read32(bar + NVME_REG_CRTO);
aqa = mmio_read32(bar + NVME_REG_AQA);
asq = mmio_read64(bar + NVME_REG_ASQ);
acq = mmio_read64(bar + NVME_REG_ACQ);
@@ -3015,6 +3045,10 @@ void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags fla
printf("\tNVM Subsystem Reset Control (NSSRC): %u\n\n",
nssr);
}
+ if (crto != 0xffffffff) {
+ printf("crto : %x\n", crto);
+ nvme_show_registers_crto(crto);
+ }
if (!fabrics) {
printf("intms : %x\n", intms);
printf("\tInterrupt Vector Mask Set (IVMS): %x\n\n",
@@ -3087,6 +3121,8 @@ void nvme_show_ctrl_registers(void *bar, bool fabrics, enum nvme_print_flags fla
printf("csts : %x\n", csts);
if (nssr != 0xffffffff)
printf("nssr : %x\n", nssr);
+ if (crto != 0xffffffff)
+ printf("crto : %x\n", crto);
if (!fabrics) {
printf("intms : %x\n", intms);
printf("intmc : %x\n", intmc);
@@ -3157,6 +3193,11 @@ void nvme_show_single_property(int offset, uint64_t value64, int human)
value32);
break;
+ case NVME_REG_CRTO:
+ printf("crto : %x\n", value32);
+ nvme_show_registers_crto(value32);
+ break;
+
default:
printf("unknown property: 0x%02x (%s), value: %"PRIx64"\n",
offset, nvme_register_to_string(offset), value64);
@@ -3331,10 +3372,10 @@ static void nvme_show_id_ctrl_ctratt(__le32 ctrl_ctratt)
__u32 rrl = (ctratt & NVME_CTRL_CTRATT_READ_RECV_LVLS) >> 3;
__u32 eg = (ctratt & NVME_CTRL_CTRATT_ENDURANCE_GROUPS) >> 4;
__u32 iod = (ctratt & NVME_CTRL_CTRATT_PREDICTABLE_LAT) >> 5;
+ __u32 tbkas = (ctratt & NVME_CTRL_CTRATT_TBKAS) >> 6;
__u32 ng = (ctratt & NVME_CTRL_CTRATT_NAMESPACE_GRANULARITY) >> 7;
+ __u32 sqa = (ctratt & NVME_CTRL_CTRATT_SQ_ASSOCIATIONS) >> 8;
__u32 uuidlist = (ctratt & NVME_CTRL_CTRATT_UUID_LIST) >> 9;
- __u32 rsvd6 = (ctratt & 0x00000040) >> 6;
- __u32 rsvd8 = (ctratt & 0x00000100) >> 8;
if (rsvd)
printf(" [31:16] : %#x\tReserved\n", rsvd);
@@ -3352,12 +3393,12 @@ static void nvme_show_id_ctrl_ctratt(__le32 ctrl_ctratt)
mds, mds ? "" : "Not ");
printf(" [9:9] : %#x\tUUID List %sSupported\n",
uuidlist, uuidlist ? "" : "Not ");
- if (rsvd8)
- printf(" [8:8] : %#x\tReserved\n", rsvd8);
+ printf(" [8:8] : %#x\tSQ Associations %sSupported\n",
+ sqa, sqa ? "" : "Not ");
printf(" [7:7] : %#x\tNamespace Granularity %sSupported\n",
ng, ng ? "" : "Not ");
- if (rsvd6)
- printf(" [6:6] : %#x\tReserved\n", rsvd6);
+ printf(" [6:6] : %#x\tTraffic Based Keep Alive %sSupported\n",
+ tbkas, tbkas ? "" : "Not ");
printf(" [5:5] : %#x\tPredictable Latency Mode %sSupported\n",
iod, iod ? "" : "Not ");
printf(" [4:4] : %#x\tEndurance Groups %sSupported\n",
@@ -3772,7 +3813,7 @@ static void nvme_show_id_ctrl_fna(__u8 fna)
__u8 fmns = fna & 0x1;
if (rsvd)
printf(" [7:4] : %#x\tReserved\n", rsvd);
- printf(" [3:3] : %#x\tFormatNVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
+ printf(" [3:3] : %#x\tFormat NVM Broadcast NSID (FFFFFFFFh) %sSupported\n",
bcnsid, bcnsid ? "Not " : "");
printf(" [2:2] : %#x\tCrypto Erase %sSupported as part of Secure Erase\n",
cese, cese ? "" : "Not ");
@@ -4280,7 +4321,7 @@ void nvme_show_cmd_set_independent_id_ns(
if (flags & JSON)
return json_nvme_cmd_set_independent_id_ns(ns);
- printf("NVME Identify Command Set Idependent Namespace %d:\n", nsid);
+ printf("NVME Identify Command Set Independent Namespace %d:\n", nsid);
printf("nsfeat : %#x\n", ns->nsfeat);
if (human)
nvme_show_cmd_set_independent_id_ns_nsfeat(ns->nsfeat);
@@ -4362,12 +4403,12 @@ static void json_nvme_id_ns_descs(void *data)
case NVME_NIDT_CSI:
memcpy(&desc.csi, data + off, sizeof(desc.csi));
- json_str_p += sprintf(json_str_p, "%#x", desc.csi);
+ sprintf(json_str_p, "%#x", desc.csi);
len += sizeof(desc.csi);
nidt_name = "csi";
break;
default:
- /* Skip unnkown types */
+ /* Skip unknown types */
len = cur->nidl;
break;
}
@@ -4452,7 +4493,7 @@ void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flag
len += sizeof(csi);
break;
default:
- /* Skip unnkown types */
+ /* Skip unknown types */
len = cur->nidl;
break;
}
@@ -4461,22 +4502,45 @@ void nvme_show_id_ns_descs(void *data, unsigned nsid, enum nvme_print_flags flag
}
}
+static void print_psd_workload(__u8 apw)
+{
+ switch (apw & 0x7) {
+ case NVME_PSD_WORKLOAD_NP:
+ /* Unknown or not provided */
+ printf("-");
+ break;
+
+ case 1:
+ /* Extended idle period with burst of random write */
+ printf("1MiB 32 RW, 30s idle");
+ break;
+
+ case 2:
+ /* Heavy sequential writes */
+ printf("80K 128KiB SW");
+ break;
+
+ default:
+ printf("reserved");
+ }
+}
+
static void print_ps_power_and_scale(__le16 ctr_power, __u8 scale)
{
__u16 power = le16_to_cpu(ctr_power);
switch (scale & 0x3) {
- case 0:
+ case NVME_PSD_PS_NOT_REPORTED:
/* Not reported for this power state */
printf("-");
break;
- case 1:
+ case NVME_PSD_PS_100_MICRO_WATT:
/* Units of 0.0001W */
printf("%01u.%04uW", power / 10000, power % 10000);
break;
- case 2:
+ case NVME_PSD_PS_10_MILLI_WATT:
/* Units of 0.01W */
printf("%01u.%02uW", power / 100, power % 100);
break;
@@ -4493,7 +4557,7 @@ static void nvme_show_id_ctrl_power(struct nvme_id_ctrl *ctrl)
for (i = 0; i <= ctrl->npss; i++) {
__u16 max_power = le16_to_cpu(ctrl->psd[i].mp);
- printf("ps %4d : mp:", i);
+ printf("ps %4d : mp:", i);
if (ctrl->psd[i].flags & NVME_PSD_FLAGS_MXPS)
printf("%01u.%04uW ", max_power / 10000, max_power % 10000);
@@ -4504,7 +4568,7 @@ static void nvme_show_id_ctrl_power(struct nvme_id_ctrl *ctrl)
printf("non-");
printf("operational enlat:%d exlat:%d rrt:%d rrl:%d\n"
- " rwt:%d rwl:%d idle_power:",
+ " rwt:%d rwl:%d idle_power:",
le32_to_cpu(ctrl->psd[i].enlat),
le32_to_cpu(ctrl->psd[i].exlat),
ctrl->psd[i].rrt, ctrl->psd[i].rrl,
@@ -4514,6 +4578,8 @@ static void nvme_show_id_ctrl_power(struct nvme_id_ctrl *ctrl)
printf(" active_power:");
print_ps_power_and_scale(ctrl->psd[i].actp,
nvme_psd_power_scale(ctrl->psd[i].apws));
+ printf("\n active_power_workload:");
+ print_psd_workload(ctrl->psd[i].apws);
printf("\n");
}
@@ -4568,7 +4634,7 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
nvme_show_id_ctrl_vwci(ctrl->vwci);
printf("mec : %u\n", ctrl->mec);
if (human)
- nvme_show_id_ctrl_mec(ctrl->vwci);
+ nvme_show_id_ctrl_mec(ctrl->mec);
printf("oacs : %#x\n", le16_to_cpu(ctrl->oacs));
if (human)
@@ -4662,7 +4728,7 @@ void nvme_show_id_ctrl(struct nvme_id_ctrl *ctrl, enum nvme_print_flags flags,
nvme_show_id_ctrl_vwc(ctrl->vwc);
printf("awun : %d\n", le16_to_cpu(ctrl->awun));
printf("awupf : %d\n", le16_to_cpu(ctrl->awupf));
- printf("icsvscc : %d\n", ctrl->icsvscc);
+ printf("icsvscc : %d\n", ctrl->icsvscc);
if (human)
nvme_show_id_ctrl_icsvscc(ctrl->icsvscc);
printf("nwpc : %d\n", ctrl->nwpc);
@@ -4767,12 +4833,14 @@ static void json_nvme_nvm_id_ns(struct nvme_nvm_id_ns *nvm_ns,
static void nvme_show_nvm_id_ns_pic(__u8 pic)
{
- __u8 rsvd = (pic & 0xFC) >> 2;
+ __u8 rsvd = (pic & 0xF8) >> 3;
+ __u8 stcrs = (pic & 0x3) >> 2;
__u8 pic_16bpistm = (pic & 0x2) >> 1;
__u8 pic_16bpists = pic & 0x1;
if (rsvd)
- printf(" [7:2] : %#x\tReserved\n", rsvd);
+ printf(" [7:3] : %#x\tReserved\n", rsvd);
+ printf(" [2:2] : %#x\tStorage Tag Check Read Support\n", stcrs);
printf(" [1:1] : %#x\t16b Guard Protection Information Storage Tag Mask\n",
pic_16bpistm);
printf(" [0:0] : %#x\t16b Guard Protection Information Storage Tag Support\n",
@@ -4917,14 +4985,14 @@ static void show_nvme_id_ns_zoned_ozcs(__le16 ns_ozcs)
zrwasup ? "Yes" : "No");
}
-static void nvme_show_zns_id_ns_recommandeded_limit(__le32 ns_rl, int human,
+static void nvme_show_zns_id_ns_recommended_limit(__le32 ns_rl, int human,
const char *target_limit)
{
- unsigned int recommandeded_limit = le32_to_cpu(ns_rl);
- if (!recommandeded_limit && human)
+ unsigned int recommended_limit = le32_to_cpu(ns_rl);
+ if (!recommended_limit && human)
printf("%s : Not Reported\n", target_limit);
else
- printf("%s : %u\n", target_limit, recommandeded_limit);
+ printf("%s : %u\n", target_limit, recommended_limit);
}
static void nvme_show_zns_id_ns_zrwacap(__u8 zrwacap)
@@ -4988,14 +5056,14 @@ void nvme_show_zns_id_ns(struct nvme_zns_id_ns *ns,
printf("mor : %#x\n", le32_to_cpu(ns->mor));
}
- nvme_show_zns_id_ns_recommandeded_limit(ns->rrl, human, "rrl ");
- nvme_show_zns_id_ns_recommandeded_limit(ns->frl, human, "frl ");
- nvme_show_zns_id_ns_recommandeded_limit(ns->rrl1, human, "rrl1");
- nvme_show_zns_id_ns_recommandeded_limit(ns->rrl2, human, "rrl2");
- nvme_show_zns_id_ns_recommandeded_limit(ns->rrl3, human, "rrl3");
- nvme_show_zns_id_ns_recommandeded_limit(ns->frl, human, "frl1");
- nvme_show_zns_id_ns_recommandeded_limit(ns->frl, human, "frl2");
- nvme_show_zns_id_ns_recommandeded_limit(ns->frl, human, "frl3");
+ nvme_show_zns_id_ns_recommended_limit(ns->rrl, human, "rrl ");
+ nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl ");
+ nvme_show_zns_id_ns_recommended_limit(ns->rrl1, human, "rrl1");
+ nvme_show_zns_id_ns_recommended_limit(ns->rrl2, human, "rrl2");
+ nvme_show_zns_id_ns_recommended_limit(ns->rrl3, human, "rrl3");
+ nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl1");
+ nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl2");
+ nvme_show_zns_id_ns_recommended_limit(ns->frl, human, "frl3");
printf("numzrwa : %#x\n", le32_to_cpu(ns->numzrwa));
printf("zrwafg : %u\n", le16_to_cpu(ns->zrwafg));
@@ -5172,16 +5240,16 @@ static void json_nvme_zns_report_zones(void *report, __u32 descs,
static void nvme_show_zns_report_zone_attributes(__u8 za, __u8 zai)
{
- const char *const recommanded_limit[4] = {"","1","2","3"};
+ const char *const recommended_limit[4] = {"","1","2","3"};
printf("Attrs: Zone Descriptor Extension is %sVaild\n",
(za & NVME_ZNS_ZA_ZDEV)? "" : "Not ");
if(za & NVME_ZNS_ZA_RZR) {
printf(" Reset Zone Recommended with Reset Recommended Limit%s\n",
- recommanded_limit[(zai&0xd)>>2]);
+ recommended_limit[(zai&0xd)>>2]);
}
if (za & NVME_ZNS_ZA_FZR) {
printf(" Finish Zone Recommended with Finish Recommended Limit%s\n",
- recommanded_limit[zai&0x3]);
+ recommended_limit[zai&0x3]);
}
if (za & NVME_ZNS_ZA_ZFC) {
printf(" Zone Finished by Controller\n");
@@ -5298,9 +5366,9 @@ static void json_nvme_id_nvmset(struct nvme_id_nvmset_list *nvmset)
le32_to_cpu(nvmset->ent[i].rr4kt));
json_object_add_value_int(entry, "optimal_write_size",
le32_to_cpu(nvmset->ent[i].ows));
- json_object_add_value_float(entry, "total_nvmset_cap",
+ json_object_add_value_double(entry, "total_nvmset_cap",
int128_to_double(nvmset->ent[i].tnvmsetcap));
- json_object_add_value_float(entry, "unalloc_nvmset_cap",
+ json_object_add_value_double(entry, "unalloc_nvmset_cap",
int128_to_double(nvmset->ent[i].unvmsetcap));
json_array_add_value_object(entries, entry);
}
@@ -5648,9 +5716,9 @@ static void json_id_domain_list(struct nvme_id_domain_list *id_dom)
max_egrp_dom_cap = int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap);
json_object_add_value_uint(entry, "dom_id", le16_to_cpu(id_dom->domain_attr[i].dom_id));
- json_object_add_value_float(entry, "dom_cap", dom_cap);
- json_object_add_value_float(entry, "unalloc_dom_cap", unalloc_dom_cap);
- json_object_add_value_float(entry, "max_egrp_dom_cap", max_egrp_dom_cap);
+ json_object_add_value_double(entry, "dom_cap", dom_cap);
+ json_object_add_value_double(entry, "unalloc_dom_cap", unalloc_dom_cap);
+ json_object_add_value_double(entry, "max_egrp_dom_cap", max_egrp_dom_cap);
json_array_add_value_object(entries, entry);
}
@@ -5670,7 +5738,7 @@ void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
else if (flags & JSON)
return json_id_domain_list(id_dom);
- printf("Number of Domain Entires: %u\n", id_dom->num);
+ printf("Number of Domain Entries: %u\n", id_dom->num);
for (i = 0; i < id_dom->num; i++) {
printf("Domain Id for Attr Entry[%u]: %u\n", i,
le16_to_cpu(id_dom->domain_attr[i].dom_id));
@@ -5678,7 +5746,7 @@ void nvme_show_id_domain_list(struct nvme_id_domain_list *id_dom,
int128_to_double(id_dom->domain_attr[i].dom_cap));
printf("Unallocated Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
int128_to_double(id_dom->domain_attr[i].unalloc_dom_cap));
- printf("Max Endurange Group Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
+ printf("Max Endurance Group Domain Capacity for Attr Entry[%u]: %.0Lf\n", i,
int128_to_double(id_dom->domain_attr[i].max_egrp_dom_cap));
}
}
@@ -6093,7 +6161,7 @@ void nvme_show_supported_log(struct nvme_supported_log_pages *support_log,
else if (flags & JSON)
return json_support_log(support_log);
- printf("Support Log Pages Deatils for %s:\n", devname);
+ printf("Support Log Pages Details for %s:\n", devname);
for (lid = 0; lid < 256; lid++) {
support = le32_to_cpu(support_log->lid_support[lid]);
if (support & 0x1) {
@@ -6473,12 +6541,12 @@ const char *nvme_feature_to_string(enum nvme_features_id feature)
case NVME_FEAT_FID_HCTM: return "Host Controlled Thermal Management";
case NVME_FEAT_FID_NOPSC: return "Non-Operational Power State Config";
case NVME_FEAT_FID_RRL: return "Read Recovery Level";
- case NVME_FEAT_FID_PLM_CONFIG: return "Predicatable Latency Mode Config";
- case NVME_FEAT_FID_PLM_WINDOW: return "Predicatable Latency Mode Window";
+ case NVME_FEAT_FID_PLM_CONFIG: return "Predictable Latency Mode Config";
+ case NVME_FEAT_FID_PLM_WINDOW: return "Predictable Latency Mode Window";
case NVME_FEAT_FID_LBA_STS_INTERVAL: return "LBA Status Interval";
case NVME_FEAT_FID_HOST_BEHAVIOR: return "Host Behavior";
case NVME_FEAT_FID_SANITIZE: return "Sanitize";
- case NVME_FEAT_FID_ENDURANCE_EVT_CFG: return "Enduarance Event Group Configuration";
+ case NVME_FEAT_FID_ENDURANCE_EVT_CFG: return "Endurance Event Group Configuration";
case NVME_FEAT_FID_IOCS_PROFILE: return "I/O Command Set Profile";
case NVME_FEAT_FID_SPINUP_CONTROL: return "Spinup Control";
case NVME_FEAT_FID_ENH_CTRL_METADATA: return "Enhanced Controller Metadata";
@@ -6488,7 +6556,7 @@ const char *nvme_feature_to_string(enum nvme_features_id feature)
case NVME_FEAT_FID_HOST_ID: return "Host Identifier";
case NVME_FEAT_FID_RESV_MASK: return "Reservation Notification Mask";
case NVME_FEAT_FID_RESV_PERSIST:return "Reservation Persistence";
- case NVME_FEAT_FID_WRITE_PROTECT: return "Namespce Write Protect";
+ case NVME_FEAT_FID_WRITE_PROTECT: return "Namespace Write Protect";
}
/*
* We don't use the "default:" statement to let the compiler warning if
@@ -6637,14 +6705,14 @@ static void nvme_show_auto_pst(struct nvme_feat_auto_pst *apst)
static void nvme_show_timestamp(struct nvme_timestamp *ts)
{
struct tm *tm;
- char buffer[32];
+ char buffer[320];
time_t timestamp = int48_to_long(ts->timestamp) / 1000;
tm = localtime(&timestamp);
- strftime(buffer, sizeof(buffer), "%c %Z", tm);
- printf("\tThe timestamp is : %"PRIu64" (%s)\n",
- int48_to_long(ts->timestamp), buffer);
+ printf("\tThe timestamp is : %'"PRIu64" (%s)\n",
+ int48_to_long(ts->timestamp),
+ strftime(buffer, sizeof(buffer), "%c %Z", tm) ? buffer : "-");
printf("\t%s\n", (ts->attr & 2) ?
"The Timestamp field was initialized with a "\
"Timestamp value using a Set Features command." :
@@ -6726,7 +6794,7 @@ static void nvme_directive_show_fields(__u8 dtype, __u8 doper,
*(__u32 *) (field + 16));
printf("\tStream Granularity Size (in unit of SWS) (SGS): %u\n",
*(__u16 *) (field + 20));
- printf("\tNamespece Streams Allocated (NSA): %u\n",
+ printf("\tNamespace Streams Allocated (NSA): %u\n",
*(__u16 *) (field + 22));
printf("\tNamespace Streams Open (NSO): %u\n",
*(__u16 *) (field + 24));
@@ -6907,7 +6975,8 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un
case NVME_FEAT_FID_LBA_RANGE:
field = result & 0x0000003f;
printf("\tNumber of LBA Ranges (NUM): %u\n", field + 1);
- nvme_show_lba_range((struct nvme_lba_range_type *)buf, field);
+ if (buf)
+ nvme_show_lba_range((struct nvme_lba_range_type *)buf, field);
break;
case NVME_FEAT_FID_TEMP_THRESH:
field = (result & 0x00300000) >> 20;
@@ -6966,14 +7035,17 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un
case NVME_FEAT_FID_AUTO_PST:
printf("\tAutonomous Power State Transition Enable (APSTE): %s\n",
(result & 0x00000001) ? "Enabled":"Disabled");
- nvme_show_auto_pst((struct nvme_feat_auto_pst *)buf);
+ if (buf)
+ nvme_show_auto_pst((struct nvme_feat_auto_pst *)buf);
break;
case NVME_FEAT_FID_HOST_MEM_BUF:
printf("\tEnable Host Memory (EHM): %s\n", (result & 0x00000001) ? "Enabled":"Disabled");
- nvme_show_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf);
+ if (buf)
+ nvme_show_host_mem_buffer((struct nvme_host_mem_buf_attrs *)buf);
break;
case NVME_FEAT_FID_TIMESTAMP:
- nvme_show_timestamp((struct nvme_timestamp *)buf);
+ if (buf)
+ nvme_show_timestamp((struct nvme_timestamp *)buf);
break;
case NVME_FEAT_FID_KATO:
printf("\tKeep Alive Timeout (KATO) in milliseconds: %u\n", result);
@@ -6993,7 +7065,8 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un
break;
case NVME_FEAT_FID_PLM_CONFIG:
printf("\tPredictable Latency Window Enabled: %s\n", result & 0x1 ? "True":"False");
- nvme_show_plm_config((struct nvme_plm_config *)buf);
+ if (buf)
+ nvme_show_plm_config((struct nvme_plm_config *)buf);
break;
case NVME_FEAT_FID_PLM_WINDOW:
printf("\tWindow Select: %s", nvme_plm_window(result));
@@ -7002,7 +7075,8 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un
nvme_show_lba_status_info(result);
break;
case NVME_FEAT_FID_HOST_BEHAVIOR:
- printf("\tHost Behavior Support: %s\n", (buf[0] & 0x1) ? "True" : "False");
+ if (buf)
+ printf("\tHost Behavior Support: %s\n", (buf[0] & 0x1) ? "True" : "False");
break;
case NVME_FEAT_FID_SANITIZE:
printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", result & 0x1);
@@ -7020,16 +7094,19 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un
case NVME_FEAT_FID_ENH_CTRL_METADATA:
case NVME_FEAT_FID_CTRL_METADATA:
case NVME_FEAT_FID_NS_METADATA:
- nvme_show_host_metadata(fid, (struct nvme_host_metadata *)buf);
+ if (buf)
+ nvme_show_host_metadata(fid, (struct nvme_host_metadata *)buf);
break;
case NVME_FEAT_FID_SW_PROGRESS:
printf("\tPre-boot Software Load Count (PBSLC): %u\n", result & 0x000000ff);
break;
case NVME_FEAT_FID_HOST_ID:
- ull = buf[7]; ull <<= 8; ull |= buf[6]; ull <<= 8; ull |= buf[5]; ull <<= 8;
- ull |= buf[4]; ull <<= 8; ull |= buf[3]; ull <<= 8; ull |= buf[2]; ull <<= 8;
- ull |= buf[1]; ull <<= 8; ull |= buf[0];
- printf("\tHost Identifier (HOSTID): %" PRIu64 "\n", ull);
+ if (buf) {
+ ull = buf[7]; ull <<= 8; ull |= buf[6]; ull <<= 8; ull |= buf[5]; ull <<= 8;
+ ull |= buf[4]; ull <<= 8; ull |= buf[3]; ull <<= 8; ull |= buf[2]; ull <<= 8;
+ ull |= buf[1]; ull <<= 8; ull |= buf[0];
+ printf("\tHost Identifier (HOSTID): %" PRIu64 "\n", ull);
+ }
break;
case NVME_FEAT_FID_RESV_MASK:
printf("\tMask Reservation Preempted Notification (RESPRE): %s\n",