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-print.c b/nvme-print.c index 7a96604d1c..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, false, 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..f5fa09646e 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; } @@ -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; }