Skip to content

Commit db5bd1e

Browse files
AlanSternJames Bottomley
authored andcommitted
[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>
1 parent df64d3c commit db5bd1e

File tree

4 files changed

+105
-47
lines changed

4 files changed

+105
-47
lines changed

drivers/scsi/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ scsi_mod-$(CONFIG_SCSI_NETLINK) += scsi_netlink.o
163163
scsi_mod-$(CONFIG_SYSCTL) += scsi_sysctl.o
164164
scsi_mod-$(CONFIG_SCSI_PROC_FS) += scsi_proc.o
165165
scsi_mod-y += scsi_trace.o
166+
scsi_mod-$(CONFIG_PM_OPS) += scsi_pm.o
166167

167168
scsi_tgt-y += scsi_tgt_lib.o scsi_tgt_if.o
168169

drivers/scsi/scsi_pm.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* scsi_pm.c Copyright (C) 2010 Alan Stern
3+
*
4+
* SCSI dynamic Power Management
5+
* Initial version: Alan Stern <stern@rowland.harvard.edu>
6+
*/
7+
8+
#include <linux/pm_runtime.h>
9+
10+
#include <scsi/scsi.h>
11+
#include <scsi/scsi_device.h>
12+
#include <scsi/scsi_driver.h>
13+
#include <scsi/scsi_host.h>
14+
15+
#include "scsi_priv.h"
16+
17+
static int scsi_dev_type_suspend(struct device *dev, pm_message_t msg)
18+
{
19+
struct device_driver *drv;
20+
int err;
21+
22+
err = scsi_device_quiesce(to_scsi_device(dev));
23+
if (err == 0) {
24+
drv = dev->driver;
25+
if (drv && drv->suspend)
26+
err = drv->suspend(dev, msg);
27+
}
28+
dev_dbg(dev, "scsi suspend: %d\n", err);
29+
return err;
30+
}
31+
32+
static int scsi_dev_type_resume(struct device *dev)
33+
{
34+
struct device_driver *drv;
35+
int err = 0;
36+
37+
drv = dev->driver;
38+
if (drv && drv->resume)
39+
err = drv->resume(dev);
40+
scsi_device_resume(to_scsi_device(dev));
41+
dev_dbg(dev, "scsi resume: %d\n", err);
42+
return err;
43+
}
44+
45+
#ifdef CONFIG_PM_SLEEP
46+
47+
static int scsi_bus_suspend_common(struct device *dev, pm_message_t msg)
48+
{
49+
int err = 0;
50+
51+
if (scsi_is_sdev_device(dev))
52+
err = scsi_dev_type_suspend(dev, msg);
53+
return err;
54+
}
55+
56+
static int scsi_bus_resume_common(struct device *dev)
57+
{
58+
int err = 0;
59+
60+
if (scsi_is_sdev_device(dev))
61+
err = scsi_dev_type_resume(dev);
62+
return err;
63+
}
64+
65+
static int scsi_bus_suspend(struct device *dev)
66+
{
67+
return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
68+
}
69+
70+
static int scsi_bus_freeze(struct device *dev)
71+
{
72+
return scsi_bus_suspend_common(dev, PMSG_FREEZE);
73+
}
74+
75+
static int scsi_bus_poweroff(struct device *dev)
76+
{
77+
return scsi_bus_suspend_common(dev, PMSG_HIBERNATE);
78+
}
79+
80+
#else /* CONFIG_PM_SLEEP */
81+
82+
#define scsi_bus_resume_common NULL
83+
#define scsi_bus_suspend NULL
84+
#define scsi_bus_freeze NULL
85+
#define scsi_bus_poweroff NULL
86+
87+
#endif /* CONFIG_PM_SLEEP */
88+
89+
const struct dev_pm_ops scsi_bus_pm_ops = {
90+
.suspend = scsi_bus_suspend,
91+
.resume = scsi_bus_resume_common,
92+
.freeze = scsi_bus_freeze,
93+
.thaw = scsi_bus_resume_common,
94+
.poweroff = scsi_bus_poweroff,
95+
.restore = scsi_bus_resume_common,
96+
};

drivers/scsi/scsi_priv.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ static inline void scsi_netlink_init(void) {}
144144
static inline void scsi_netlink_exit(void) {}
145145
#endif
146146

147+
/* scsi_pm.c */
148+
#ifdef CONFIG_PM_OPS
149+
extern const struct dev_pm_ops scsi_bus_pm_ops;
150+
#else
151+
#define scsi_bus_pm_ops (*NULL)
152+
#endif
153+
147154
/*
148155
* internal scsi timeout functions: for use by mid-layer and transport
149156
* classes.

drivers/scsi/scsi_sysfs.c

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -376,57 +376,11 @@ static int scsi_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
376376
return 0;
377377
}
378378

379-
static int scsi_bus_suspend(struct device * dev, pm_message_t state)
380-
{
381-
struct device_driver *drv;
382-
struct scsi_device *sdev;
383-
int err;
384-
385-
if (dev->type != &scsi_dev_type)
386-
return 0;
387-
388-
drv = dev->driver;
389-
sdev = to_scsi_device(dev);
390-
391-
err = scsi_device_quiesce(sdev);
392-
if (err)
393-
return err;
394-
395-
if (drv && drv->suspend) {
396-
err = drv->suspend(dev, state);
397-
if (err)
398-
return err;
399-
}
400-
401-
return 0;
402-
}
403-
404-
static int scsi_bus_resume(struct device * dev)
405-
{
406-
struct device_driver *drv;
407-
struct scsi_device *sdev;
408-
int err = 0;
409-
410-
if (dev->type != &scsi_dev_type)
411-
return 0;
412-
413-
drv = dev->driver;
414-
sdev = to_scsi_device(dev);
415-
416-
if (drv && drv->resume)
417-
err = drv->resume(dev);
418-
419-
scsi_device_resume(sdev);
420-
421-
return err;
422-
}
423-
424379
struct bus_type scsi_bus_type = {
425380
.name = "scsi",
426381
.match = scsi_bus_match,
427382
.uevent = scsi_bus_uevent,
428-
.suspend = scsi_bus_suspend,
429-
.resume = scsi_bus_resume,
383+
.pm = &scsi_bus_pm_ops,
430384
};
431385
EXPORT_SYMBOL_GPL(scsi_bus_type);
432386

0 commit comments

Comments
 (0)