From: Tokunori Ikegami <ikegami.t@gmail.com> Date: Thu, 9 Mar 2023 17:42:53 +0000 (+0900) Subject: plugins/ocp: Add support for EOL/PLP failure mode feature X-Git-Tag: v2.4~36 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=7e86bd3acf153afffc2566f76dca1b3efdbb670e;p=users%2Fsagi%2Fnvme-cli.git plugins/ocp: Add support for EOL/PLP failure mode feature Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com> --- diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c index 6b166efe..59ced1cb 100644 --- a/plugins/ocp/ocp-nvme.c +++ b/plugins/ocp/ocp-nvme.c @@ -805,3 +805,140 @@ static int clear_fw_update_history(int argc, char **argv, { return ocp_clear_fw_update_history(argc, argv, cmd, plugin); } + +static const char *eol_plp_failure_mode_to_string(__u8 mode) +{ + switch (mode) { + case 1: + return "Read only mode (ROM)"; + case 2: + return "Write through mode (WTM)"; + case 3: + return "Normal mode"; + default: + break; + } + + return "Reserved"; +} + +static int eol_plp_failure_mode_get(struct nvme_dev *dev, const __u32 nsid, + const __u8 fid, __u8 sel) +{ + __u32 result; + int err; + + struct nvme_get_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = fid, + .nsid = nsid, + .sel = sel, + .cdw11 = 0, + .uuidx = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + + err = nvme_get_features(&args); + if (!err) { + printf("End of Life Behavior (feature: %#0*x): %#0*x (%s: %s)\n", + fid ? 4 : 2, fid, result ? 10 : 8, result, + nvme_select_to_string(sel), + eol_plp_failure_mode_to_string(result)); + if (sel == NVME_GET_FEATURES_SEL_SUPPORTED) + nvme_show_select_result(result); + } else { + printf("Could not get feature: %#0*x.\n", fid ? 4 : 2, fid); + } + + return err; +} + +static int eol_plp_failure_mode_set(struct nvme_dev *dev, const __u32 nsid, + const __u8 fid, __u8 mode, bool save) +{ + __u32 result; + int err; + + struct nvme_set_features_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .fid = fid, + .nsid = nsid, + .cdw11 = mode << 30, + .cdw12 = 0, + .save = save, + .uuidx = 0, + .cdw15 = 0, + .data_len = 0, + .data = NULL, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = &result, + }; + + err = nvme_set_features(&args); + if (err > 0) { + nvme_show_status(err); + } else if (err < 0) { + perror("Define EOL/PLP failure mode"); + fprintf(stderr, "Command failed while parsing.\n"); + } else { + printf("Successfully set mode (feature: %#0*x): %#0*x (%s: %s).\n", + fid ? 4 : 2, fid, mode ? 10 : 8, mode, + save ? "Save" : "Not save", + eol_plp_failure_mode_to_string(mode)); + } + + return err; +} + +static int eol_plp_failure_mode(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + const char *desc = "Define EOL or PLP circuitry failure mode.\n"\ + "No argument prints current mode."; + const char *mode = "[0-3]: default/rom/wtm/normal"; + const char *save = "Specifies that the controller shall save the attribute"; + const char *sel = "[0-3,8]: current/default/saved/supported/changed"; + const __u32 nsid = 0; + const __u8 fid = 0xc2; + struct nvme_dev *dev; + int err; + + struct config { + __u8 mode; + bool save; + __u8 sel; + }; + + struct config cfg = { + .mode = 0, + .save = false, + .sel = 0, + }; + + OPT_ARGS(opts) = { + OPT_BYTE("mode", 'm', &cfg.mode, mode), + OPT_FLAG("save", 's', &cfg.save, save), + OPT_BYTE("sel", 'S', &cfg.sel, sel), + {NULL} + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + + if (err) + return err; + + if (opts[0].seen) + err = eol_plp_failure_mode_set(dev, nsid, fid, cfg.mode, + cfg.save); + else + err = eol_plp_failure_mode_get(dev, nsid, fid, cfg.sel); + + dev_close(dev); + + return err; +} diff --git a/plugins/ocp/ocp-nvme.h b/plugins/ocp/ocp-nvme.h index 16ac750c..fcc54299 100644 --- a/plugins/ocp/ocp-nvme.h +++ b/plugins/ocp/ocp-nvme.h @@ -18,6 +18,7 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", NVME_VERSION), ENTRY("smart-add-log", "Retrieve extended SMART Information", ocp_smart_add_log) ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", ocp_latency_monitor_log) ENTRY("clear-fw-activate-history", "Clear firmware update history log", clear_fw_update_history) + ENTRY("eol-plp-failure-mode", "Define EOL or PLP circuitry failure mode.", eol_plp_failure_mode) ) );