diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 67 |
1 files changed, 40 insertions, 27 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 19c9a232a754..76577fae60fa 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -1276,27 +1276,8 @@ void scsi_rescan_device(struct device *dev) | |||
1276 | } | 1276 | } |
1277 | EXPORT_SYMBOL(scsi_rescan_device); | 1277 | EXPORT_SYMBOL(scsi_rescan_device); |
1278 | 1278 | ||
1279 | /** | 1279 | static void __scsi_scan_target(struct device *parent, unsigned int channel, |
1280 | * scsi_scan_target - scan a target id, possibly including all LUNs on the | 1280 | unsigned int id, unsigned int lun, int rescan) |
1281 | * target. | ||
1282 | * @sdevsca: Scsi_Device handle for scanning | ||
1283 | * @shost: host to scan | ||
1284 | * @channel: channel to scan | ||
1285 | * @id: target id to scan | ||
1286 | * | ||
1287 | * Description: | ||
1288 | * Scan the target id on @shost, @channel, and @id. Scan at least LUN | ||
1289 | * 0, and possibly all LUNs on the target id. | ||
1290 | * | ||
1291 | * Use the pre-allocated @sdevscan as a handle for the scanning. This | ||
1292 | * function sets sdevscan->host, sdevscan->id and sdevscan->lun; the | ||
1293 | * scanning functions modify sdevscan->lun. | ||
1294 | * | ||
1295 | * First try a REPORT LUN scan, if that does not scan the target, do a | ||
1296 | * sequential scan of LUNs on the target id. | ||
1297 | **/ | ||
1298 | void scsi_scan_target(struct device *parent, unsigned int channel, | ||
1299 | unsigned int id, unsigned int lun, int rescan) | ||
1300 | { | 1281 | { |
1301 | struct Scsi_Host *shost = dev_to_shost(parent); | 1282 | struct Scsi_Host *shost = dev_to_shost(parent); |
1302 | int bflags = 0; | 1283 | int bflags = 0; |
@@ -1310,9 +1291,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel, | |||
1310 | */ | 1291 | */ |
1311 | return; | 1292 | return; |
1312 | 1293 | ||
1313 | |||
1314 | starget = scsi_alloc_target(parent, channel, id); | 1294 | starget = scsi_alloc_target(parent, channel, id); |
1315 | |||
1316 | if (!starget) | 1295 | if (!starget) |
1317 | return; | 1296 | return; |
1318 | 1297 | ||
@@ -1358,6 +1337,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel, | |||
1358 | 1337 | ||
1359 | put_device(&starget->dev); | 1338 | put_device(&starget->dev); |
1360 | } | 1339 | } |
1340 | |||
1341 | /** | ||
1342 | * scsi_scan_target - scan a target id, possibly including all LUNs on the | ||
1343 | * target. | ||
1344 | * @parent: host to scan | ||
1345 | * @channel: channel to scan | ||
1346 | * @id: target id to scan | ||
1347 | * @lun: Specific LUN to scan or SCAN_WILD_CARD | ||
1348 | * @rescan: passed to LUN scanning routines | ||
1349 | * | ||
1350 | * Description: | ||
1351 | * Scan the target id on @parent, @channel, and @id. Scan at least LUN 0, | ||
1352 | * and possibly all LUNs on the target id. | ||
1353 | * | ||
1354 | * First try a REPORT LUN scan, if that does not scan the target, do a | ||
1355 | * sequential scan of LUNs on the target id. | ||
1356 | **/ | ||
1357 | void scsi_scan_target(struct device *parent, unsigned int channel, | ||
1358 | unsigned int id, unsigned int lun, int rescan) | ||
1359 | { | ||
1360 | struct Scsi_Host *shost = dev_to_shost(parent); | ||
1361 | |||
1362 | down(&shost->scan_mutex); | ||
1363 | if (scsi_host_scan_allowed(shost)) | ||
1364 | __scsi_scan_target(parent, channel, id, lun, rescan); | ||
1365 | up(&shost->scan_mutex); | ||
1366 | } | ||
1361 | EXPORT_SYMBOL(scsi_scan_target); | 1367 | EXPORT_SYMBOL(scsi_scan_target); |
1362 | 1368 | ||
1363 | static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, | 1369 | static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, |
@@ -1383,10 +1389,12 @@ static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, | |||
1383 | order_id = shost->max_id - id - 1; | 1389 | order_id = shost->max_id - id - 1; |
1384 | else | 1390 | else |
1385 | order_id = id; | 1391 | order_id = id; |
1386 | scsi_scan_target(&shost->shost_gendev, channel, order_id, lun, rescan); | 1392 | __scsi_scan_target(&shost->shost_gendev, channel, |
1393 | order_id, lun, rescan); | ||
1387 | } | 1394 | } |
1388 | else | 1395 | else |
1389 | scsi_scan_target(&shost->shost_gendev, channel, id, lun, rescan); | 1396 | __scsi_scan_target(&shost->shost_gendev, channel, |
1397 | id, lun, rescan); | ||
1390 | } | 1398 | } |
1391 | 1399 | ||
1392 | int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | 1400 | int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, |
@@ -1484,12 +1492,15 @@ void scsi_forget_host(struct Scsi_Host *shost) | |||
1484 | */ | 1492 | */ |
1485 | struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) | 1493 | struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) |
1486 | { | 1494 | { |
1487 | struct scsi_device *sdev; | 1495 | struct scsi_device *sdev = NULL; |
1488 | struct scsi_target *starget; | 1496 | struct scsi_target *starget; |
1489 | 1497 | ||
1498 | down(&shost->scan_mutex); | ||
1499 | if (!scsi_host_scan_allowed(shost)) | ||
1500 | goto out; | ||
1490 | starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id); | 1501 | starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id); |
1491 | if (!starget) | 1502 | if (!starget) |
1492 | return NULL; | 1503 | goto out; |
1493 | 1504 | ||
1494 | sdev = scsi_alloc_sdev(starget, 0, NULL); | 1505 | sdev = scsi_alloc_sdev(starget, 0, NULL); |
1495 | if (sdev) { | 1506 | if (sdev) { |
@@ -1497,6 +1508,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) | |||
1497 | sdev->borken = 0; | 1508 | sdev->borken = 0; |
1498 | } | 1509 | } |
1499 | put_device(&starget->dev); | 1510 | put_device(&starget->dev); |
1511 | out: | ||
1512 | up(&shost->scan_mutex); | ||
1500 | return sdev; | 1513 | return sdev; |
1501 | } | 1514 | } |
1502 | EXPORT_SYMBOL(scsi_get_host_dev); | 1515 | EXPORT_SYMBOL(scsi_get_host_dev); |