diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a24d3461fc78..31d05ab0b2fc 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -397,6 +397,32 @@ void scsi_target_reap(struct scsi_target *starget) | |||
397 | } | 397 | } |
398 | 398 | ||
399 | /** | 399 | /** |
400 | * sanitize_inquiry_string - remove non-graphical chars from an INQUIRY result string | ||
401 | * @s: INQUIRY result string to sanitize | ||
402 | * @len: length of the string | ||
403 | * | ||
404 | * Description: | ||
405 | * The SCSI spec says that INQUIRY vendor, product, and revision | ||
406 | * strings must consist entirely of graphic ASCII characters, | ||
407 | * padded on the right with spaces. Since not all devices obey | ||
408 | * this rule, we will replace non-graphic or non-ASCII characters | ||
409 | * with spaces. Exception: a NUL character is interpreted as a | ||
410 | * string terminator, so all the following characters are set to | ||
411 | * spaces. | ||
412 | **/ | ||
413 | static void sanitize_inquiry_string(unsigned char *s, int len) | ||
414 | { | ||
415 | int terminated = 0; | ||
416 | |||
417 | for (; len > 0; (--len, ++s)) { | ||
418 | if (*s == 0) | ||
419 | terminated = 1; | ||
420 | if (terminated || *s < 0x20 || *s > 0x7e) | ||
421 | *s = ' '; | ||
422 | } | ||
423 | } | ||
424 | |||
425 | /** | ||
400 | * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY | 426 | * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY |
401 | * @sdev: scsi_device to probe | 427 | * @sdev: scsi_device to probe |
402 | * @inq_result: area to store the INQUIRY result | 428 | * @inq_result: area to store the INQUIRY result |
@@ -410,7 +436,7 @@ void scsi_target_reap(struct scsi_target *starget) | |||
410 | * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length | 436 | * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length |
411 | * are copied to the scsi_device any flags value is stored in *@bflags. | 437 | * are copied to the scsi_device any flags value is stored in *@bflags. |
412 | **/ | 438 | **/ |
413 | static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, | 439 | static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, |
414 | int result_len, int *bflags) | 440 | int result_len, int *bflags) |
415 | { | 441 | { |
416 | unsigned char scsi_cmd[MAX_COMMAND_SIZE]; | 442 | unsigned char scsi_cmd[MAX_COMMAND_SIZE]; |
@@ -469,7 +495,11 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, | |||
469 | } | 495 | } |
470 | 496 | ||
471 | if (result == 0) { | 497 | if (result == 0) { |
472 | response_len = (unsigned char) inq_result[4] + 5; | 498 | sanitize_inquiry_string(&inq_result[8], 8); |
499 | sanitize_inquiry_string(&inq_result[16], 16); | ||
500 | sanitize_inquiry_string(&inq_result[32], 4); | ||
501 | |||
502 | response_len = inq_result[4] + 5; | ||
473 | if (response_len > 255) | 503 | if (response_len > 255) |
474 | response_len = first_inquiry_len; /* sanity */ | 504 | response_len = first_inquiry_len; /* sanity */ |
475 | 505 | ||
@@ -575,7 +605,8 @@ static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result, | |||
575 | * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device | 605 | * SCSI_SCAN_NO_RESPONSE: could not allocate or setup a scsi_device |
576 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized | 606 | * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized |
577 | **/ | 607 | **/ |
578 | static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags) | 608 | static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, |
609 | int *bflags) | ||
579 | { | 610 | { |
580 | /* | 611 | /* |
581 | * XXX do not save the inquiry, since it can change underneath us, | 612 | * XXX do not save the inquiry, since it can change underneath us, |