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