]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins: add NVMe feature extension
authorTokunori Ikegami <ikegami.t@gmail.com>
Tue, 1 Apr 2025 15:18:10 +0000 (00:18 +0900)
committerDaniel Wagner <wagi@monom.org>
Wed, 2 Apr 2025 07:15:07 +0000 (07:15 +0000)
This extension is for adding each features commands to get and set.

Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
plugins/feat/feat-nvme.c [new file with mode: 0644]
plugins/feat/feat-nvme.h [new file with mode: 0644]
plugins/feat/meson.build [new file with mode: 0644]
plugins/meson.build

diff --git a/plugins/feat/feat-nvme.c b/plugins/feat/feat-nvme.c
new file mode 100644 (file)
index 0000000..7f13545
--- /dev/null
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include "nvme.h"
+#include "plugin.h"
+#include "nvme-print.h"
+
+#define CREATE_CMD
+#include "feat-nvme.h"
+
+static const char *power_mgmt_feat = "power management feature";
+static const char *sel = "[0-3]: current/default/saved/supported";
+static const char *save = "Specifies that the controller shall save the attribute";
+
+static int power_mgmt_get(struct nvme_dev *dev, 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,
+               .sel            = sel,
+               .timeout        = NVME_DEFAULT_IOCTL_TIMEOUT,
+               .result         = &result,
+       };
+
+       err = nvme_get_features(&args);
+       if (!err) {
+               if (NVME_CHECK(sel, GET_FEATURES_SEL, SUPPORTED))
+                       nvme_show_select_result(fid, result);
+               else
+                       nvme_feature_show_fields(fid, result, NULL);
+       } else {
+               nvme_show_error("Get %s", power_mgmt_feat);
+       }
+
+       return err;
+}
+
+static int power_mgmt_set(struct nvme_dev *dev, const __u8 fid, __u8 ps, __u8 wh, bool save)
+{
+       __u32 result;
+       int err;
+
+       struct nvme_set_features_args args = {
+               .args_size = sizeof(args),
+               .fd = dev_fd(dev),
+               .fid = fid,
+               .cdw11 = NVME_SET(ps, FEAT_PWRMGMT_PS) | NVME_SET(wh, FEAT_PWRMGMT_WH),
+               .save = save,
+               .timeout = NVME_DEFAULT_IOCTL_TIMEOUT,
+               .result = &result,
+       };
+
+       err = nvme_set_features(&args);
+
+       nvme_show_init();
+
+       if (err > 0) {
+               nvme_show_status(err);
+       } else if (err < 0) {
+               nvme_show_perror("Set %s", power_mgmt_feat);
+       } else {
+               nvme_show_result("Set %s: 0x%04x (%s)", power_mgmt_feat, args.cdw11,
+                                save ? "Save" : "Not save");
+               nvme_feature_show_fields(fid, args.cdw11, NULL);
+       }
+
+       nvme_show_finish();
+
+       return err;
+}
+
+static int feat_power_mgmt(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+       const char *ps = "power state";
+       const char *wh = "workload hint";
+       const __u8 fid = NVME_FEAT_FID_POWER_MGMT;
+
+       _cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
+       int err;
+
+       struct config {
+               __u8 ps;
+               __u8 wh;
+               bool save;
+               __u8 sel;
+       };
+
+       struct config cfg = { 0 };
+
+       NVME_ARGS(opts,
+                 OPT_BYTE("ps", 'p', &cfg.ps, ps),
+                 OPT_BYTE("wh", 'w', &cfg.wh, wh),
+                 OPT_FLAG("save", 's', &cfg.save, save),
+                 OPT_BYTE("sel", 'S', &cfg.sel, sel));
+
+       err = parse_and_open(&dev, argc, argv, POWER_MGMT_DESC, opts);
+       if (err)
+               return err;
+
+       if (argconfig_parse_seen(opts, "ps"))
+               err = power_mgmt_set(dev, fid, cfg.ps, cfg.wh, cfg.save);
+       else
+               err = power_mgmt_get(dev, fid, cfg.sel);
+
+       return err;
+}
diff --git a/plugins/feat/feat-nvme.h b/plugins/feat/feat-nvme.h
new file mode 100644 (file)
index 0000000..6277300
--- /dev/null
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include "cmd.h"
+
+#undef CMD_INC_FILE
+#define CMD_INC_FILE plugins/feat/feat-nvme
+
+#include "define_cmd.h"
+
+#if !defined(FEAT_NVME) || defined(CMD_HEADER_MULTI_READ)
+#define FEAT_NVME
+
+#define FEAT_PLUGIN_VERSION "1.0"
+#define POWER_MGMT_DESC "Get and set power management feature"
+
+PLUGIN(NAME("feat", "NVMe feature extensions", FEAT_PLUGIN_VERSION),
+       COMMAND_LIST(
+               ENTRY("power-mgmt", POWER_MGMT_DESC, feat_power_mgmt)
+       )
+);
+#endif /* !FEAT_NVME || CMD_HEADER_MULTI_READ */
+
+#ifndef FEAT_NVME_H
+#define FEAT_NVME_H
+
+#endif /* FEAT_NVME_H */
diff --git a/plugins/feat/meson.build b/plugins/feat/meson.build
new file mode 100644 (file)
index 0000000..588b5d2
--- /dev/null
@@ -0,0 +1,3 @@
+sources += [
+  'plugins/feat/feat-nvme.c',
+]
index e0ac31404a4149fcdd1fcd11b6a2b081f29b6a9f..ebefedcb7a7138aa9e49cc61b63ed48bed49501c 100644 (file)
@@ -30,6 +30,7 @@ sources += [
   'plugins/zns/zns.c',
 ]
 
+subdir('feat')
 subdir('lm')
 subdir('ocp')