From e4ffd65bf12699a03562071624277abbceff65ce Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Wed, 2 Apr 2025 00:18:10 +0900 Subject: [PATCH] plugins: add NVMe feature extension This extension is for adding each features commands to get and set. Signed-off-by: Tokunori Ikegami --- plugins/feat/feat-nvme.c | 108 +++++++++++++++++++++++++++++++++++++++ plugins/feat/feat-nvme.h | 25 +++++++++ plugins/feat/meson.build | 3 ++ plugins/meson.build | 1 + 4 files changed, 137 insertions(+) create mode 100644 plugins/feat/feat-nvme.c create mode 100644 plugins/feat/feat-nvme.h create mode 100644 plugins/feat/meson.build diff --git a/plugins/feat/feat-nvme.c b/plugins/feat/feat-nvme.c new file mode 100644 index 00000000..7f135458 --- /dev/null +++ b/plugins/feat/feat-nvme.c @@ -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 index 00000000..6277300e --- /dev/null +++ b/plugins/feat/feat-nvme.h @@ -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 index 00000000..588b5d23 --- /dev/null +++ b/plugins/feat/meson.build @@ -0,0 +1,3 @@ +sources += [ + 'plugins/feat/feat-nvme.c', +] diff --git a/plugins/meson.build b/plugins/meson.build index e0ac3140..ebefedcb 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -30,6 +30,7 @@ sources += [ 'plugins/zns/zns.c', ] +subdir('feat') subdir('lm') subdir('ocp') -- 2.50.1