1 | /* |
2 | * Copyright (c) 2007 Apple Inc. All rights reserved. |
3 | * |
4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ |
5 | * |
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 |
24 | * limitations under the License. |
25 | * |
26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ |
27 | */ |
28 | |
29 | #ifndef _IOKIT_IOSERVICEPMPRIVATE_H |
30 | #define _IOKIT_IOSERVICEPMPRIVATE_H |
31 | |
32 | #include <IOKit/IOCommand.h> |
33 | #include <IOKit/IOEventSource.h> |
34 | |
35 | //****************************************************************************** |
36 | // PM command types |
37 | //****************************************************************************** |
38 | |
39 | enum { |
40 | /* Command Types */ |
41 | kIOPMRequestTypeInvalid = 0x00, |
42 | kIOPMRequestTypePMStop = 0x01, |
43 | kIOPMRequestTypeAddPowerChild1 = 0x02, |
44 | kIOPMRequestTypeAddPowerChild2 = 0x03, |
45 | kIOPMRequestTypeAddPowerChild3 = 0x04, |
46 | kIOPMRequestTypeRegisterPowerDriver = 0x05, |
47 | kIOPMRequestTypeAdjustPowerState = 0x06, |
48 | kIOPMRequestTypePowerDomainWillChange = 0x07, |
49 | kIOPMRequestTypePowerDomainDidChange = 0x08, |
50 | kIOPMRequestTypePowerOverrideOnPriv = 0x09, |
51 | kIOPMRequestTypePowerOverrideOffPriv = 0x0A, |
52 | kIOPMRequestTypeActivityTickle = 0x0B, |
53 | kIOPMRequestTypeRequestPowerState = 0x0C, |
54 | kIOPMRequestTypeSynchronizePowerTree = 0x0D, |
55 | kIOPMRequestTypeRequestPowerStateOverride = 0x0E, |
56 | kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, |
57 | kIOPMRequestTypeIgnoreIdleTimer = 0x10, |
58 | kIOPMRequestTypeQuiescePowerTree = 0x11, |
59 | |
60 | /* Reply Types */ |
61 | kIOPMRequestTypeReplyStart = 0x80, |
62 | kIOPMRequestTypeAckPowerChange = 0x81, |
63 | kIOPMRequestTypeAckSetPowerState = 0x82, |
64 | kIOPMRequestTypeAllowPowerChange = 0x83, |
65 | kIOPMRequestTypeCancelPowerChange = 0x84, |
66 | kIOPMRequestTypeInterestChanged = 0x85, |
67 | kIOPMRequestTypeIdleCancel = 0x86, |
68 | kIOPMRequestTypeChildNotifyDelayCancel = 0x87 |
69 | }; |
70 | |
71 | //****************************************************************************** |
72 | // PM actions - For root domain only |
73 | //****************************************************************************** |
74 | |
75 | struct IOPMActions; |
76 | |
77 | typedef void |
78 | (*IOPMActionPowerChangeStart)( |
79 | void * target, |
80 | IOService * service, |
81 | IOPMActions * actions, |
82 | IOPMPowerStateIndex powerState, |
83 | IOPMPowerChangeFlags * changeFlags, |
84 | IOPMRequestTag requestTag ); |
85 | |
86 | typedef void |
87 | (*IOPMActionPowerChangeDone)( |
88 | void * target, |
89 | IOService * service, |
90 | IOPMActions * actions, |
91 | IOPMPowerStateIndex powerState, |
92 | IOPMPowerChangeFlags changeFlags, |
93 | IOPMRequestTag requestTag ); |
94 | |
95 | typedef void |
96 | (*IOPMActionPowerChangeOverride)( |
97 | void * target, |
98 | IOService * service, |
99 | IOPMActions * actions, |
100 | IOPMPowerStateIndex * powerState, |
101 | IOPMPowerChangeFlags * changeFlags, |
102 | IOPMRequestTag requestTag ); |
103 | |
104 | typedef void |
105 | (*IOPMActionActivityTickle)( |
106 | void * target, |
107 | IOService * service, |
108 | IOPMActions * actions ); |
109 | |
110 | typedef void |
111 | (*IOPMActionUpdatePowerClient)( |
112 | void * target, |
113 | IOService * service, |
114 | IOPMActions * actions, |
115 | const OSSymbol * powerClient, |
116 | IOPMPowerStateIndex oldPowerState, |
117 | IOPMPowerStateIndex newPowerState |
118 | ); |
119 | |
120 | struct IOPMActions { |
121 | void * target; |
122 | uint32_t parameter; |
123 | IOPMActionPowerChangeStart actionPowerChangeStart; |
124 | IOPMActionPowerChangeDone actionPowerChangeDone; |
125 | IOPMActionPowerChangeOverride actionPowerChangeOverride; |
126 | IOPMActionActivityTickle actionActivityTickle; |
127 | IOPMActionUpdatePowerClient actionUpdatePowerClient; |
128 | }; |
129 | |
130 | // IOPMActions parameter flags |
131 | enum { |
132 | kPMActionsFlagIsDisplayWrangler = 0x00000100, |
133 | kPMActionsFlagIsGraphicsDevice = 0x00000200, |
134 | kPMActionsFlagIsAudioDevice = 0x00000400, |
135 | kPMActionsFlagLimitPower = 0x00000800, |
136 | kPMActionsPCIBitNumberMask = 0x000000ff |
137 | }; |
138 | |
139 | //****************************************************************************** |
140 | // Internal concise representation of IOPMPowerState |
141 | struct IOPMPSEntry |
142 | { |
143 | IOPMPowerFlags capabilityFlags; |
144 | IOPMPowerFlags outputPowerFlags; |
145 | IOPMPowerFlags inputPowerFlags; |
146 | uint32_t staticPower; |
147 | uint32_t settleUpTime; |
148 | uint32_t settleDownTime; |
149 | IOPMPowerStateIndex stateOrder; |
150 | IOPMPowerStateIndex stateOrderToIndex; |
151 | }; |
152 | |
153 | //****************************************************************************** |
154 | // IOServicePM |
155 | //****************************************************************************** |
156 | |
157 | class IOServicePM : public OSObject |
158 | { |
159 | friend class IOService; |
160 | friend class IOPMWorkQueue; |
161 | |
162 | OSDeclareDefaultStructors( IOServicePM ) |
163 | |
164 | private: |
165 | // Link IOServicePM objects on IOPMWorkQueue. |
166 | queue_chain_t WorkChain; |
167 | |
168 | // Queue of IOPMRequest objects. |
169 | queue_head_t RequestHead; |
170 | |
171 | // IOService creator and owner. |
172 | IOService * Owner; |
173 | |
174 | // List of interested drivers (protected by PMLock). |
175 | IOPMinformeeList * InterestedDrivers; |
176 | |
177 | // How long to wait for controlling driver to acknowledge. |
178 | IOReturn DriverTimer; |
179 | |
180 | // Current power management machine state. |
181 | uint32_t MachineState; |
182 | |
183 | thread_call_t AckTimer; |
184 | thread_call_t SettleTimer; |
185 | thread_call_t IdleTimer; |
186 | thread_call_t WatchdogTimer; |
187 | thread_call_t SpinDumpTimer; |
188 | |
189 | IOLock * WatchdogLock; |
190 | OSArray * BlockedArray; |
191 | uint64_t PendingResponseDeadline; |
192 | uint64_t WatchdogDeadline; |
193 | |
194 | // Settle time after changing power state. |
195 | uint32_t SettleTimeUS; |
196 | uint32_t IdleTimerGeneration; |
197 | |
198 | // The flags describing current change note. |
199 | IOPMPowerChangeFlags HeadNoteChangeFlags; |
200 | |
201 | // The new power state number being changed to. |
202 | IOPMPowerStateIndex HeadNotePowerState; |
203 | |
204 | // Points to the entry in the power state array. |
205 | IOPMPSEntry * HeadNotePowerArrayEntry; |
206 | |
207 | // Power flags supplied by all parents (domain). |
208 | IOPMPowerFlags HeadNoteDomainFlags; |
209 | |
210 | // Power flags supplied by domain accounting for parent changes. |
211 | IOPMPowerFlags HeadNoteDomainTargetFlags; |
212 | |
213 | // Connection attached to the changing parent. |
214 | IOPowerConnection * HeadNoteParentConnection; |
215 | |
216 | // Power flags supplied by the changing parent. |
217 | IOPMPowerFlags HeadNoteParentFlags; |
218 | |
219 | // Number of acks still outstanding. |
220 | uint32_t HeadNotePendingAcks; |
221 | |
222 | // PM state lock. |
223 | IOLock * PMLock; |
224 | |
225 | unsigned int InitialPowerChange :1; |
226 | unsigned int InitialSetPowerState :1; |
227 | unsigned int DeviceOverrideEnabled :1; |
228 | unsigned int DoNotPowerDown :1; |
229 | unsigned int ParentsKnowState :1; |
230 | unsigned int StrictTreeOrder :1; |
231 | unsigned int IdleTimerStopped :1; |
232 | unsigned int AdjustPowerScheduled :1; |
233 | |
234 | unsigned int IsPreChange :1; |
235 | unsigned int DriverCallBusy :1; |
236 | unsigned int PCDFunctionOverride :1; |
237 | unsigned int IdleTimerIgnored :1; |
238 | unsigned int HasAdvisoryDesire :1; |
239 | unsigned int AdvisoryTickleUsed :1; |
240 | unsigned int ResetPowerStateOnWake :1; |
241 | |
242 | // Time of last device activity. |
243 | AbsoluteTime DeviceActiveTimestamp; |
244 | AbsoluteTime MaxPowerStateEntryTime; |
245 | AbsoluteTime MaxPowerStateExitTime; |
246 | |
247 | // Used to protect activity flag. |
248 | IOLock * ActivityLock; |
249 | |
250 | // Idle timer's period in seconds. |
251 | unsigned long IdleTimerPeriod; |
252 | unsigned long IdleTimerMinPowerState; |
253 | unsigned long NextIdleTimerPeriod; |
254 | AbsoluteTime IdleTimerStartTime; |
255 | |
256 | // Power state desired by a subclassed device object. |
257 | IOPMPowerStateIndex DeviceDesire; |
258 | |
259 | // This is the power state we desire currently. |
260 | IOPMPowerStateIndex DesiredPowerState; |
261 | |
262 | // This is what our parent thinks our need is. |
263 | IOPMPowerFlags PreviousRequestPowerFlags; |
264 | |
265 | // Cache result from getName(), used in logging. |
266 | const char * Name; |
267 | |
268 | // Number of power states in the power array. |
269 | IOPMPowerStateIndex NumberOfPowerStates; |
270 | |
271 | // Ordered highest power state in the power array. |
272 | IOPMPowerStateIndex HighestPowerState; |
273 | |
274 | // Power state array. |
275 | IOPMPSEntry * PowerStates; |
276 | |
277 | // The controlling driver. |
278 | IOService * ControllingDriver; |
279 | |
280 | // Our current power state. |
281 | IOPMPowerStateIndex CurrentPowerState; |
282 | |
283 | // Logical OR of power flags for each power domain parent. |
284 | IOPMPowerFlags ParentsCurrentPowerFlags; |
285 | |
286 | // The highest power state we can achieve in current power domain. |
287 | IOPMPowerStateIndex MaxPowerState; |
288 | |
289 | // Logical OR of all output power flags in the power state array. |
290 | IOPMPowerFlags MergedOutputPowerFlags; |
291 | |
292 | // OSArray which manages responses from notified apps and clients. |
293 | OSArray * ResponseArray; |
294 | OSArray * NotifyClientArray; |
295 | |
296 | // Used to uniquely identify power management notification to apps and clients. |
297 | UInt16 SerialNumber; |
298 | |
299 | // Used to communicate desired function to tellClientsWithResponse(). |
300 | // This is used because it avoids changing the signatures of the affected virtual methods. |
301 | int OutOfBandParameter; |
302 | |
303 | AbsoluteTime DriverCallStartTime; |
304 | IOPMPowerFlags CurrentCapabilityFlags; |
305 | unsigned long CurrentPowerConsumption; |
306 | IOPMPowerStateIndex TempClampPowerState; |
307 | OSArray * NotifyChildArray; |
308 | OSDictionary * PowerClients; |
309 | thread_call_t DriverCallEntry; |
310 | void * DriverCallParamPtr; |
311 | IOItemCount DriverCallParamCount; |
312 | IOItemCount DriverCallParamSlots; |
313 | uint32_t DriverCallReason; |
314 | uint32_t OutOfBandMessage; |
315 | uint32_t TempClampCount; |
316 | uint32_t OverrideMaxPowerState; |
317 | uint32_t DeviceUsablePowerState; |
318 | |
319 | // Protected by ActivityLock - BEGIN |
320 | IOPMPowerStateIndex ActivityTicklePowerState; |
321 | IOPMPowerStateIndex AdvisoryTicklePowerState; |
322 | uint32_t ActivityTickleCount; |
323 | uint32_t DeviceWasActive : 1; |
324 | uint32_t AdvisoryTickled : 1; |
325 | // Protected by ActivityLock - END |
326 | |
327 | uint32_t WaitReason; |
328 | uint32_t SavedMachineState; |
329 | |
330 | // Protected by PMLock - BEGIN |
331 | struct { |
332 | uint32_t PMStop : 1; |
333 | uint32_t PMDriverCallWait : 1; |
334 | } LockedFlags; |
335 | |
336 | queue_head_t PMDriverCallQueue; |
337 | OSSet * InsertInterestSet; |
338 | OSSet * RemoveInterestSet; |
339 | |
340 | // IOReporter Data |
341 | uint32_t ReportClientCnt; |
342 | void * ReportBuf; |
343 | // Protected by PMLock - END |
344 | |
345 | #if PM_VARS_SUPPORT |
346 | IOPMprot * PMVars; |
347 | #endif |
348 | |
349 | IOPMActions PMActions; |
350 | |
351 | // Serialize IOServicePM state for debug output. |
352 | IOReturn gatedSerialize( OSSerialize * s ) const; |
353 | virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; |
354 | |
355 | // PM log and trace |
356 | void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; |
357 | void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; |
358 | }; |
359 | |
360 | #define fOwner pwrMgt->Owner |
361 | #define fInterestedDrivers pwrMgt->InterestedDrivers |
362 | #define fDriverTimer pwrMgt->DriverTimer |
363 | #define fMachineState pwrMgt->MachineState |
364 | #define fAckTimer pwrMgt->AckTimer |
365 | #define fSettleTimer pwrMgt->SettleTimer |
366 | #define fIdleTimer pwrMgt->IdleTimer |
367 | #define fWatchdogTimer pwrMgt->WatchdogTimer |
368 | #define fWatchdogDeadline pwrMgt->WatchdogDeadline |
369 | #define fWatchdogLock pwrMgt->WatchdogLock |
370 | #define fBlockedArray pwrMgt->BlockedArray |
371 | #define fPendingResponseDeadline pwrMgt->PendingResponseDeadline |
372 | #define fSpinDumpTimer pwrMgt->SpinDumpTimer |
373 | #define fSettleTimeUS pwrMgt->SettleTimeUS |
374 | #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration |
375 | #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags |
376 | #define fHeadNotePowerState pwrMgt->HeadNotePowerState |
377 | #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry |
378 | #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags |
379 | #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags |
380 | #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection |
381 | #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags |
382 | #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks |
383 | #define fPMLock pwrMgt->PMLock |
384 | #define fInitialPowerChange pwrMgt->InitialPowerChange |
385 | #define fInitialSetPowerState pwrMgt->InitialSetPowerState |
386 | #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled |
387 | #define fDoNotPowerDown pwrMgt->DoNotPowerDown |
388 | #define fParentsKnowState pwrMgt->ParentsKnowState |
389 | #define fStrictTreeOrder pwrMgt->StrictTreeOrder |
390 | #define fIdleTimerStopped pwrMgt->IdleTimerStopped |
391 | #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled |
392 | #define fIsPreChange pwrMgt->IsPreChange |
393 | #define fDriverCallBusy pwrMgt->DriverCallBusy |
394 | #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride |
395 | #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored |
396 | #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire |
397 | #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed |
398 | #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake |
399 | #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp |
400 | #define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime |
401 | #define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime |
402 | #define fActivityLock pwrMgt->ActivityLock |
403 | #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod |
404 | #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState |
405 | #define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod |
406 | #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime |
407 | #define fDeviceDesire pwrMgt->DeviceDesire |
408 | #define fDesiredPowerState pwrMgt->DesiredPowerState |
409 | #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags |
410 | #define fName pwrMgt->Name |
411 | #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates |
412 | #define fHighestPowerState pwrMgt->HighestPowerState |
413 | #define fPowerStates pwrMgt->PowerStates |
414 | #define fControllingDriver pwrMgt->ControllingDriver |
415 | #define fCurrentPowerState pwrMgt->CurrentPowerState |
416 | #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags |
417 | #define fMaxPowerState pwrMgt->MaxPowerState |
418 | #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags |
419 | #define fResponseArray pwrMgt->ResponseArray |
420 | #define fNotifyClientArray pwrMgt->NotifyClientArray |
421 | #define fSerialNumber pwrMgt->SerialNumber |
422 | #define fOutOfBandParameter pwrMgt->OutOfBandParameter |
423 | #define fDriverCallStartTime pwrMgt->DriverCallStartTime |
424 | #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags |
425 | #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption |
426 | #define fTempClampPowerState pwrMgt->TempClampPowerState |
427 | #define fNotifyChildArray pwrMgt->NotifyChildArray |
428 | #define fPowerClients pwrMgt->PowerClients |
429 | #define fDriverCallEntry pwrMgt->DriverCallEntry |
430 | #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr |
431 | #define fDriverCallParamCount pwrMgt->DriverCallParamCount |
432 | #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots |
433 | #define fDriverCallReason pwrMgt->DriverCallReason |
434 | #define fOutOfBandMessage pwrMgt->OutOfBandMessage |
435 | #define fTempClampCount pwrMgt->TempClampCount |
436 | #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState |
437 | #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState |
438 | #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState |
439 | #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState |
440 | #define fActivityTickleCount pwrMgt->ActivityTickleCount |
441 | #define fDeviceWasActive pwrMgt->DeviceWasActive |
442 | #define fAdvisoryTickled pwrMgt->AdvisoryTickled |
443 | #define fWaitReason pwrMgt->WaitReason |
444 | #define fSavedMachineState pwrMgt->SavedMachineState |
445 | #define fLockedFlags pwrMgt->LockedFlags |
446 | #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue |
447 | #define fInsertInterestSet pwrMgt->InsertInterestSet |
448 | #define fRemoveInterestSet pwrMgt->RemoveInterestSet |
449 | #define fReportClientCnt pwrMgt->ReportClientCnt |
450 | #define fReportBuf pwrMgt->ReportBuf |
451 | #define fPMVars pwrMgt->PMVars |
452 | #define fPMActions pwrMgt->PMActions |
453 | |
454 | #define StateOrder(state) (((state) < fNumberOfPowerStates) \ |
455 | ? pwrMgt->PowerStates[(state)].stateOrder \ |
456 | : (state)) |
457 | #define StateMax(a,b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) |
458 | #define StateMin(a,b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) |
459 | |
460 | #define kPowerStateZero (0) |
461 | |
462 | /* |
463 | When an IOService is waiting for acknowledgement to a power change |
464 | notification from an interested driver or the controlling driver, |
465 | the ack timer is ticking every tenth of a second. |
466 | (100000000 nanoseconds are one tenth of a second). |
467 | */ |
468 | #define ACK_TIMER_PERIOD 100000000 |
469 | |
470 | #if defined(__i386__) || defined(__x86_64__) |
471 | #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs |
472 | #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs |
473 | #else |
474 | #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs |
475 | #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs |
476 | #endif |
477 | |
478 | // Max wait time in microseconds for kernel priority and capability clients |
479 | // with async message handlers to acknowledge. |
480 | // |
481 | #define kPriorityClientMaxWait (90 * 1000 * 1000) |
482 | #define kCapabilityClientMaxWait (240 * 1000 * 1000) |
483 | |
484 | // Attributes describing a power state change. |
485 | // See IOPMPowerChangeFlags data type. |
486 | // |
487 | #define kIOPMParentInitiated 0x0001 // power change initiated by our parent |
488 | #define kIOPMSelfInitiated 0x0002 // power change initiated by this device |
489 | #define kIOPMNotDone 0x0004 // we couldn't make this change |
490 | #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo |
491 | #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo |
492 | #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power |
493 | #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires |
494 | #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase |
495 | #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync |
496 | #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree |
497 | #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages |
498 | #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake |
499 | #define kIOPMInitialPowerChange 0x1000 // set for initial power change |
500 | #define kIOPMRootChangeUp 0x2000 // Root power domain change up |
501 | #define kIOPMRootChangeDown 0x4000 // Root power domain change down |
502 | #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration |
503 | |
504 | #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ |
505 | kIOPMRootChangeUp | kIOPMRootChangeDown) |
506 | |
507 | // Activity tickle request flags |
508 | #define kTickleTypePowerDrop 0x01 |
509 | #define kTickleTypePowerRise 0x02 |
510 | #define kTickleTypeActivity 0x04 |
511 | #define kTickleTypeAdvisory 0x08 |
512 | |
513 | enum { |
514 | kDriverCallInformPreChange, |
515 | kDriverCallInformPostChange, |
516 | kDriverCallSetPowerState, |
517 | kRootDomainInformPreChange |
518 | }; |
519 | |
520 | struct DriverCallParam { |
521 | OSObject * Target; |
522 | IOReturn Result; |
523 | }; |
524 | |
525 | // values of OutOfBandParameter |
526 | enum { |
527 | kNotifyApps, |
528 | kNotifyPriority, |
529 | kNotifyCapabilityChangeApps, |
530 | kNotifyCapabilityChangePriority |
531 | }; |
532 | |
533 | typedef bool (*IOPMMessageFilter)( |
534 | void * target, void * object, void * arg1, void * arg2, void * arg3 ); |
535 | |
536 | // used for applyToInterested |
537 | struct IOPMInterestContext { |
538 | OSArray * responseArray; |
539 | OSArray * notifyClients; |
540 | uint16_t serialNumber; |
541 | uint8_t isPreChange; |
542 | uint8_t enableTracing; |
543 | uint32_t maxTimeRequested; |
544 | uint32_t messageType; |
545 | uint32_t notifyType; |
546 | IOService * us; |
547 | IOPMPowerStateIndex stateNumber; |
548 | IOPMPowerFlags stateFlags; |
549 | IOPMPowerChangeFlags changeFlags; |
550 | const char * errorLog; |
551 | IOPMMessageFilter messageFilter; |
552 | }; |
553 | |
554 | // assertPMDriverCall() options |
555 | enum { |
556 | kIOPMADC_NoInactiveCheck = 1 |
557 | }; |
558 | |
559 | //****************************************************************************** |
560 | // PM Statistics & Diagnostics |
561 | //****************************************************************************** |
562 | |
563 | extern const OSSymbol *gIOPMStatsResponseTimedOut; |
564 | extern const OSSymbol *gIOPMStatsResponseCancel; |
565 | extern const OSSymbol *gIOPMStatsResponseSlow; |
566 | extern const OSSymbol *gIOPMStatsResponsePrompt; |
567 | extern const OSSymbol *gIOPMStatsDriverPSChangeSlow; |
568 | |
569 | //****************************************************************************** |
570 | // IOPMRequest |
571 | //****************************************************************************** |
572 | |
573 | class IOPMRequest : public IOCommand |
574 | { |
575 | OSDeclareDefaultStructors( IOPMRequest ) |
576 | |
577 | protected: |
578 | IOService * fTarget; // request target |
579 | IOPMRequest * fRequestNext; // the next request in the chain |
580 | IOPMRequest * fRequestRoot; // the root request in the call tree |
581 | IOItemCount fWorkWaitCount; // execution blocked if non-zero |
582 | IOItemCount fFreeWaitCount; // completion blocked if non-zero |
583 | uint32_t fRequestType; // request type |
584 | bool fIsQuiesceBlocker; |
585 | |
586 | IOPMCompletionAction fCompletionAction; |
587 | void * fCompletionTarget; |
588 | void * fCompletionParam; |
589 | |
590 | public: |
591 | uint32_t fRequestTag; |
592 | void * fArg0; |
593 | void * fArg1; |
594 | void * fArg2; |
595 | |
596 | inline bool isWorkBlocked( void ) const |
597 | { |
598 | return (fWorkWaitCount != 0); |
599 | } |
600 | |
601 | inline bool isFreeBlocked( void ) const |
602 | { |
603 | return (fFreeWaitCount != 0); |
604 | } |
605 | |
606 | inline IOPMRequest * getNextRequest( void ) const |
607 | { |
608 | return fRequestNext; |
609 | } |
610 | |
611 | inline IOPMRequest * getRootRequest( void ) const |
612 | { |
613 | if (fRequestRoot) return fRequestRoot; |
614 | #if NOT_READY |
615 | if (fCompletionAction) return (IOPMRequest *) this; |
616 | #endif |
617 | return 0; |
618 | } |
619 | |
620 | inline uint32_t getType( void ) const |
621 | { |
622 | return fRequestType; |
623 | } |
624 | |
625 | inline bool isReplyType( void ) const |
626 | { |
627 | return (fRequestType > kIOPMRequestTypeReplyStart); |
628 | } |
629 | |
630 | inline IOService * getTarget( void ) const |
631 | { |
632 | return fTarget; |
633 | } |
634 | |
635 | inline bool isQuiesceBlocker( void ) const |
636 | { |
637 | return fIsQuiesceBlocker; |
638 | } |
639 | |
640 | inline bool isQuiesceType( void ) const |
641 | { |
642 | return ((kIOPMRequestTypeQuiescePowerTree == fRequestType) && |
643 | (fCompletionAction != 0) && (fCompletionTarget != 0)); |
644 | } |
645 | |
646 | inline void installCompletionAction( |
647 | void * target, |
648 | IOPMCompletionAction action, |
649 | void * param ) |
650 | { |
651 | fCompletionTarget = target; |
652 | fCompletionAction = action; |
653 | fCompletionParam = param; |
654 | } |
655 | |
656 | static IOPMRequest * create( void ); |
657 | bool init( IOService * owner, IOOptionBits type ); |
658 | void reset( void ); |
659 | bool attachNextRequest( IOPMRequest * next ); |
660 | bool detachNextRequest( void ); |
661 | bool attachRootRequest( IOPMRequest * root ); |
662 | bool detachRootRequest( void ); |
663 | }; |
664 | |
665 | //****************************************************************************** |
666 | // IOPMRequestQueue |
667 | //****************************************************************************** |
668 | |
669 | class IOPMRequestQueue : public IOEventSource |
670 | { |
671 | OSDeclareDefaultStructors( IOPMRequestQueue ) |
672 | |
673 | public: |
674 | typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); |
675 | |
676 | protected: |
677 | queue_head_t fQueue; |
678 | IOLock * fLock; |
679 | |
680 | enum { kMaxDequeueCount = 256 }; |
681 | |
682 | virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; |
683 | virtual void free( void ) APPLE_KEXT_OVERRIDE; |
684 | virtual bool init( IOService * inOwner, Action inAction ); |
685 | |
686 | public: |
687 | static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); |
688 | void queuePMRequest( IOPMRequest * request ); |
689 | void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); |
690 | }; |
691 | |
692 | //****************************************************************************** |
693 | // IOPMWorkQueue |
694 | //****************************************************************************** |
695 | |
696 | #define WORK_QUEUE_STATS 1 |
697 | |
698 | class IOPMWorkQueue : public IOEventSource |
699 | { |
700 | OSDeclareDefaultStructors( IOPMWorkQueue ) |
701 | |
702 | public: |
703 | typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); |
704 | |
705 | #if WORK_QUEUE_STATS |
706 | uint64_t fStatCheckForWork; |
707 | uint64_t fStatScanEntries; |
708 | uint64_t fStatQueueEmpty; |
709 | uint64_t fStatNoWorkDone; |
710 | #endif |
711 | |
712 | protected: |
713 | queue_head_t fWorkQueue; |
714 | Action fInvokeAction; |
715 | Action fRetireAction; |
716 | uint32_t fQueueLength; |
717 | uint32_t fConsumerCount; |
718 | volatile uint32_t fProducerCount; |
719 | IOPMRequest * fQuiesceRequest; |
720 | AbsoluteTime fQuiesceStartTime; |
721 | AbsoluteTime fQuiesceFinishTime; |
722 | |
723 | virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; |
724 | virtual bool init( IOService * inOwner, Action invoke, Action retire ); |
725 | bool checkRequestQueue( queue_head_t * queue, bool * empty ); |
726 | |
727 | public: |
728 | static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); |
729 | bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); |
730 | void signalWorkAvailable( void ); |
731 | void incrementProducerCount( void ); |
732 | void attachQuiesceRequest( IOPMRequest * quiesceRequest ); |
733 | void finishQuiesceRequest( IOPMRequest * quiesceRequest ); |
734 | }; |
735 | |
736 | //****************************************************************************** |
737 | // IOPMCompletionQueue |
738 | //****************************************************************************** |
739 | |
740 | class IOPMCompletionQueue : public IOEventSource |
741 | { |
742 | OSDeclareDefaultStructors( IOPMCompletionQueue ) |
743 | |
744 | public: |
745 | typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); |
746 | |
747 | protected: |
748 | queue_head_t fQueue; |
749 | |
750 | virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; |
751 | virtual bool init( IOService * inOwner, Action inAction ); |
752 | |
753 | public: |
754 | static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); |
755 | bool queuePMRequest( IOPMRequest * request ); |
756 | }; |
757 | |
758 | #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ |
759 | |