X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..cb3231590a3c94ab4375e2228bd5e86b0cf1ad7e:/iokit/Kernel/IOServicePMPrivate.h diff --git a/iokit/Kernel/IOServicePMPrivate.h b/iokit/Kernel/IOServicePMPrivate.h index 40baaa62c..7d5a2bc54 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 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@ */ @@ -37,34 +37,35 @@ //****************************************************************************** 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, - - /* 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 }; //****************************************************************************** @@ -75,119 +76,77 @@ struct IOPMActions; typedef void (*IOPMActionPowerChangeStart)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex powerState, - IOPMPowerChangeFlags * changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags * changeFlags, + IOPMRequestTag requestTag ); typedef void (*IOPMActionPowerChangeDone)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex powerState, - IOPMPowerChangeFlags changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex powerState, + IOPMPowerChangeFlags changeFlags, + IOPMRequestTag requestTag ); typedef void (*IOPMActionPowerChangeOverride)( - void * target, - IOService * service, - IOPMActions * actions, - IOPMPowerStateIndex * powerState, - IOPMPowerChangeFlags * changeFlags, - IOPMRequestTag requestTag ); + void * target, + IOService * service, + IOPMActions * actions, + IOPMPowerStateIndex * powerState, + IOPMPowerChangeFlags * changeFlags, + IOPMRequestTag requestTag ); 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; + uint32_t parameter; + IOPMActionPowerChangeStart actionPowerChangeStart; + IOPMActionPowerChangeDone actionPowerChangeDone; + IOPMActionPowerChangeOverride actionPowerChangeOverride; + IOPMActionActivityTickle actionActivityTickle; + IOPMActionUpdatePowerClient actionUpdatePowerClient; }; // IOPMActions parameter flags enum { - kPMActionsFlagIsDisplayWrangler = 0x00000100, - kPMActionsFlagIsGraphicsDevice = 0x00000200, - kPMActionsFlagIsAudioDevice = 0x00000400, - kPMActionsFlagLimitPower = 0x00000800, - kPMActionsPCIBitNumberMask = 0x000000ff + kPMActionsFlagIsDisplayWrangler = 0x00000100, + kPMActionsFlagIsGraphicsDevice = 0x00000200, + kPMActionsFlagIsAudioDevice = 0x00000400, + kPMActionsFlagLimitPower = 0x00000800, + kPMActionsPCIBitNumberMask = 0x000000ff }; //****************************************************************************** - -enum { - kIOPMEventClassSystemEvent = 0x00, - kIOPMEventClassDriverEvent = 0x1 -}; - -class PMEventDetails : public OSObject -{ - OSDeclareDefaultStructors( PMEventDetails ); - friend class IOServicePM; - friend class IOPMrootDomain; - friend class IOPMTimeline; -public: - static PMEventDetails *eventDetails(uint32_t type, - const char *ownerName, - uintptr_t ownerUnique, - const char *interestName, - uint8_t oldState, - uint8_t newState, - uint32_t result, - uint32_t elapsedTimeUS); - - static PMEventDetails *eventDetails(uint32_t type, - const char *uuid, - uint32_t reason, - uint32_t result); -private: - uint8_t eventClassifier; - uint32_t eventType; - const char *ownerName; - uintptr_t ownerUnique; - const char *interestName; - uint8_t oldState; - uint8_t newState; - uint32_t result; - uint32_t elapsedTimeUS; - - const char *uuid; - uint32_t reason; -}; - // 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; + uint32_t staticPower; + uint32_t settleUpTime; + uint32_t settleDownTime; + IOPMPowerStateIndex stateOrder; + IOPMPowerStateIndex stateOrderToIndex; }; //****************************************************************************** @@ -196,198 +155,205 @@ 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; + +// Queue of IOPMRequest objects. + queue_head_t RequestHead; + +// IOService creator and owner. + IOService * Owner; + +// List of interested drivers (protected by PMLock). + IOPMinformeeList * InterestedDrivers; + +// How long to wait for controlling driver to acknowledge. + IOReturn DriverTimer; + +// Current power management machine state. + uint32_t MachineState; + + thread_call_t AckTimer; + thread_call_t SettleTimer; + thread_call_t IdleTimer; + thread_call_t WatchdogTimer; + thread_call_t SpinDumpTimer; - // IOService creator and owner. - IOService * Owner; + IOLock * WatchdogLock; + OSArray * BlockedArray; + uint64_t PendingResponseDeadline; + uint64_t WatchdogDeadline; - // List of interested drivers (protected by PMLock). - IOPMinformeeList * InterestedDrivers; +// Settle time after changing power state. + uint32_t SettleTimeUS; + uint32_t IdleTimerGeneration; - // How long to wait for controlling driver to acknowledge. - IOReturn DriverTimer; +// The flags describing current change note. + IOPMPowerChangeFlags HeadNoteChangeFlags; - // Current power management machine state. - uint32_t MachineState; +// The new power state number being changed to. + IOPMPowerStateIndex HeadNotePowerState; - thread_call_t AckTimer; - thread_call_t SettleTimer; - thread_call_t IdleTimer; - thread_call_t WatchdogTimer; +// Points to the entry in the power state array. + IOPMPSEntry * HeadNotePowerArrayEntry; - // Settle time after changing power state. - uint32_t SettleTimeUS; +// Power flags supplied by all parents (domain). + IOPMPowerFlags HeadNoteDomainFlags; - // The flags describing current change note. - IOPMPowerChangeFlags HeadNoteChangeFlags; +// Power flags supplied by domain accounting for parent changes. + IOPMPowerFlags HeadNoteDomainTargetFlags; - // The new power state number being changed to. - IOPMPowerStateIndex HeadNotePowerState; +// Connection attached to the changing parent. + IOPowerConnection * HeadNoteParentConnection; - // Points to the entry in the power state array. - IOPMPSEntry * HeadNotePowerArrayEntry; +// Power flags supplied by the changing parent. + IOPMPowerFlags HeadNoteParentFlags; - // Power flags supplied by all parents (domain). - IOPMPowerFlags HeadNoteDomainFlags; +// Number of acks still outstanding. + uint32_t HeadNotePendingAcks; - // Power flags supplied by domain accounting for parent changes. - IOPMPowerFlags HeadNoteDomainTargetFlags; - - // Connection attached to the changing parent. - IOPowerConnection * HeadNoteParentConnection; - - // Power flags supplied by the changing parent. - IOPMPowerFlags HeadNoteParentFlags; - - // Number of acks still outstanding. - uint32_t HeadNotePendingAcks; - - // 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; - - // Used to protect activity flag. - IOLock * ActivityLock; - - // Idle timer's period in seconds. - unsigned long IdleTimerPeriod; - unsigned long 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 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; - uint32_t RootDomainState; - - // 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. + 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; +// 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 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 #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; - - // PM log and trace - void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; - void pmTrace( uint32_t event, 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 @@ -398,7 +364,12 @@ private: #define fSettleTimer pwrMgt->SettleTimer #define fIdleTimer pwrMgt->IdleTimer #define fWatchdogTimer pwrMgt->WatchdogTimer +#define fWatchdogDeadline pwrMgt->WatchdogDeadline +#define fWatchdogLock pwrMgt->WatchdogLock +#define fBlockedArray pwrMgt->BlockedArray +#define fPendingResponseDeadline pwrMgt->PendingResponseDeadline #define fSettleTimeUS pwrMgt->SettleTimeUS +#define fIdleTimerGeneration pwrMgt->IdleTimerGeneration #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags #define fHeadNotePowerState pwrMgt->HeadNotePowerState #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry @@ -424,9 +395,12 @@ private: #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp +#define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime +#define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime #define fActivityLock pwrMgt->ActivityLock #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState +#define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime #define fDeviceDesire pwrMgt->DeviceDesire #define fDesiredPowerState pwrMgt->DesiredPowerState @@ -466,7 +440,6 @@ private: #define fAdvisoryTickled pwrMgt->AdvisoryTickled #define fWaitReason pwrMgt->WaitReason #define fSavedMachineState pwrMgt->SavedMachineState -#define fRootDomainState pwrMgt->RootDomainState #define fLockedFlags pwrMgt->LockedFlags #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue #define fInsertInterestSet pwrMgt->InsertInterestSet @@ -476,27 +449,33 @@ private: #define fPMVars pwrMgt->PMVars #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)) +#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)) #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 -#define WATCHDOG_TIMER_PERIOD (300) // 300 secs +#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 +#endif // Max wait time in microseconds for kernel priority and capability clients // with async message handlers to acknowledge. -// +// #define kPriorityClientMaxWait (90 * 1000 * 1000) #define kCapabilityClientMaxWait (240 * 1000 * 1000) @@ -521,7 +500,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 @@ -530,153 +509,181 @@ 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 *gIOPMStatsApplicationResponseTimedOut; -extern const OSSymbol *gIOPMStatsApplicationResponseCancel; -extern const OSSymbol *gIOPMStatsApplicationResponseSlow; +extern const OSSymbol *gIOPMStatsResponseTimedOut; +extern const OSSymbol *gIOPMStatsResponseCancel; +extern const OSSymbol *gIOPMStatsResponseSlow; +extern const OSSymbol *gIOPMStatsResponsePrompt; +extern const OSSymbol *gIOPMStatsDriverPSChangeSlow; //****************************************************************************** // IOPMRequest //****************************************************************************** -typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status); - 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 issue tree - IOItemCount fWorkWaitCount; // execution blocked if non-zero - IOItemCount fFreeWaitCount; // completion blocked if non-zero - uint32_t fType; // request type - -#if NOT_READY - IOPMCompletionAction fCompletionAction; - void * fCompletionTarget; - void * fCompletionParam; - IOReturn fCompletionStatus; -#endif + 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; 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 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; + } #if NOT_READY - if (fCompletionAction) return (IOPMRequest *) this; + if (fCompletionAction) { + return (IOPMRequest *) this; + } #endif - return 0; - } - - inline uint32_t getType( void ) const - { - return fType; - } - - inline bool isReplyType( void ) const - { - return (fType > kIOPMRequestTypeReplyStart); - } - - inline IOService * getTarget( void ) const - { - return fTarget; - } - -#if NOT_READY - inline bool isCompletionInstalled( void ) - { - return (fCompletionAction != 0); - } - - inline void installCompletionAction( - IOPMCompletionAction action, - void * target, - void * param ) - { - fCompletionAction = action; - fCompletionTarget = target; - fCompletionParam = param; - } -#endif /* NOT_READY */ - - 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 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; + } + + 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 ); }; //****************************************************************************** @@ -685,23 +692,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; - virtual bool checkForWork( void ); - virtual void free( void ); - virtual bool init( IOService * inOwner, Action inAction ); + enum { kMaxDequeueCount = 256 }; + + 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( IOPMRequest * request ); + void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); }; //****************************************************************************** @@ -712,35 +721,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 fWorkAction; - Action fRetireAction; - uint32_t fQueueLength; - uint32_t fConsumerCount; - volatile uint32_t fProducerCount; - - virtual bool checkForWork( void ); - virtual bool init( IOService * inOwner, Action work, 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 work, Action retire ); - bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); - void signalWorkAvailable( void ); - void incrementProducerCount( void ); + 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 ); }; //****************************************************************************** @@ -749,20 +763,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 ); - 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 */