diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
| -rw-r--r-- | drivers/scsi/scsi_scan.c | 34 | 
1 files changed, 11 insertions, 23 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 2e5fe584aad..56a93794c47 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -147,7 +147,7 @@ int scsi_complete_async_scans(void)  	do {  		if (list_empty(&scanning_hosts)) -			goto out; +			return 0;  		/* If we can't get memory immediately, that's OK.  Just  		 * sleep a little.  Even if we never get memory, the async  		 * scans will finish eventually. @@ -179,26 +179,11 @@ int scsi_complete_async_scans(void)  	}   done:  	spin_unlock(&async_scan_lock); -	kfree(data); - - out: -	async_synchronize_full_domain(&scsi_sd_probe_domain); +	kfree(data);  	return 0;  } -/* Only exported for the benefit of scsi_wait_scan */ -EXPORT_SYMBOL_GPL(scsi_complete_async_scans); - -#ifndef MODULE -/* - * For async scanning we need to wait for all the scans to complete before - * trying to mount the root fs.  Otherwise non-modular drivers may not be ready - * yet. - */ -late_initcall(scsi_complete_async_scans); -#endif -  /**   * scsi_unlock_floptical - unlock device via a special MODE SENSE command   * @sdev:	scsi device to send command to @@ -1717,6 +1702,9 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)  {  	struct scsi_device *sdev;  	shost_for_each_device(sdev, shost) { +		/* target removed before the device could be added */ +		if (sdev->sdev_state == SDEV_DEL) +			continue;  		if (!scsi_host_scan_allowed(shost) ||  		    scsi_sysfs_add_sdev(sdev) != 0)  			__scsi_remove_device(sdev); @@ -1842,14 +1830,13 @@ static void do_scsi_scan_host(struct Scsi_Host *shost)  	}  } -static int do_scan_async(void *_data) +static void do_scan_async(void *_data, async_cookie_t c)  {  	struct async_scan_data *data = _data;  	struct Scsi_Host *shost = data->shost;  	do_scsi_scan_host(shost);  	scsi_finish_async_scan(data); -	return 0;  }  /** @@ -1858,7 +1845,6 @@ static int do_scan_async(void *_data)   **/  void scsi_scan_host(struct Scsi_Host *shost)  { -	struct task_struct *p;  	struct async_scan_data *data;  	if (strncmp(scsi_scan_type, "none", 4) == 0) @@ -1873,9 +1859,11 @@ void scsi_scan_host(struct Scsi_Host *shost)  		return;  	} -	p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); -	if (IS_ERR(p)) -		do_scan_async(data); +	/* register with the async subsystem so wait_for_device_probe() +	 * will flush this work +	 */ +	async_schedule(do_scan_async, data); +  	/* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */  }  EXPORT_SYMBOL(scsi_scan_host);  |