aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r--drivers/scsi/scsi_scan.c146
1 files changed, 77 insertions, 69 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 1bd92b9b46d9..fd9e281c3bfe 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -134,59 +134,6 @@ static void scsi_unlock_floptical(struct scsi_device *sdev,
134} 134}
135 135
136/** 136/**
137 * print_inquiry - printk the inquiry information
138 * @inq_result: printk this SCSI INQUIRY
139 *
140 * Description:
141 * printk the vendor, model, and other information found in the
142 * INQUIRY data in @inq_result.
143 *
144 * Notes:
145 * Remove this, and replace with a hotplug event that logs any
146 * relevant information.
147 **/
148static void print_inquiry(unsigned char *inq_result)
149{
150 int i;
151
152 printk(KERN_NOTICE " Vendor: ");
153 for (i = 8; i < 16; i++)
154 if (inq_result[i] >= 0x20 && i < inq_result[4] + 5)
155 printk("%c", inq_result[i]);
156 else
157 printk(" ");
158
159 printk(" Model: ");
160 for (i = 16; i < 32; i++)
161 if (inq_result[i] >= 0x20 && i < inq_result[4] + 5)
162 printk("%c", inq_result[i]);
163 else
164 printk(" ");
165
166 printk(" Rev: ");
167 for (i = 32; i < 36; i++)
168 if (inq_result[i] >= 0x20 && i < inq_result[4] + 5)
169 printk("%c", inq_result[i]);
170 else
171 printk(" ");
172
173 printk("\n");
174
175 i = inq_result[0] & 0x1f;
176
177 printk(KERN_NOTICE " Type: %s ",
178 i <
179 MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
180 "Unknown ");
181 printk(" ANSI SCSI revision: %02x",
182 inq_result[2] & 0x07);
183 if ((inq_result[2] & 0x07) == 1 && (inq_result[3] & 0x0f) == 1)
184 printk(" CCS\n");
185 else
186 printk("\n");
187}
188
189/**
190 * scsi_alloc_sdev - allocate and setup a scsi_Device 137 * scsi_alloc_sdev - allocate and setup a scsi_Device
191 * 138 *
192 * Description: 139 * Description:
@@ -319,6 +266,18 @@ static struct scsi_target *__scsi_find_target(struct device *parent,
319 return found_starget; 266 return found_starget;
320} 267}
321 268
269/**
270 * scsi_alloc_target - allocate a new or find an existing target
271 * @parent: parent of the target (need not be a scsi host)
272 * @channel: target channel number (zero if no channels)
273 * @id: target id number
274 *
275 * Return an existing target if one exists, provided it hasn't already
276 * gone into STARGET_DEL state, otherwise allocate a new target.
277 *
278 * The target is returned with an incremented reference, so the caller
279 * is responsible for both reaping and doing a last put
280 */
322static struct scsi_target *scsi_alloc_target(struct device *parent, 281static struct scsi_target *scsi_alloc_target(struct device *parent,
323 int channel, uint id) 282 int channel, uint id)
324{ 283{
@@ -384,14 +343,15 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
384 return NULL; 343 return NULL;
385 } 344 }
386 } 345 }
346 get_device(dev);
387 347
388 return starget; 348 return starget;
389 349
390 found: 350 found:
391 found_target->reap_ref++; 351 found_target->reap_ref++;
392 spin_unlock_irqrestore(shost->host_lock, flags); 352 spin_unlock_irqrestore(shost->host_lock, flags);
393 put_device(parent);
394 if (found_target->state != STARGET_DEL) { 353 if (found_target->state != STARGET_DEL) {
354 put_device(parent);
395 kfree(starget); 355 kfree(starget);
396 return found_target; 356 return found_target;
397 } 357 }
@@ -450,6 +410,32 @@ void scsi_target_reap(struct scsi_target *starget)
450} 410}
451 411
452/** 412/**
413 * sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string
414 * @s: INQUIRY result string to sanitize
415 * @len: length of the string
416 *
417 * Description:
418 * The SCSI spec says that INQUIRY vendor, product, and revision
419 * strings must consist entirely of graphic ASCII characters,
420 * padded on the right with spaces. Since not all devices obey
421 * this rule, we will replace non-graphic or non-ASCII characters
422 * with spaces. Exception: a NUL character is interpreted as a
423 * string terminator, so all the following characters are set to
424 * spaces.
425 **/
426static void sanitize_inquiry_string(unsigned char *s, int len)
427{
428 int terminated = 0;
429
430 for (; len > 0; (--len, ++s)) {
431 if (*s == 0)
432 terminated = 1;
433 if (terminated || *s < 0x20 || *s > 0x7e)
434 *s = ' ';
435 }
436}
437
438/**
453 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 439 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
454 * @sdev: scsi_device to probe 440 * @sdev: scsi_device to probe
455 * @inq_result: area to store the INQUIRY result 441 * @inq_result: area to store the INQUIRY result
@@ -463,7 +449,7 @@ void scsi_target_reap(struct scsi_target *starget)
463 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length 449 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
464 * are copied to the scsi_device any flags value is stored in *@bflags. 450 * are copied to the scsi_device any flags value is stored in *@bflags.
465 **/ 451 **/
466static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, 452static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
467 int result_len, int *bflags) 453 int result_len, int *bflags)
468{ 454{
469 unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 455 unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -522,7 +508,11 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
522 } 508 }
523 509
524 if (result == 0) { 510 if (result == 0) {
525 response_len = (unsigned char) inq_result[4] + 5; 511 sanitize_inquiry_string(&inq_result[8], 8);
512 sanitize_inquiry_string(&inq_result[16], 16);
513 sanitize_inquiry_string(&inq_result[32], 4);
514
515 response_len = inq_result[4] + 5;
526 if (response_len > 255) 516 if (response_len > 255)
527 response_len = first_inquiry_len; /* sanity */ 517 response_len = first_inquiry_len; /* sanity */
528 518
@@ -628,7 +618,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
628 * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device 618 * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device
629 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized 619 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
630 **/ 620 **/
631static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) 621static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
622 int *bflags)
632{ 623{
633 /* 624 /*
634 * XXX do not save the inquiry, since it can change underneath us, 625 * XXX do not save the inquiry, since it can change underneath us,
@@ -653,9 +644,8 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
653 if (*bflags & BLIST_ISROM) { 644 if (*bflags & BLIST_ISROM) {
654 /* 645 /*
655 * It would be better to modify sdev->type, and set 646 * It would be better to modify sdev->type, and set
656 * sdev->removable, but then the print_inquiry() output 647 * sdev->removable; this can now be done since
657 * would not show TYPE_ROM; if print_inquiry() is removed 648 * print_inquiry has gone away.
658 * the issue goes away.
659 */ 649 */
660 inq_result[0] = TYPE_ROM; 650 inq_result[0] = TYPE_ROM;
661 inq_result[1] |= 0x80; /* removable */ 651 inq_result[1] |= 0x80; /* removable */
@@ -684,8 +674,6 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
684 printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type); 674 printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type);
685 } 675 }
686 676
687 print_inquiry(inq_result);
688
689 /* 677 /*
690 * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI 678 * For a peripheral qualifier (PQ) value of 1 (001b), the SCSI
691 * spec says: The device server is capable of supporting the 679 * spec says: The device server is capable of supporting the
@@ -715,6 +703,12 @@ static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
715 if (inq_result[7] & 0x10) 703 if (inq_result[7] & 0x10)
716 sdev->sdtr = 1; 704 sdev->sdtr = 1;
717 705
706 sdev_printk(KERN_NOTICE, sdev, "%s %.8s %.16s %.4s PQ: %d "
707 "ANSI: %d%s\n", scsi_device_type(sdev->type),
708 sdev->vendor, sdev->model, sdev->rev,
709 sdev->inq_periph_qual, inq_result[2] & 0x07,
710 (inq_result[3] & 0x0f) == 1 ? " CCS" : "");
711
718 /* 712 /*
719 * End sysfs code. 713 * End sysfs code.
720 */ 714 */
@@ -943,11 +937,26 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
943 } 937 }
944 938
945 /* 939 /*
946 * Non-standard SCSI targets may set the PDT to 0x1f (unknown or 940 * Some targets may set slight variations of PQ and PDT to signal
947 * no device type) instead of using the Peripheral Qualifier to 941 * that no LUN is present, so don't add sdev in these cases.
948 * indicate that no LUN is present. For example, USB UFI does this. 942 * Two specific examples are:
943 * 1) NetApp targets: return PQ=1, PDT=0x1f
944 * 2) USB UFI: returns PDT=0x1f, with the PQ bits being "reserved"
945 * in the UFI 1.0 spec (we cannot rely on reserved bits).
946 *
947 * References:
948 * 1) SCSI SPC-3, pp. 145-146
949 * PQ=1: "A peripheral device having the specified peripheral
950 * device type is not connected to this logical unit. However, the
951 * device server is capable of supporting the specified peripheral
952 * device type on this logical unit."
953 * PDT=0x1f: "Unknown or no device type"
954 * 2) USB UFI 1.0, p. 20
955 * PDT=00h Direct-access device (floppy)
956 * PDT=1Fh none (no FDD connected to the requested logical unit)
949 */ 957 */
950 if (starget->pdt_1f_for_no_lun && (result[0] & 0x1f) == 0x1f) { 958 if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
959 (result[0] & 0x1f) == 0x1f) {
951 SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO 960 SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
952 "scsi scan: peripheral device type" 961 "scsi scan: peripheral device type"
953 " of 31, no device added\n")); 962 " of 31, no device added\n"));
@@ -1345,7 +1354,6 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
1345 if (!starget) 1354 if (!starget)
1346 return ERR_PTR(-ENOMEM); 1355 return ERR_PTR(-ENOMEM);
1347 1356
1348 get_device(&starget->dev);
1349 mutex_lock(&shost->scan_mutex); 1357 mutex_lock(&shost->scan_mutex);
1350 if (scsi_host_scan_allowed(shost)) 1358 if (scsi_host_scan_allowed(shost))
1351 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); 1359 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
@@ -1404,7 +1412,6 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
1404 if (!starget) 1412 if (!starget)
1405 return; 1413 return;
1406 1414
1407 get_device(&starget->dev);
1408 if (lun != SCAN_WILD_CARD) { 1415 if (lun != SCAN_WILD_CARD) {
1409 /* 1416 /*
1410 * Scan for a specific host/chan/id/lun. 1417 * Scan for a specific host/chan/id/lun.
@@ -1586,7 +1593,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
1586 if (sdev) { 1593 if (sdev) {
1587 sdev->sdev_gendev.parent = get_device(&starget->dev); 1594 sdev->sdev_gendev.parent = get_device(&starget->dev);
1588 sdev->borken = 0; 1595 sdev->borken = 0;
1589 } 1596 } else
1597 scsi_target_reap(starget);
1590 put_device(&starget->dev); 1598 put_device(&starget->dev);
1591 out: 1599 out:
1592 mutex_unlock(&shost->scan_mutex); 1600 mutex_unlock(&shost->scan_mutex);