summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_scan.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-07-26 10:18:45 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-09-09 10:24:31 -0500
commite517d3133f62c27b211f305a6dbd6f6ccac0db1b (patch)
treed427be7f70d9467d123063a8f547822e54ca1d2f /drivers/scsi/scsi_scan.c
parentcaf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff)
downloadlwn-e517d3133f62c27b211f305a6dbd6f6ccac0db1b.tar.gz
lwn-e517d3133f62c27b211f305a6dbd6f6ccac0db1b.zip
[SCSI] add missing scan mutex to scsi_scan_target()
This patch (as543) adds a private entry point to scsi_scan_target, for use when the caller already owns the scan_mutex, and updates the kerneldoc for that routine (which was badly out-of-date). It converts scsi_scan_channel to use the new entry point. Lastly, it modifies scsi_get_host_dev to make it acquire the scan_mutex, necessary since the routine adds a new scsi_device even if it doesn't do any actual scanning. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-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)
}
EXPORT_SYMBOL(scsi_rescan_device);
-/**
- * scsi_scan_target - scan a target id, possibly including all LUNs on the
- * target.
- * @sdevsca: Scsi_Device handle for scanning
- * @shost: host to scan
- * @channel: channel to scan
- * @id: target id to scan
- *
- * Description:
- * Scan the target id on @shost, @channel, and @id. Scan at least LUN
- * 0, and possibly all LUNs on the target id.
- *
- * Use the pre-allocated @sdevscan as a handle for the scanning. This
- * function sets sdevscan->host, sdevscan->id and sdevscan->lun; the
- * scanning functions modify sdevscan->lun.
- *
- * First try a REPORT LUN scan, if that does not scan the target, do a
- * sequential scan of LUNs on the target id.
- **/
-void scsi_scan_target(struct device *parent, unsigned int channel,
- unsigned int id, unsigned int lun, int rescan)
+static void __scsi_scan_target(struct device *parent, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
{
struct Scsi_Host *shost = dev_to_shost(parent);
int bflags = 0;
@@ -1310,9 +1291,7 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
*/
return;
-
starget = scsi_alloc_target(parent, channel, id);
-
if (!starget)
return;
@@ -1358,6 +1337,33 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
put_device(&starget->dev);
}
+
+/**
+ * scsi_scan_target - scan a target id, possibly including all LUNs on the
+ * target.
+ * @parent: host to scan
+ * @channel: channel to scan
+ * @id: target id to scan
+ * @lun: Specific LUN to scan or SCAN_WILD_CARD
+ * @rescan: passed to LUN scanning routines
+ *
+ * Description:
+ * Scan the target id on @parent, @channel, and @id. Scan at least LUN 0,
+ * and possibly all LUNs on the target id.
+ *
+ * First try a REPORT LUN scan, if that does not scan the target, do a
+ * sequential scan of LUNs on the target id.
+ **/
+void scsi_scan_target(struct device *parent, unsigned int channel,
+ unsigned int id, unsigned int lun, int rescan)
+{
+ struct Scsi_Host *shost = dev_to_shost(parent);
+
+ down(&shost->scan_mutex);
+ if (scsi_host_scan_allowed(shost))
+ __scsi_scan_target(parent, channel, id, lun, rescan);
+ up(&shost->scan_mutex);
+}
EXPORT_SYMBOL(scsi_scan_target);
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,
order_id = shost->max_id - id - 1;
else
order_id = id;
- scsi_scan_target(&shost->shost_gendev, channel, order_id, lun, rescan);
+ __scsi_scan_target(&shost->shost_gendev, channel,
+ order_id, lun, rescan);
}
else
- scsi_scan_target(&shost->shost_gendev, channel, id, lun, rescan);
+ __scsi_scan_target(&shost->shost_gendev, channel,
+ id, lun, rescan);
}
int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
@@ -1484,12 +1492,15 @@ void scsi_forget_host(struct Scsi_Host *shost)
*/
struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
{
- struct scsi_device *sdev;
+ struct scsi_device *sdev = NULL;
struct scsi_target *starget;
+ down(&shost->scan_mutex);
+ if (!scsi_host_scan_allowed(shost))
+ goto out;
starget = scsi_alloc_target(&shost->shost_gendev, 0, shost->this_id);
if (!starget)
- return NULL;
+ goto out;
sdev = scsi_alloc_sdev(starget, 0, NULL);
if (sdev) {
@@ -1497,6 +1508,8 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
sdev->borken = 0;
}
put_device(&starget->dev);
+ out:
+ up(&shost->scan_mutex);
return sdev;
}
EXPORT_SYMBOL(scsi_get_host_dev);