linux-pm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] scsi: sr: use block layer runtime PM
@ 2013-09-05  5:52 Aaron Lu
  2013-09-05 14:25 ` Alan Stern
  2013-09-09  2:01 ` [PATCH v3] " Aaron Lu
  0 siblings, 2 replies; 12+ messages in thread
From: Aaron Lu @ 2013-09-05  5:52 UTC (permalink / raw)
  To: James Bottomley, Alan Stern
  Cc: Rafael J. Wysocki, Linux-pm mailing list, SCSI development list

Migrate SCSI Optical Disk Drive(ODD) driver sr to make use of block
layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
simplified as all SCSI devices that implement runtime PM are now request
based.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
---
Note that due to ODD will be polled every 2 seconds, for suspend to
actually happen, the autosuspend_delay can not be set to more than 2
seconds.

Also, make sure to use the util-linux utility of version 2.23.2 or later,
as there is a bug fix for eject command to correctly update the ODD's
locked state. If the fix is not applied, after the ODD is ejected with the
eject command, it will not be able to enter runtime suspend state any
more due to SCSI EH code will submit a lock door command for the ODD
right after its parent ATA port is runtime suspended.
https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04

 drivers/scsi/scsi_pm.c | 58 ++++++++++++--------------------------------------
 drivers/scsi/sr.c      | 37 +++++++++++---------------------
 2 files changed, 27 insertions(+), 68 deletions(-)

diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index 4c5aabe..752edf0 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -144,38 +144,22 @@ static int scsi_bus_restore(struct device *dev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_suspend(struct device *dev)
 {
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	struct scsi_device *sdev = to_scsi_device(dev);
 	int err;
 
 	err = blk_pre_runtime_suspend(sdev->request_queue);
 	if (err)
 		return err;
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_suspend)
+		err = pm->runtime_suspend(dev);
 	blk_post_runtime_suspend(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_suspend(struct device *dev)
-{
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
-	struct scsi_device *sdev = to_scsi_device(dev);
-	int err;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_suspend(sdev, cb);
-
-	err = scsi_dev_type_suspend(dev, cb);
-	if (err == -EAGAIN)
-		pm_schedule_suspend(dev, jiffies_to_msecs(
-					round_jiffies_up_relative(HZ/10)));
-	return err;
-}
-
 static int scsi_runtime_suspend(struct device *dev)
 {
 	int err = 0;
@@ -189,31 +173,20 @@ static int scsi_runtime_suspend(struct device *dev)
 	return err;
 }
 
-static int sdev_blk_runtime_resume(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_resume(struct device *dev)
 {
+	struct scsi_device *sdev = to_scsi_device(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int err = 0;
 
 	blk_pre_runtime_resume(sdev->request_queue);
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_resume)
+		err = pm->runtime_resume(dev);
 	blk_post_runtime_resume(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_resume(struct device *dev)
-{
-	struct scsi_device *sdev = to_scsi_device(dev);
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_resume(sdev, cb);
-	else
-		return scsi_dev_type_resume(dev, cb);
-}
-
 static int scsi_runtime_resume(struct device *dev)
 {
 	int err = 0;
@@ -234,14 +207,11 @@ static int scsi_runtime_idle(struct device *dev)
 	/* Insert hooks here for targets, hosts, and transport classes */
 
 	if (scsi_is_sdev_device(dev)) {
-		struct scsi_device *sdev = to_scsi_device(dev);
-
-		if (sdev->request_queue->dev) {
-			pm_runtime_mark_last_busy(dev);
-			pm_runtime_autosuspend(dev);
-			return -EBUSY;
-		}
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_autosuspend(dev);
+		return -EBUSY;
 	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 119d67f..40d8592 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)
 		goto out;
 	cd = scsi_cd(disk);
 	kref_get(&cd->kref);
-	if (scsi_device_get(cd->device))
-		goto out_put;
-	if (!scsi_autopm_get_device(cd->device))
-		goto out;
-
- out_put:
-	kref_put(&cd->kref, sr_kref_release);
-	cd = NULL;
+	if (scsi_device_get(cd->device)) {
+		kref_put(&cd->kref, sr_kref_release);
+		cd = NULL;
+	}
  out:
 	mutex_unlock(&sr_ref_mutex);
 	return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
 
 	mutex_lock(&sr_ref_mutex);
 	kref_put(&cd->kref, sr_kref_release);
-	scsi_autopm_put_device(sdev);
 	scsi_device_put(sdev);
 	mutex_unlock(&sr_ref_mutex);
 }
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	scsi_autopm_get_device(cd->device);
-
 	mutex_lock(&sr_mutex);
 
 	/*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 out:
 	mutex_unlock(&sr_mutex);
-	scsi_autopm_put_device(cd->device);
 	return ret;
 }
 
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
 					  unsigned int clearing)
 {
 	struct scsi_cd *cd = scsi_cd(disk);
-	unsigned int ret;
 
-	if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
-		scsi_autopm_get_device(cd->device);
-		ret = cdrom_check_events(&cd->cdi, clearing);
-		scsi_autopm_put_device(cd->device);
-	} else {
-		ret = 0;
-	}
+	if (atomic_read(&cd->device->disk_events_disable_depth))
+		return 0;
 
-	return ret;
+	return cdrom_check_events(&cd->cdi, clearing);
 }
 
 static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	struct scsi_cd *cd = scsi_cd(disk);
 	struct scsi_sense_hdr sshdr;
 
-	scsi_autopm_get_device(cd->device);
-
 	/* if the unit is not ready, nothing more to do */
 	if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
 		goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	sr_cd_check(&cd->cdi);
 	get_sectorsize(cd);
 out:
-	scsi_autopm_put_device(cd->device);
 	return 0;
 }
 
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
 	if (register_cdrom(&cd->cdi))
 		goto fail_put;
 
+	/*
+	 * Initialize block layer runtime PM stuffs before the
+	 * periodic event checking request gets started in add_disk.
+	 */
+	blk_pm_runtime_init(sdev->request_queue, dev);
+
 	dev_set_drvdata(dev, cd);
 	disk->flags |= GENHD_FL_REMOVABLE;
 	add_disk(disk);
-- 
1.8.3.2.10.g43d11f4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] scsi: sr: use block layer runtime PM
  2013-09-05  5:52 [PATCH] scsi: sr: use block layer runtime PM Aaron Lu
@ 2013-09-05 14:25 ` Alan Stern
  2013-09-06  1:36   ` Aaron Lu
  2013-09-06  2:01   ` [PATCH v2] " Aaron Lu
  2013-09-09  2:01 ` [PATCH v3] " Aaron Lu
  1 sibling, 2 replies; 12+ messages in thread
From: Alan Stern @ 2013-09-05 14:25 UTC (permalink / raw)
  To: Aaron Lu
  Cc: James Bottomley, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On Thu, 5 Sep 2013, Aaron Lu wrote:

> Migrate SCSI Optical Disk Drive(ODD) driver sr to make use of block
> layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
> simplified as all SCSI devices that implement runtime PM are now request
> based.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
> ---
> Note that due to ODD will be polled every 2 seconds, for suspend to
> actually happen, the autosuspend_delay can not be set to more than 2
> seconds.

Or the polling delay must be increased.

> Also, make sure to use the util-linux utility of version 2.23.2 or later,
> as there is a bug fix for eject command to correctly update the ODD's
> locked state. If the fix is not applied, after the ODD is ejected with the
> eject command, it will not be able to enter runtime suspend state any
> more due to SCSI EH code will submit a lock door command for the ODD
> right after its parent ATA port is runtime suspended.
> https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04

I think this patch will cause a compile warning if you have
CONFIG_PM_RUNTIME set and CONFIG_PM_SLEEP disabled.  The
scsi_dev_type_suspend and scsi_dev_type_resume routines will be defined
but not used.

Otherwise it seems okay.

Alan Stern


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] scsi: sr: use block layer runtime PM
  2013-09-05 14:25 ` Alan Stern
@ 2013-09-06  1:36   ` Aaron Lu
  2013-09-06  2:01   ` [PATCH v2] " Aaron Lu
  1 sibling, 0 replies; 12+ messages in thread
From: Aaron Lu @ 2013-09-06  1:36 UTC (permalink / raw)
  To: Alan Stern
  Cc: James Bottomley, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On 09/05/2013 10:25 PM, Alan Stern wrote:
> On Thu, 5 Sep 2013, Aaron Lu wrote:
> 
>> Migrate SCSI Optical Disk Drive(ODD) driver sr to make use of block
>> layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
>> simplified as all SCSI devices that implement runtime PM are now request
>> based.
>>
>> Signed-off-by: Aaron Lu <aaron.lu@intel.com>
>> ---
>> Note that due to ODD will be polled every 2 seconds, for suspend to
>> actually happen, the autosuspend_delay can not be set to more than 2
>> seconds.
> 
> Or the polling delay must be increased.
> 
>> Also, make sure to use the util-linux utility of version 2.23.2 or later,
>> as there is a bug fix for eject command to correctly update the ODD's
>> locked state. If the fix is not applied, after the ODD is ejected with the
>> eject command, it will not be able to enter runtime suspend state any
>> more due to SCSI EH code will submit a lock door command for the ODD
>> right after its parent ATA port is runtime suspended.
>> https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04
> 
> I think this patch will cause a compile warning if you have
> CONFIG_PM_RUNTIME set and CONFIG_PM_SLEEP disabled.  The
> scsi_dev_type_suspend and scsi_dev_type_resume routines will be defined
> but not used.

Oh, right, thanks for the remind. I'll move CONFIG_PM_SLEEP up to cover
scsi_dev_type_suspend/resume in v2.

> 
> Otherwise it seems okay.
>

Thanks,
Aaron

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-05 14:25 ` Alan Stern
  2013-09-06  1:36   ` Aaron Lu
@ 2013-09-06  2:01   ` Aaron Lu
  2013-09-06 14:26     ` Alan Stern
  2013-09-06 15:00     ` James Bottomley
  1 sibling, 2 replies; 12+ messages in thread
From: Aaron Lu @ 2013-09-06  2:01 UTC (permalink / raw)
  To: Alan Stern, James Bottomley
  Cc: Rafael J. Wysocki, Linux-pm mailing list, SCSI development list

Migrate SCSI Optical Disk Drive(ODD) driver sr to make use of block
layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
simplified as all SCSI devices that implement runtime PM are now request
based.

Note that due to ODD will be polled every 2 seconds, for suspend to
actually happen, the autosuspend_delay can not be set to more than 2
seconds or the polling interval has to be increased.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
---
v2: scsi_dev_type_suspend/resume should be covered by CONFIG_PM_SLEEP,
suggested by Alan Stern.

Make sure to use the util-linux utility of version 2.23.2 or later if
a ATA host is in use, as there is a bug fix for eject command to
correctly update the ODD's locked state. If the fix is not applied,
after the ODD is ejected with the eject command, it will not be able to
enter runtime suspend state any more due to SCSI EH code will submit a
lock door command for the ODD right after its parent ATA port is runtime
suspended.
https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04

 drivers/scsi/scsi_pm.c | 62 +++++++++++++-------------------------------------
 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 4c5aabe..bb31fc9 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -16,6 +16,8 @@
 
 #include "scsi_priv.h"
 
+#ifdef CONFIG_PM_SLEEP
+
 static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
 {
 	int err;
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
 	return err;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
 static int
 scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
 {
@@ -144,38 +144,22 @@ static int scsi_bus_restore(struct device *dev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_suspend(struct device *dev)
 {
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	struct scsi_device *sdev = to_scsi_device(dev);
 	int err;
 
 	err = blk_pre_runtime_suspend(sdev->request_queue);
 	if (err)
 		return err;
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_suspend)
+		err = pm->runtime_suspend(dev);
 	blk_post_runtime_suspend(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_suspend(struct device *dev)
-{
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
-	struct scsi_device *sdev = to_scsi_device(dev);
-	int err;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_suspend(sdev, cb);
-
-	err = scsi_dev_type_suspend(dev, cb);
-	if (err == -EAGAIN)
-		pm_schedule_suspend(dev, jiffies_to_msecs(
-					round_jiffies_up_relative(HZ/10)));
-	return err;
-}
-
 static int scsi_runtime_suspend(struct device *dev)
 {
 	int err = 0;
@@ -189,31 +173,20 @@ static int scsi_runtime_suspend(struct device *dev)
 	return err;
 }
 
-static int sdev_blk_runtime_resume(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_resume(struct device *dev)
 {
+	struct scsi_device *sdev = to_scsi_device(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int err = 0;
 
 	blk_pre_runtime_resume(sdev->request_queue);
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_resume)
+		err = pm->runtime_resume(dev);
 	blk_post_runtime_resume(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_resume(struct device *dev)
-{
-	struct scsi_device *sdev = to_scsi_device(dev);
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_resume(sdev, cb);
-	else
-		return scsi_dev_type_resume(dev, cb);
-}
-
 static int scsi_runtime_resume(struct device *dev)
 {
 	int err = 0;
@@ -234,14 +207,11 @@ static int scsi_runtime_idle(struct device *dev)
 	/* Insert hooks here for targets, hosts, and transport classes */
 
 	if (scsi_is_sdev_device(dev)) {
-		struct scsi_device *sdev = to_scsi_device(dev);
-
-		if (sdev->request_queue->dev) {
-			pm_runtime_mark_last_busy(dev);
-			pm_runtime_autosuspend(dev);
-			return -EBUSY;
-		}
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_autosuspend(dev);
+		return -EBUSY;
 	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 119d67f..40d8592 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)
 		goto out;
 	cd = scsi_cd(disk);
 	kref_get(&cd->kref);
-	if (scsi_device_get(cd->device))
-		goto out_put;
-	if (!scsi_autopm_get_device(cd->device))
-		goto out;
-
- out_put:
-	kref_put(&cd->kref, sr_kref_release);
-	cd = NULL;
+	if (scsi_device_get(cd->device)) {
+		kref_put(&cd->kref, sr_kref_release);
+		cd = NULL;
+	}
  out:
 	mutex_unlock(&sr_ref_mutex);
 	return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
 
 	mutex_lock(&sr_ref_mutex);
 	kref_put(&cd->kref, sr_kref_release);
-	scsi_autopm_put_device(sdev);
 	scsi_device_put(sdev);
 	mutex_unlock(&sr_ref_mutex);
 }
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	scsi_autopm_get_device(cd->device);
-
 	mutex_lock(&sr_mutex);
 
 	/*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 out:
 	mutex_unlock(&sr_mutex);
-	scsi_autopm_put_device(cd->device);
 	return ret;
 }
 
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
 					  unsigned int clearing)
 {
 	struct scsi_cd *cd = scsi_cd(disk);
-	unsigned int ret;
 
-	if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
-		scsi_autopm_get_device(cd->device);
-		ret = cdrom_check_events(&cd->cdi, clearing);
-		scsi_autopm_put_device(cd->device);
-	} else {
-		ret = 0;
-	}
+	if (atomic_read(&cd->device->disk_events_disable_depth))
+		return 0;
 
-	return ret;
+	return cdrom_check_events(&cd->cdi, clearing);
 }
 
 static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	struct scsi_cd *cd = scsi_cd(disk);
 	struct scsi_sense_hdr sshdr;
 
-	scsi_autopm_get_device(cd->device);
-
 	/* if the unit is not ready, nothing more to do */
 	if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
 		goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	sr_cd_check(&cd->cdi);
 	get_sectorsize(cd);
 out:
-	scsi_autopm_put_device(cd->device);
 	return 0;
 }
 
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
 	if (register_cdrom(&cd->cdi))
 		goto fail_put;
 
+	/*
+	 * Initialize block layer runtime PM stuffs before the
+	 * periodic event checking request gets started in add_disk.
+	 */
+	blk_pm_runtime_init(sdev->request_queue, dev);
+
 	dev_set_drvdata(dev, cd);
 	disk->flags |= GENHD_FL_REMOVABLE;
 	add_disk(disk);
-- 
1.8.3.2.10.g43d11f4


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-06  2:01   ` [PATCH v2] " Aaron Lu
@ 2013-09-06 14:26     ` Alan Stern
  2013-09-06 15:00     ` James Bottomley
  1 sibling, 0 replies; 12+ messages in thread
From: Alan Stern @ 2013-09-06 14:26 UTC (permalink / raw)
  To: Aaron Lu
  Cc: James Bottomley, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On Fri, 6 Sep 2013, Aaron Lu wrote:

> Migrate SCSI Optical Disk Drive(ODD) driver sr to make use of block
> layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
> simplified as all SCSI devices that implement runtime PM are now request
> based.
> 
> Note that due to ODD will be polled every 2 seconds, for suspend to
> actually happen, the autosuspend_delay can not be set to more than 2
> seconds or the polling interval has to be increased.
> 
> Signed-off-by: Aaron Lu <aaron.lu@intel.com>

Acked-by: Alan Stern <stern@rowland.harvard.edu>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-06  2:01   ` [PATCH v2] " Aaron Lu
  2013-09-06 14:26     ` Alan Stern
@ 2013-09-06 15:00     ` James Bottomley
  2013-09-06 15:56       ` Alan Stern
  2013-09-07 14:45       ` Aaron Lu
  1 sibling, 2 replies; 12+ messages in thread
From: James Bottomley @ 2013-09-06 15:00 UTC (permalink / raw)
  To: Aaron Lu
  Cc: Alan Stern, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On Fri, 2013-09-06 at 10:01 +0800, Aaron Lu wrote:
> Migrate SCSI Optical Disk Drive(ODD)

I'm not very keen on this description because it's not quite accurate.
sr stands for SCSI ROM.  You could say optical SCSI ROM perhaps, but
Magneto Optical disks are handled by sd not sr.

>  driver sr to make use of block

I'd just say "Migrate sr to make use of .."

> layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
> simplified as all SCSI devices that implement runtime PM are now request
> based.

OK, let's now try for a descriptive changelog.  All SCSI devices
(including sr) are "request based".  I think what you mean is "all SCSI
devices which implement runtime PM have an exposed block device"?

> Note that due to ODD will be polled every 2 seconds,

Since the device will be polled every 2 seconds

>  for suspend to
> actually happen, the autosuspend_delay can not be set to more than 2
> seconds or the polling interval has to be increased.

Is this true?  What about event driven devices?  Supposing a distro has
a different interval.

How about

If your Distribution polls the device, the autosuspend interval cannot
be set to longer than the polling interval otherwise the device will
never suspend.

James



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-06 15:00     ` James Bottomley
@ 2013-09-06 15:56       ` Alan Stern
  2013-09-07 15:05         ` Aaron Lu
  2013-09-07 14:45       ` Aaron Lu
  1 sibling, 1 reply; 12+ messages in thread
From: Alan Stern @ 2013-09-06 15:56 UTC (permalink / raw)
  To: James Bottomley
  Cc: Aaron Lu, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On Fri, 6 Sep 2013, James Bottomley wrote:

> > layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
> > simplified as all SCSI devices that implement runtime PM are now request
> > based.
> 
> OK, let's now try for a descriptive changelog.  All SCSI devices
> (including sr) are "request based".  I think what you mean is "all SCSI
> devices which implement runtime PM have an exposed block device"?

Actually Aaron means "All SCSI drivers implementing runtime PM now use
the block layer's request-based mechanism."

> > Note that due to ODD will be polled every 2 seconds,
> 
> Since the device will be polled every 2 seconds
> 
> >  for suspend to
> > actually happen, the autosuspend_delay can not be set to more than 2
> > seconds or the polling interval has to be increased.
> 
> Is this true?  What about event driven devices?  Supposing a distro has
> a different interval.
> 
> How about
> 
> If your Distribution polls the device, the autosuspend interval cannot
> be set to longer than the polling interval otherwise the device will
> never suspend.

The default polling done by the kernel uses 2-second intervals.  Of 
course, distributions and users can change this or disable it entirely.

Alan Stern


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-06 15:00     ` James Bottomley
  2013-09-06 15:56       ` Alan Stern
@ 2013-09-07 14:45       ` Aaron Lu
  1 sibling, 0 replies; 12+ messages in thread
From: Aaron Lu @ 2013-09-07 14:45 UTC (permalink / raw)
  To: James Bottomley
  Cc: Alan Stern, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On 09/06/2013 11:00 PM, James Bottomley wrote:
> On Fri, 2013-09-06 at 10:01 +0800, Aaron Lu wrote:
>> Migrate SCSI Optical Disk Drive(ODD)
> 
> I'm not very keen on this description because it's not quite accurate.
> sr stands for SCSI ROM.  You could say optical SCSI ROM perhaps, but
> Magneto Optical disks are handled by sd not sr.
> 
>>  driver sr to make use of block
> 
> I'd just say "Migrate sr to make use of .."

OK, will update in v3, thanks for the correction.

Thanks,
Aaron

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-06 15:56       ` Alan Stern
@ 2013-09-07 15:05         ` Aaron Lu
  2013-09-07 15:22           ` Alan Stern
  0 siblings, 1 reply; 12+ messages in thread
From: Aaron Lu @ 2013-09-07 15:05 UTC (permalink / raw)
  To: Alan Stern, James Bottomley
  Cc: Rafael J. Wysocki, Linux-pm mailing list, SCSI development list

On 09/06/2013 11:56 PM, Alan Stern wrote:
> On Fri, 6 Sep 2013, James Bottomley wrote:
> 
>>> layer runtime PM. Accordingly, the SCSI bus layer runtime PM callback is
>>> simplified as all SCSI devices that implement runtime PM are now request
>>> based.
>>
>> OK, let's now try for a descriptive changelog.  All SCSI devices
>> (including sr) are "request based".  I think what you mean is "all SCSI
>> devices which implement runtime PM have an exposed block device"?
> 
> Actually Aaron means "All SCSI drivers implementing runtime PM now use
> the block layer's request-based mechanism."

Exactly, thanks for the clarification Alan. I'll update changlog using
the above words in v3.

> 
>>> Note that due to ODD will be polled every 2 seconds,
>>
>> Since the device will be polled every 2 seconds
>>
>>>  for suspend to
>>> actually happen, the autosuspend_delay can not be set to more than 2
>>> seconds or the polling interval has to be increased.
>>
>> Is this true?  What about event driven devices?  Supposing a distro has
>> a different interval.
>>
>> How about
>>
>> If your Distribution polls the device, the autosuspend interval cannot
>> be set to longer than the polling interval otherwise the device will
>> never suspend.
> 
> The default polling done by the kernel uses 2-second intervals.  Of 
> course, distributions and users can change this or disable it entirely.

What about:
Note that due to the device will be polled by kernel at a constant
interval specified at /sys/module/block/parameters/events_dfl_poll_msecs,
the default value is 2 seconds, the autosuspend delay cannot be set to
longer than the polling interval otherwise the device will never suspend.

Thanks,
Aaron

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2] scsi: sr: use block layer runtime PM
  2013-09-07 15:05         ` Aaron Lu
@ 2013-09-07 15:22           ` Alan Stern
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Stern @ 2013-09-07 15:22 UTC (permalink / raw)
  To: Aaron Lu
  Cc: James Bottomley, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list

On Sat, 7 Sep 2013, Aaron Lu wrote:

> >>> Note that due to ODD will be polled every 2 seconds,
> >>
> >> Since the device will be polled every 2 seconds
> >>
> >>>  for suspend to
> >>> actually happen, the autosuspend_delay can not be set to more than 2
> >>> seconds or the polling interval has to be increased.
> >>
> >> Is this true?  What about event driven devices?  Supposing a distro has
> >> a different interval.
> >>
> >> How about
> >>
> >> If your Distribution polls the device, the autosuspend interval cannot
> >> be set to longer than the polling interval otherwise the device will
> >> never suspend.
> > 
> > The default polling done by the kernel uses 2-second intervals.  Of 
> > course, distributions and users can change this or disable it entirely.
> 
> What about:
> Note that due to the device will be polled by kernel at a constant
> interval specified at /sys/module/block/parameters/events_dfl_poll_msecs,
> the default value is 2 seconds, the autosuspend delay cannot be set to
> longer than the polling interval otherwise the device will never suspend.

Well, I wouldn't say "cannot" -- people can set the delay to whatever
they want.  Just: If the autosuspend delay is set longer than the
polling interval then the device will never suspend.

Also, the actual polling interval is controlled by
/sys/block/sdX/events_poll_msec.  The file you mentioned merely
contains the default polling interval used for new devices.

Alan Stern


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3] scsi: sr: use block layer runtime PM
  2013-09-05  5:52 [PATCH] scsi: sr: use block layer runtime PM Aaron Lu
  2013-09-05 14:25 ` Alan Stern
@ 2013-09-09  2:01 ` Aaron Lu
  2013-10-28  7:27   ` [RESEND PATCH " Aaron Lu
  1 sibling, 1 reply; 12+ messages in thread
From: Aaron Lu @ 2013-09-09  2:01 UTC (permalink / raw)
  To: James Bottomley, Alan Stern
  Cc: Aaron Lu, Rafael J. Wysocki, Linux-pm mailing list,
	SCSI development list


Migrate sr to make use of block layer runtime PM. Accordingly, the
SCSI bus layer runtime PM callback is simplified as all SCSI drivers
implementing runtime PM now use the block layer's request-based
mechanism.

Note that due to the device will be polled by kernel at a constant
interval, if the autosuspend delay is set longer than the polling
interval then the device will never suspend.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
v2: scsi_dev_type_suspend/resume should be covered by CONFIG_PM_SLEEP,
suggested by Alan Stern.
v3: Modify changelog as suggested by Alan Stern and James Bottomley to
be more accurate and add Alan Stern's Acked-by tag.

The polling interval for a block device is specified by the per-device
setting at: /sys/block/sdX/events_poll_msecs. If its value is -1, then
/sys/module/block/parameters/events_dfl_poll_msecs is used.

Make sure to use the util-linux utility of version 2.23.2 or later if
a ATA host is in use, as there is a bug fix for eject command to
correctly update the ODD's locked state. If the fix is not applied,
after the ODD is ejected with the eject command, it will not be able to
enter runtime suspend state any more due to SCSI EH code will submit a
lock door command for the ODD right after its parent ATA port is runtime
suspended.
https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04

 drivers/scsi/scsi_pm.c | 62 +++++++++++++-------------------------------------
 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 4c5aabe..bb31fc9 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -16,6 +16,8 @@
 
 #include "scsi_priv.h"
 
+#ifdef CONFIG_PM_SLEEP
+
 static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
 {
 	int err;
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
 	return err;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
 static int
 scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
 {
@@ -144,38 +144,22 @@ static int scsi_bus_restore(struct device *dev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_suspend(struct device *dev)
 {
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	struct scsi_device *sdev = to_scsi_device(dev);
 	int err;
 
 	err = blk_pre_runtime_suspend(sdev->request_queue);
 	if (err)
 		return err;
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_suspend)
+		err = pm->runtime_suspend(dev);
 	blk_post_runtime_suspend(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_suspend(struct device *dev)
-{
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
-	struct scsi_device *sdev = to_scsi_device(dev);
-	int err;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_suspend(sdev, cb);
-
-	err = scsi_dev_type_suspend(dev, cb);
-	if (err == -EAGAIN)
-		pm_schedule_suspend(dev, jiffies_to_msecs(
-					round_jiffies_up_relative(HZ/10)));
-	return err;
-}
-
 static int scsi_runtime_suspend(struct device *dev)
 {
 	int err = 0;
@@ -189,31 +173,20 @@ static int scsi_runtime_suspend(struct device *dev)
 	return err;
 }
 
-static int sdev_blk_runtime_resume(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_resume(struct device *dev)
 {
+	struct scsi_device *sdev = to_scsi_device(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int err = 0;
 
 	blk_pre_runtime_resume(sdev->request_queue);
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_resume)
+		err = pm->runtime_resume(dev);
 	blk_post_runtime_resume(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_resume(struct device *dev)
-{
-	struct scsi_device *sdev = to_scsi_device(dev);
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_resume(sdev, cb);
-	else
-		return scsi_dev_type_resume(dev, cb);
-}
-
 static int scsi_runtime_resume(struct device *dev)
 {
 	int err = 0;
@@ -234,14 +207,11 @@ static int scsi_runtime_idle(struct device *dev)
 	/* Insert hooks here for targets, hosts, and transport classes */
 
 	if (scsi_is_sdev_device(dev)) {
-		struct scsi_device *sdev = to_scsi_device(dev);
-
-		if (sdev->request_queue->dev) {
-			pm_runtime_mark_last_busy(dev);
-			pm_runtime_autosuspend(dev);
-			return -EBUSY;
-		}
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_autosuspend(dev);
+		return -EBUSY;
 	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 119d67f..40d8592 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)
 		goto out;
 	cd = scsi_cd(disk);
 	kref_get(&cd->kref);
-	if (scsi_device_get(cd->device))
-		goto out_put;
-	if (!scsi_autopm_get_device(cd->device))
-		goto out;
-
- out_put:
-	kref_put(&cd->kref, sr_kref_release);
-	cd = NULL;
+	if (scsi_device_get(cd->device)) {
+		kref_put(&cd->kref, sr_kref_release);
+		cd = NULL;
+	}
  out:
 	mutex_unlock(&sr_ref_mutex);
 	return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
 
 	mutex_lock(&sr_ref_mutex);
 	kref_put(&cd->kref, sr_kref_release);
-	scsi_autopm_put_device(sdev);
 	scsi_device_put(sdev);
 	mutex_unlock(&sr_ref_mutex);
 }
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	scsi_autopm_get_device(cd->device);
-
 	mutex_lock(&sr_mutex);
 
 	/*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 out:
 	mutex_unlock(&sr_mutex);
-	scsi_autopm_put_device(cd->device);
 	return ret;
 }
 
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
 					  unsigned int clearing)
 {
 	struct scsi_cd *cd = scsi_cd(disk);
-	unsigned int ret;
 
-	if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
-		scsi_autopm_get_device(cd->device);
-		ret = cdrom_check_events(&cd->cdi, clearing);
-		scsi_autopm_put_device(cd->device);
-	} else {
-		ret = 0;
-	}
+	if (atomic_read(&cd->device->disk_events_disable_depth))
+		return 0;
 
-	return ret;
+	return cdrom_check_events(&cd->cdi, clearing);
 }
 
 static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	struct scsi_cd *cd = scsi_cd(disk);
 	struct scsi_sense_hdr sshdr;
 
-	scsi_autopm_get_device(cd->device);
-
 	/* if the unit is not ready, nothing more to do */
 	if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
 		goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	sr_cd_check(&cd->cdi);
 	get_sectorsize(cd);
 out:
-	scsi_autopm_put_device(cd->device);
 	return 0;
 }
 
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
 	if (register_cdrom(&cd->cdi))
 		goto fail_put;
 
+	/*
+	 * Initialize block layer runtime PM stuffs before the
+	 * periodic event checking request gets started in add_disk.
+	 */
+	blk_pm_runtime_init(sdev->request_queue, dev);
+
 	dev_set_drvdata(dev, cd);
 	disk->flags |= GENHD_FL_REMOVABLE;
 	add_disk(disk);
-- 1.8.3.2.10.g43d11f4 --



^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [RESEND PATCH v3] scsi: sr: use block layer runtime PM
  2013-09-09  2:01 ` [PATCH v3] " Aaron Lu
@ 2013-10-28  7:27   ` Aaron Lu
  0 siblings, 0 replies; 12+ messages in thread
From: Aaron Lu @ 2013-10-28  7:27 UTC (permalink / raw)
  To: 'James Bottomley'
  Cc: Rafael J. Wysocki, Linux-pm mailing list, SCSI development list,
	Aaron Lu, Alan Stern

Migrate sr to make use of block layer runtime PM. Accordingly, the
SCSI bus layer runtime PM callback is simplified as all SCSI drivers
implementing runtime PM now use the block layer's request-based
mechanism.

Note that due to the device will be polled by kernel at a constant
interval, if the autosuspend delay is set longer than the polling
interval then the device will never suspend.

Signed-off-by: Aaron Lu <aaron.lu@intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
---
v2: scsi_dev_type_suspend/resume should be covered by CONFIG_PM_SLEEP,
suggested by Alan Stern.
v3: Modify changelog as suggested by Alan Stern and James Bottomley to
be more accurate and add Alan Stern's Acked-by tag.

The polling interval for a block device is specified by the per-device
setting at: /sys/block/sdX/events_poll_msecs. If its value is -1, then
/sys/module/block/parameters/events_dfl_poll_msecs is used.

Make sure to use the util-linux utility of version 2.23.2 or later if
a ATA host is in use, as there is a bug fix for eject command to
correctly update the ODD's locked state. If the fix is not applied,
after the ODD is ejected with the eject command, it will not be able to
enter runtime suspend state any more due to SCSI EH code will submit a
lock door command for the ODD right after its parent ATA port is runtime
suspended.
https://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=12272030e563201e0b06732d8a87d8cea7157a04

 drivers/scsi/scsi_pm.c | 62 +++++++++++++-------------------------------------
 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 4c5aabe..bb31fc9 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -16,6 +16,8 @@
 
 #include "scsi_priv.h"
 
+#ifdef CONFIG_PM_SLEEP
+
 static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device *))
 {
 	int err;
@@ -43,8 +45,6 @@ static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device *))
 	return err;
 }
 
-#ifdef CONFIG_PM_SLEEP
-
 static int
 scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
 {
@@ -144,38 +144,22 @@ static int scsi_bus_restore(struct device *dev)
 
 #ifdef CONFIG_PM_RUNTIME
 
-static int sdev_blk_runtime_suspend(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_suspend(struct device *dev)
 {
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+	struct scsi_device *sdev = to_scsi_device(dev);
 	int err;
 
 	err = blk_pre_runtime_suspend(sdev->request_queue);
 	if (err)
 		return err;
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_suspend)
+		err = pm->runtime_suspend(dev);
 	blk_post_runtime_suspend(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_suspend(struct device *dev)
-{
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_suspend : NULL;
-	struct scsi_device *sdev = to_scsi_device(dev);
-	int err;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_suspend(sdev, cb);
-
-	err = scsi_dev_type_suspend(dev, cb);
-	if (err == -EAGAIN)
-		pm_schedule_suspend(dev, jiffies_to_msecs(
-					round_jiffies_up_relative(HZ/10)));
-	return err;
-}
-
 static int scsi_runtime_suspend(struct device *dev)
 {
 	int err = 0;
@@ -189,31 +173,20 @@ static int scsi_runtime_suspend(struct device *dev)
 	return err;
 }
 
-static int sdev_blk_runtime_resume(struct scsi_device *sdev,
-					int (*cb)(struct device *))
+static int sdev_runtime_resume(struct device *dev)
 {
+	struct scsi_device *sdev = to_scsi_device(dev);
+	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
 	int err = 0;
 
 	blk_pre_runtime_resume(sdev->request_queue);
-	if (cb)
-		err = cb(&sdev->sdev_gendev);
+	if (pm && pm->runtime_resume)
+		err = pm->runtime_resume(dev);
 	blk_post_runtime_resume(sdev->request_queue, err);
 
 	return err;
 }
 
-static int sdev_runtime_resume(struct device *dev)
-{
-	struct scsi_device *sdev = to_scsi_device(dev);
-	const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-	int (*cb)(struct device *) = pm ? pm->runtime_resume : NULL;
-
-	if (sdev->request_queue->dev)
-		return sdev_blk_runtime_resume(sdev, cb);
-	else
-		return scsi_dev_type_resume(dev, cb);
-}
-
 static int scsi_runtime_resume(struct device *dev)
 {
 	int err = 0;
@@ -234,14 +207,11 @@ static int scsi_runtime_idle(struct device *dev)
 	/* Insert hooks here for targets, hosts, and transport classes */
 
 	if (scsi_is_sdev_device(dev)) {
-		struct scsi_device *sdev = to_scsi_device(dev);
-
-		if (sdev->request_queue->dev) {
-			pm_runtime_mark_last_busy(dev);
-			pm_runtime_autosuspend(dev);
-			return -EBUSY;
-		}
+		pm_runtime_mark_last_busy(dev);
+		pm_runtime_autosuspend(dev);
+		return -EBUSY;
 	}
+
 	return 0;
 }
 
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 119d67f..40d8592 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)
 		goto out;
 	cd = scsi_cd(disk);
 	kref_get(&cd->kref);
-	if (scsi_device_get(cd->device))
-		goto out_put;
-	if (!scsi_autopm_get_device(cd->device))
-		goto out;
-
- out_put:
-	kref_put(&cd->kref, sr_kref_release);
-	cd = NULL;
+	if (scsi_device_get(cd->device)) {
+		kref_put(&cd->kref, sr_kref_release);
+		cd = NULL;
+	}
  out:
 	mutex_unlock(&sr_ref_mutex);
 	return cd;
@@ -180,7 +176,6 @@ static void scsi_cd_put(struct scsi_cd *cd)
 
 	mutex_lock(&sr_ref_mutex);
 	kref_put(&cd->kref, sr_kref_release);
-	scsi_autopm_put_device(sdev);
 	scsi_device_put(sdev);
 	mutex_unlock(&sr_ref_mutex);
 }
@@ -558,8 +553,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 	void __user *argp = (void __user *)arg;
 	int ret;
 
-	scsi_autopm_get_device(cd->device);
-
 	mutex_lock(&sr_mutex);
 
 	/*
@@ -591,7 +584,6 @@ static int sr_block_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
 
 out:
 	mutex_unlock(&sr_mutex);
-	scsi_autopm_put_device(cd->device);
 	return ret;
 }
 
@@ -599,17 +591,11 @@ static unsigned int sr_block_check_events(struct gendisk *disk,
 					  unsigned int clearing)
 {
 	struct scsi_cd *cd = scsi_cd(disk);
-	unsigned int ret;
 
-	if (atomic_read(&cd->device->disk_events_disable_depth) == 0) {
-		scsi_autopm_get_device(cd->device);
-		ret = cdrom_check_events(&cd->cdi, clearing);
-		scsi_autopm_put_device(cd->device);
-	} else {
-		ret = 0;
-	}
+	if (atomic_read(&cd->device->disk_events_disable_depth))
+		return 0;
 
-	return ret;
+	return cdrom_check_events(&cd->cdi, clearing);
 }
 
 static int sr_block_revalidate_disk(struct gendisk *disk)
@@ -617,8 +603,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	struct scsi_cd *cd = scsi_cd(disk);
 	struct scsi_sense_hdr sshdr;
 
-	scsi_autopm_get_device(cd->device);
-
 	/* if the unit is not ready, nothing more to do */
 	if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr))
 		goto out;
@@ -626,7 +610,6 @@ static int sr_block_revalidate_disk(struct gendisk *disk)
 	sr_cd_check(&cd->cdi);
 	get_sectorsize(cd);
 out:
-	scsi_autopm_put_device(cd->device);
 	return 0;
 }
 
@@ -747,6 +730,12 @@ static int sr_probe(struct device *dev)
 	if (register_cdrom(&cd->cdi))
 		goto fail_put;
 
+	/*
+	 * Initialize block layer runtime PM stuffs before the
+	 * periodic event checking request gets started in add_disk.
+	 */
+	blk_pm_runtime_init(sdev->request_queue, dev);
+
 	dev_set_drvdata(dev, cd);
 	disk->flags |= GENHD_FL_REMOVABLE;
 	add_disk(disk);
-- 1.8.3.2.10.g43d11f4 --

^ permalink raw reply related	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-10-28  7:27 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-05  5:52 [PATCH] scsi: sr: use block layer runtime PM Aaron Lu
2013-09-05 14:25 ` Alan Stern
2013-09-06  1:36   ` Aaron Lu
2013-09-06  2:01   ` [PATCH v2] " Aaron Lu
2013-09-06 14:26     ` Alan Stern
2013-09-06 15:00     ` James Bottomley
2013-09-06 15:56       ` Alan Stern
2013-09-07 15:05         ` Aaron Lu
2013-09-07 15:22           ` Alan Stern
2013-09-07 14:45       ` Aaron Lu
2013-09-09  2:01 ` [PATCH v3] " Aaron Lu
2013-10-28  7:27   ` [RESEND PATCH " Aaron Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).