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