From fa7c1db9a078d74b2cf2b77281f1b3b54dec89c5 Mon Sep 17 00:00:00 2001 From: Jeff Lien Date: Tue, 22 Mar 2022 14:47:40 -0500 Subject: [PATCH] nvme: add get_mi_cmd_support_effects_log command Signed-off-by: Jeff Lien --- nvme-builtin.h | 1 + nvme-print.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ nvme-print.h | 2 ++ nvme.c | 49 ++++++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) diff --git a/nvme-builtin.h b/nvme-builtin.h index ab7f8f49..497d712a 100644 --- a/nvme-builtin.h +++ b/nvme-builtin.h @@ -53,6 +53,7 @@ COMMAND_LIST( ENTRY("self-test-log", "Retrieve the SELF-TEST Log, show it", self_test_log) ENTRY("supported-log-pages", "Retrieve the Supported Log pages details, show it", get_supported_log_pages) ENTRY("fid-support-effects-log", "Retrieve FID Support and Effects log and show it", get_fid_support_effects_log) + ENTRY("mi-cmd-support-effects-log", "Retrieve MI Command Support and Effects log and show it", get_mi_cmd_support_effects_log) ENTRY("media-unit-stat-log", "Retrieve the configuration and wear of media units, show it", get_media_unit_stat_log) ENTRY("supported-cap-config-log", "Retrieve the list of Supported Capacity Configuration Descriptors", get_supp_cap_config_log) ENTRY("set-feature", "Set a feature and show the resulting value", set_feature) diff --git a/nvme-print.c b/nvme-print.c index 4cb6f3cc..734f3305 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -2023,6 +2023,82 @@ void nvme_show_fid_support_effects_log(struct nvme_fid_supported_effects_log *fi } } +static void json_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log) +{ + struct json_object *root; + struct json_object *mi_cmds; + struct json_object *mi_cmds_list; + unsigned int mi_cmd; + char key[128]; + __u32 mi_cmd_support; + + root = json_create_object(); + mi_cmds_list = json_create_array(); + for (mi_cmd = 0; mi_cmd < 256; mi_cmd++) { + mi_cmd_support = le32_to_cpu(mi_cmd_log->mi_cmd_support[mi_cmd]); + if (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) { + mi_cmds = json_create_object(); + sprintf(key, "mi_cmd_%u", mi_cmd); + json_object_add_value_uint(mi_cmds, key, mi_cmd_support); + json_array_add_value_object(mi_cmds_list, mi_cmds); + } + } + + json_object_add_value_object(root, "mi_command_support", mi_cmds_list); + json_print_object(root, NULL); + printf("\n"); + + json_free_object(root); +} + +static void nvme_show_mi_cmd_support_effects_log_human(__u32 mi_cmd_support) +{ + const char *set = "+"; + const char *clr = "-"; + __u16 csp; + + printf(" CSUPP+"); + printf(" UDCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_UDCC) ? set : clr); + printf(" NCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NCC) ? set : clr); + printf(" NIC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_NIC) ? set : clr); + printf(" CCC%s", (mi_cmd_support & NVME_MI_CMD_SUPPORTED_EFFECTS_CCC) ? set : clr); + + csp = (mi_cmd_support >> NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_SHIFT) & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_MASK; + + printf(" NAMESPACE SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NS) ? set : clr); + printf(" CONTROLLER SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_CTRL) ? set : clr); + printf(" NVM SET SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NVM_SET) ? set : clr); + printf(" ENDURANCE GROUP SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_ENDGRP) ? set : clr); + printf(" DOMAIN SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_DOMAIN) ? set : clr); + printf(" NVM Subsystem SCOPE%s", (csp & NVME_MI_CMD_SUPPORTED_EFFECTS_SCOPE_NSS) ? set : clr); +} + +void nvme_show_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log, + const char *devname, enum nvme_print_flags flags) +{ + __u32 mi_cmd_effect; + int i, human = flags & VERBOSE; + + if (flags & BINARY) + return d_raw((unsigned char *)mi_cmd_log, sizeof(*mi_cmd_log)); + if (flags & JSON) + return json_mi_cmd_support_effects_log(mi_cmd_log); + + printf("MI Commands Support Effects Log for device: %s\n", devname); + printf("Admin Command Set\n"); + for (i = 0; i < NVME_LOG_MI_CMD_SUPPORTED_EFFECTS_MAX; i++) { + mi_cmd_effect = le32_to_cpu(mi_cmd_log->mi_cmd_support[i]); + if (mi_cmd_effect & NVME_MI_CMD_SUPPORTED_EFFECTS_CSUPP) { + printf("MI CMD %02x -> Support Effects Log: %08x", i, + mi_cmd_effect); + if (human) + nvme_show_mi_cmd_support_effects_log_human(mi_cmd_effect); + else + printf("\n"); + } + } +} + static void json_boot_part_log(void *bp_log) { struct nvme_boot_partition *hdr; diff --git a/nvme-print.h b/nvme-print.h index 94e6fff9..0251f404 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -75,6 +75,8 @@ void nvme_show_boot_part_log(void *bp_log, const char *devname, __u32 size, enum nvme_print_flags flags); void nvme_show_fid_support_effects_log(struct nvme_fid_supported_effects_log *fid_log, const char *devname, enum nvme_print_flags flags); +void nvme_show_mi_cmd_support_effects_log(struct nvme_mi_cmd_supported_effects_log *mi_cmd_log, + const char *devname, enum nvme_print_flags flags); void nvme_show_media_unit_stat_log(struct nvme_media_unit_stat_log *mus, enum nvme_print_flags flags); void nvme_show_supported_cap_config_log(struct nvme_supported_cap_config_list_log *caplog, diff --git a/nvme.c b/nvme.c index cda1c93b..39c006e9 100644 --- a/nvme.c +++ b/nvme.c @@ -1878,6 +1878,55 @@ ret: return err; } +static int get_mi_cmd_support_effects_log(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + const char *desc = "Retrieve NVMe-MI Command Support and Effects log and show it."; + const char *human_readable = "show log in readable format"; + struct nvme_mi_cmd_supported_effects_log mi_cmd_support_log; + enum nvme_print_flags flags; + int fd, err = -1; + + struct config { + char *output_format; + bool human_readable; + }; + + struct config cfg = { + .output_format = "normal", + .human_readable = false, + }; + + OPT_ARGS(opts) = { + OPT_FMT("output-format", 'o', &cfg.output_format, output_format), + OPT_FLAG("human-readable",'H', &cfg.human_readable, human_readable), + OPT_END() + }; + + err = fd = parse_and_open(argc, argv, desc, opts); + if (fd < 0) + goto ret; + + err = flags = validate_output_format(cfg.output_format); + if (flags < 0) + goto close_fd; + if (cfg.human_readable) + flags |= VERBOSE; + + err = nvme_get_log_mi_cmd_supported_effects(fd, false, &mi_cmd_support_log); + if (!err) + nvme_show_mi_cmd_support_effects_log(&mi_cmd_support_log, devicename, flags); + else if (err > 0) + nvme_show_status(err); + else + fprintf(stderr, "mi command support effects log: %s\n", + nvme_strerror(errno)); +close_fd: + close(fd); +ret: + return err; +} + static int list_ctrl(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Show controller list information for the subsystem the "\ -- 2.50.1