diff options
-rw-r--r-- | drivers/scsi/scsi_pm.c | 62 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 37 |
2 files changed, 29 insertions, 70 deletions
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c index af4c050ce6e4..001e9ceda4c3 100644 --- a/drivers/scsi/scsi_pm.c +++ b/drivers/scsi/scsi_pm.c | |||
@@ -16,6 +16,8 @@ | |||
16 | 16 | ||
17 | #include "scsi_priv.h" | 17 | #include "scsi_priv.h" |
18 | 18 | ||
19 | #ifdef CONFIG_PM_SLEEP | ||
20 | |||
19 | static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *)) | 21 | static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *)) |
20 | { | 22 | { |
21 | int err; | 23 | int err; |
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *)) | |||
43 | return err; | 45 | return err; |
44 | } | 46 | } |
45 | 47 | ||
46 | #ifdef CONFIG_PM_SLEEP | ||
47 | |||
48 | static int | 48 | static int |
49 | scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *)) | 49 | scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *)) |
50 | { | 50 | { |
@@ -145,38 +145,22 @@ static int scsi_bus_restore(struct device *dev) | |||
145 | 145 | ||
146 | #ifdef CONFIG_PM_RUNTIME | 146 | #ifdef CONFIG_PM_RUNTIME |
147 | 147 | ||
148 | static int sdev_blk_runtime_suspend(struct scsi_device *sdev, | 148 | static int sdev_runtime_suspend(struct device *dev) |
149 | int (*cb)(struct device *)) | ||
150 | { | 149 | { |
150 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
151 | struct scsi_device *sdev = to_scsi_device(dev); | ||
151 | int err; | 152 | int err; |
152 | 153 | ||
153 | err = blk_pre_runtime_suspend(sdev->request_queue); | 154 | err = blk_pre_runtime_suspend(sdev->request_queue); |
154 | if (err) | 155 | if (err) |
155 | return err; | 156 | return err; |
156 | if (cb) | 157 | if (pm && pm->runtime_suspend) |
157 | err = cb(&sdev->sdev_gendev); | 158 | err = pm->runtime_suspend(dev); |
158 | blk_post_runtime_suspend(sdev->request_queue, err); | 159 | blk_post_runtime_suspend(sdev->request_queue, err); |
159 | 160 | ||
160 | return err; | 161 | return err; |
161 | } | 162 | } |
162 | 163 | ||
163 | static int sdev_runtime_suspend(struct device *dev) | ||
164 | { | ||
165 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
166 | int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL; | ||
167 | struct scsi_device *sdev = to_scsi_device(dev); | ||
168 | int err; | ||
169 | |||
170 | if (sdev->request_queue->dev) | ||
171 | return sdev_blk_runtime_suspend(sdev, cb); | ||
172 | |||
173 | err = scsi_dev_type_suspend(dev, cb); | ||
174 | if (err == -EAGAIN) | ||
175 | pm_schedule_suspend(dev, jiffies_to_msecs( | ||
176 | round_jiffies_up_relative(HZ/10))); | ||
177 | return err; | ||
178 | } | ||
179 | |||
180 | static int scsi_runtime_suspend(struct device *dev) | 164 | static int scsi_runtime_suspend(struct device *dev) |
181 | { | 165 | { |
182 | int err = 0; | 166 | int err = 0; |
@@ -190,31 +174,20 @@ static int scsi_runtime_suspend(struct device *dev) | |||
190 | return err; | 174 | return err; |
191 | } | 175 | } |
192 | 176 | ||
193 | static int sdev_blk_runtime_resume(struct scsi_device *sdev, | 177 | static int sdev_runtime_resume(struct device *dev) |
194 | int (*cb)(struct device *)) | ||
195 | { | 178 | { |
179 | struct scsi_device *sdev = to_scsi_device(dev); | ||
180 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
196 | int err = 0; | 181 | int err = 0; |
197 | 182 | ||
198 | blk_pre_runtime_resume(sdev->request_queue); | 183 | blk_pre_runtime_resume(sdev->request_queue); |
199 | if (cb) | 184 | if (pm && pm->runtime_resume) |
200 | err = cb(&sdev->sdev_gendev); | 185 | err = pm->runtime_resume(dev); |
201 | blk_post_runtime_resume(sdev->request_queue, err); | 186 | blk_post_runtime_resume(sdev->request_queue, err); |
202 | 187 | ||
203 | return err; | 188 | return err; |
204 | } | 189 | } |
205 | 190 | ||
206 | static int sdev_runtime_resume(struct device *dev) | ||
207 | { | ||
208 | struct scsi_device *sdev = to_scsi_device(dev); | ||
209 | const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; | ||
210 | int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL; | ||
211 | |||
212 | if (sdev->request_queue->dev) | ||
213 | return sdev_blk_runtime_resume(sdev, cb); | ||
214 | else | ||
215 | return scsi_dev_type_resume(dev, cb); | ||
216 | } | ||
217 | |||
218 | static int scsi_runtime_resume(struct device *dev) | 191 | static int scsi_runtime_resume(struct device *dev) |
219 | { | 192 | { |
220 | int err = 0; | 193 | int err = 0; |
@@ -235,14 +208,11 @@ static int scsi_runtime_idle(struct device *dev) | |||
235 | /* Insert hooks here for targets, hosts, and transport classes */ | 208 | /* Insert hooks here for targets, hosts, and transport classes */ |
236 | 209 | ||
237 | if (scsi_is_sdev_device(dev)) { | 210 | if (scsi_is_sdev_device(dev)) { |
238 | struct scsi_device *sdev = to_scsi_device(dev); | 211 | pm_runtime_mark_last_busy(dev); |
239 | 212 | pm_runtime_autosuspend(dev); | |
240 | if (sdev->request_queue->dev) { | 213 | return -EBUSY; |
241 | pm_runtime_mark_last_busy(dev); | ||
242 | pm_runtime_autosuspend(dev); | ||
243 | return -EBUSY; | ||
244 | } | ||
245 | } | 214 | } |
215 | |||
246 | return 0; | 216 | return 0; |
247 | } | 217 | } |
248 | 218 | ||
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 119d67f9c47e..40d85929aefe 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -161,14 +161,10 @@ static inline struct scsi_cd *scsi_cd_get(struct gendisk *disk) | |||
161 | goto out; | 161 | goto out; |
162 | cd = scsi_cd(disk); | 162 | cd = scsi_cd(disk); |
163 | kref_get(&cd->kref); | 163 | kref_get(&cd->kref); |
164 | if (scsi_device_get(cd->device)) | 164 | if (scsi_device_get(cd->device)) { |
165 | goto out_put; | 165 | kref_put(&cd->kref, sr_kref_release); |
166 | if (!scsi_autopm_get_device(cd->device)) | 166 | cd = NULL; |
167 | goto out; | 167 | } |
168 | |||
169 | out_put: | ||
170 | kref_put(&cd->kref, sr_kref_release); | ||
171 | cd = NULL; | ||
172 | out: | 168 | out: |
173 | mutex_unlock(&sr_ref_mutex); | 169 | mutex_unlock(&sr_ref_mutex); |
174 | return cd; | 170 | return cd; |
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd) | |||
180 | 176 | ||
181 | mutex_lock(&sr_ref_mutex); | 177 | mutex_lock(&sr_ref_mutex); |
182 | kref_put(&cd->kref, sr_kref_release); | 178 | kref_put(&cd->kref, sr_kref_release); |
183 | scsi_autopm_put_device(sdev); | ||
184 | scsi_device_put(sdev); | 179 | scsi_device_put(sdev); |
185 | mutex_unlock(&sr_ref_mutex); | 180 | mutex_unlock(&sr_ref_mutex); |
186 | } | 181 | } |
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
558 | void __user *argp = (void __user *)arg; | 553 | void __user *argp = (void __user *)arg; |
559 | int ret; | 554 | int ret; |
560 | 555 | ||
561 | scsi_autopm_get_device(cd->device); | ||
562 | |||
563 | mutex_lock(&sr_mutex); | 556 | mutex_lock(&sr_mutex); |
564 | 557 | ||
565 | /* | 558 | /* |
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
591 | 584 | ||
592 | out: | 585 | out: |
593 | mutex_unlock(&sr_mutex); | 586 | mutex_unlock(&sr_mutex); |
594 | scsi_autopm_put_device(cd->device); | ||
595 | return ret; | 587 | return ret; |
596 | } | 588 | } |
597 | 589 | ||
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk, | |||
599 | unsigned int clearing) | 591 | unsigned int clearing) |
600 | { | 592 | { |
601 | struct scsi_cd *cd = scsi_cd(disk); | 593 | struct scsi_cd *cd = scsi_cd(disk); |
602 | unsigned int ret; | ||
603 | 594 | ||
604 | if (atomic_read(&cd->device->disk_events_disable_depth) == 0) { | 595 | if (atomic_read(&cd->device->disk_events_disable_depth)) |
605 | scsi_autopm_get_device(cd->device); | 596 | return 0; |
606 | ret = cdrom_check_events(&cd->cdi, clearing); | ||
607 | scsi_autopm_put_device(cd->device); | ||
608 | } else { | ||
609 | ret = 0; | ||
610 | } | ||
611 | 597 | ||
612 | return ret; | 598 | return cdrom_check_events(&cd->cdi, clearing); |
613 | } | 599 | } |
614 | 600 | ||
615 | static int sr_block_revalidate_disk(struct gendisk *disk) | 601 | static int sr_block_revalidate_disk(struct gendisk *disk) |
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk) | |||
617 | struct scsi_cd *cd = scsi_cd(disk); | 603 | struct scsi_cd *cd = scsi_cd(disk); |
618 | struct scsi_sense_hdr sshdr; | 604 | struct scsi_sense_hdr sshdr; |
619 | 605 | ||
620 | scsi_autopm_get_device(cd->device); | ||
621 | |||
622 | /* if the unit is not ready, nothing more to do */ | 606 | /* if the unit is not ready, nothing more to do */ |
623 | if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) | 607 | if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) |
624 | goto out; | 608 | goto out; |
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk) | |||
626 | sr_cd_check(&cd->cdi); | 610 | sr_cd_check(&cd->cdi); |
627 | get_sectorsize(cd); | 611 | get_sectorsize(cd); |
628 | out: | 612 | out: |
629 | scsi_autopm_put_device(cd->device); | ||
630 | return 0; | 613 | return 0; |
631 | } | 614 | } |
632 | 615 | ||
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev) | |||
747 | if (register_cdrom(&cd->cdi)) | 730 | if (register_cdrom(&cd->cdi)) |
748 | goto fail_put; | 731 | goto fail_put; |
749 | 732 | ||
733 | /* | ||
734 | * Initialize block layer runtime PM stuffs before the | ||
735 | * periodic event checking request gets started in add_disk. | ||
736 | */ | ||
737 | blk_pm_runtime_init(sdev->request_queue, dev); | ||
738 | |||
750 | dev_set_drvdata(dev, cd); | 739 | dev_set_drvdata(dev, cd); |
751 | disk->flags |= GENHD_FL_REMOVABLE; | 740 | disk->flags |= GENHD_FL_REMOVABLE; |
752 | add_disk(disk); | 741 | add_disk(disk); |