Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 204304
b: refs/heads/master
c: db5bd1e
h: refs/heads/master
v: v3
  • Loading branch information
Alan Stern authored and James Bottomley committed Jul 28, 2010
1 parent 4b0e497 commit 8e2f372
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 48 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: df64d3caab8db6ae17dacd229a03d7689a10c432
refs/heads/master: db5bd1e0b505c54ff492172ce4abc245cf6cd639
1 change: 1 addition & 0 deletions trunk/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 trunk/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 trunk/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 trunk/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 8e2f372

Please sign in to comment.