2025-02-16 11:09:01 +01:00
|
|
|
#include <linux/types.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "nvme.h"
|
|
|
|
#include "nvme-status.h"
|
|
|
|
|
|
|
|
static inline __u8 nvme_generic_status_to_errno(__u16 status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case NVME_SC_INVALID_OPCODE:
|
|
|
|
case NVME_SC_INVALID_FIELD:
|
|
|
|
case NVME_SC_INVALID_NS:
|
|
|
|
case NVME_SC_SGL_INVALID_LAST:
|
|
|
|
case NVME_SC_SGL_INVALID_COUNT:
|
|
|
|
case NVME_SC_SGL_INVALID_DATA:
|
|
|
|
case NVME_SC_SGL_INVALID_METADATA:
|
|
|
|
case NVME_SC_SGL_INVALID_TYPE:
|
|
|
|
case NVME_SC_SGL_INVALID_OFFSET:
|
|
|
|
case NVME_SC_CMB_INVALID_USE:
|
|
|
|
case NVME_SC_PRP_INVALID_OFFSET:
|
|
|
|
return EINVAL;
|
|
|
|
case NVME_SC_CMDID_CONFLICT:
|
|
|
|
return EADDRINUSE;
|
|
|
|
case NVME_SC_DATA_XFER_ERROR:
|
|
|
|
case NVME_SC_INTERNAL:
|
|
|
|
case NVME_SC_SANITIZE_FAILED:
|
|
|
|
return EIO;
|
|
|
|
case NVME_SC_POWER_LOSS:
|
|
|
|
case NVME_SC_ABORT_REQ:
|
|
|
|
case NVME_SC_ABORT_QUEUE:
|
|
|
|
case NVME_SC_FUSED_FAIL:
|
|
|
|
case NVME_SC_FUSED_MISSING:
|
|
|
|
return EWOULDBLOCK;
|
|
|
|
case NVME_SC_CMD_SEQ_ERROR:
|
|
|
|
return EILSEQ;
|
|
|
|
case NVME_SC_SANITIZE_IN_PROGRESS:
|
|
|
|
case NVME_SC_FORMAT_IN_PROGRESS:
|
|
|
|
return EINPROGRESS;
|
|
|
|
case NVME_SC_NS_WRITE_PROTECTED:
|
|
|
|
case NVME_SC_NS_NOT_READY:
|
|
|
|
case NVME_SC_RESERVATION_CONFLICT:
|
|
|
|
return EACCES;
|
|
|
|
case NVME_SC_LBA_RANGE:
|
|
|
|
return EREMOTEIO;
|
|
|
|
case NVME_SC_CAP_EXCEEDED:
|
|
|
|
return ENOSPC;
|
|
|
|
case NVME_SC_OPERATION_DENIED:
|
|
|
|
return EPERM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline __u8 nvme_cmd_specific_status_to_errno(__u16 status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case NVME_SC_CQ_INVALID:
|
|
|
|
case NVME_SC_QID_INVALID:
|
|
|
|
case NVME_SC_QUEUE_SIZE:
|
|
|
|
case NVME_SC_FIRMWARE_SLOT:
|
|
|
|
case NVME_SC_FIRMWARE_IMAGE:
|
|
|
|
case NVME_SC_INVALID_VECTOR:
|
|
|
|
case NVME_SC_INVALID_LOG_PAGE:
|
|
|
|
case NVME_SC_INVALID_FORMAT:
|
|
|
|
case NVME_SC_INVALID_QUEUE:
|
|
|
|
case NVME_SC_NS_INSUFFICIENT_CAP:
|
|
|
|
case NVME_SC_NS_ID_UNAVAILABLE:
|
|
|
|
case NVME_SC_CTRL_LIST_INVALID:
|
|
|
|
case NVME_SC_BAD_ATTRIBUTES:
|
|
|
|
case NVME_SC_INVALID_PI:
|
|
|
|
case NVME_SC_INVALID_CTRL_ID:
|
|
|
|
case NVME_SC_INVALID_SECONDARY_CTRL_STATE:
|
|
|
|
case NVME_SC_INVALID_NUM_CTRL_RESOURCE:
|
|
|
|
case NVME_SC_INVALID_RESOURCE_ID:
|
|
|
|
case NVME_SC_ANA_INVALID_GROUP_ID:
|
|
|
|
return EINVAL;
|
|
|
|
case NVME_SC_ABORT_LIMIT:
|
|
|
|
case NVME_SC_ASYNC_LIMIT:
|
|
|
|
return EDQUOT;
|
|
|
|
case NVME_SC_FW_NEEDS_CONV_RESET:
|
|
|
|
case NVME_SC_FW_NEEDS_SUBSYS_RESET:
|
|
|
|
case NVME_SC_FW_NEEDS_MAX_TIME:
|
|
|
|
return ERESTART;
|
|
|
|
case NVME_SC_FEATURE_NOT_SAVEABLE:
|
|
|
|
case NVME_SC_FEATURE_NOT_CHANGEABLE:
|
|
|
|
case NVME_SC_FEATURE_NOT_PER_NS:
|
|
|
|
case NVME_SC_FW_ACTIVATE_PROHIBITED:
|
|
|
|
case NVME_SC_NS_IS_PRIVATE:
|
|
|
|
case NVME_SC_BP_WRITE_PROHIBITED:
|
|
|
|
case NVME_SC_READ_ONLY:
|
|
|
|
case NVME_SC_PMR_SAN_PROHIBITED:
|
|
|
|
return EPERM;
|
|
|
|
case NVME_SC_OVERLAPPING_RANGE:
|
|
|
|
case NVME_SC_NS_NOT_ATTACHED:
|
|
|
|
return ENOSPC;
|
|
|
|
case NVME_SC_NS_ALREADY_ATTACHED:
|
|
|
|
return EALREADY;
|
|
|
|
case NVME_SC_THIN_PROV_NOT_SUPP:
|
|
|
|
return EOPNOTSUPP;
|
|
|
|
case NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS:
|
|
|
|
return EINPROGRESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline __u8 nvme_fabrics_status_to_errno(__u16 status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case NVME_SC_CONNECT_FORMAT:
|
|
|
|
case NVME_SC_CONNECT_INVALID_PARAM:
|
|
|
|
return EINVAL;
|
|
|
|
case NVME_SC_CONNECT_CTRL_BUSY:
|
|
|
|
return EBUSY;
|
|
|
|
case NVME_SC_CONNECT_RESTART_DISC:
|
|
|
|
return ERESTART;
|
|
|
|
case NVME_SC_CONNECT_INVALID_HOST:
|
|
|
|
return ECONNREFUSED;
|
|
|
|
case NVME_SC_DISCOVERY_RESTART:
|
|
|
|
return EAGAIN;
|
|
|
|
case NVME_SC_AUTH_REQUIRED:
|
|
|
|
return EPERM;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EIO;
|
|
|
|
}
|
|
|
|
|
2025-02-16 11:31:10 +01:00
|
|
|
static inline __u8 nvme_path_status_to_errno(__u16 status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case NVME_SC_INTERNAL_PATH_ERROR:
|
|
|
|
case NVME_SC_ANA_PERSISTENT_LOSS:
|
|
|
|
case NVME_SC_ANA_INACCESSIBLE:
|
|
|
|
case NVME_SC_ANA_TRANSITION:
|
|
|
|
case NVME_SC_CTRL_PATHING_ERROR:
|
|
|
|
case NVME_SC_HOST_PATHING_ERROR:
|
|
|
|
case NVME_SC_HOST_CMD_ABORT:
|
|
|
|
return EACCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EIO;
|
|
|
|
}
|
|
|
|
|
2025-02-16 11:09:01 +01:00
|
|
|
/*
|
|
|
|
* nvme_status_to_errno - It converts given status to errno mapped
|
|
|
|
* @status: >= 0 for nvme status field in completion queue entry,
|
|
|
|
* < 0 for linux internal errors
|
|
|
|
* @fabrics: true if given status is for fabrics
|
|
|
|
*
|
|
|
|
* Notes: This function will convert a given status to an errno mapped
|
|
|
|
*/
|
|
|
|
__u8 nvme_status_to_errno(int status, bool fabrics)
|
|
|
|
{
|
|
|
|
__u8 sct;
|
|
|
|
|
|
|
|
if (!status)
|
|
|
|
return 0;
|
|
|
|
|
2025-02-16 11:31:10 +01:00
|
|
|
if (status < 0) {
|
|
|
|
if (errno)
|
|
|
|
return errno;
|
|
|
|
return status;
|
|
|
|
}
|
2025-02-16 11:09:01 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* The actual status code is enough with masking 0xff, but we need to
|
|
|
|
* cover status code type which is 3bits with 0x7ff.
|
|
|
|
*/
|
|
|
|
status &= 0x7ff;
|
|
|
|
|
|
|
|
sct = nvme_status_type(status);
|
2025-02-16 11:31:10 +01:00
|
|
|
switch (sct) {
|
|
|
|
case NVME_SCT_GENERIC:
|
2025-02-16 11:09:01 +01:00
|
|
|
return nvme_generic_status_to_errno(status);
|
2025-02-16 11:31:10 +01:00
|
|
|
case NVME_SCT_CMD_SPECIFIC:
|
|
|
|
if (!fabrics) {
|
|
|
|
return nvme_cmd_specific_status_to_errno(status);
|
|
|
|
}
|
2025-02-16 11:09:01 +01:00
|
|
|
return nvme_fabrics_status_to_errno(status);
|
2025-02-16 11:31:10 +01:00
|
|
|
case NVME_SCT_PATH:
|
|
|
|
return nvme_path_status_to_errno(status);
|
|
|
|
}
|
2025-02-16 11:09:01 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Media, integrity related status, and the others will be mapped to
|
|
|
|
* EIO.
|
|
|
|
*/
|
|
|
|
return EIO;
|
|
|
|
}
|