From 04b3c8c0025a1d91a0e133e9b2734a002960f472 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Mon, 21 Nov 2022 21:26:02 -0600 Subject: scsi: sd: Convert SCSI errors to PR errors This converts the SCSI errors we commonly see during PR handling to PR_STS errors or -Exyz errors. pr_ops callers can then handle SCSI and NVMe errors without knowing the device types. Signed-off-by: Mike Christie Link: https://lore.kernel.org/r/20221122032603.32766-4-michael.christie@oracle.com Reviewed-by: Christoph Hellwig Reviewed-by: Chaitanya Kulkarni Signed-off-by: Martin K. Petersen --- drivers/scsi/sd.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'drivers/scsi') diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index faa2b55d1a21..47dafe6b8a66 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1709,6 +1709,36 @@ static char sd_pr_type(enum pr_type type) } }; +static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result) +{ + switch (host_byte(result)) { + case DID_TRANSPORT_MARGINAL: + case DID_TRANSPORT_DISRUPTED: + case DID_BUS_BUSY: + return PR_STS_RETRY_PATH_FAILURE; + case DID_NO_CONNECT: + return PR_STS_PATH_FAILED; + case DID_TRANSPORT_FAILFAST: + return PR_STS_PATH_FAST_FAILED; + } + + switch (status_byte(result)) { + case SAM_STAT_RESERVATION_CONFLICT: + return PR_STS_RESERVATION_CONFLICT; + case SAM_STAT_CHECK_CONDITION: + if (!scsi_sense_valid(sshdr)) + return PR_STS_IOERR; + + if (sshdr->sense_key == ILLEGAL_REQUEST && + (sshdr->asc == 0x26 || sshdr->asc == 0x24)) + return -EINVAL; + + fallthrough; + default: + return PR_STS_IOERR; + } +} + static int sd_pr_command(struct block_device *bdev, u8 sa, u64 key, u64 sa_key, u8 type, u8 flags) { @@ -1737,7 +1767,10 @@ static int sd_pr_command(struct block_device *bdev, u8 sa, scsi_print_sense_hdr(sdev, NULL, &sshdr); } - return result; + if (result <= 0) + return result; + + return sd_scsi_to_pr_err(&sshdr, result); } static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key, -- cgit v1.2.3