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