Commit 04b3c8c0 authored by Mike Christie's avatar Mike Christie Committed by Martin K. Petersen

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: default avatarMike Christie <michael.christie@oracle.com>
Link: https://lore.kernel.org/r/20221122032603.32766-4-michael.christie@oracle.comReviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarChaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent c9293c11
...@@ -1709,6 +1709,36 @@ static char sd_pr_type(enum pr_type type) ...@@ -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, static int sd_pr_command(struct block_device *bdev, u8 sa,
u64 key, u64 sa_key, u8 type, u8 flags) u64 key, u64 sa_key, u8 type, u8 flags)
{ {
...@@ -1737,7 +1767,10 @@ static int sd_pr_command(struct block_device *bdev, u8 sa, ...@@ -1737,7 +1767,10 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
scsi_print_sense_hdr(sdev, NULL, &sshdr); 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, static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,
......
...@@ -121,6 +121,7 @@ enum scsi_disposition { ...@@ -121,6 +121,7 @@ enum scsi_disposition {
* msg_byte (unused) * msg_byte (unused)
* host_byte = set by low-level driver to indicate status. * host_byte = set by low-level driver to indicate status.
*/ */
#define status_byte(result) (result & 0xff)
#define host_byte(result) (((result) >> 16) & 0xff) #define host_byte(result) (((result) >> 16) & 0xff)
#define sense_class(sense) (((sense) >> 4) & 0x7) #define sense_class(sense) (((sense) >> 4) & 0x7)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment