[SCSI] convert to the new PM framework
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>
This commit is contained in:
committed by
James Bottomley
parent
df64d3caab
commit
db5bd1e0b5
@@ -163,6 +163,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
|
|||||||
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
|
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
|
||||||
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
|
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
|
||||||
scsi_mod-y += scsi_trace.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
|
scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
|
||||||
|
|
||||||
|
96
drivers/scsi/scsi_pm.c
Normal file
96
drivers/scsi/scsi_pm.c
Normal file
@@ -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,
|
||||||
|
};
|
@@ -144,6 +144,13 @@ static inline void scsi_netlink_init(void) {}
|
|||||||
static inline void scsi_netlink_exit(void) {}
|
static inline void scsi_netlink_exit(void) {}
|
||||||
#endif
|
#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
|
* internal scsi timeout functions: for use by mid-layer and transport
|
||||||
* classes.
|
* classes.
|
||||||
|
@@ -376,57 +376,11 @@ static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
|
|||||||
return 0;
|
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 = {
|
struct bus_type scsi_bus_type = {
|
||||||
.name = "scsi",
|
.name = "scsi",
|
||||||
.match = scsi_bus_match,
|
.match = scsi_bus_match,
|
||||||
.uevent = scsi_bus_uevent,
|
.uevent = scsi_bus_uevent,
|
||||||
.suspend = scsi_bus_suspend,
|
.pm = &scsi_bus_pm_ops,
|
||||||
.resume = scsi_bus_resume,
|
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(scsi_bus_type);
|
EXPORT_SYMBOL_GPL(scsi_bus_type);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user