diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 108daead7ae8..8e2e893db9e7 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -796,6 +796,10 @@ static int sd_open(struct block_device *bdev, fmode_t mode) | |||
796 | 796 | ||
797 | sdev = sdkp->device; | 797 | sdev = sdkp->device; |
798 | 798 | ||
799 | retval = scsi_autopm_get_device(sdev); | ||
800 | if (retval) | ||
801 | goto error_autopm; | ||
802 | |||
799 | /* | 803 | /* |
800 | * If the device is in error recovery, wait until it is done. | 804 | * If the device is in error recovery, wait until it is done. |
801 | * If the device is offline, then disallow any access to it. | 805 | * If the device is offline, then disallow any access to it. |
@@ -840,6 +844,8 @@ static int sd_open(struct block_device *bdev, fmode_t mode) | |||
840 | return 0; | 844 | return 0; |
841 | 845 | ||
842 | error_out: | 846 | error_out: |
847 | scsi_autopm_put_device(sdev); | ||
848 | error_autopm: | ||
843 | scsi_disk_put(sdkp); | 849 | scsi_disk_put(sdkp); |
844 | return retval; | 850 | return retval; |
845 | } | 851 | } |
@@ -873,6 +879,8 @@ static int sd_release(struct gendisk *disk, fmode_t mode) | |||
873 | * XXX and what if there are packets in flight and this close() | 879 | * XXX and what if there are packets in flight and this close() |
874 | * XXX is followed by a "rmmod sd_mod"? | 880 | * XXX is followed by a "rmmod sd_mod"? |
875 | */ | 881 | */ |
882 | |||
883 | scsi_autopm_put_device(sdev); | ||
876 | scsi_disk_put(sdkp); | 884 | scsi_disk_put(sdkp); |
877 | return 0; | 885 | return 0; |
878 | } | 886 | } |
@@ -2273,7 +2281,6 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2273 | if (sdp->removable) | 2281 | if (sdp->removable) |
2274 | gd->flags |= GENHD_FL_REMOVABLE; | 2282 | gd->flags |= GENHD_FL_REMOVABLE; |
2275 | 2283 | ||
2276 | dev_set_drvdata(dev, sdkp); | ||
2277 | add_disk(gd); | 2284 | add_disk(gd); |
2278 | sd_dif_config_host(sdkp); | 2285 | sd_dif_config_host(sdkp); |
2279 | 2286 | ||
@@ -2281,6 +2288,7 @@ static void sd_probe_async(void *data, async_cookie_t cookie) | |||
2281 | 2288 | ||
2282 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", | 2289 | sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", |
2283 | sdp->removable ? "removable " : ""); | 2290 | sdp->removable ? "removable " : ""); |
2291 | scsi_autopm_put_device(sdp); | ||
2284 | put_device(&sdkp->dev); | 2292 | put_device(&sdkp->dev); |
2285 | } | 2293 | } |
2286 | 2294 | ||
@@ -2358,14 +2366,15 @@ static int sd_probe(struct device *dev) | |||
2358 | } | 2366 | } |
2359 | 2367 | ||
2360 | device_initialize(&sdkp->dev); | 2368 | device_initialize(&sdkp->dev); |
2361 | sdkp->dev.parent = &sdp->sdev_gendev; | 2369 | sdkp->dev.parent = dev; |
2362 | sdkp->dev.class = &sd_disk_class; | 2370 | sdkp->dev.class = &sd_disk_class; |
2363 | dev_set_name(&sdkp->dev, dev_name(&sdp->sdev_gendev)); | 2371 | dev_set_name(&sdkp->dev, dev_name(dev)); |
2364 | 2372 | ||
2365 | if (device_add(&sdkp->dev)) | 2373 | if (device_add(&sdkp->dev)) |
2366 | goto out_free_index; | 2374 | goto out_free_index; |
2367 | 2375 | ||
2368 | get_device(&sdp->sdev_gendev); | 2376 | get_device(dev); |
2377 | dev_set_drvdata(dev, sdkp); | ||
2369 | 2378 | ||
2370 | get_device(&sdkp->dev); /* prevent release before async_schedule */ | 2379 | get_device(&sdkp->dev); /* prevent release before async_schedule */ |
2371 | async_schedule(sd_probe_async, sdkp); | 2380 | async_schedule(sd_probe_async, sdkp); |
@@ -2399,8 +2408,10 @@ static int sd_remove(struct device *dev) | |||
2399 | { | 2408 | { |
2400 | struct scsi_disk *sdkp; | 2409 | struct scsi_disk *sdkp; |
2401 | 2410 | ||
2402 | async_synchronize_full(); | ||
2403 | sdkp = dev_get_drvdata(dev); | 2411 | sdkp = dev_get_drvdata(dev); |
2412 | scsi_autopm_get_device(sdkp->device); | ||
2413 | |||
2414 | async_synchronize_full(); | ||
2404 | blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); | 2415 | blk_queue_prep_rq(sdkp->device->request_queue, scsi_prep_fn); |
2405 | blk_queue_unprep_rq(sdkp->device->request_queue, NULL); | 2416 | blk_queue_unprep_rq(sdkp->device->request_queue, NULL); |
2406 | device_del(&sdkp->dev); | 2417 | device_del(&sdkp->dev); |