mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 04:02:20 +00:00
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 <michael.christie@oracle.com> Link: https://lore.kernel.org/r/20221122032603.32766-4-michael.christie@oracle.com Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
c9293c1199
commit
04b3c8c002
@ -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,
|
||||
|
@ -121,6 +121,7 @@ enum scsi_disposition {
|
||||
* msg_byte (unused)
|
||||
* host_byte = set by low-level driver to indicate status.
|
||||
*/
|
||||
#define status_byte(result) (result & 0xff)
|
||||
#define host_byte(result) (((result) >> 16) & 0xff)
|
||||
|
||||
#define sense_class(sense) (((sense) >> 4) & 0x7)
|
||||
|
Loading…
Reference in New Issue
Block a user