diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-07-26 05:11:40 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2022-07-26 05:18:07 +0000 |
commit | 2e650c1f5f2f79e7db10dec5dcdd1cffcaf47891 (patch) | |
tree | 82f2949088d2502e947b83ba9973de54f9bf4402 /nvme-print.c | |
parent | Releasing debian version 2.0-1. (diff) | |
download | nvme-cli-2e650c1f5f2f79e7db10dec5dcdd1cffcaf47891.tar.xz nvme-cli-2e650c1f5f2f79e7db10dec5dcdd1cffcaf47891.zip |
Merging upstream version 2.1~rc0 (Closes: #1015722).
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nvme-print.c')
-rw-r--r-- | nvme-print.c | 397 |
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(×tamp); - 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", |