]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/ocp: Add support for EOL/PLP failure mode feature
authorTokunori Ikegami <ikegami.t@gmail.com>
Thu, 9 Mar 2023 17:42:53 +0000 (02:42 +0900)
committerDaniel Wagner <wagi@monom.org>
Wed, 15 Mar 2023 07:24:35 +0000 (08:24 +0100)
Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
plugins/ocp/ocp-nvme.c
plugins/ocp/ocp-nvme.h

index 6b166efe450fc0c42b60548fa7b62fc621198b59..59ced1cbf30aa6f19b321a491236048f7a7adc7b 100644 (file)
@@ -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;
+}
index 16ac750c9ceb36894dcf9656b8f962b2ebbd554d..fcc542990a85ea7b41b82443e94b354fa7c6f5f6 100644 (file)
@@ -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)
        )
 );