From b1567901d9b7df723035e765174ee3f5bcd1494f Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Fri, 21 May 2021 02:40:07 +0900 Subject: [PATCH] nvme: split get_feature to get multiple feature ids Signed-off-by: Tokunori Ikegami --- nvme-print.c | 6 +-- nvme.c | 129 +++++++++++++++++++++++++++++---------------------- 2 files changed, 76 insertions(+), 59 deletions(-) diff --git a/nvme-print.c b/nvme-print.c index 5b5bc4a3..cb7a2675 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -5660,7 +5660,7 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un case NVME_FEAT_FID_ENDURANCE_EVT_CFG: printf("\tEndurance Group Identifier (ENDGID): %u\n", result & 0xffff); printf("\tEndurance Group Critical Warnings : %u\n", (result >> 16) & 0xff); - break; + break; case NVME_FEAT_FID_IOCS_PROFILE: printf("\tI/O Command Set Profile: %s\n", result & 0x1 ? "True":"False"); break; @@ -5704,8 +5704,8 @@ void nvme_feature_show_fields(enum nvme_features_id fid, unsigned int result, un printf("\tHost Behavior Support: %s\n", (buf[0] & 0x1) ? "True" : "False"); break; case NVME_FEAT_FID_SANITIZE: - printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", result & 0x1); - break; + printf("\tNo-Deallocate Response Mode (NODRM) : %u\n", result & 0x1); + break; case NVME_FEAT_FID_RRL: printf("\tRead Recovery Level (RRL): %u\n", result & 0xf); break; diff --git a/nvme.c b/nvme.c index f40b47e6..dae44ad7 100644 --- a/nvme.c +++ b/nvme.c @@ -61,6 +61,17 @@ #define CREATE_CMD #include "nvme-builtin.h" +struct feat_cfg { + enum nvme_features_id feature_id; + __u32 namespace_id; + enum nvme_get_features_sel sel; + __u32 cdw11; + __u8 uuid_index; + __u32 data_len; + int raw_binary; + int human_readable; +}; + static struct stat nvme_stat; const char *devicename; @@ -2703,6 +2714,60 @@ ret: return nvme_status_to_errno(err, false); } +static int get_feature_id(int fd, struct feat_cfg cfg) +{ + int err; + __u32 result; + void *buf = NULL; + + nvme_get_feature_length(cfg.feature_id, cfg.cdw11, &cfg.data_len); + + /* check for Extended Host Identifier */ + if (cfg.feature_id == NVME_FEAT_FID_HOST_ID && (cfg.cdw11 & 0x1)) + cfg.data_len = 16; + + if (cfg.sel == 3) + cfg.data_len = 0; + + if (cfg.data_len) { + if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { + fprintf(stderr, "can not allocate feature payload\n"); + errno = ENOMEM; + return -1; + } + memset(buf, 0, cfg.data_len); + } + + err = nvme_get_features(fd, cfg.feature_id, cfg.namespace_id, cfg.sel, + cfg.cdw11, cfg.uuid_index, cfg.data_len, buf, + &result); + if (!err) { + if (!cfg.raw_binary || !buf) { + printf("get-feature:%#0*x (%s), %s value:%#0*x\n", + cfg.feature_id ? 4 : 2, cfg.feature_id, + nvme_feature_to_string(cfg.feature_id), + nvme_select_to_string(cfg.sel), result ? 10 : 8, + result); + if (cfg.sel == 3) + nvme_show_select_result(result); + else if (cfg.human_readable) + nvme_feature_show_fields(cfg.feature_id, result, + buf); + else if (buf) + d(buf, cfg.data_len, 16, 1); + } else if (buf) + d_raw(buf, cfg.data_len); + } else if (err > 0) { + nvme_show_status(err); + } else { + perror("get-feature"); + } + + free(buf); + + return err; +} + static int get_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin) { const char *desc = "Read operating parameters of the "\ @@ -2715,31 +2780,19 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin "are vendor-specific and not changeable. Use set-feature to "\ "change saveable Features."; const char *raw = "show feature in binary format"; - const char *namespace_id = "identifier of desired namespace"; const char *feature_id = "feature identifier"; + const char *namespace_id = "identifier of desired namespace"; const char *sel = "[0-3]: current/default/saved/supported"; const char *data_len = "buffer len if data is returned through host memory buffer"; const char *cdw11 = "dword 11 for interrupt vector config"; const char *human_readable = "show feature in readable format"; const char *uuid_index = "specify uuid index"; - int err, fd; - __u32 result; - void *buf = NULL; - - struct config { - __u32 namespace_id; - __u8 feature_id; - __u8 sel; - __u32 cdw11; - __u8 uuid_index; - __u32 data_len; - int raw_binary; - int human_readable; - }; + int err; + int fd; - struct config cfg = { - .namespace_id = 0, + struct feat_cfg cfg = { .feature_id = 0, + .namespace_id = 0, .sel = 0, .cdw11 = 0, .uuid_index = 0, @@ -2747,8 +2800,8 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin }; OPT_ARGS(opts) = { - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), OPT_BYTE("feature-id", 'f', &cfg.feature_id, feature_id), + OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id), OPT_BYTE("sel", 's', &cfg.sel, sel), OPT_UINT("data-len", 'l', &cfg.data_len, data_len), OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw), @@ -2779,6 +2832,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin err = -EINVAL; goto close_fd; } + if (!cfg.feature_id) { fprintf(stderr, "feature-id required param\n"); err = -EINVAL; @@ -2792,44 +2846,7 @@ static int get_feature(int argc, char **argv, struct command *cmd, struct plugin goto close_fd; } - nvme_get_feature_length(cfg.feature_id, cfg.cdw11, &cfg.data_len); - - if (cfg.sel == 3) - cfg.data_len = 0; - - if (cfg.data_len) { - if (posix_memalign(&buf, getpagesize(), cfg.data_len)) { - fprintf(stderr, "can not allocate feature payload\n"); - err = -ENOMEM; - goto close_fd; - } - memset(buf, 0, cfg.data_len); - } - - err = nvme_get_features(fd, cfg.feature_id, cfg.namespace_id, cfg.sel, - cfg.cdw11, cfg.uuid_index, cfg.data_len, - buf, &result); - if (!err) { - if (!cfg.raw_binary || !buf) { - printf("get-feature:%#0*x (%s), %s value:%#0*x\n", - cfg.feature_id ? 4 : 2, cfg.feature_id, - nvme_feature_to_string(cfg.feature_id), - nvme_select_to_string(cfg.sel), result ? 10 : 8, - result); - if (cfg.sel == 3) - nvme_show_select_result(result); - else if (cfg.human_readable) - nvme_feature_show_fields(cfg.feature_id, result, buf); - else if (buf) - d(buf, cfg.data_len, 16, 1); - } else if (buf) - d_raw(buf, cfg.data_len); - } else if (err > 0) { - nvme_show_status(err); - } else - perror("get-feature"); - - free(buf); + err = get_feature_id(fd, cfg); close_fd: close(fd); -- 2.50.1