1pm_raise_power(9F) Kernel Functions for Drivers pm_raise_power(9F)
2
3
4
6 pm_raise_power, pm_lower_power - Raise or lower power of components
7
9 #include <sys/ddi.h>
10 #include <sys/sunddi.h>
11
12 int pm_raise_power(dev_info_t *dip, int component, int level);
13
14
15 int pm_lower_power(dev_info_t *dip, int component, int level);
16
17
19 Solaris DDI specific (Solaris DDI)
20
22 pm_raise_power
23 dip Pointer to the device's dev_info structure
24
25
26 component The number of the component for which a power level change
27 is desired
28
29
30 level The power level to which the indicated component will be
31 raised
32
33
34 pm_lower_power
35 dip Pointer to the device's dev_info structure
36
37
38 component Number of the component for which a power level change is
39 desired
40
41
42 level Power level to which the indicated component will be low‐
43 ered
44
45
47 The pm_raise_power(9F) function requests the Power Management framework
48 to raise the power level of component of dip to at least level.
49
50
51 The state of the device should be examined before each physical access.
52 The pm_raise_power(9F) function should be called to set a component to
53 the required power level if the operation to be performed requires the
54 component to be at a power level higher than its current power level.
55
56
57 When pm_raise_power(9F) returns with success, the component is guaran‐
58 teed to be at least at the requested power level. All devices that
59 depend on this will be at their full power level. Since the actual
60 device power level may be higher than requested by the driver, the
61 driver should not make any assumption about the absolute power level on
62 successful return from pm_raise_power(9F).
63
64
65 The pm_raise_power(9F) function may cause re-entry of the driver
66 power(9E) to raise the power level. Deadlock may result if the driver
67 locks are held across the call to pm_raise_power(9F).
68
69
70 The pm_lower_power(9F) function requests the Power Management framework
71 to lower the power level of component of dip to at most level.
72
73
74 Normally, transitions to lower power levels are initiated by the Power
75 Management framework based on component idleness. However, when detach‐
76 ing, the driver should also initiate reduced power levels by setting
77 the power level of all device components to their lowest levels. The
78 pm_lower_power(9F) function is intended for this use only, and will
79 return DDI_FAILURE if the driver is not detaching at the time of the
80 call.
81
82
83 If automatic Power Management is disabled (see dtpower(1M) and
84 power.conf(4)), pm_lower_power(9F) returns DDI_SUCCESS without changing
85 the power level of the component. Otherwise, when pm_lower_power(9F)
86 returns with success, the component is guaranteed to be at most at the
87 requested power level. Since the actual device power level may be lower
88 than requested by the driver, the driver should not make any assumption
89 about the absolute power level on successful return from
90 pm_lower_power(9F).
91
92
93 The pm_lower_power(9F) function may cause re-entry of the driver
94 power(9E) to lower the power level. Deadlock may result if the driver
95 locks are held across the call to pm_lower_power(9F).
96
97 Note -
98
99 If these functions are called as a result of entry into the driver's
100 attach(9E), detach(9E) or power(9E) entry point, these functions must
101 be called from the same thread which entered attach(9E), detach(9E)
102 or power(9E).
103
105 The pm_raise_power(9F) function returns:
106
107 DDI_SUCCESS Component is now at the requested power level or higher.
108
109
110 DDI_FAILURE Component or level is out of range, or the framework was
111 unable to raise the power level of the component to the
112 requested level.
113
114
115
116 The pm_lower_power(9F) function returns:
117
118 DDI_SUCCESS Component is now at the requested power level or
119 lower, or automatic Power Management is disabled.
120
121
122 DDI_FAILURE Component or level is out of range, or the framework
123 was unable to lower the power level of the component to
124 the requested level, or the device is not detaching.
125
126
128 A hypothetical disk driver might include this code to handle
129 pm_raise_power(9F):
130
131 static int
132 xxdisk_strategy(struct buf *bp)
133 {
134
135 ...
136
137 /*
138 * At this point we have determined that we need to raise the
139 * power level of the device. Since we have to drop the
140 * mutex, we need to take care of case where framework is
141 * lowering power at the same time we are raising power.
142 * We resolve this by marking the device busy and failing
143 * lower power in power() entry point when device is busy.
144 */
145
146 ASSERT(mutex_owned(xsp->lock));
147 if (xsp->pm_busycnt < 1) {
148 /*
149 * Component is not already marked busy
150 */
151 if (pm_busy_component(xsp->dip,
152 XXDISK_COMPONENT) != DDI_SUCCESS) {
153 bioerror(bp,EIO);
154 biodone(bp);
155 return (0);
156 }
157 xsp->pm_busycnt++;
158 }
159 mutex_exit(xsp->lock);
160 if (pm_raise_power(xsp->dip,
161 XXDISK_COMPONENT, XXPOWER_SPUN_UP) != DDI_SUCCESS) {
162 bioerror(bp,EIO);
163 biodone(bp);
164 return (0);
165 }
166 mutex_enter(xsp->lock);
167
168 ....
169
170 }
171
172
173 xxdisk_power(dev_info *dip, int comp, int level)
174 {
175
176 ...
177
178 /*
179 * We fail the power() entry point if the device is busy and
180 * request is to lower the power level.
181
182 */
183
184 ASSERT(mutex_owned( xsp->lock));
185 if (xsp->pm_busycnt >= 1) {
186 if (level < xsp->cur_level) {
187 mutex_exit( xsp->lock);
188 return (DDI_FAILURE);
189 }
190 }
191
192 ...
193
194 }
195
196
198 These functions can be called from user or kernel context.
199
201 See attributes(5) for a description of the following attribute:
202
203
204
205
206 ┌─────────────────────────────┬─────────────────────────────┐
207 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
208 ├─────────────────────────────┼─────────────────────────────┤
209 │Interface stability │Committed │
210 └─────────────────────────────┴─────────────────────────────┘
211
213 power.conf(4), pm(7D), attach(9E), detach(9E), power(9E), pm_busy_com‐
214 ponent(9F), pm_idle_component(9F), pm(9P), pm-components(9P)
215
216
217 Writing Device Drivers
218
219
220
221SunOS 5.11 22 March 2005 pm_raise_power(9F)