This has scsi_probe_lun ask scsi-ml to retry UAs instead of driving them itself. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> Reviewed-by: Bart Van Assche <bvanassche@xxxxxxx> --- drivers/scsi/scsi_scan.c | 51 ++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 58edd5d641f8..ffdb043bda5f 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -653,8 +653,29 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, unsigned char scsi_cmd[MAX_COMMAND_SIZE]; int first_inquiry_len, try_inquiry_len, next_inquiry_len; int response_len = 0; - int pass, count, result; - struct scsi_sense_hdr sshdr; + int pass, count, result, i; + /* + * 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. + */ + struct scsi_failure failures[] = { + { + .sense = UNIT_ATTENTION, + .asc = 0x28, + .ascq = 0, + .allowed = 3, + .result = SAM_STAT_CHECK_CONDITION, + }, + { + .sense = UNIT_ATTENTION, + .asc = 0x29, + .ascq = 0, + .allowed = 3, + .result = SAM_STAT_CHECK_CONDITION, + }, + {}, + }; *bflags = 0; @@ -671,6 +692,11 @@ 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 */ + for (i = 0; i < ARRAY_SIZE(failures); i++) { + if (failures[i].sense == UNIT_ATTENTION) + failures[i].retries = 0; + } + for (count = 0; count < 3; ++count) { int resid; @@ -686,32 +712,17 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, .data_dir = DMA_FROM_DEVICE, .buf = inq_result, .buf_len = try_inquiry_len, - .sshdr = &sshdr, .timeout = HZ / 2 + HZ * scsi_inq_timeout, .retries = 3, - .resid = &resid })); + .resid = &resid, + .failures = failures })); SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, "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 -- 2.25.1