On Friday 12 of October 2012 14:59:37 Aaron Lu wrote:
> Use of pm_message_t is deprecated and device driver is not supposed
> to use that. This patch tries to migrate the SCSI bus level pm callbacks
> to call device's pm callbacks defined in its driver's dev_pm_ops.
Well, as Yoda had said: “Do or do not... there is no try.” ;-)
The patch looks OK, though.
> This is achieved by finding out which device pm callback should be used
> in bus callback function, and then pass that callback function pointer
> as a param to the scsi_bus_{suspend,resume}_common routine, which will
> further pass that callback to scsi_dev_type_{suspend,resume} after
> proper handling.
>
> The special case for freeze in scsi_bus_suspend_common is not necessary
> since there is no high level SCSI driver has implemented freeze, so no
> need to runtime resume the device if it is in runtime suspended state
> for system freeze, just return like the system suspend/hibernate case.
>
> Since only sd has implemented drv->suspend/drv->resume, and I'll update
> sd driver to use the new callbacks in the following patch, there is no
> need to fallback to call drv->suspend/drv->resume if dev_pm_ops is NULL.
>
> Signed-off-by: Aaron Lu <[email protected]>
> ---
> drivers/scsi/scsi_pm.c | 85
> ++++++++++++++++++++++++++++++--------------------
> 1 file changed, 52 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
> index 9923b26..6e70a16 100644
> --- a/drivers/scsi/scsi_pm.c
> +++ b/drivers/scsi/scsi_pm.c
> @@ -16,16 +16,14 @@
>
> #include "scsi_priv.h"
>
> -static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
> +static int scsi_dev_type_suspend(struct device *dev, int (*cb)(struct device
> *))
> {
> - struct device_driver *drv;
> int err;
>
> err = scsi_device_quiesce(to_scsi_device(dev));
> if (err == 0) {
> - drv = dev->driver;
> - if (drv && drv->suspend) {
> - err = drv->suspend(dev, msg);
> + if (cb) {
> + err = cb(dev);
> if (err)
> scsi_device_resume(to_scsi_device(dev));
> }
> @@ -34,14 +32,12 @@ static int scsi_dev_type_suspend(struct device *dev,
> pm_message_t msg)
> return err;
> }
>
> -static int scsi_dev_type_resume(struct device *dev)
> +static int scsi_dev_type_resume(struct device *dev, int (*cb)(struct device
> *))
> {
> - struct device_driver *drv;
> int err = 0;
>
> - drv = dev->driver;
> - if (drv && drv->resume)
> - err = drv->resume(dev);
> + if (cb)
> + err = cb(dev);
> scsi_device_resume(to_scsi_device(dev));
> dev_dbg(dev, "scsi resume: %d\n", err);
> return err;
> @@ -49,35 +45,33 @@ static int scsi_dev_type_resume(struct device *dev)
>
> #ifdef CONFIG_PM_SLEEP
>
> -static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
> +static int
> +scsi_bus_suspend_common(struct device *dev, int (*cb)(struct device *))
> {
> int err = 0;
>
> if (scsi_is_sdev_device(dev)) {
> /*
> - * sd is the only high-level SCSI driver to implement runtime
> - * PM, and sd treats runtime suspend, system suspend, and
> - * system hibernate identically (but not system freeze).
> + * All the high-level SCSI drivers that implement runtime
> + * PM treat runtime suspend, system suspend, and system
> + * hibernate identically.
> */
> - if (pm_runtime_suspended(dev)) {
> - if (msg.event == PM_EVENT_SUSPEND ||
> - msg.event == PM_EVENT_HIBERNATE)
> - return 0; /* already suspended */
> + if (pm_runtime_suspended(dev))
> + return 0;
>
> - /* wake up device so that FREEZE will succeed */
> - pm_runtime_resume(dev);
> - }
> - err = scsi_dev_type_suspend(dev, msg);
> + err = scsi_dev_type_suspend(dev, cb);
> }
> +
> return err;
> }
>
> -static int scsi_bus_resume_common(struct device *dev)
> +static int
> +scsi_bus_resume_common(struct device *dev, int (*cb)(struct device *))
> {
> int err = 0;
>
> if (scsi_is_sdev_device(dev))
> - err = scsi_dev_type_resume(dev);
> + err = scsi_dev_type_resume(dev, cb);
>
> if (err == 0) {
> pm_runtime_disable(dev);
> @@ -102,26 +96,49 @@ static int scsi_bus_prepare(struct device *dev)
>
> static int scsi_bus_suspend(struct device *dev)
> {
> - return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_suspend_common(dev, pm ? pm->suspend : NULL);
> +}
> +
> +static int scsi_bus_resume(struct device *dev)
> +{
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_resume_common(dev, pm ? pm->resume : NULL);
> }
>
> static int scsi_bus_freeze(struct device *dev)
> {
> - return scsi_bus_suspend_common(dev, PMSG_FREEZE);
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_suspend_common(dev, pm ? pm->freeze : NULL);
> +}
> +
> +static int scsi_bus_thaw(struct device *dev)
> +{
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_resume_common(dev, pm ? pm->thaw : NULL);
> }
>
> static int scsi_bus_poweroff(struct device *dev)
> {
> - return scsi_bus_suspend_common(dev, PMSG_HIBERNATE);
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_suspend_common(dev, pm ? pm->poweroff : NULL);
> +}
> +
> +static int scsi_bus_restore(struct device *dev)
> +{
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
> + return scsi_bus_resume_common(dev, pm ? pm->restore : NULL);
> }
>
> #else /* CONFIG_PM_SLEEP */
>
> -#define scsi_bus_resume_common NULL
> #define scsi_bus_prepare NULL
> #define scsi_bus_suspend NULL
> +#define scsi_bus_resume NULL
> #define scsi_bus_freeze NULL
> +#define scsi_bus_thaw NULL
> #define scsi_bus_poweroff NULL
> +#define scsi_bus_restore NULL
>
> #endif /* CONFIG_PM_SLEEP */
>
> @@ -130,10 +147,11 @@ static int scsi_bus_poweroff(struct device *dev)
> static int scsi_runtime_suspend(struct device *dev)
> {
> int err = 0;
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>
> dev_dbg(dev, "scsi_runtime_suspend\n");
> if (scsi_is_sdev_device(dev)) {
> - err = scsi_dev_type_suspend(dev, PMSG_AUTO_SUSPEND);
> + err = scsi_dev_type_suspend(dev, pm ? pm->runtime_suspend :
> NULL);
> if (err == -EAGAIN)
> pm_schedule_suspend(dev, jiffies_to_msecs(
> round_jiffies_up_relative(HZ/10)));
> @@ -147,10 +165,11 @@ static int scsi_runtime_suspend(struct device *dev)
> static int scsi_runtime_resume(struct device *dev)
> {
> int err = 0;
> + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
>
> dev_dbg(dev, "scsi_runtime_resume\n");
> if (scsi_is_sdev_device(dev))
> - err = scsi_dev_type_resume(dev);
> + err = scsi_dev_type_resume(dev, pm ? pm->runtime_resume : NULL);
>
> /* Insert hooks here for targets, hosts, and transport classes */
>
> @@ -229,11 +248,11 @@ void scsi_autopm_put_host(struct Scsi_Host *shost)
> const struct dev_pm_ops scsi_bus_pm_ops = {
> .prepare = scsi_bus_prepare,
> .suspend = scsi_bus_suspend,
> - .resume = scsi_bus_resume_common,
> + .resume = scsi_bus_resume,
> .freeze = scsi_bus_freeze,
> - .thaw = scsi_bus_resume_common,
> + .thaw = scsi_bus_thaw,
> .poweroff = scsi_bus_poweroff,
> - .restore = scsi_bus_resume_common,
> + .restore = scsi_bus_restore,
> .runtime_suspend = scsi_runtime_suspend,
> .runtime_resume = scsi_runtime_resume,
> .runtime_idle = scsi_runtime_idle,
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html