Signed-off-by: Rob Evers <revers@xxxxxxxxxx> --- drivers/scsi/scsi_scan.c | 109 +++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 50 deletions(-) diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3e58b22..b2abf22 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1282,6 +1282,64 @@ void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun) } EXPORT_SYMBOL(int_to_scsilun); +int scsi_do_report_luns(struct scsi_device *sdev, int length, + struct scsi_lun *lun_data, char *devname) +{ + unsigned int retries; + unsigned char scsi_cmd[MAX_COMMAND_SIZE]; + struct scsi_sense_hdr sshdr; + int result; + + scsi_cmd[0] = REPORT_LUNS; + + /* + * bytes 1 - 5: reserved, set to zero. + */ + memset(&scsi_cmd[1], 0, 5); + + /* + * bytes 6 - 9: length of the command. + */ + scsi_cmd[6] = (unsigned char) (length >> 24) & 0xff; + scsi_cmd[7] = (unsigned char) (length >> 16) & 0xff; + scsi_cmd[8] = (unsigned char) (length >> 8) & 0xff; + scsi_cmd[9] = (unsigned char) length & 0xff; + + scsi_cmd[10] = 0; /* reserved */ + scsi_cmd[11] = 0; /* control */ + + /* + * We can get a UNIT ATTENTION, for example a power on/reset, so + * retry a few times (like sd.c does for TEST UNIT READY). + * Experience shows some combinations of adapter/devices get at + * least two power on/resets. + * + * Illegal requests (for devices that do not support REPORT LUNS) + * should come through as a check condition, and will not generate + * a retry. + */ + for (retries = 0; retries < 3; retries++) { + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sending" + " REPORT LUNS to %s (try %d)\n", devname, + retries)); + result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, + lun_data, length, &sshdr, + SCSI_TIMEOUT + 4 * HZ, 3, NULL); + + SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "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; + } + } + + return result; +} + /** * scsi_report_lun_scan - Scan using SCSI REPORT LUN results * @starget: which target @@ -1306,15 +1364,12 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, int rescan) { char devname[64]; - unsigned char scsi_cmd[MAX_COMMAND_SIZE]; unsigned int length; unsigned int lun; unsigned int num_luns; - unsigned int retries; int result; struct scsi_lun *lunp, *lun_data; u8 *data; - struct scsi_sense_hdr sshdr; struct scsi_device *sdev; struct Scsi_Host *shost = dev_to_shost(&starget->dev); int ret = 0; @@ -1369,53 +1424,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, goto out; } - scsi_cmd[0] = REPORT_LUNS; - - /* - * bytes 1 - 5: reserved, set to zero. - */ - memset(&scsi_cmd[1], 0, 5); - - /* - * bytes 6 - 9: length of the command. - */ - scsi_cmd[6] = (unsigned char) (length >> 24) & 0xff; - scsi_cmd[7] = (unsigned char) (length >> 16) & 0xff; - scsi_cmd[8] = (unsigned char) (length >> 8) & 0xff; - scsi_cmd[9] = (unsigned char) length & 0xff; - - scsi_cmd[10] = 0; /* reserved */ - scsi_cmd[11] = 0; /* control */ - - /* - * We can get a UNIT ATTENTION, for example a power on/reset, so - * retry a few times (like sd.c does for TEST UNIT READY). - * Experience shows some combinations of adapter/devices get at - * least two power on/resets. - * - * Illegal requests (for devices that do not support REPORT LUNS) - * should come through as a check condition, and will not generate - * a retry. - */ - for (retries = 0; retries < 3; retries++) { - SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending" - " REPORT LUNS to %s (try %d)\n", devname, - retries)); - - result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, - lun_data, length, &sshdr, - SCSI_TIMEOUT + 4 * HZ, 3, NULL); - - SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "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; - } - } + result = scsi_do_report_luns(sdev, length, lun_data, devname); if (result) { /* -- 1.7.11.7 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html