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

Reply via email to