Blame nvme-status.c

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