X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fscsi%2Fscsi_scan.c;h=166cb9ab33f13dd4dc73e581893790eaa1a14783;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=370afffe6955c31998e263b6e534b94c3d391301;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 370afffe6..166cb9ab3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -32,11 +32,13 @@ #include #include +#include +#include #include #include #include +#include #include -#include "scsi.h" #include "scsi_priv.h" #include "scsi_logging.h" @@ -44,6 +46,11 @@ #define ALLOC_FAILURE_MSG KERN_ERR "%s: Allocation failure during" \ " SCSI scanning, some SCSI devices might not be configured\n" +/* + * Default timeout + */ +#define SCSI_TIMEOUT (2*HZ) + /* * Prefix values for the SCSI id's (stored in driverfs name field) */ @@ -80,7 +87,6 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_luns, "last scsi LUN (should be between 1 and 2^32-1)"); -#ifdef CONFIG_SCSI_REPORT_LUNS /* * max_scsi_report_luns: the maximum number of LUNS that will be * returned from the REPORT LUNS command. 8 times this value must @@ -88,13 +94,19 @@ MODULE_PARM_DESC(max_luns, * in practice, the maximum number of LUNs suppored by any device * is about 16k. */ -static unsigned int max_scsi_report_luns = 128; +static unsigned int max_scsi_report_luns = 511; module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR); MODULE_PARM_DESC(max_report_luns, "REPORT LUNS maximum number of LUNS received (should be" " between 1 and 16384)"); -#endif + +static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ+3; + +module_param_named(inq_timeout, scsi_inq_timeout, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(inq_timeout, + "Timeout (in seconds) waiting for devices to answer INQUIRY." + " Default is 5. Some non-compliant devices need more."); /** * scsi_unlock_floptical - unlock device via a special MODE SENSE command @@ -212,6 +224,11 @@ static struct scsi_device *scsi_alloc_sdev(struct Scsi_Host *shost, INIT_LIST_HEAD(&sdev->starved_entry); spin_lock_init(&sdev->list_lock); + + /* if the device needs this changing, it may do so in the + * slave_configure function */ + sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED; + /* * Some low level driver could use device->type */ @@ -330,6 +347,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, struct scsi_device *sdev = sreq->sr_device; /* a bit ugly */ unsigned char scsi_cmd[MAX_COMMAND_SIZE]; int possible_inq_resp_len; + int count = 0; *bflags = 0; repeat_inquiry: @@ -345,24 +363,29 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, memset(inq_result, 0, 36); scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, 36, - SCSI_TIMEOUT + 4 * HZ, 3); + HZ/2 + HZ*scsi_inq_timeout, 3); SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: 1st INQUIRY %s with" " code 0x%x\n", sreq->sr_result ? "failed" : "successful", sreq->sr_result)); + ++count; if (sreq->sr_result) { if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) != 0 && (sreq->sr_sense_buffer[2] & 0xf) == UNIT_ATTENTION && - sreq->sr_sense_buffer[12] == 0x28 && + (sreq->sr_sense_buffer[12] == 0x28 || + sreq->sr_sense_buffer[12] == 0x29) && sreq->sr_sense_buffer[13] == 0) { - /* not-ready to ready transition - good */ + /* not-ready to ready transition or power-on - good */ /* dpg: bogus? INQUIRY never returns UNIT_ATTENTION */ - } else - /* - * assume no peripheral if any other sort of error - */ - return; + /* Supposedly, but many buggy devices do so anyway */ + if (count < 3) + goto repeat_inquiry; + } + /* + * assume no peripheral if any other sort of error + */ + return; } /* @@ -394,7 +417,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, memset(inq_result, 0, possible_inq_resp_len); scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, - possible_inq_resp_len, SCSI_TIMEOUT + 4 * HZ, 3); + possible_inq_resp_len, (1+scsi_inq_timeout)*(HZ/2), 3); SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: 2nd INQUIRY" " %s with code 0x%x\n", sreq->sr_result ? "failed" : "successful", sreq->sr_result)); @@ -543,17 +566,12 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) * 011 the same. Stay compatible with previous code, and create a * Scsi_Device for a PQ of 1 * - * XXX Save the PQ field let the upper layers figure out if they - * want to attach or not to this device, do not set online FALSE; - * otherwise, offline devices still get an sd allocated, and they - * use up an sd slot. - */ - if (((inq_result[0] >> 5) & 7) == 1) { - SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: peripheral" - " qualifier of 1, device offlined\n")); - scsi_device_set_state(sdev, SDEV_OFFLINE); - } + * Don't set the device offline here; rather let the upper + * level drivers eval the PQ to decide whether they should + * attach. So remove ((inq_result[0] >> 5) & 7) == 1 check. + */ + sdev->inq_periph_qual = (inq_result[0] >> 5) & 7; sdev->removable = (0x80 & inq_result[1]) >> 7; sdev->lockable = sdev->removable; sdev->soft_reset = (inq_result[7] & 1) && ((inq_result[3] & 7) == 2); @@ -627,10 +645,6 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) spin_unlock_irqrestore(sdev->host->host_lock, flags); } - /* if the device needs this changing, it may do so in the detect - * function */ - sdev->max_device_blocked = SCSI_DEFAULT_DEVICE_BLOCKED; - sdev->use_10_for_rw = 1; if (*bflags & BLIST_MS_SKIP_PAGE_08) @@ -649,6 +663,9 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) if (*bflags & BLIST_MS_192_BYTES_FOR_3F) sdev->use_192_bytes_for_3f = 1; + if (*bflags & BLIST_NOT_LOCKABLE) + sdev->lockable = 0; + if(sdev->host->hostt->slave_configure) sdev->host->hostt->slave_configure(sdev); @@ -862,7 +879,6 @@ static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel, return; } -#ifdef CONFIG_SCSI_REPORT_LUNS /** * scsilun_to_int: convert a scsi_lun to an int * @scsilun: struct scsi_lun to be converted. @@ -923,9 +939,14 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, u8 *data; /* - * Only support SCSI-3 and up devices. + * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. + * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does + * support more than 8 LUNs. */ - if (sdev->scsi_level < SCSI_3) + if ((bflags & BLIST_NOREPORTLUN) || + sdev->scsi_level < SCSI_2 || + (sdev->scsi_level < SCSI_3 && + (!(bflags & BLIST_REPORTLUN2) || sdev->host->max_lun <= 8)) ) return 1; if (bflags & BLIST_NOLUN) return 0; @@ -1089,9 +1110,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags, printk(ALLOC_FAILURE_MSG, __FUNCTION__); return 0; } -#else -# define scsi_report_lun_scan(sdev, blags, rescan) (1) -#endif /* CONFIG_SCSI_REPORT_LUNS */ struct scsi_device *scsi_add_device(struct Scsi_Host *shost, uint channel, uint id, uint lun)