Skip to content

Commit 04b3c8c

Browse files
mikechristiemartinkpetersen
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Chaitanya Kulkarni <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent c9293c1 commit 04b3c8c

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

drivers/scsi/sd.c

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1709,6 +1709,36 @@ static char sd_pr_type(enum pr_type type)
17091709
}
17101710
};
17111711

1712+
static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result)
1713+
{
1714+
switch (host_byte(result)) {
1715+
case DID_TRANSPORT_MARGINAL:
1716+
case DID_TRANSPORT_DISRUPTED:
1717+
case DID_BUS_BUSY:
1718+
return PR_STS_RETRY_PATH_FAILURE;
1719+
case DID_NO_CONNECT:
1720+
return PR_STS_PATH_FAILED;
1721+
case DID_TRANSPORT_FAILFAST:
1722+
return PR_STS_PATH_FAST_FAILED;
1723+
}
1724+
1725+
switch (status_byte(result)) {
1726+
case SAM_STAT_RESERVATION_CONFLICT:
1727+
return PR_STS_RESERVATION_CONFLICT;
1728+
case SAM_STAT_CHECK_CONDITION:
1729+
if (!scsi_sense_valid(sshdr))
1730+
return PR_STS_IOERR;
1731+
1732+
if (sshdr->sense_key == ILLEGAL_REQUEST &&
1733+
(sshdr->asc == 0x26 || sshdr->asc == 0x24))
1734+
return -EINVAL;
1735+
1736+
fallthrough;
1737+
default:
1738+
return PR_STS_IOERR;
1739+
}
1740+
}
1741+
17121742
static int sd_pr_command(struct block_device *bdev, u8 sa,
17131743
u64 key, u64 sa_key, u8 type, u8 flags)
17141744
{
@@ -1737,7 +1767,10 @@ static int sd_pr_command(struct block_device *bdev, u8 sa,
17371767
scsi_print_sense_hdr(sdev, NULL, &sshdr);
17381768
}
17391769

1740-
return result;
1770+
if (result <= 0)
1771+
return result;
1772+
1773+
return sd_scsi_to_pr_err(&sshdr, result);
17411774
}
17421775

17431776
static int sd_pr_register(struct block_device *bdev, u64 old_key, u64 new_key,

include/scsi/scsi.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ enum scsi_disposition {
121121
* msg_byte (unused)
122122
* host_byte = set by low-level driver to indicate status.
123123
*/
124+
#define status_byte(result) (result & 0xff)
124125
#define host_byte(result) (((result) >> 16) & 0xff)
125126

126127
#define sense_class(sense) (((sense) >> 4) & 0x7)

0 commit comments

Comments
 (0)