This has scsi_report_lun_scan have scsi-ml retry errors instead of driving them itself. There is one behavior change where we no longer retry when scsi_execute_cmd returns < 0, but we should be ok. We don't need to retry for failures like the queue being removed, and for the case where there are no tags/reqs the block layer waits/retries for us. For possible memory allocation failures from blk_rq_map_kern we use GFP_NOIO, so retrying will probably not help. Signed-off-by: Mike Christie <michael.christie@xxxxxxxxxx> Reviewed-by: Christoph Hellwig <hch@xxxxxx> --- drivers/scsi/scsi_scan.c | 56 +++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index eeaefba6c9a9..9646f90878f0 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1412,14 +1412,33 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag unsigned int length; u64 lun; unsigned int num_luns; - unsigned int retries; int result; struct scsi_lun *lunp, *lun_data; - struct scsi_sense_hdr sshdr; struct scsi_device *sdev; struct Scsi_Host *shost = dev_to_shost(&starget->dev); + struct scsi_failure failures[] = { + { + .sense = UNIT_ATTENTION, + .asc = SCMD_FAILURE_ASC_ANY, + .ascq = SCMD_FAILURE_ASCQ_ANY, + .allowed = 3, + .result = SAM_STAT_CHECK_CONDITION, + }, + /* Fail all CCs except the UA above */ + { + .sense = SCMD_FAILURE_SENSE_ANY, + .allowed = 0, + .result = SAM_STAT_CHECK_CONDITION, + }, + /* Retry any oher errors not listed above */ + { + .result = SCMD_FAILURE_RESULT_ANY, + .allowed = 3, + }, + {}, + }; const struct scsi_exec_args exec_args = { - .sshdr = &sshdr, + .failures = failures, }; int ret = 0; @@ -1490,29 +1509,18 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag * should come through as a check condition, and will not generate * a retry. */ - for (retries = 0; retries < 3; retries++) { - SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, - "scsi scan: Sending REPORT LUNS to (try %d)\n", - retries)); - - result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, - lun_data, length, - SCSI_REPORT_LUNS_TIMEOUT, 3, - &exec_args); + scsi_reset_failures(failures); - SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, - "scsi scan: REPORT LUNS" - " %s (try %d) result 0x%x\n", - result ? "failed" : "successful", - retries, result)); - if (result == 0) - break; - else if (scsi_sense_valid(&sshdr)) { - if (sshdr.sense_key != UNIT_ATTENTION) - break; - } - } + SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, + "scsi scan: Sending REPORT LUNS\n")); + + result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, lun_data, + length, SCSI_REPORT_LUNS_TIMEOUT, 3, + &exec_args); + SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, + "scsi scan: REPORT LUNS %s result 0x%x\n", + result ? "failed" : "successful", result)); if (result) { /* * The device probably does not support a REPORT LUN command -- 2.34.1