Skip to content

Commit

Permalink
[SCSI] convert to the new PM framework
Browse files Browse the repository at this point in the history
This patch (as1397b) converts the SCSI midlayer to use the new PM
callbacks (struct dev_pm_ops).  A new source file, scsi_pm.c, is
created to hold the new callback routines, and the existing
suspend/resume code is moved there.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
  • Loading branch information
Alan Stern authored and James Bottomley committed Jul 28, 2010
1 parent df64d3c commit db5bd1e
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 47 deletions.
1 change: 1 addition & 0 deletions drivers/scsi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
scsi_mod-y += scsi_trace.o
scsi_mod-$(CONFIG_PM_OPS) += scsi_pm.o

scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o

Expand Down
96 changes: 96 additions & 0 deletions drivers/scsi/scsi_pm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* scsi_pm.c Copyright (C) 2010 Alan Stern
*
* SCSI dynamic Power Management
* Initial version: Alan Stern <stern@rowland.harvard.edu>
*/

#include <linux/pm_runtime.h>

#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_driver.h>
#include <scsi/scsi_host.h>

#include "scsi_priv.h"

static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
{
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);
}
dev_dbg(dev, "scsi suspend: %d\n", err);
return err;
}

static int scsi_dev_type_resume(struct device *dev)
{
struct device_driver *drv;
int err = 0;

drv = dev->driver;
if (drv && drv->resume)
err = drv->resume(dev);
scsi_device_resume(to_scsi_device(dev));
dev_dbg(dev, "scsi resume: %d\n", err);
return err;
}

#ifdef CONFIG_PM_SLEEP

static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
{
int err = 0;

if (scsi_is_sdev_device(dev))
err = scsi_dev_type_suspend(dev, msg);
return err;
}

static int scsi_bus_resume_common(struct device *dev)
{
int err = 0;

if (scsi_is_sdev_device(dev))
err = scsi_dev_type_resume(dev);
return err;
}

static int scsi_bus_suspend(struct device *dev)
{
return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
}

static int scsi_bus_freeze(struct device *dev)
{
return scsi_bus_suspend_common(dev, PMSG_FREEZE);
}

static int scsi_bus_poweroff(struct device *dev)
{
return scsi_bus_suspend_common(dev, PMSG_HIBERNATE);
}

#else /* CONFIG_PM_SLEEP */

#define scsi_bus_resume_common NULL
#define scsi_bus_suspend NULL
#define scsi_bus_freeze NULL
#define scsi_bus_poweroff NULL

#endif /* CONFIG_PM_SLEEP */

const struct dev_pm_ops scsi_bus_pm_ops = {
.suspend = scsi_bus_suspend,
.resume = scsi_bus_resume_common,
.freeze = scsi_bus_freeze,
.thaw = scsi_bus_resume_common,
.poweroff = scsi_bus_poweroff,
.restore = scsi_bus_resume_common,
};
7 changes: 7 additions & 0 deletions drivers/scsi/scsi_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,13 @@ static inline void scsi_netlink_init(void) {}
static inline void scsi_netlink_exit(void) {}
#endif

/* scsi_pm.c */
#ifdef CONFIG_PM_OPS
extern const struct dev_pm_ops scsi_bus_pm_ops;
#else
#define scsi_bus_pm_ops (*NULL)
#endif

/*
* internal scsi timeout functions: for use by mid-layer and transport
* classes.
Expand Down
48 changes: 1 addition & 47 deletions drivers/scsi/scsi_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,57 +376,11 @@ static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}

static int scsi_bus_suspend(struct device * dev, pm_message_t state)
{
struct device_driver *drv;
struct scsi_device *sdev;
int err;

if (dev->type != &scsi_dev_type)
return 0;

drv = dev->driver;
sdev = to_scsi_device(dev);

err = scsi_device_quiesce(sdev);
if (err)
return err;

if (drv && drv->suspend) {
err = drv->suspend(dev, state);
if (err)
return err;
}

return 0;
}

static int scsi_bus_resume(struct device * dev)
{
struct device_driver *drv;
struct scsi_device *sdev;
int err = 0;

if (dev->type != &scsi_dev_type)
return 0;

drv = dev->driver;
sdev = to_scsi_device(dev);

if (drv && drv->resume)
err = drv->resume(dev);

scsi_device_resume(sdev);

return err;
}

struct bus_type scsi_bus_type = {
.name = "scsi",
.match = scsi_bus_match,
.uevent = scsi_bus_uevent,
.suspend = scsi_bus_suspend,
.resume = scsi_bus_resume,
.pm = &scsi_bus_pm_ops,
};
EXPORT_SYMBOL_GPL(scsi_bus_type);

Expand Down

0 comments on commit db5bd1e

Please sign in to comment.