aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/scsi_scan.c67
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}
1277EXPORT_SYMBOL(scsi_rescan_device); 1277EXPORT_SYMBOL(scsi_rescan_device);
1278 1278
1279/** 1279static 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 **/
1298void 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 **/
1357void 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}
1361EXPORT_SYMBOL(scsi_scan_target); 1367EXPORT_SYMBOL(scsi_scan_target);
1362 1368
1363static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel, 1369static 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
1392int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, 1400int 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 */
1485struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) 1493struct 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}
1502EXPORT_SYMBOL(scsi_get_host_dev); 1515EXPORT_SYMBOL(scsi_get_host_dev);