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