From 728d91e52ff1a793a1375f1ef8bfc8fb19cc0c8b Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Tue, 31 Mar 2026 00:40:08 +0900 Subject: [PATCH 1/3] nvme-print: fix nvme_show_cmd_err to pass admin parameter Since previously always use false without the admin value. Signed-off-by: Tokunori Ikegami --- nvme-print.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nvme-print.c b/nvme-print.c index 7a96604d1c..31dff19c28 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -530,7 +530,7 @@ static void nvme_show_cmd_err(const char *msg, bool admin, else if (err < 0) nvme_show_error("%s: %s", msg, nvme_strerror(-err)); else if (cmd) - nvme_show_opcode_status(err, false, cmd->opcode); + nvme_show_opcode_status(err, admin, cmd->opcode); else nvme_show_status(err); } From 4dae9ac84eaaa765d009a44c245f13f789e08b70 Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Tue, 31 Mar 2026 00:41:11 +0900 Subject: [PATCH 2/3] nvme-print: change nvme_show_cmd_err cmd parameter to opcode Since only cmd parameter opcode value used by the print function. Signed-off-by: Tokunori Ikegami --- nvme-print.c | 19 ++++++++----------- nvme-print.h | 6 ++---- nvme.c | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/nvme-print.c b/nvme-print.c index 31dff19c28..8fb8095ac8 100644 --- a/nvme-print.c +++ b/nvme-print.c @@ -522,34 +522,31 @@ void nvme_show_status(int status) ops->show_status(status); } -static void nvme_show_cmd_err(const char *msg, bool admin, - struct nvme_passthru_cmd *cmd, int err) +static void nvme_show_cmd_err(const char *msg, bool admin, __u8 opcode, int err) { if (!err) return; else if (err < 0) nvme_show_error("%s: %s", msg, nvme_strerror(-err)); - else if (cmd) - nvme_show_opcode_status(err, admin, cmd->opcode); + else if (opcode) + nvme_show_opcode_status(err, admin, opcode); else nvme_show_status(err); } void nvme_show_err(const char *msg, int err) { - nvme_show_cmd_err(msg, false, NULL, err); + nvme_show_cmd_err(msg, false, 0, err); } -void nvme_show_io_cmd_err(const char *msg, struct nvme_passthru_cmd *cmd, - int err) +void nvme_show_io_cmd_err(const char *msg, __u8 opcode, int err) { - nvme_show_cmd_err(msg, false, cmd, err); + nvme_show_cmd_err(msg, false, opcode, err); } -void nvme_show_admin_cmd_err(const char *msg, struct nvme_passthru_cmd *cmd, - int err) +void nvme_show_admin_cmd_err(const char *msg, __u8 opcode, int err) { - nvme_show_cmd_err(msg, true, cmd, err); + nvme_show_cmd_err(msg, true, opcode, err); } void nvme_show_opcode_status(int status, bool admin, __u8 opcode) diff --git a/nvme-print.h b/nvme-print.h index dedc7337c2..e075cae1b9 100644 --- a/nvme-print.h +++ b/nvme-print.h @@ -162,10 +162,8 @@ struct print_ops *nvme_get_binary_print_ops(nvme_print_flags_t flags); void nvme_show_status(int status); void nvme_show_err(const char *msg, int err); -void nvme_show_io_cmd_err(const char *msg, struct nvme_passthru_cmd *cmd, - int err); -void nvme_show_admin_cmd_err(const char *msg, struct nvme_passthru_cmd *cmd, - int err); +void nvme_show_io_cmd_err(const char *msg, __u8 opcode, int err); +void nvme_show_admin_cmd_err(const char *msg, __u8 opcode, int err); void nvme_show_opcode_status(int status, bool admin, __u8 opcode); void nvme_show_lba_status_info(__u64 result); void nvme_show_relatives(struct nvme_global_ctx *ctx, const char *name, nvme_print_flags_t flags); diff --git a/nvme.c b/nvme.c index 8a458d8155..9bb9fd71b7 100644 --- a/nvme.c +++ b/nvme.c @@ -5751,7 +5751,7 @@ static int sanitize_ns_cmd(int argc, char **argv, struct command *acmd, } err = nvme_submit_admin_passthru(hdl, &cmd); if (err) { - nvme_show_admin_cmd_err("sanitize ns", &cmd, err); + nvme_show_admin_cmd_err("sanitize ns", cmd.opcode, err); return err; } From e848bfc9bd7d5d65545677444654dc7bb141294c Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Fri, 27 Mar 2026 23:40:50 +0900 Subject: [PATCH 3/3] nvme: add get and set features specific status code string Since the status code is duplicated with the fw-download status code. Signed-off-by: Tokunori Ikegami --- libnvme/src/nvme/types.h | 15 ++++++++++++++ libnvme/src/nvme/util.h | 43 ++++++++++++++++++++++++++++++++++++++-- nvme.c | 3 ++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/libnvme/src/nvme/types.h b/libnvme/src/nvme/types.h index e7e61eb0ca..5eaaccb2bf 100644 --- a/libnvme/src/nvme/types.h +++ b/libnvme/src/nvme/types.h @@ -8215,6 +8215,11 @@ struct nvme_mi_vpd_hdr { * @NVME_SC_NS_INSUFFICIENT_CAP: Namespace Insufficient Capacity: Creating * the namespace requires more free space * than is currently available. + * @NVME_SC_FEAT_IOCS_COMBINATION_REJECTED: Set Features - I/O Command Set + * Combination Rejected: This error indicates + * that the controller did not accept the + * request to select the requested I/O + * Command Set Combination. * @NVME_SC_NS_ID_UNAVAILABLE: Namespace Identifier Unavailable: The * number of namespaces supported has been * exceeded. @@ -8306,6 +8311,10 @@ struct nvme_mi_vpd_hdr { * suspended. * @NVME_SC_CONTROLLER_DATA_QUEUE_FULL: The controller detected that a * Controller Data Queue became full. + * @NVME_SC_INVALID_POWER_LIMIT: Invalid Power Limit: The power limit + * specified for the Power Limit feature is + * invalid because that power limit prohibits + * all operational power states. * @NVME_SC_BAD_ATTRIBUTES: Conflicting Dataset Management Attributes * @NVME_SC_INVALID_PI: Invalid Protection Information * @NVME_SC_READ_ONLY: Attempted Write to Read Only Range @@ -8535,6 +8544,7 @@ enum nvme_status_field { NVME_SC_FW_ACTIVATE_PROHIBITED = 0x13, NVME_SC_OVERLAPPING_RANGE = 0x14, NVME_SC_NS_INSUFFICIENT_CAP = 0x15, + NVME_SC_FEAT_IOCS_COMBINATION_REJECTED = 0x15, NVME_SC_NS_ID_UNAVAILABLE = 0x16, NVME_SC_NS_ALREADY_ATTACHED = 0x18, NVME_SC_NS_IS_PRIVATE = 0x19, @@ -8582,6 +8592,11 @@ enum nvme_status_field { NVME_SC_CONTROLLER_NOT_SUSPENDED = 0x3A, NVME_SC_CONTROLLER_DATA_QUEUE_FULL = 0x3B, + /* + * Command Set Specific - Set Features + */ + NVME_SC_INVALID_POWER_LIMIT = 0x3e, + /* * I/O Command Set Specific - NVM commands: */ diff --git a/libnvme/src/nvme/util.h b/libnvme/src/nvme/util.h index eb75a133bb..90459bb4f3 100644 --- a/libnvme/src/nvme/util.h +++ b/libnvme/src/nvme/util.h @@ -103,6 +103,35 @@ nvme_sanitize_ns_status_to_string(__u16 sc) return NULL; }; +/** + * nvme_set_features_status_to_string() - Returns set features status string. + * @sc: Return status code from an set features command + * + * Return: The set features status string if it is a specific status code. + */ +static inline const char * +nvme_set_features_status_to_string(__u16 sc) +{ + switch (sc) { + case NVME_SC_FEATURE_NOT_SAVEABLE: + case NVME_SC_FEATURE_NOT_CHANGEABLE: + case NVME_SC_FEATURE_NOT_PER_NS: + break; + case NVME_SC_OVERLAPPING_RANGE: + return "Overlapping Range: LBA range type data structure"; + case NVME_SC_FEAT_IOCS_COMBINATION_REJECTED: + return "I/O Command Set Combination Rejected"; + case NVME_SC_INVALID_CONTROLER_DATA_QUEUE: + break; + case NVME_SC_INVALID_POWER_LIMIT: + return "Invalid Power Limit"; + default: + break; + } + + return NULL; +}; + /** * nvme_opcode_status_to_string() - Returns nvme opcode status string. * @status: Return status from an nvme passthrough command @@ -120,8 +149,18 @@ nvme_opcode_status_to_string(int status, bool admin, __u8 opcode) const char *s = NULL; if (status >= 0 && sct == NVME_SCT_CMD_SPECIFIC) { - if (admin && opcode == nvme_admin_sanitize_ns) - s = nvme_sanitize_ns_status_to_string(sc); + if (admin) { + switch (opcode) { + case nvme_admin_sanitize_ns: + s = nvme_sanitize_ns_status_to_string(sc); + break; + case nvme_admin_set_features: + s = nvme_set_features_status_to_string(sc); + break; + default: + break; + } + } } if (s) diff --git a/nvme.c b/nvme.c index 9bb9fd71b7..f5fa09646e 100644 --- a/nvme.c +++ b/nvme.c @@ -6995,7 +6995,8 @@ static int set_feature(int argc, char **argv, struct command *acmd, struct plugi err = nvme_set_features(hdl, cfg.nsid, cfg.fid, cfg.sv, cfg.value, cfg.cdw12, 0, cfg.uidx, 0, buf, cfg.data_len, &result); if (err) { - nvme_show_err("set-feature", err); + nvme_show_admin_cmd_err("set-feature", nvme_admin_set_features, + err); return err; }