aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c21
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
842error_out: 846error_out:
847 scsi_autopm_put_device(sdev);
848error_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);