X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d9a64523371fa019c4575bb400cbbc3a50ac9903..f427ee49d309d8fc33ebf3042c3a775f2f530ded:/iokit/Kernel/IOServicePMPrivate.h diff --git a/iokit/Kernel/IOServicePMPrivate.h b/iokit/Kernel/IOServicePMPrivate.h index 26bfbee7f..31e42e28c 100644 --- a/iokit/Kernel/IOServicePMPrivate.h +++ b/iokit/Kernel/IOServicePMPrivate.h @@ -1,8 +1,8 @@ /* - * Copyright (c) 2007 Apple Inc. All rights reserved. + * Copyright (c) 2019-2020 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ @@ -32,40 +32,42 @@ #include #include +#define USE_SETTLE_TIMER 0 + //****************************************************************************** // PM command types //****************************************************************************** enum { - /* Command Types */ - kIOPMRequestTypeInvalid = 0x00, - kIOPMRequestTypePMStop = 0x01, - kIOPMRequestTypeAddPowerChild1 = 0x02, - kIOPMRequestTypeAddPowerChild2 = 0x03, - kIOPMRequestTypeAddPowerChild3 = 0x04, - kIOPMRequestTypeRegisterPowerDriver = 0x05, - kIOPMRequestTypeAdjustPowerState = 0x06, - kIOPMRequestTypePowerDomainWillChange = 0x07, - kIOPMRequestTypePowerDomainDidChange = 0x08, - kIOPMRequestTypePowerOverrideOnPriv = 0x09, - kIOPMRequestTypePowerOverrideOffPriv = 0x0A, - kIOPMRequestTypeActivityTickle = 0x0B, - kIOPMRequestTypeRequestPowerState = 0x0C, - kIOPMRequestTypeSynchronizePowerTree = 0x0D, - kIOPMRequestTypeRequestPowerStateOverride = 0x0E, - kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, - kIOPMRequestTypeIgnoreIdleTimer = 0x10, - kIOPMRequestTypeQuiescePowerTree = 0x11, - - /* Reply Types */ - kIOPMRequestTypeReplyStart = 0x80, - kIOPMRequestTypeAckPowerChange = 0x81, - kIOPMRequestTypeAckSetPowerState = 0x82, - kIOPMRequestTypeAllowPowerChange = 0x83, - kIOPMRequestTypeCancelPowerChange = 0x84, - kIOPMRequestTypeInterestChanged = 0x85, - kIOPMRequestTypeIdleCancel = 0x86, - kIOPMRequestTypeChildNotifyDelayCancel = 0x87 + /* Command Types */ + kIOPMRequestTypeInvalid = 0x00, + kIOPMRequestTypePMStop = 0x01, + kIOPMRequestTypeAddPowerChild1 = 0x02, + kIOPMRequestTypeAddPowerChild2 = 0x03, + kIOPMRequestTypeAddPowerChild3 = 0x04, + kIOPMRequestTypeRegisterPowerDriver = 0x05, + kIOPMRequestTypeAdjustPowerState = 0x06, + kIOPMRequestTypePowerDomainWillChange = 0x07, + kIOPMRequestTypePowerDomainDidChange = 0x08, + kIOPMRequestTypePowerOverrideOnPriv = 0x09, + kIOPMRequestTypePowerOverrideOffPriv = 0x0A, + kIOPMRequestTypeActivityTickle = 0x0B, + kIOPMRequestTypeRequestPowerState = 0x0C, + kIOPMRequestTypeSynchronizePowerTree = 0x0D, + kIOPMRequestTypeRequestPowerStateOverride = 0x0E, + kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, + kIOPMRequestTypeIgnoreIdleTimer = 0x10, + kIOPMRequestTypeQuiescePowerTree = 0x11, + + /* Reply Types */ + kIOPMRequestTypeReplyStart = 0x80, + kIOPMRequestTypeAckPowerChange = 0x81, + kIOPMRequestTypeAckSetPowerState = 0x82, + kIOPMRequestTypeAllowPowerChange = 0x83, + kIOPMRequestTypeCancelPowerChange = 0x84, + kIOPMRequestTypeInterestChanged = 0x85, + kIOPMRequestTypeIdleCancel = 0x86, + kIOPMRequestTypeChildNotifyDelayCancel = 0x87 }; //****************************************************************************** @@ -76,78 +78,85 @@ struct IOPMActions; typedef void (*IOPMActionPowerChangeStart)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex powerState, - IOPMPowerChangeFlags * changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + const IOPMRequest * request, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags * changeFlagsPtr ); typedef void (*IOPMActionPowerChangeDone)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex powerState, - IOPMPowerChangeFlags changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + const IOPMRequest * request, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags changeFlags ); typedef void (*IOPMActionPowerChangeOverride)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex * powerState, - IOPMPowerChangeFlags * changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + const IOPMRequest * request, + IOPMPowerStateIndex * powerStatePtr, + IOPMPowerChangeFlags * changeFlagsPtr ); typedef void (*IOPMActionActivityTickle)( - void * target, - IOService * service, - IOPMActions * actions ); + void * target, + IOService * service, + IOPMActions * actions ); typedef void (*IOPMActionUpdatePowerClient)( - void * target, - IOService * service, - IOPMActions * actions, - const OSSymbol * powerClient, - IOPMPowerStateIndex oldPowerState, - IOPMPowerStateIndex newPowerState -); + void * target, + IOService * service, + IOPMActions * actions, + const OSSymbol * powerClient, + IOPMPowerStateIndex oldPowerState, + IOPMPowerStateIndex newPowerState ); struct IOPMActions { - void * target; - uint32_t parameter; - IOPMActionPowerChangeStart actionPowerChangeStart; - IOPMActionPowerChangeDone actionPowerChangeDone; - IOPMActionPowerChangeOverride actionPowerChangeOverride; - IOPMActionActivityTickle actionActivityTickle; - IOPMActionUpdatePowerClient actionUpdatePowerClient; + void * target; + IOPMActionPowerChangeStart actionPowerChangeStart; + IOPMActionPowerChangeDone actionPowerChangeDone; + IOPMActionPowerChangeOverride actionPowerChangeOverride; + IOPMActionActivityTickle actionActivityTickle; + IOPMActionUpdatePowerClient actionUpdatePowerClient; + uint32_t darkWakePowerState; + uint16_t flags; + uint16_t state; }; -// IOPMActions parameter flags +// IOPMActions flags enum { - kPMActionsFlagIsDisplayWrangler = 0x00000100, - kPMActionsFlagIsGraphicsDevice = 0x00000200, - kPMActionsFlagIsAudioDevice = 0x00000400, - kPMActionsFlagLimitPower = 0x00000800, - kPMActionsPCIBitNumberMask = 0x000000ff + kPMActionsPCIBitNumberMask = 0x00ff, + kPMActionsFlagIsDisplayWrangler = 0x0100, + kPMActionsFlagIsGraphicsDriver = 0x0200, + kPMActionsFlagIsAudioDriver = 0x0400, + kPMActionsFlagHasDarkWakePowerState = 0x0800 +}; + +// IOPMActions state +enum { + kPMActionsStatePowerClamped = 0x0001 }; //****************************************************************************** // Internal concise representation of IOPMPowerState -struct IOPMPSEntry -{ - IOPMPowerFlags capabilityFlags; - IOPMPowerFlags outputPowerFlags; - IOPMPowerFlags inputPowerFlags; - uint32_t staticPower; - uint32_t settleUpTime; - uint32_t settleDownTime; - IOPMPowerStateIndex stateOrder; - IOPMPowerStateIndex stateOrderToIndex; +struct IOPMPSEntry { + IOPMPowerFlags capabilityFlags; + IOPMPowerFlags outputPowerFlags; + IOPMPowerFlags inputPowerFlags; + unsigned long staticPower; +#if USE_SETTLE_TIMER + uint32_t settleUpTime; + uint32_t settleDownTime; +#endif + IOPMPowerStateIndex stateOrder; + IOPMPowerStateIndex stateOrderToIndex; }; //****************************************************************************** @@ -156,205 +165,209 @@ struct IOPMPSEntry class IOServicePM : public OSObject { - friend class IOService; - friend class IOPMWorkQueue; + friend class IOService; + friend class IOPMWorkQueue; - OSDeclareDefaultStructors( IOServicePM ) + OSDeclareDefaultStructors( IOServicePM ); private: - // Link IOServicePM objects on IOPMWorkQueue. - queue_chain_t WorkChain; - - // Queue of IOPMRequest objects. - queue_head_t RequestHead; +// Link IOServicePM objects on IOPMWorkQueue. + queue_chain_t WorkChain; - // IOService creator and owner. - IOService * Owner; +// Queue of IOPMRequest objects. + queue_head_t RequestHead; - // List of interested drivers (protected by PMLock). - IOPMinformeeList * InterestedDrivers; +// IOService creator and owner. + IOService * Owner; - // How long to wait for controlling driver to acknowledge. - IOReturn DriverTimer; +// List of interested drivers (protected by PMLock). + IOPMinformeeList * InterestedDrivers; - // Current power management machine state. - uint32_t MachineState; +// How long to wait for controlling driver to acknowledge. + IOReturn DriverTimer; - thread_call_t AckTimer; - thread_call_t SettleTimer; - thread_call_t IdleTimer; - thread_call_t WatchdogTimer; - thread_call_t SpinDumpTimer; +// Current power management machine state. + uint32_t MachineState; - IOLock * WatchdogLock; - OSArray * BlockedArray; - uint64_t PendingResponseDeadline; - uint64_t WatchdogDeadline; - - // Settle time after changing power state. - uint32_t SettleTimeUS; - uint32_t IdleTimerGeneration; - - // The flags describing current change note. - IOPMPowerChangeFlags HeadNoteChangeFlags; - - // The new power state number being changed to. - IOPMPowerStateIndex HeadNotePowerState; + thread_call_t AckTimer; +#if USE_SETTLE_TIMER + thread_call_t SettleTimer; +#endif + thread_call_t IdleTimer; + thread_call_t WatchdogTimer; + thread_call_t SpinDumpTimer; + + IOLock * WatchdogLock; + OSArray * BlockedArray; + uint64_t PendingResponseDeadline; + uint64_t WatchdogDeadline; + +// Settle time after changing power state. +#if USE_SETTLE_TIMER + uint32_t SettleTimeUS; +#endif + IOPMPowerStateIndex IdleTimerGeneration; - // Points to the entry in the power state array. - IOPMPSEntry * HeadNotePowerArrayEntry; +// The flags describing current change note. + IOPMPowerChangeFlags HeadNoteChangeFlags; - // Power flags supplied by all parents (domain). - IOPMPowerFlags HeadNoteDomainFlags; +// The new power state number being changed to. + IOPMPowerStateIndex HeadNotePowerState; - // Power flags supplied by domain accounting for parent changes. - IOPMPowerFlags HeadNoteDomainTargetFlags; +// Points to the entry in the power state array. + IOPMPSEntry * HeadNotePowerArrayEntry; - // Connection attached to the changing parent. - IOPowerConnection * HeadNoteParentConnection; +// Power flags supplied by all parents (domain). + IOPMPowerFlags HeadNoteDomainFlags; - // Power flags supplied by the changing parent. - IOPMPowerFlags HeadNoteParentFlags; +// Power flags supplied by domain accounting for parent changes. + IOPMPowerFlags HeadNoteDomainTargetFlags; - // Number of acks still outstanding. - uint32_t HeadNotePendingAcks; +// Connection attached to the changing parent. + IOPowerConnection * HeadNoteParentConnection; - // PM state lock. - IOLock * PMLock; - - unsigned int InitialPowerChange :1; - unsigned int InitialSetPowerState :1; - unsigned int DeviceOverrideEnabled :1; - unsigned int DoNotPowerDown :1; - unsigned int ParentsKnowState :1; - unsigned int StrictTreeOrder :1; - unsigned int IdleTimerStopped :1; - unsigned int AdjustPowerScheduled :1; - - unsigned int IsPreChange :1; - unsigned int DriverCallBusy :1; - unsigned int PCDFunctionOverride :1; - unsigned int IdleTimerIgnored :1; - unsigned int HasAdvisoryDesire :1; - unsigned int AdvisoryTickleUsed :1; - unsigned int ResetPowerStateOnWake :1; - - // Time of last device activity. - AbsoluteTime DeviceActiveTimestamp; - AbsoluteTime MaxPowerStateEntryTime; - AbsoluteTime MaxPowerStateExitTime; - - // Used to protect activity flag. - IOLock * ActivityLock; - - // Idle timer's period in seconds. - unsigned long IdleTimerPeriod; - unsigned long IdleTimerMinPowerState; - unsigned long NextIdleTimerPeriod; - AbsoluteTime IdleTimerStartTime; - - // Power state desired by a subclassed device object. - IOPMPowerStateIndex DeviceDesire; - - // This is the power state we desire currently. - IOPMPowerStateIndex DesiredPowerState; - - // This is what our parent thinks our need is. - IOPMPowerFlags PreviousRequestPowerFlags; - - // Cache result from getName(), used in logging. - const char * Name; +// Power flags supplied by the changing parent. + IOPMPowerFlags HeadNoteParentFlags; - // Number of power states in the power array. - IOPMPowerStateIndex NumberOfPowerStates; +// Number of acks still outstanding. + uint32_t HeadNotePendingAcks; - // Ordered highest power state in the power array. - IOPMPowerStateIndex HighestPowerState; - - // Power state array. - IOPMPSEntry * PowerStates; - - // The controlling driver. - IOService * ControllingDriver; - - // Our current power state. - IOPMPowerStateIndex CurrentPowerState; - - // Logical OR of power flags for each power domain parent. - IOPMPowerFlags ParentsCurrentPowerFlags; - - // The highest power state we can achieve in current power domain. - IOPMPowerStateIndex MaxPowerState; - - // Logical OR of all output power flags in the power state array. - IOPMPowerFlags MergedOutputPowerFlags; - - // OSArray which manages responses from notified apps and clients. - OSArray * ResponseArray; - OSArray * NotifyClientArray; - - // Used to uniquely identify power management notification to apps and clients. - UInt16 SerialNumber; - - // Used to communicate desired function to tellClientsWithResponse(). - // This is used because it avoids changing the signatures of the affected virtual methods. - int OutOfBandParameter; - - AbsoluteTime DriverCallStartTime; - IOPMPowerFlags CurrentCapabilityFlags; - unsigned long CurrentPowerConsumption; - IOPMPowerStateIndex TempClampPowerState; - OSArray * NotifyChildArray; - OSDictionary * PowerClients; - thread_call_t DriverCallEntry; - void * DriverCallParamPtr; - IOItemCount DriverCallParamCount; - IOItemCount DriverCallParamSlots; - uint32_t DriverCallReason; - uint32_t OutOfBandMessage; - uint32_t TempClampCount; - uint32_t OverrideMaxPowerState; - uint32_t DeviceUsablePowerState; - - // Protected by ActivityLock - BEGIN - IOPMPowerStateIndex ActivityTicklePowerState; - IOPMPowerStateIndex AdvisoryTicklePowerState; - uint32_t ActivityTickleCount; - uint32_t DeviceWasActive : 1; - uint32_t AdvisoryTickled : 1; - // Protected by ActivityLock - END - - uint32_t WaitReason; - uint32_t SavedMachineState; - - // Protected by PMLock - BEGIN - struct { - uint32_t PMStop : 1; - uint32_t PMDriverCallWait : 1; - } LockedFlags; - - queue_head_t PMDriverCallQueue; - OSSet * InsertInterestSet; - OSSet * RemoveInterestSet; - - // IOReporter Data - uint32_t ReportClientCnt; - void * ReportBuf; - // Protected by PMLock - END +// PM state lock. + IOLock * PMLock; + + unsigned int InitialPowerChange :1; + unsigned int InitialSetPowerState :1; + unsigned int DeviceOverrideEnabled :1; + unsigned int DoNotPowerDown :1; + unsigned int ParentsKnowState :1; + unsigned int StrictTreeOrder :1; + unsigned int IdleTimerStopped :1; + unsigned int AdjustPowerScheduled :1; + + unsigned int IsPreChange :1; + unsigned int DriverCallBusy :1; + unsigned int PCDFunctionOverride :1; + unsigned int IdleTimerIgnored :1; + unsigned int HasAdvisoryDesire :1; + unsigned int AdvisoryTickleUsed :1; + unsigned int ResetPowerStateOnWake :1; + +// Time of last device activity. + AbsoluteTime DeviceActiveTimestamp; + AbsoluteTime MaxPowerStateEntryTime; + AbsoluteTime MaxPowerStateExitTime; + +// Used to protect activity flag. + IOLock * ActivityLock; + +// Idle timer's period in seconds. + int IdleTimerPeriod; + int NextIdleTimerPeriod; + IOPMPowerStateIndex IdleTimerMinPowerState; + AbsoluteTime IdleTimerStartTime; + +// Power state desired by a subclassed device object. + IOPMPowerStateIndex DeviceDesire; + +// This is the power state we desire currently. + IOPMPowerStateIndex DesiredPowerState; + +// This is what our parent thinks our need is. + IOPMPowerFlags PreviousRequestPowerFlags; + +// Cache result from getName(), used in logging. + const char * Name; + +// Number of power states in the power array. + IOPMPowerStateIndex NumberOfPowerStates; + +// Ordered highest power state in the power array. + IOPMPowerStateIndex HighestPowerState; + +// Power state array. + IOPMPSEntry * PowerStates; + +// The controlling driver. + IOService * ControllingDriver; + +// Our current power state. + IOPMPowerStateIndex CurrentPowerState; + +// Logical OR of power flags for each power domain parent. + IOPMPowerFlags ParentsCurrentPowerFlags; + +// The highest power state we can achieve in current power domain. + IOPMPowerStateIndex MaxPowerState; + +// Logical OR of all output power flags in the power state array. + IOPMPowerFlags MergedOutputPowerFlags; + +// OSArray which manages responses from notified apps and clients. + OSArray * ResponseArray; + OSArray * NotifyClientArray; + +// Used to uniquely identify power management notification to apps and clients. + uint16_t SerialNumber; + +// Used to communicate desired function to tellClientsWithResponse(). +// This is used because it avoids changing the signatures of the affected virtual methods. + int OutOfBandParameter; + + AbsoluteTime DriverCallStartTime; + IOPMPowerFlags CurrentCapabilityFlags; + unsigned long CurrentPowerConsumption; + IOPMPowerStateIndex TempClampPowerState; + OSArray * NotifyChildArray; + OSDictionary * PowerClients; + thread_call_t DriverCallEntry; + void * DriverCallParamPtr; + IOItemCount DriverCallParamCount; + IOItemCount DriverCallParamSlots; + uint32_t DriverCallReason; + uint32_t OutOfBandMessage; + uint32_t TempClampCount; + IOPMPowerStateIndex OverrideMaxPowerState; + IOPMPowerStateIndex DeviceUsablePowerState; + +// Protected by ActivityLock - BEGIN + IOPMPowerStateIndex ActivityTicklePowerState; + IOPMPowerStateIndex AdvisoryTicklePowerState; + uint32_t ActivityTickleCount; + uint32_t DeviceWasActive : 1; + uint32_t AdvisoryTickled : 1; +// Protected by ActivityLock - END + + uint32_t WaitReason; + uint32_t SavedMachineState; + +// Protected by PMLock - BEGIN + struct { + uint32_t PMStop : 1; + uint32_t PMDriverCallWait : 1; + } LockedFlags; + + queue_head_t PMDriverCallQueue; + OSSet * InsertInterestSet; + OSSet * RemoveInterestSet; + +// IOReporter Data + uint32_t ReportClientCnt; + void * ReportBuf; +// Protected by PMLock - END #if PM_VARS_SUPPORT - IOPMprot * PMVars; + IOPMprot * PMVars; #endif - IOPMActions PMActions; + IOPMActions PMActions; - // Serialize IOServicePM state for debug output. - IOReturn gatedSerialize( OSSerialize * s ) const; - virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; +// Serialize IOServicePM state for debug output. + IOReturn gatedSerialize( OSSerialize * s ) const; + virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; - // PM log and trace - void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; - void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; +// PM log and trace + void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; + void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; }; #define fOwner pwrMgt->Owner @@ -369,7 +382,6 @@ private: #define fWatchdogLock pwrMgt->WatchdogLock #define fBlockedArray pwrMgt->BlockedArray #define fPendingResponseDeadline pwrMgt->PendingResponseDeadline -#define fSpinDumpTimer pwrMgt->SpinDumpTimer #define fSettleTimeUS pwrMgt->SettleTimeUS #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags @@ -452,27 +464,27 @@ private: #define fPMActions pwrMgt->PMActions #define StateOrder(state) (((state) < fNumberOfPowerStates) \ - ? pwrMgt->PowerStates[(state)].stateOrder \ - : (state)) -#define StateMax(a,b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) -#define StateMin(a,b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) + ? pwrMgt->PowerStates[(state)].stateOrder \ + : (state)) +#define StateMax(a, b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) +#define StateMin(a, b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) #define kPowerStateZero (0) /* -When an IOService is waiting for acknowledgement to a power change -notification from an interested driver or the controlling driver, -the ack timer is ticking every tenth of a second. -(100000000 nanoseconds are one tenth of a second). -*/ + * When an IOService is waiting for acknowledgement to a power change + * notification from an interested driver or the controlling driver, + * the ack timer is ticking every tenth of a second. + * (100000000 nanoseconds are one tenth of a second). + */ #define ACK_TIMER_PERIOD 100000000 #if defined(__i386__) || defined(__x86_64__) #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs #else -#define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs -#define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs +#define WATCHDOG_SLEEP_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) +#define WATCHDOG_WAKE_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) #endif // Max wait time in microseconds for kernel priority and capability clients @@ -502,7 +514,7 @@ the ack timer is ticking every tenth of a second. #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ - kIOPMRootChangeUp | kIOPMRootChangeDown) + kIOPMRootChangeUp | kIOPMRootChangeDown) // Activity tickle request flags #define kTickleTypePowerDrop 0x01 @@ -511,60 +523,72 @@ the ack timer is ticking every tenth of a second. #define kTickleTypeAdvisory 0x08 enum { - kDriverCallInformPreChange, - kDriverCallInformPostChange, - kDriverCallSetPowerState, - kRootDomainInformPreChange + kDriverCallInformPreChange, + kDriverCallInformPostChange, + kDriverCallSetPowerState, + kRootDomainInformPreChange }; struct DriverCallParam { - OSObject * Target; - IOReturn Result; + OSObject * Target; + IOReturn Result; }; // values of OutOfBandParameter enum { - kNotifyApps, - kNotifyPriority, - kNotifyCapabilityChangeApps, - kNotifyCapabilityChangePriority + kNotifyApps, + kNotifyPriority, + kNotifyCapabilityChangeApps, + kNotifyCapabilityChangePriority }; typedef bool (*IOPMMessageFilter)( - void * target, void * object, void * arg1, void * arg2, void * arg3 ); + void * target, void * object, void * arg1, void * arg2, void * arg3 ); // used for applyToInterested struct IOPMInterestContext { - OSArray * responseArray; - OSArray * notifyClients; - uint16_t serialNumber; - uint8_t isPreChange; - uint8_t enableTracing; - uint32_t maxTimeRequested; - uint32_t messageType; - uint32_t notifyType; - IOService * us; - IOPMPowerStateIndex stateNumber; - IOPMPowerFlags stateFlags; - IOPMPowerChangeFlags changeFlags; - const char * errorLog; - IOPMMessageFilter messageFilter; + OSArray * responseArray; + OSArray * notifyClients; + uint16_t serialNumber; + uint8_t isPreChange; + uint8_t enableTracing; + uint32_t maxTimeRequested; + uint32_t messageType; + uint32_t notifyType; + uint32_t skippedInDark; + uint32_t notSkippedInDark; + IOService * us; + IOPMPowerStateIndex stateNumber; + IOPMPowerFlags stateFlags; + IOPMPowerChangeFlags changeFlags; + const char * errorLog; + IOPMMessageFilter messageFilter; }; // assertPMDriverCall() options enum { - kIOPMADC_NoInactiveCheck = 1 + kIOPMDriverCallNoInactiveCheck = 1 +}; + +// assertPMDriverCall() method +enum { + kIOPMDriverCallMethodUnknown = 0, + kIOPMDriverCallMethodSetPowerState = 1, + kIOPMDriverCallMethodWillChange = 2, + kIOPMDriverCallMethodDidChange = 3, + kIOPMDriverCallMethodChangeDone = 4, + kIOPMDriverCallMethodSetAggressive = 5 }; //****************************************************************************** // PM Statistics & Diagnostics //****************************************************************************** -extern const OSSymbol *gIOPMStatsResponseTimedOut; -extern const OSSymbol *gIOPMStatsResponseCancel; -extern const OSSymbol *gIOPMStatsResponseSlow; -extern const OSSymbol *gIOPMStatsResponsePrompt; -extern const OSSymbol *gIOPMStatsDriverPSChangeSlow; +extern OSPtr gIOPMStatsResponseTimedOut; +extern OSPtr gIOPMStatsResponseCancel; +extern OSPtr gIOPMStatsResponseSlow; +extern OSPtr gIOPMStatsResponsePrompt; +extern OSPtr gIOPMStatsDriverPSChangeSlow; //****************************************************************************** // IOPMRequest @@ -572,94 +596,127 @@ extern const OSSymbol *gIOPMStatsDriverPSChangeSlow; class IOPMRequest : public IOCommand { - OSDeclareDefaultStructors( IOPMRequest ) + OSDeclareDefaultStructors( IOPMRequest ); protected: - IOService * fTarget; // request target - IOPMRequest * fRequestNext; // the next request in the chain - IOPMRequest * fRequestRoot; // the root request in the call tree - IOItemCount fWorkWaitCount; // execution blocked if non-zero - IOItemCount fFreeWaitCount; // completion blocked if non-zero - uint32_t fRequestType; // request type - bool fIsQuiesceBlocker; - - IOPMCompletionAction fCompletionAction; - void * fCompletionTarget; - void * fCompletionParam; + IOService * fTarget; // request target + IOPMRequest * fRequestNext; // the next request in the chain + IOPMRequest * fRequestRoot; // the root request in the call tree + uint32_t fWorkWaitCount; // execution blocked if non-zero + uint32_t fFreeWaitCount; // completion blocked if non-zero + uint64_t fTimestamp; // MCTU + uint32_t fRequestType; // request type + bool fIsQuiesceBlocker; + + IOPMCompletionAction fCompletionAction; + void * fCompletionTarget; + void * fCompletionParam; public: - uint32_t fRequestTag; - void * fArg0; - void * fArg1; - void * fArg2; - - inline bool isWorkBlocked( void ) const - { - return (fWorkWaitCount != 0); - } - - inline bool isFreeBlocked( void ) const - { - return (fFreeWaitCount != 0); - } - - inline IOPMRequest * getNextRequest( void ) const - { - return fRequestNext; - } - - inline IOPMRequest * getRootRequest( void ) const - { - if (fRequestRoot) return fRequestRoot; + uint32_t fTag; + void * fArg0; + void * fArg1; + void * fArg2; + + inline bool + isWorkBlocked( void ) const + { + return fWorkWaitCount != 0; + } + + inline bool + isFreeBlocked( void ) const + { + return fFreeWaitCount != 0; + } + + inline IOPMRequest * + getNextRequest( void ) const + { + return fRequestNext; + } + + inline IOPMRequest * + getRootRequest( void ) const + { + if (fRequestRoot) { + return fRequestRoot; + } #if NOT_READY - if (fCompletionAction) return (IOPMRequest *) this; + if (fCompletionAction) { + return (IOPMRequest *) this; + } #endif - return 0; - } - - inline uint32_t getType( void ) const - { - return fRequestType; - } - - inline bool isReplyType( void ) const - { - return (fRequestType > kIOPMRequestTypeReplyStart); - } - - inline IOService * getTarget( void ) const - { - return fTarget; - } - - inline bool isQuiesceBlocker( void ) const - { - return fIsQuiesceBlocker; - } - - inline bool isQuiesceType( void ) const - { - return ((kIOPMRequestTypeQuiescePowerTree == fRequestType) && - (fCompletionAction != 0) && (fCompletionTarget != 0)); - } - - inline void installCompletionAction( - void * target, - IOPMCompletionAction action, - void * param ) - { - fCompletionTarget = target; - fCompletionAction = action; - fCompletionParam = param; - } - - static IOPMRequest * create( void ); - bool init( IOService * owner, IOOptionBits type ); - void reset( void ); - bool attachNextRequest( IOPMRequest * next ); - bool detachNextRequest( void ); - bool attachRootRequest( IOPMRequest * root ); - bool detachRootRequest( void ); + return NULL; + } + + inline uint32_t + getType( void ) const + { + return fRequestType; + } + + inline uint32_t + getTag( void ) const + { + return fTag; + } + + inline bool + isReplyType( void ) const + { + return fRequestType > kIOPMRequestTypeReplyStart; + } + + inline IOService * + getTarget( void ) const + { + return fTarget; + } + + inline bool + isQuiesceBlocker( void ) const + { + return fIsQuiesceBlocker; + } + + inline bool + isQuiesceType( void ) const + { + return (kIOPMRequestTypeQuiescePowerTree == fRequestType) && + (fCompletionAction != NULL) && (fCompletionTarget != NULL); + } + + inline void + installCompletionAction( + void * target, + IOPMCompletionAction action, + void * param ) + { + fCompletionTarget = target; + fCompletionAction = action; + fCompletionParam = param; + } + + inline void + setTimestamp( uint64_t time ) + { + fTimestamp = time; + } + + inline uint64_t + getTimestamp( void ) const + { + return fTimestamp; + } + + static IOPMRequest * create( void ); + bool init( IOService * owner, IOOptionBits type ); + void reset( void ); + bool attachNextRequest( IOPMRequest * next ); + bool detachNextRequest( void ); + bool attachRootRequest( IOPMRequest * root ); + bool detachRootRequest( void ); }; //****************************************************************************** @@ -668,25 +725,25 @@ public: class IOPMRequestQueue : public IOEventSource { - OSDeclareDefaultStructors( IOPMRequestQueue ) + OSDeclareDefaultStructors( IOPMRequestQueue ); public: - typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); + typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); protected: - queue_head_t fQueue; - IOLock * fLock; + queue_head_t fQueue; + IOLock * fLock; - enum { kMaxDequeueCount = 256 }; + enum { kMaxDequeueCount = 256 }; - virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; - virtual void free( void ) APPLE_KEXT_OVERRIDE; - virtual bool init( IOService * inOwner, Action inAction ); + virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; + virtual void free( void ) APPLE_KEXT_OVERRIDE; + virtual bool init( IOService * inOwner, Action inAction ); public: - static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); - void queuePMRequest( IOPMRequest * request ); - void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); + static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); + void queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request ); + void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); }; //****************************************************************************** @@ -697,40 +754,40 @@ public: class IOPMWorkQueue : public IOEventSource { - OSDeclareDefaultStructors( IOPMWorkQueue ) + OSDeclareDefaultStructors( IOPMWorkQueue ); public: - typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); + typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); #if WORK_QUEUE_STATS - uint64_t fStatCheckForWork; - uint64_t fStatScanEntries; - uint64_t fStatQueueEmpty; - uint64_t fStatNoWorkDone; + uint64_t fStatCheckForWork; + uint64_t fStatScanEntries; + uint64_t fStatQueueEmpty; + uint64_t fStatNoWorkDone; #endif protected: - queue_head_t fWorkQueue; - Action fInvokeAction; - Action fRetireAction; - uint32_t fQueueLength; - uint32_t fConsumerCount; - volatile uint32_t fProducerCount; - IOPMRequest * fQuiesceRequest; - AbsoluteTime fQuiesceStartTime; - AbsoluteTime fQuiesceFinishTime; - - virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; - virtual bool init( IOService * inOwner, Action invoke, Action retire ); - bool checkRequestQueue( queue_head_t * queue, bool * empty ); + queue_head_t fWorkQueue; + Action fInvokeAction; + Action fRetireAction; + uint32_t fQueueLength; + uint32_t fConsumerCount; + volatile uint32_t fProducerCount; + IOPMRequest * fQuiesceRequest; + AbsoluteTime fQuiesceStartTime; + AbsoluteTime fQuiesceFinishTime; + + virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; + virtual bool init( IOService * inOwner, Action invoke, Action retire ); + bool checkRequestQueue( queue_head_t * queue, bool * empty ); public: - static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); - bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); - void signalWorkAvailable( void ); - void incrementProducerCount( void ); - void attachQuiesceRequest( IOPMRequest * quiesceRequest ); - void finishQuiesceRequest( IOPMRequest * quiesceRequest ); + static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); + bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); + void signalWorkAvailable( void ); + void incrementProducerCount( void ); + void attachQuiesceRequest( IOPMRequest * quiesceRequest ); + void finishQuiesceRequest( IOPMRequest * quiesceRequest ); }; //****************************************************************************** @@ -739,20 +796,20 @@ public: class IOPMCompletionQueue : public IOEventSource { - OSDeclareDefaultStructors( IOPMCompletionQueue ) + OSDeclareDefaultStructors( IOPMCompletionQueue ); public: - typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); + typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); protected: - queue_head_t fQueue; + queue_head_t fQueue; - virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; - virtual bool init( IOService * inOwner, Action inAction ); + virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; + virtual bool init( IOService * inOwner, Action inAction ); public: - static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); - bool queuePMRequest( IOPMRequest * request ); + static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); + bool queuePMRequest( IOPMRequest * request ); }; #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */