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