scsi: core: Have midlayer retry scsi_probe_lun() errors
This has scsi_probe_lun() ask the SCSI midlayer to retry UAs instead of driving them itself. Signed-off-by: Mike Christie <michael.christie@oracle.com> Link: https://lore.kernel.org/r/20240123002220.129141-3-michael.christie@oracle.com Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
994724e6b3
commit
2a1f96f60a
@ -626,6 +626,7 @@ void scsi_sanitize_inquiry_string(unsigned char *s, int len)
|
||||
}
|
||||
EXPORT_SYMBOL(scsi_sanitize_inquiry_string);
|
||||
|
||||
|
||||
/**
|
||||
* scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
|
||||
* @sdev: scsi_device to probe
|
||||
@ -647,10 +648,32 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
int first_inquiry_len, try_inquiry_len, next_inquiry_len;
|
||||
int response_len = 0;
|
||||
int pass, count, result, resid;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
struct scsi_failure failure_defs[] = {
|
||||
/*
|
||||
* not-ready to ready transition [asc/ascq=0x28/0x0] or
|
||||
* power-on, reset [asc/ascq=0x29/0x0], continue. INQUIRY
|
||||
* should not yield UNIT_ATTENTION but many buggy devices do
|
||||
* so anyway.
|
||||
*/
|
||||
{
|
||||
.sense = UNIT_ATTENTION,
|
||||
.asc = 0x28,
|
||||
.result = SAM_STAT_CHECK_CONDITION,
|
||||
},
|
||||
{
|
||||
.sense = UNIT_ATTENTION,
|
||||
.asc = 0x29,
|
||||
.result = SAM_STAT_CHECK_CONDITION,
|
||||
},
|
||||
{}
|
||||
};
|
||||
struct scsi_failures failures = {
|
||||
.total_allowed = 3,
|
||||
.failure_definitions = failure_defs,
|
||||
};
|
||||
const struct scsi_exec_args exec_args = {
|
||||
.sshdr = &sshdr,
|
||||
.resid = &resid,
|
||||
.failures = &failures,
|
||||
};
|
||||
|
||||
*bflags = 0;
|
||||
@ -668,6 +691,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
pass, try_inquiry_len));
|
||||
|
||||
/* Each pass gets up to three chances to ignore Unit Attention */
|
||||
scsi_failures_reset_retries(&failures);
|
||||
|
||||
for (count = 0; count < 3; ++count) {
|
||||
memset(scsi_cmd, 0, 6);
|
||||
scsi_cmd[0] = INQUIRY;
|
||||
@ -684,22 +709,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
|
||||
"scsi scan: INQUIRY %s with code 0x%x\n",
|
||||
result ? "failed" : "successful", result));
|
||||
|
||||
if (result > 0) {
|
||||
/*
|
||||
* not-ready to ready transition [asc/ascq=0x28/0x0]
|
||||
* or power-on, reset [asc/ascq=0x29/0x0], continue.
|
||||
* INQUIRY should not yield UNIT_ATTENTION
|
||||
* but many buggy devices do so anyway.
|
||||
*/
|
||||
if (scsi_status_is_check_condition(result) &&
|
||||
scsi_sense_valid(&sshdr)) {
|
||||
if ((sshdr.sense_key == UNIT_ATTENTION) &&
|
||||
((sshdr.asc == 0x28) ||
|
||||
(sshdr.asc == 0x29)) &&
|
||||
(sshdr.ascq == 0))
|
||||
continue;
|
||||
}
|
||||
} else if (result == 0) {
|
||||
if (result == 0) {
|
||||
/*
|
||||
* if nothing was transferred, we try
|
||||
* again. It's a workaround for some USB
|
||||
|
Loading…
x
Reference in New Issue
Block a user