]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
d7e50217 | 6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. |
1c79356b | 7 | * |
d7e50217 A |
8 | * This file contains Original Code and/or Modifications of Original Code |
9 | * as defined in and that are subject to the Apple Public Source License | |
10 | * Version 2.0 (the 'License'). You may not use this file except in | |
11 | * compliance with the License. Please obtain a copy of the License at | |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
13 | * file. | |
14 | * | |
15 | * The Original Code and all software distributed under the License are | |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
1c79356b A |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
d7e50217 A |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
20 | * Please see the License for the specific language governing rights and | |
21 | * limitations under the License. | |
1c79356b A |
22 | * |
23 | * @APPLE_LICENSE_HEADER_END@ | |
24 | */ | |
25 | ||
26 | extern "C" { | |
27 | #include <kern/thread_call.h> | |
28 | } | |
29 | ||
30 | #include <libkern/c++/OSObject.h> | |
31 | #include <IOKit/IOLocks.h> | |
32 | class IOPMinformee; | |
33 | class IOPMinformeeList; | |
34 | class IOPMchangeNoteList; | |
35 | class IOPMpmChild; | |
36 | class IOWorkLoop; | |
37 | class IOCommandQueue; | |
38 | class IOCommandGate; | |
39 | class IOTimerEventSource; | |
40 | class IOPlatformExpert; | |
41 | ||
42 | #include <IOKit/pwr_mgt/IOPM.h> | |
43 | ||
44 | ||
45 | /*! | |
46 | @defined ACK_TIMER_PERIOD | |
47 | @discussion When an IOService is waiting for acknowledgement to a power state change | |
48 | notification from an interested driver or the controlling driver its ack timer is ticking every tenth of a second. | |
49 | (100000000 nanoseconds are one tenth of a second). | |
50 | */ | |
51 | #define ACK_TIMER_PERIOD 100000000 | |
52 | ||
53 | ||
54 | ||
55 | /*! | |
56 | @class IOPMpriv : public OSObject | |
57 | @abstract Private power management private instance variables for IOService objects. | |
58 | */ | |
59 | class IOPMpriv : public OSObject | |
60 | { | |
61 | friend class IOService; | |
62 | ||
63 | OSDeclareDefaultStructors(IOPMpriv) | |
64 | ||
65 | public: | |
66 | ||
67 | /*! @field we_are_root TRUE if this device is the root power domain */ | |
68 | bool we_are_root; | |
69 | ||
70 | /*! @field interestedDrivers list of interested drivers */ | |
71 | IOPMinformeeList * interestedDrivers; | |
72 | ||
73 | /*! @field children list of power domain children */ | |
74 | IOPMinformeeList * children; | |
75 | ||
76 | /*! @field changeList list of pending power state changes */ | |
77 | IOPMchangeNoteList * changeList; | |
78 | ||
79 | /*! @field driver_timer timeout on waiting for controlling driver to acknowledgeSetPowerState */ | |
80 | IOReturn driver_timer; | |
81 | ||
82 | /*! @field ackTimer */ | |
83 | thread_call_t ackTimer; | |
84 | ||
85 | /*! @field settleTimer */ | |
86 | thread_call_t settleTimer; | |
87 | ||
88 | /*! @field machine_state state number of state machine processing current change note */ | |
89 | unsigned long machine_state; | |
90 | ||
91 | /*! @field settle_time settle timer after changing power state */ | |
92 | unsigned long settle_time; | |
93 | ||
94 | /*! @field head_note ordinal of change note currently being processed */ | |
95 | long head_note; | |
96 | ||
97 | /*! @field head_note_flags copy of flags field in change note currently being processed*/ | |
98 | unsigned long head_note_flags; | |
99 | ||
100 | /*! @field head_note_state copy of newStateNumberfield in change note currently being processed */ | |
101 | unsigned long head_note_state; | |
102 | ||
103 | /*! @field head_note_outputFlags outputPowerCharacter field from change note currently being processed */ | |
104 | unsigned long head_note_outputFlags; | |
105 | ||
106 | /*! @field head_note_domainState power domain flags from parent... (only on parent change) */ | |
107 | unsigned long head_note_domainState; | |
108 | ||
109 | /*! @field head_note_parent pointer to initiating parent... (only on parent change) */ | |
110 | IOPowerConnection * head_note_parent; | |
111 | ||
112 | /*! @field head_note_capabilityFlags copy of capabilityFlags field in change note currently being processed */ | |
113 | unsigned long head_note_capabilityFlags; | |
114 | ||
115 | /*! @field head_note_pendingAcks number of acks we are waiting for during notification */ | |
116 | unsigned long head_note_pendingAcks; | |
117 | ||
118 | /*! @field our_lock used to control access to head_note_pendingAcks and driver_timer */ | |
119 | IOLock * our_lock; | |
120 | ||
121 | /*! @field flags_lock used to control access to response flags array */ | |
122 | IOLock * flags_lock; | |
123 | ||
0b4e3aa0 A |
124 | /*! @field queue_lock used to control access to change note queue */ |
125 | IOLock * queue_lock; | |
126 | ||
1c79356b A |
127 | /*! @field initial_change true forces first state to be broadcast even if it isn't a change */ |
128 | bool initial_change; | |
129 | ||
130 | /*! @field need_to_become_usable someone called makeUsable before we had a controlling driver */ | |
131 | bool need_to_become_usable; | |
132 | ||
133 | /*! @field device_overrides state changes are made based only on subclass's desire */ | |
134 | bool device_overrides; | |
135 | ||
136 | /*! @field clampOn domain is clamped on till first child registers */ | |
137 | bool clampOn; | |
138 | ||
139 | /*! @field owner points to object which made this struct. Used for debug output only */ | |
140 | IOService * owner; | |
141 | ||
142 | /*! @field activityLock used to protect activity flag */ | |
143 | IOLock * activityLock; | |
144 | ||
145 | /*! @field timerEventSrc an idle timer */ | |
146 | IOTimerEventSource * timerEventSrc; | |
147 | ||
148 | /*! @field idle_timer_period its period in seconds */ | |
149 | unsigned long idle_timer_period; | |
150 | ||
151 | /*! @field clampTimerEventSrc timer for clamping power on */ | |
152 | IOTimerEventSource * clampTimerEventSrc; | |
153 | ||
154 | /*! @field device_active true: there has been device activity since last idle timer expiration */ | |
155 | bool device_active; | |
156 | ||
e7c99d92 A |
157 | /*! @field device_active_timestamp time in ticks of last activity */ |
158 | AbsoluteTime device_active_timestamp; | |
159 | ||
1c79356b A |
160 | /*! @field driverDesire |
161 | This is the power state desired by our controlling driver. It is initialized to myCurrentState and is changed | |
162 | when the controlling driver calls changePowerStateTo. A change in driverDesire may cause a change in ourDesiredPowerState. | |
163 | */ | |
164 | unsigned long driverDesire; | |
165 | ||
166 | ||
167 | ||
168 | /*! @field deviceDesire | |
169 | This is the power state desired by a subclassed device object. It is initialized to myCurrentState and is changed | |
170 | when the subclassed object calls changePowerStateToPriv. A change in deviceDesire may cause a change in ourDesiredPowerState. | |
171 | */ | |
172 | unsigned long deviceDesire; | |
173 | ||
174 | ||
175 | ||
176 | /*! @field ourDesiredPowerState | |
177 | This is the power state we desire currently. If equal to myCurrentState, we're happy. | |
178 | Otherwise, we're waiting for the parent to raise the power domain to at least this level. | |
179 | ||
180 | If this is a power domain, this is the maximum of all our children's desires, driverDesire, and deviceDesire. | |
181 | It increases when: | |
182 | a child asks for more power via requestDomainState, | |
183 | the controlling driver asks for more power via changePowerStateTo | |
184 | ||
185 | It decreases when: | |
186 | we lose a child and the child had the highest power need of all our children, | |
187 | the child with the highest power need suggests a lower power domain state, | |
188 | the controlling driver asks for lower power for some reason via changePowerStateTo | |
189 | ||
190 | If this is not a power domain, ourDesiredPowerState represents the greater of driverDesire and deviceDesire. | |
191 | It increases when: | |
192 | the controlling driver asks for more power via changePowerStateTo | |
193 | some driver calls makeUsable | |
194 | a subclassed object asks for more power via changePowerStateToPriv | |
195 | ||
196 | It decreases when: | |
197 | the controlling driver asks for lower power for some reason via changePowerStateTo | |
198 | a subclassed object asks for lower power for some reason via changePowerStateToPriv | |
199 | */ | |
200 | unsigned long ourDesiredPowerState; | |
201 | ||
202 | ||
203 | /*! @field previousRequest | |
204 | This is a reminder of what our parent thinks our need is. Whenever it changes, | |
205 | we call requestDomainState in the parent to keep it current. It is usually equal to ourDesiredPowerState | |
206 | except while a power change is in progress. | |
207 | */ | |
208 | unsigned long previousRequest; | |
209 | ||
210 | ||
211 | /*! @field askingFor | |
0b4e3aa0 | 212 | Not used. |
1c79356b A |
213 | */ |
214 | unsigned long askingFor; | |
215 | ||
216 | ||
217 | /*! @field imminentState | |
218 | Usually the same as myCurrentState, except right after calling powerStateWillChangeTo. | |
219 | */ | |
220 | unsigned long imminentState; | |
221 | ||
222 | /*! @function serialize | |
223 | Serialize private instance variables for debug output (IORegistryDumper). | |
224 | */ | |
225 | virtual bool serialize(OSSerialize *s) const; | |
226 | ||
227 | }; | |
228 | ||
229 | ||
230 | ||
231 | ||
232 | /*! | |
233 | @class IOPMprot : public OSObject | |
234 | @abstract Protected power management instance variables for IOService objects. | |
235 | */ | |
236 | class IOPMprot : public OSObject //management | |
237 | { | |
238 | friend class IOService; | |
239 | ||
240 | OSDeclareDefaultStructors(IOPMprot) | |
241 | ||
242 | public: | |
243 | ||
244 | /*! @field ourName from getName(), used in logging */ | |
245 | const char * ourName; | |
246 | ||
247 | /*! @field thePlatform from getPlatform, used in logging and registering */ | |
248 | IOPlatformExpert * thePlatform; | |
249 | ||
250 | /*! @field theNumberOfPowerStates the number of states in the array */ | |
251 | unsigned long theNumberOfPowerStates; // the number of states in the array | |
252 | ||
253 | /*! @field thePowerStates the array */ | |
254 | IOPMPowerState thePowerStates[IOPMMaxPowerStates]; | |
255 | ||
256 | /*! @field theControllingDriver points to the controlling driver */ | |
257 | IOService * theControllingDriver; | |
258 | ||
259 | /*! @field aggressiveness current value of power management aggressiveness */ | |
260 | unsigned long aggressiveness; | |
261 | ||
262 | /*! @field current_aggressiveness_values array of aggressiveness values */ | |
263 | unsigned long current_aggressiveness_values [kMaxType+1]; | |
264 | ||
265 | /*! @field current_aggressiveness_validity true for values that are currently valid */ | |
266 | bool current_aggressiveness_valid [kMaxType+1]; | |
267 | ||
268 | /*! @field myCurrentState the ordinal of our current power state */ | |
269 | unsigned long myCurrentState; | |
270 | ||
271 | /*! @field parentsKnowState true if all our parents know the state of their power domain */ | |
272 | bool parentsKnowState; | |
273 | ||
274 | /*! @field parentsCurrentPowerFlags logical OR of power flags for the current state of each power domainparent */ | |
275 | IOPMPowerFlags parentsCurrentPowerFlags; | |
276 | ||
277 | /*! @field maxCapability ordinal of highest state we can achieve in current power domain state */ | |
278 | unsigned long maxCapability; | |
279 | ||
280 | /*! @field PMworkloop points to the single power management workloop */ | |
281 | IOWorkLoop * PMworkloop; | |
282 | ||
283 | /*! @field commandQueue used to serialize idle-power-down and busy-power-up */ | |
284 | IOCommandQueue * commandQueue; | |
285 | ||
286 | /*! @field PMcommandGate used to serialize timer expirations and incoming acknowledgements */ | |
287 | IOCommandGate * PMcommandGate; | |
288 | ||
289 | /*! @field myCharacterFlags logical OR of all output power character flags in the array */ | |
290 | IOPMPowerFlags myCharacterFlags; | |
291 | ||
292 | /*! @field serialNumber used to uniquely identify power management notification to apps and clients */ | |
293 | UInt16 serialNumber; | |
294 | ||
295 | /*! @field responseFlags points to an OSArray which manages responses from notified apps and clients */ | |
296 | OSArray* responseFlags; | |
297 | ||
298 | /*! @field doNotPowerDown keeps track of any negative responses from notified apps and clients */ | |
299 | bool doNotPowerDown; | |
300 | ||
0b4e3aa0 A |
301 | /*! @field childLock used to serialize scanning the children */ |
302 | IOLock * childLock; | |
303 | ||
304 | /*! @field parentLock used to serialize scanning the parents */ | |
305 | IOLock * parentLock; | |
306 | ||
307 | /*! @field outofbandparameter used to communicate desired function to tellClientsWithResponse(). | |
308 | This is used because it avoids changing the signatures of the affected | |
309 | virtual methods. */ | |
310 | int outofbandparameter; | |
311 | ||
1c79356b A |
312 | /*! @function serialize |
313 | Serialize protected instance variables for debug output (IORegistryDumper). | |
314 | */ | |
315 | virtual bool serialize(OSSerialize *s) const; | |
316 | ||
317 | }; | |
318 |