aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sr.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 5fc97d2ba2fd..2e8ddd77366f 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -45,6 +45,7 @@
45#include <linux/blkdev.h> 45#include <linux/blkdev.h>
46#include <linux/mutex.h> 46#include <linux/mutex.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/pm_runtime.h>
48#include <asm/uaccess.h> 49#include <asm/uaccess.h>
49 50
50#include <scsi/scsi.h> 51#include <scsi/scsi.h>
@@ -79,6 +80,11 @@ static DEFINE_MUTEX(sr_mutex);
79static int sr_probe(struct device *); 80static int sr_probe(struct device *);
80static int sr_remove(struct device *); 81static int sr_remove(struct device *);
81static int sr_done(struct scsi_cmnd *); 82static int sr_done(struct scsi_cmnd *);
83static int sr_runtime_suspend(struct device *dev);
84
85static struct dev_pm_ops sr_pm_ops = {
86 .runtime_suspend = sr_runtime_suspend,
87};
82 88
83static struct scsi_driver sr_template = { 89static struct scsi_driver sr_template = {
84 .owner = THIS_MODULE, 90 .owner = THIS_MODULE,
@@ -86,6 +92,7 @@ static struct scsi_driver sr_template = {
86 .name = "sr", 92 .name = "sr",
87 .probe = sr_probe, 93 .probe = sr_probe,
88 .remove = sr_remove, 94 .remove = sr_remove,
95 .pm = &sr_pm_ops,
89 }, 96 },
90 .done = sr_done, 97 .done = sr_done,
91}; 98};
@@ -131,6 +138,16 @@ static inline struct scsi_cd *scsi_cd(struct gendisk *disk)
131 return container_of(disk->private_data, struct scsi_cd, driver); 138 return container_of(disk->private_data, struct scsi_cd, driver);
132} 139}
133 140
141static int sr_runtime_suspend(struct device *dev)
142{
143 struct scsi_cd *cd = dev_get_drvdata(dev);
144
145 if (cd->media_present)
146 return -EBUSY;
147 else
148 return 0;
149}
150
134/* 151/*
135 * The get and put routines for the struct scsi_cd. Note this entity 152 * The get and put routines for the struct scsi_cd. Note this entity
136 * has a scsi_device pointer and owns a reference to this. 153 * has a scsi_device pointer and owns a reference to this.
@@ -146,7 +163,8 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk)
146 kref_get(&cd->kref); 163 kref_get(&cd->kref);
147 if (scsi_device_get(cd->device)) 164 if (scsi_device_get(cd->device))
148 goto out_put; 165 goto out_put;
149 goto out; 166 if (!scsi_autopm_get_device(cd->device))
167 goto out;
150 168
151 out_put: 169 out_put:
152 kref_put(&cd->kref, sr_kref_release); 170 kref_put(&cd->kref, sr_kref_release);
@@ -162,6 +180,7 @@ static void scsi_cd_put(struct scsi_cd *cd)
162 180
163 mutex_lock(&sr_ref_mutex); 181 mutex_lock(&sr_ref_mutex);
164 kref_put(&cd->kref, sr_kref_release); 182 kref_put(&cd->kref, sr_kref_release);
183 scsi_autopm_put_device(sdev);
165 scsi_device_put(sdev); 184 scsi_device_put(sdev);
166 mutex_unlock(&sr_ref_mutex); 185 mutex_unlock(&sr_ref_mutex);
167} 186}
@@ -540,6 +559,8 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
540 void __user *argp = (void __user *)arg; 559 void __user *argp = (void __user *)arg;
541 int ret; 560 int ret;
542 561
562 scsi_autopm_get_device(cd->device);
563
543 mutex_lock(&sr_mutex); 564 mutex_lock(&sr_mutex);
544 565
545 /* 566 /*
@@ -571,6 +592,7 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
571 592
572out: 593out:
573 mutex_unlock(&sr_mutex); 594 mutex_unlock(&sr_mutex);
595 scsi_autopm_put_device(cd->device);
574 return ret; 596 return ret;
575} 597}
576 598
@@ -578,7 +600,13 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
578 unsigned int clearing) 600 unsigned int clearing)
579{ 601{
580 struct scsi_cd *cd = scsi_cd(disk); 602 struct scsi_cd *cd = scsi_cd(disk);
581 return cdrom_check_events(&cd->cdi, clearing); 603 unsigned int ret;
604
605 scsi_autopm_get_device(cd->device);
606 ret = cdrom_check_events(&cd->cdi, clearing);
607 scsi_autopm_put_device(cd->device);
608
609 return ret;
582} 610}
583 611
584static int sr_block_revalidate_disk(struct gendisk *disk) 612static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -586,12 +614,16 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
586 struct scsi_cd *cd = scsi_cd(disk); 614 struct scsi_cd *cd = scsi_cd(disk);
587 struct scsi_sense_hdr sshdr; 615 struct scsi_sense_hdr sshdr;
588 616
617 scsi_autopm_get_device(cd->device);
618
589 /* if the unit is not ready, nothing more to do */ 619 /* if the unit is not ready, nothing more to do */
590 if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) 620 if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
591 return 0; 621 goto out;
592 622
593 sr_cd_check(&cd->cdi); 623 sr_cd_check(&cd->cdi);
594 get_sectorsize(cd); 624 get_sectorsize(cd);
625out:
626 scsi_autopm_put_device(cd->device);
595 return 0; 627 return 0;
596} 628}
597 629
@@ -718,6 +750,8 @@ static int sr_probe(struct device *dev)
718 750
719 sdev_printk(KERN_DEBUG, sdev, 751 sdev_printk(KERN_DEBUG, sdev,
720 "Attached scsi CD-ROM %s\n", cd->cdi.name); 752 "Attached scsi CD-ROM %s\n", cd->cdi.name);
753 scsi_autopm_put_device(cd->device);
754
721 return 0; 755 return 0;
722 756
723fail_put: 757fail_put:
@@ -965,6 +999,8 @@ static int sr_remove(struct device *dev)
965{ 999{
966 struct scsi_cd *cd = dev_get_drvdata(dev); 1000 struct scsi_cd *cd = dev_get_drvdata(dev);
967 1001
1002 scsi_autopm_get_device(cd->device);
1003
968 blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn); 1004 blk_queue_prep_rq(cd->device->request_queue, scsi_prep_fn);
969 del_gendisk(cd->disk); 1005 del_gendisk(cd->disk);
970 1006