diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 187 |
1 files changed, 81 insertions, 106 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index e02b3aab56ce..56675dbbf681 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -81,15 +81,11 @@ static const char *scsi_null_device_strs = "nullnullnullnull"; #define MAX_SCSI_LUNS 512 -#ifdef CONFIG_SCSI_MULTI_LUN -static unsigned int max_scsi_luns = MAX_SCSI_LUNS; -#else -static unsigned int max_scsi_luns = 1; -#endif +static u64 max_scsi_luns = MAX_SCSI_LUNS; -module_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR); +module_param_named(max_luns, max_scsi_luns, ullong, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_luns, - "last scsi LUN (should be between 1 and 2^32-1)"); + "last scsi LUN (should be between 1 and 2^64-1)"); #ifdef CONFIG_SCSI_SCAN_ASYNC #define SCSI_SCAN_TYPE_DEFAULT "async" @@ -198,7 +194,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev, { unsigned char scsi_cmd[MAX_COMMAND_SIZE]; - printk(KERN_NOTICE "scsi: unlocking floptical drive\n"); + sdev_printk(KERN_NOTICE, sdev, "unlocking floptical drive\n"); scsi_cmd[0] = MODE_SENSE; scsi_cmd[1] = 0; scsi_cmd[2] = 0x2e; @@ -224,7 +220,7 @@ static void scsi_unlock_floptical(struct scsi_device *sdev, * scsi_Device pointer, or NULL on failure. **/ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, - unsigned int lun, void *hostdata) + u64 lun, void *hostdata) { struct scsi_device *sdev; int display_failure_msg = 1, ret; @@ -277,7 +273,10 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, */ sdev->borken = 1; - sdev->request_queue = scsi_alloc_queue(sdev); + if (shost_use_blk_mq(shost)) + sdev->request_queue = scsi_mq_alloc_queue(sdev); + else + sdev->request_queue = scsi_alloc_queue(sdev); if (!sdev->request_queue) { /* release fn is set up in scsi_sysfs_device_initialise, so * have to free and put manually here */ @@ -600,8 +599,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, HZ / 2 + HZ * scsi_inq_timeout, 3, &resid); - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s " - "with code 0x%x\n", + 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) { @@ -671,9 +670,10 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, } } else if (pass == 2) { - printk(KERN_INFO "scsi scan: %d byte inquiry failed. " - "Consider BLIST_INQUIRY_36 for this device\n", - try_inquiry_len); + sdev_printk(KERN_INFO, sdev, + "scsi scan: %d byte inquiry failed. " + "Consider BLIST_INQUIRY_36 for this device\n", + try_inquiry_len); /* If this pass failed, the third pass goes back and transfers * the same amount as we successfully got in the first pass. */ @@ -706,8 +706,9 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, * strings. */ if (sdev->inquiry_len < 36) { - printk(KERN_INFO "scsi scan: INQUIRY result too short (%d)," - " using 36\n", sdev->inquiry_len); + sdev_printk(KERN_INFO, sdev, + "scsi scan: INQUIRY result too short (%d)," + " using 36\n", sdev->inquiry_len); sdev->inquiry_len = 36; } @@ -806,29 +807,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, sdev->removable = (inq_result[1] & 0x80) >> 7; } - switch (sdev->type) { - case TYPE_RBC: - case TYPE_TAPE: - case TYPE_DISK: - case TYPE_PRINTER: - case TYPE_MOD: - case TYPE_PROCESSOR: - case TYPE_SCANNER: - case TYPE_MEDIUM_CHANGER: - case TYPE_ENCLOSURE: - case TYPE_COMM: - case TYPE_RAID: - case TYPE_OSD: - sdev->writeable = 1; - break; - case TYPE_ROM: - case TYPE_WORM: - sdev->writeable = 0; - break; - default: - printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type); - } - if (sdev->type == TYPE_RBC || sdev->type == TYPE_ROM) { /* RBC and MMC devices can return SCSI-3 compliance and yet * still not support REPORT LUNS, so make them act as @@ -922,6 +900,12 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_USE_10_BYTE_MS) sdev->use_10_for_ms = 1; + /* some devices don't like REPORT SUPPORTED OPERATION CODES + * and will simply timeout causing sd_mod init to take a very + * very long time */ + if (*bflags & BLIST_NO_RSOC) + sdev->no_report_opcodes = 1; + /* set the device running here so that slave configure * may do I/O */ ret = scsi_device_set_state(sdev, SDEV_RUNNING); @@ -950,7 +934,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, sdev->eh_timeout = SCSI_DEFAULT_EH_TIMEOUT; - if (*bflags & BLIST_SKIP_VPD_PAGES) + if (*bflags & BLIST_TRY_VPD_PAGES) + sdev->try_vpd_pages = 1; + else if (*bflags & BLIST_SKIP_VPD_PAGES) sdev->skip_vpd_pages = 1; transport_configure_device(&sdev->sdev_gendev); @@ -1032,7 +1018,7 @@ static unsigned char *scsi_inq_str(unsigned char *buf, unsigned char *inq, * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized **/ static int scsi_probe_and_add_lun(struct scsi_target *starget, - uint lun, int *bflagsp, + u64 lun, int *bflagsp, struct scsi_device **sdevp, int rescan, void *hostdata) { @@ -1048,7 +1034,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, sdev = scsi_device_lookup_by_target(starget, lun); if (sdev) { if (rescan || !scsi_device_created(sdev)) { - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO + SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, "scsi scan: device exists on %s\n", dev_name(&sdev->sdev_gendev))); if (sdevp) @@ -1135,7 +1121,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && (result[0] & 0x1f) == 0x1f && !scsi_is_wlun(lun)) { - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO + SCSI_LOG_SCAN_BUS(3, sdev_printk(KERN_INFO, sdev, "scsi scan: peripheral device type" " of 31, no device added\n")); res = SCSI_SCAN_TARGET_PRESENT; @@ -1185,11 +1171,12 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, static void scsi_sequential_lun_scan(struct scsi_target *starget, int bflags, int scsi_level, int rescan) { - unsigned int sparse_lun, lun, max_dev_lun; + uint max_dev_lun; + u64 sparse_lun, lun; struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: Sequential scan of" - "%s\n", dev_name(&starget->dev))); + SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget, + "scsi scan: Sequential scan\n")); max_dev_lun = min(max_scsi_luns, shost->max_lun); /* @@ -1239,6 +1226,12 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, max_dev_lun = min(8U, max_dev_lun); /* + * Stop scanning at 255 unless BLIST_SCSI3LUN + */ + if (!(bflags & BLIST_SCSI3LUN)) + max_dev_lun = min(256U, max_dev_lun); + + /* * We have already scanned LUN 0, so start at LUN 1. Keep scanning * until we reach the max, or no LUN is found and we are not * sparse_lun. @@ -1260,24 +1253,25 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget, * truncation before using this function. * * Notes: - * The struct scsi_lun is assumed to be four levels, with each level - * effectively containing a SCSI byte-ordered (big endian) short; the - * addressing bits of each level are ignored (the highest two bits). * For a description of the LUN format, post SCSI-3 see the SCSI * Architecture Model, for SCSI-3 see the SCSI Controller Commands. * - * Given a struct scsi_lun of: 0a 04 0b 03 00 00 00 00, this function returns - * the integer: 0x0b030a04 + * Given a struct scsi_lun of: d2 04 0b 03 00 00 00 00, this function + * returns the integer: 0x0b03d204 + * + * This encoding will return a standard integer LUN for LUNs smaller + * than 256, which typically use a single level LUN structure with + * addressing method 0. **/ -int scsilun_to_int(struct scsi_lun *scsilun) +u64 scsilun_to_int(struct scsi_lun *scsilun) { int i; - unsigned int lun; + u64 lun; lun = 0; for (i = 0; i < sizeof(lun); i += 2) - lun = lun | (((scsilun->scsi_lun[i] << 8) | - scsilun->scsi_lun[i + 1]) << (i * 8)); + lun = lun | (((u64)scsilun->scsi_lun[i] << ((i + 1) * 8)) | + ((u64)scsilun->scsi_lun[i + 1] << (i * 8))); return lun; } EXPORT_SYMBOL(scsilun_to_int); @@ -1291,16 +1285,13 @@ EXPORT_SYMBOL(scsilun_to_int); * Reverts the functionality of the scsilun_to_int, which packed * an 8-byte lun value into an int. This routine unpacks the int * back into the lun value. - * Note: the scsilun_to_int() routine does not truly handle all - * 8bytes of the lun value. This functions restores only as much - * as was set by the routine. * * Notes: - * Given an integer : 0x0b030a04, this function returns a - * scsi_lun of : struct scsi_lun of: 0a 04 0b 03 00 00 00 00 + * Given an integer : 0x0b03d204, this function returns a + * struct scsi_lun of: d2 04 0b 03 00 00 00 00 * **/ -void int_to_scsilun(unsigned int lun, struct scsi_lun *scsilun) +void int_to_scsilun(u64 lun, struct scsi_lun *scsilun) { int i; @@ -1340,7 +1331,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, char devname[64]; unsigned char scsi_cmd[MAX_COMMAND_SIZE]; unsigned int length; - unsigned int lun; + u64 lun; unsigned int num_luns; unsigned int retries; int result; @@ -1430,17 +1421,19 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * 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, + SCSI_LOG_SCAN_BUS(3, sdev_printk (KERN_INFO, sdev, + "scsi scan: Sending REPORT LUNS to (try %d)\n", 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)); + 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)) { @@ -1466,10 +1459,11 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, num_luns = (length / sizeof(struct scsi_lun)); if (num_luns > max_scsi_report_luns) { - printk(KERN_WARNING "scsi: On %s only %d (max_scsi_report_luns)" - " of %d luns reported, try increasing" - " max_scsi_report_luns.\n", devname, - max_scsi_report_luns, num_luns); + sdev_printk(KERN_WARNING, sdev, + "Only %d (max_scsi_report_luns)" + " of %d luns reported, try increasing" + " max_scsi_report_luns.\n", + max_scsi_report_luns, num_luns); num_luns = max_scsi_report_luns; } @@ -1483,27 +1477,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, for (lunp = &lun_data[1]; lunp <= &lun_data[num_luns]; lunp++) { lun = scsilun_to_int(lunp); - /* - * Check if the unused part of lunp is non-zero, and so - * does not fit in lun. - */ - if (memcmp(&lunp->scsi_lun[sizeof(lun)], "\0\0\0\0", 4)) { - int i; - - /* - * Output an error displaying the LUN in byte order, - * this differs from what linux would print for the - * integer LUN value. - */ - printk(KERN_WARNING "scsi: %s lun 0x", devname); - data = (char *)lunp->scsi_lun; - for (i = 0; i < sizeof(struct scsi_lun); i++) - printk("%02x", data[i]); - printk(" has a LUN larger than currently supported.\n"); - } else if (lun > sdev->host->max_lun) { - printk(KERN_WARNING "scsi: %s lun%d has a LUN larger" - " than allowed by the host adapter\n", - devname, lun); + if (lun > sdev->host->max_lun) { + sdev_printk(KERN_WARNING, sdev, + "lun%llu has a LUN larger than" + " allowed by the host adapter\n", lun); } else { int res; @@ -1515,8 +1492,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, */ sdev_printk(KERN_ERR, sdev, "Unexpected response" - " from lun %d while scanning, scan" - " aborted\n", lun); + " from lun %llu while scanning, scan" + " aborted\n", (unsigned long long)lun); break; } } @@ -1535,7 +1512,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, } struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, - uint id, uint lun, void *hostdata) + uint id, u64 lun, void *hostdata) { struct scsi_device *sdev = ERR_PTR(-ENODEV); struct device *parent = &shost->shost_gendev; @@ -1571,7 +1548,7 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, EXPORT_SYMBOL(__scsi_add_device); int scsi_add_device(struct Scsi_Host *host, uint channel, - uint target, uint lun) + uint target, u64 lun) { struct scsi_device *sdev = __scsi_add_device(host, channel, target, lun, NULL); @@ -1600,7 +1577,7 @@ void scsi_rescan_device(struct device *dev) EXPORT_SYMBOL(scsi_rescan_device); static void __scsi_scan_target(struct device *parent, unsigned int channel, - unsigned int id, unsigned int lun, int rescan) + unsigned int id, u64 lun, int rescan) { struct Scsi_Host *shost = dev_to_shost(parent); int bflags = 0; @@ -1668,7 +1645,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel, * sequential scan of LUNs on the target id. **/ void scsi_scan_target(struct device *parent, unsigned int channel, - unsigned int id, unsigned int lun, int rescan) + unsigned int id, u64 lun, int rescan) { struct Scsi_Host *shost = dev_to_shost(parent); @@ -1688,7 +1665,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel, EXPORT_SYMBOL(scsi_scan_target); static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, - unsigned int id, unsigned int lun, int rescan) + unsigned int id, u64 lun, int rescan) { uint order_id; @@ -1719,10 +1696,10 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, } int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, - unsigned int id, unsigned int lun, int rescan) + unsigned int id, u64 lun, int rescan) { SCSI_LOG_SCAN_BUS(3, shost_printk (KERN_INFO, shost, - "%s: <%u:%u:%u>\n", + "%s: <%u:%u:%llu>\n", __func__, channel, id, lun)); if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || @@ -1781,8 +1758,7 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) return NULL; if (shost->async_scan) { - printk("%s called twice for host %d", __func__, - shost->host_no); + shost_printk(KERN_INFO, shost, "%s called twice\n", __func__); dump_stack(); return NULL; } @@ -1835,8 +1811,7 @@ static void scsi_finish_async_scan(struct async_scan_data *data) mutex_lock(&shost->scan_mutex); if (!shost->async_scan) { - printk("%s called twice for host %d", __func__, - shost->host_no); + shost_printk(KERN_INFO, shost, "%s called twice\n", __func__); dump_stack(); mutex_unlock(&shost->scan_mutex); return; |