aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_scan.c
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-09-08 05:41:28 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-08 05:41:28 -0400
commit142e27fc8a3619471669d6241784eec9167c47d1 (patch)
treee88850b63ec910ee28874f93c43fb66421bb8119 /drivers/scsi/scsi_scan.c
parenta9053d0494d3c92807701c0f47df61d50c971581 (diff)
parentcaf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff)
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r--drivers/scsi/scsi_scan.c128
1 files changed, 58 insertions, 70 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 48edd67982a5..19c9a232a754 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -111,15 +111,14 @@ MODULE_PARM_DESC(inq_timeout,
111 111
112/** 112/**
113 * scsi_unlock_floptical - unlock device via a special MODE SENSE command 113 * scsi_unlock_floptical - unlock device via a special MODE SENSE command
114 * @sreq: used to send the command 114 * @sdev: scsi device to send command to
115 * @result: area to store the result of the MODE SENSE 115 * @result: area to store the result of the MODE SENSE
116 * 116 *
117 * Description: 117 * Description:
118 * Send a vendor specific MODE SENSE (not a MODE SELECT) command using 118 * Send a vendor specific MODE SENSE (not a MODE SELECT) command.
119 * @sreq to unlock a device, storing the (unused) results into result.
120 * Called for BLIST_KEY devices. 119 * Called for BLIST_KEY devices.
121 **/ 120 **/
122static void scsi_unlock_floptical(struct scsi_request *sreq, 121static void scsi_unlock_floptical(struct scsi_device *sdev,
123 unsigned char *result) 122 unsigned char *result)
124{ 123{
125 unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 124 unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -129,11 +128,10 @@ static void scsi_unlock_floptical(struct scsi_request *sreq,
129 scsi_cmd[1] = 0; 128 scsi_cmd[1] = 0;
130 scsi_cmd[2] = 0x2e; 129 scsi_cmd[2] = 0x2e;
131 scsi_cmd[3] = 0; 130 scsi_cmd[3] = 0;
132 scsi_cmd[4] = 0x2a; /* size */ 131 scsi_cmd[4] = 0x2a; /* size */
133 scsi_cmd[5] = 0; 132 scsi_cmd[5] = 0;
134 sreq->sr_cmd_len = 0; 133 scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE, result, 0x2a, NULL,
135 sreq->sr_data_direction = DMA_FROM_DEVICE; 134 SCSI_TIMEOUT, 3);
136 scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
137} 135}
138 136
139/** 137/**
@@ -433,26 +431,25 @@ void scsi_target_reap(struct scsi_target *starget)
433 431
434/** 432/**
435 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY 433 * scsi_probe_lun - probe a single LUN using a SCSI INQUIRY
436 * @sreq: used to send the INQUIRY 434 * @sdev: scsi_device to probe
437 * @inq_result: area to store the INQUIRY result 435 * @inq_result: area to store the INQUIRY result
436 * @result_len: len of inq_result
438 * @bflags: store any bflags found here 437 * @bflags: store any bflags found here
439 * 438 *
440 * Description: 439 * Description:
441 * Probe the lun associated with @sreq using a standard SCSI INQUIRY; 440 * Probe the lun associated with @req using a standard SCSI INQUIRY;
442 * 441 *
443 * If the INQUIRY is successful, sreq->sr_result is zero and: the 442 * If the INQUIRY is successful, zero is returned and the
444 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length 443 * INQUIRY data is in @inq_result; the scsi_level and INQUIRY length
445 * are copied to the Scsi_Device at @sreq->sr_device (sdev); 444 * are copied to the Scsi_Device any flags value is stored in *@bflags.
446 * any flags value is stored in *@bflags.
447 **/ 445 **/
448static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result, 446static int scsi_probe_lun(struct scsi_device *sdev, char *inq_result,
449 int *bflags) 447 int result_len, int *bflags)
450{ 448{
451 struct scsi_device *sdev = sreq->sr_device; /* a bit ugly */
452 unsigned char scsi_cmd[MAX_COMMAND_SIZE]; 449 unsigned char scsi_cmd[MAX_COMMAND_SIZE];
453 int first_inquiry_len, try_inquiry_len, next_inquiry_len; 450 int first_inquiry_len, try_inquiry_len, next_inquiry_len;
454 int response_len = 0; 451 int response_len = 0;
455 int pass, count; 452 int pass, count, result;
456 struct scsi_sense_hdr sshdr; 453 struct scsi_sense_hdr sshdr;
457 454
458 *bflags = 0; 455 *bflags = 0;
@@ -475,28 +472,26 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
475 memset(scsi_cmd, 0, 6); 472 memset(scsi_cmd, 0, 6);
476 scsi_cmd[0] = INQUIRY; 473 scsi_cmd[0] = INQUIRY;
477 scsi_cmd[4] = (unsigned char) try_inquiry_len; 474 scsi_cmd[4] = (unsigned char) try_inquiry_len;
478 sreq->sr_cmd_len = 0;
479 sreq->sr_data_direction = DMA_FROM_DEVICE;
480 475
481 memset(inq_result, 0, try_inquiry_len); 476 memset(inq_result, 0, try_inquiry_len);
482 scsi_wait_req(sreq, (void *) scsi_cmd, (void *) inq_result, 477
483 try_inquiry_len, 478 result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
484 HZ/2 + HZ*scsi_inq_timeout, 3); 479 inq_result, try_inquiry_len, &sshdr,
480 HZ / 2 + HZ * scsi_inq_timeout, 3);
485 481
486 SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s " 482 SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: INQUIRY %s "
487 "with code 0x%x\n", 483 "with code 0x%x\n",
488 sreq->sr_result ? "failed" : "successful", 484 result ? "failed" : "successful", result));
489 sreq->sr_result));
490 485
491 if (sreq->sr_result) { 486 if (result) {
492 /* 487 /*
493 * not-ready to ready transition [asc/ascq=0x28/0x0] 488 * not-ready to ready transition [asc/ascq=0x28/0x0]
494 * or power-on, reset [asc/ascq=0x29/0x0], continue. 489 * or power-on, reset [asc/ascq=0x29/0x0], continue.
495 * INQUIRY should not yield UNIT_ATTENTION 490 * INQUIRY should not yield UNIT_ATTENTION
496 * but many buggy devices do so anyway. 491 * but many buggy devices do so anyway.
497 */ 492 */
498 if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) && 493 if ((driver_byte(result) & DRIVER_SENSE) &&
499 scsi_request_normalize_sense(sreq, &sshdr)) { 494 scsi_sense_valid(&sshdr)) {
500 if ((sshdr.sense_key == UNIT_ATTENTION) && 495 if ((sshdr.sense_key == UNIT_ATTENTION) &&
501 ((sshdr.asc == 0x28) || 496 ((sshdr.asc == 0x28) ||
502 (sshdr.asc == 0x29)) && 497 (sshdr.asc == 0x29)) &&
@@ -507,7 +502,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
507 break; 502 break;
508 } 503 }
509 504
510 if (sreq->sr_result == 0) { 505 if (result == 0) {
511 response_len = (unsigned char) inq_result[4] + 5; 506 response_len = (unsigned char) inq_result[4] + 5;
512 if (response_len > 255) 507 if (response_len > 255)
513 response_len = first_inquiry_len; /* sanity */ 508 response_len = first_inquiry_len; /* sanity */
@@ -556,8 +551,8 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
556 551
557 /* If the last transfer attempt got an error, assume the 552 /* If the last transfer attempt got an error, assume the
558 * peripheral doesn't exist or is dead. */ 553 * peripheral doesn't exist or is dead. */
559 if (sreq->sr_result) 554 if (result)
560 return; 555 return -EIO;
561 556
562 /* Don't report any more data than the device says is valid */ 557 /* Don't report any more data than the device says is valid */
563 sdev->inquiry_len = min(try_inquiry_len, response_len); 558 sdev->inquiry_len = min(try_inquiry_len, response_len);
@@ -593,7 +588,7 @@ static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
593 (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1)) 588 (sdev->scsi_level == 1 && (inq_result[3] & 0x0f) == 1))
594 sdev->scsi_level++; 589 sdev->scsi_level++;
595 590
596 return; 591 return 0;
597} 592}
598 593
599/** 594/**
@@ -800,9 +795,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
800 void *hostdata) 795 void *hostdata)
801{ 796{
802 struct scsi_device *sdev; 797 struct scsi_device *sdev;
803 struct scsi_request *sreq;
804 unsigned char *result; 798 unsigned char *result;
805 int bflags, res = SCSI_SCAN_NO_RESPONSE; 799 int bflags, res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
806 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 800 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
807 801
808 /* 802 /*
@@ -831,16 +825,13 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
831 sdev = scsi_alloc_sdev(starget, lun, hostdata); 825 sdev = scsi_alloc_sdev(starget, lun, hostdata);
832 if (!sdev) 826 if (!sdev)
833 goto out; 827 goto out;
834 sreq = scsi_allocate_request(sdev, GFP_ATOMIC); 828
835 if (!sreq) 829 result = kmalloc(result_len, GFP_ATOMIC |
836 goto out_free_sdev;
837 result = kmalloc(256, GFP_ATOMIC |
838 ((shost->unchecked_isa_dma) ? __GFP_DMA : 0)); 830 ((shost->unchecked_isa_dma) ? __GFP_DMA : 0));
839 if (!result) 831 if (!result)
840 goto out_free_sreq; 832 goto out_free_sdev;
841 833
842 scsi_probe_lun(sreq, result, &bflags); 834 if (scsi_probe_lun(sdev, result, result_len, &bflags))
843 if (sreq->sr_result)
844 goto out_free_result; 835 goto out_free_result;
845 836
846 /* 837 /*
@@ -868,7 +859,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
868 if (res == SCSI_SCAN_LUN_PRESENT) { 859 if (res == SCSI_SCAN_LUN_PRESENT) {
869 if (bflags & BLIST_KEY) { 860 if (bflags & BLIST_KEY) {
870 sdev->lockable = 0; 861 sdev->lockable = 0;
871 scsi_unlock_floptical(sreq, result); 862 scsi_unlock_floptical(sdev, result);
872 } 863 }
873 if (bflagsp) 864 if (bflagsp)
874 *bflagsp = bflags; 865 *bflagsp = bflags;
@@ -876,8 +867,6 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
876 867
877 out_free_result: 868 out_free_result:
878 kfree(result); 869 kfree(result);
879 out_free_sreq:
880 scsi_release_request(sreq);
881 out_free_sdev: 870 out_free_sdev:
882 if (res == SCSI_SCAN_LUN_PRESENT) { 871 if (res == SCSI_SCAN_LUN_PRESENT) {
883 if (sdevp) { 872 if (sdevp) {
@@ -1070,8 +1059,8 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1070 unsigned int lun; 1059 unsigned int lun;
1071 unsigned int num_luns; 1060 unsigned int num_luns;
1072 unsigned int retries; 1061 unsigned int retries;
1062 int result;
1073 struct scsi_lun *lunp, *lun_data; 1063 struct scsi_lun *lunp, *lun_data;
1074 struct scsi_request *sreq;
1075 u8 *data; 1064 u8 *data;
1076 struct scsi_sense_hdr sshdr; 1065 struct scsi_sense_hdr sshdr;
1077 struct scsi_target *starget = scsi_target(sdev); 1066 struct scsi_target *starget = scsi_target(sdev);
@@ -1089,10 +1078,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1089 if (bflags & BLIST_NOLUN) 1078 if (bflags & BLIST_NOLUN)
1090 return 0; 1079 return 0;
1091 1080
1092 sreq = scsi_allocate_request(sdev, GFP_ATOMIC);
1093 if (!sreq)
1094 goto out;
1095
1096 sprintf(devname, "host %d channel %d id %d", 1081 sprintf(devname, "host %d channel %d id %d",
1097 sdev->host->host_no, sdev->channel, sdev->id); 1082 sdev->host->host_no, sdev->channel, sdev->id);
1098 1083
@@ -1110,7 +1095,7 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1110 lun_data = kmalloc(length, GFP_ATOMIC | 1095 lun_data = kmalloc(length, GFP_ATOMIC |
1111 (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0)); 1096 (sdev->host->unchecked_isa_dma ? __GFP_DMA : 0));
1112 if (!lun_data) 1097 if (!lun_data)
1113 goto out_release_request; 1098 goto out;
1114 1099
1115 scsi_cmd[0] = REPORT_LUNS; 1100 scsi_cmd[0] = REPORT_LUNS;
1116 1101
@@ -1129,8 +1114,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1129 1114
1130 scsi_cmd[10] = 0; /* reserved */ 1115 scsi_cmd[10] = 0; /* reserved */
1131 scsi_cmd[11] = 0; /* control */ 1116 scsi_cmd[11] = 0; /* control */
1132 sreq->sr_cmd_len = 0;
1133 sreq->sr_data_direction = DMA_FROM_DEVICE;
1134 1117
1135 /* 1118 /*
1136 * We can get a UNIT ATTENTION, for example a power on/reset, so 1119 * We can get a UNIT ATTENTION, for example a power on/reset, so
@@ -1146,29 +1129,29 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1146 SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending" 1129 SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: Sending"
1147 " REPORT LUNS to %s (try %d)\n", devname, 1130 " REPORT LUNS to %s (try %d)\n", devname,
1148 retries)); 1131 retries));
1149 scsi_wait_req(sreq, scsi_cmd, lun_data, length, 1132
1150 SCSI_TIMEOUT + 4*HZ, 3); 1133 result = scsi_execute_req(sdev, scsi_cmd, DMA_FROM_DEVICE,
1134 lun_data, length, &sshdr,
1135 SCSI_TIMEOUT + 4 * HZ, 3);
1136
1151 SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS" 1137 SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "scsi scan: REPORT LUNS"
1152 " %s (try %d) result 0x%x\n", sreq->sr_result 1138 " %s (try %d) result 0x%x\n", result
1153 ? "failed" : "successful", retries, 1139 ? "failed" : "successful", retries, result));
1154 sreq->sr_result)); 1140 if (result == 0)
1155 if (sreq->sr_result == 0)
1156 break; 1141 break;
1157 else if (scsi_request_normalize_sense(sreq, &sshdr)) { 1142 else if (scsi_sense_valid(&sshdr)) {
1158 if (sshdr.sense_key != UNIT_ATTENTION) 1143 if (sshdr.sense_key != UNIT_ATTENTION)
1159 break; 1144 break;
1160 } 1145 }
1161 } 1146 }
1162 1147
1163 if (sreq->sr_result) { 1148 if (result) {
1164 /* 1149 /*
1165 * The device probably does not support a REPORT LUN command 1150 * The device probably does not support a REPORT LUN command
1166 */ 1151 */
1167 kfree(lun_data); 1152 kfree(lun_data);
1168 scsi_release_request(sreq);
1169 return 1; 1153 return 1;
1170 } 1154 }
1171 scsi_release_request(sreq);
1172 1155
1173 /* 1156 /*
1174 * Get the length from the first four bytes of lun_data. 1157 * Get the length from the first four bytes of lun_data.
@@ -1242,8 +1225,6 @@ static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
1242 kfree(lun_data); 1225 kfree(lun_data);
1243 return 0; 1226 return 0;
1244 1227
1245 out_release_request:
1246 scsi_release_request(sreq);
1247 out: 1228 out:
1248 /* 1229 /*
1249 * We are out of memory, don't try scanning any further. 1230 * We are out of memory, don't try scanning any further.
@@ -1265,9 +1246,12 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
1265 1246
1266 get_device(&starget->dev); 1247 get_device(&starget->dev);
1267 down(&shost->scan_mutex); 1248 down(&shost->scan_mutex);
1268 res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); 1249 if (scsi_host_scan_allowed(shost)) {
1269 if (res != SCSI_SCAN_LUN_PRESENT) 1250 res = scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1,
1270 sdev = ERR_PTR(-ENODEV); 1251 hostdata);
1252 if (res != SCSI_SCAN_LUN_PRESENT)
1253 sdev = ERR_PTR(-ENODEV);
1254 }
1271 up(&shost->scan_mutex); 1255 up(&shost->scan_mutex);
1272 scsi_target_reap(starget); 1256 scsi_target_reap(starget);
1273 put_device(&starget->dev); 1257 put_device(&starget->dev);
@@ -1417,11 +1401,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1417 return -EINVAL; 1401 return -EINVAL;
1418 1402
1419 down(&shost->scan_mutex); 1403 down(&shost->scan_mutex);
1420 if (channel == SCAN_WILD_CARD) 1404 if (scsi_host_scan_allowed(shost)) {
1421 for (channel = 0; channel <= shost->max_channel; channel++) 1405 if (channel == SCAN_WILD_CARD)
1406 for (channel = 0; channel <= shost->max_channel;
1407 channel++)
1408 scsi_scan_channel(shost, channel, id, lun,
1409 rescan);
1410 else
1422 scsi_scan_channel(shost, channel, id, lun, rescan); 1411 scsi_scan_channel(shost, channel, id, lun, rescan);
1423 else 1412 }
1424 scsi_scan_channel(shost, channel, id, lun, rescan);
1425 up(&shost->scan_mutex); 1413 up(&shost->scan_mutex);
1426 1414
1427 return 0; 1415 return 0;