|
@@ -1513,14 +1513,18 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
|
|
|
starget = scsi_alloc_target(parent, channel, id);
|
|
|
if (!starget)
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
+ scsi_autopm_get_target(starget);
|
|
|
|
|
|
mutex_lock(&shost->scan_mutex);
|
|
|
if (!shost->async_scan)
|
|
|
scsi_complete_async_scans();
|
|
|
|
|
|
- if (scsi_host_scan_allowed(shost))
|
|
|
+ if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
|
|
scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
|
|
|
+ scsi_autopm_put_host(shost);
|
|
|
+ }
|
|
|
mutex_unlock(&shost->scan_mutex);
|
|
|
+ scsi_autopm_put_target(starget);
|
|
|
scsi_target_reap(starget);
|
|
|
put_device(&starget->dev);
|
|
|
|
|
@@ -1574,6 +1578,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
starget = scsi_alloc_target(parent, channel, id);
|
|
|
if (!starget)
|
|
|
return;
|
|
|
+ scsi_autopm_get_target(starget);
|
|
|
|
|
|
if (lun != SCAN_WILD_CARD) {
|
|
|
/*
|
|
@@ -1599,6 +1604,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
}
|
|
|
|
|
|
out_reap:
|
|
|
+ scsi_autopm_put_target(starget);
|
|
|
/* now determine if the target has any children at all
|
|
|
* and if not, nuke it */
|
|
|
scsi_target_reap(starget);
|
|
@@ -1633,8 +1639,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
|
|
|
if (!shost->async_scan)
|
|
|
scsi_complete_async_scans();
|
|
|
|
|
|
- if (scsi_host_scan_allowed(shost))
|
|
|
+ if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
|
|
__scsi_scan_target(parent, channel, id, lun, rescan);
|
|
|
+ scsi_autopm_put_host(shost);
|
|
|
+ }
|
|
|
mutex_unlock(&shost->scan_mutex);
|
|
|
}
|
|
|
EXPORT_SYMBOL(scsi_scan_target);
|
|
@@ -1686,7 +1694,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
|
|
if (!shost->async_scan)
|
|
|
scsi_complete_async_scans();
|
|
|
|
|
|
- if (scsi_host_scan_allowed(shost)) {
|
|
|
+ if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
|
|
|
if (channel == SCAN_WILD_CARD)
|
|
|
for (channel = 0; channel <= shost->max_channel;
|
|
|
channel++)
|
|
@@ -1694,6 +1702,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
|
|
|
rescan);
|
|
|
else
|
|
|
scsi_scan_channel(shost, channel, id, lun, rescan);
|
|
|
+ scsi_autopm_put_host(shost);
|
|
|
}
|
|
|
mutex_unlock(&shost->scan_mutex);
|
|
|
|
|
@@ -1831,8 +1840,11 @@ static void do_scsi_scan_host(struct Scsi_Host *shost)
|
|
|
static int do_scan_async(void *_data)
|
|
|
{
|
|
|
struct async_scan_data *data = _data;
|
|
|
- do_scsi_scan_host(data->shost);
|
|
|
+ struct Scsi_Host *shost = data->shost;
|
|
|
+
|
|
|
+ do_scsi_scan_host(shost);
|
|
|
scsi_finish_async_scan(data);
|
|
|
+ scsi_autopm_put_host(shost);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -1847,16 +1859,20 @@ void scsi_scan_host(struct Scsi_Host *shost)
|
|
|
|
|
|
if (strncmp(scsi_scan_type, "none", 4) == 0)
|
|
|
return;
|
|
|
+ if (scsi_autopm_get_host(shost) < 0)
|
|
|
+ return;
|
|
|
|
|
|
data = scsi_prep_async_scan(shost);
|
|
|
if (!data) {
|
|
|
do_scsi_scan_host(shost);
|
|
|
+ scsi_autopm_put_host(shost);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
|
|
|
if (IS_ERR(p))
|
|
|
do_scan_async(data);
|
|
|
+ /* scsi_autopm_put_host(shost) is called in do_scan_async() */
|
|
|
}
|
|
|
EXPORT_SYMBOL(scsi_scan_host);
|
|
|
|