kIOPMRequestTypeRequestPowerStateOverride = 0x0E,
kIOPMRequestTypeSetIdleTimerPeriod = 0x0F,
kIOPMRequestTypeIgnoreIdleTimer = 0x10,
-
+ kIOPMRequestTypeQuiescePowerTree = 0x11,
+
/* Reply Types */
kIOPMRequestTypeReplyStart = 0x80,
kIOPMRequestTypeAckPowerChange = 0x81,
kPMActionsFlagIsGraphicsDevice = 0x00000200,
kPMActionsFlagIsAudioDevice = 0x00000400,
kPMActionsFlagLimitPower = 0x00000800,
- kPMActionsPCIBitNumberMask = 0x000000ff
+ 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;
+ IOPMPowerFlags capabilityFlags;
+ IOPMPowerFlags outputPowerFlags;
+ IOPMPowerFlags inputPowerFlags;
uint32_t staticPower;
uint32_t settleUpTime;
uint32_t settleDownTime;
private:
// Link IOServicePM objects on IOPMWorkQueue.
queue_chain_t WorkChain;
-
+
// Queue of IOPMRequest objects.
queue_head_t RequestHead;
thread_call_t SettleTimer;
thread_call_t IdleTimer;
thread_call_t WatchdogTimer;
+ thread_call_t SpinDumpTimer;
// Settle time after changing power state.
uint32_t SettleTimeUS;
+ uint32_t IdleTimerGeneration;
// The flags describing current change note.
IOPMPowerChangeFlags HeadNoteChangeFlags;
// Connection attached to the changing parent.
IOPowerConnection * HeadNoteParentConnection;
-
+
// Power flags supplied by the changing parent.
IOPMPowerFlags HeadNoteParentFlags;
unsigned int StrictTreeOrder :1;
unsigned int IdleTimerStopped :1;
unsigned int AdjustPowerScheduled :1;
-
+
unsigned int IsPreChange :1;
unsigned int DriverCallBusy :1;
unsigned int PCDFunctionOverride :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.
uint32_t WaitReason;
uint32_t SavedMachineState;
- uint32_t RootDomainState;
// Protected by PMLock - BEGIN
struct {
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;
#endif
// Serialize IOServicePM state for debug output.
IOReturn gatedSerialize( OSSerialize * s ) const;
- virtual bool serialize( 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, 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
#define fSettleTimer pwrMgt->SettleTimer
#define fIdleTimer pwrMgt->IdleTimer
#define fWatchdogTimer pwrMgt->WatchdogTimer
+#define fSpinDumpTimer pwrMgt->SpinDumpTimer
#define fSettleTimeUS pwrMgt->SettleTimeUS
+#define fIdleTimerGeneration pwrMgt->IdleTimerGeneration
#define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags
#define fHeadNotePowerState pwrMgt->HeadNotePowerState
#define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry
#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
#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
#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)
*/
#define ACK_TIMER_PERIOD 100000000
+#if defined(__i386__) || defined(__x86_64__)
#define WATCHDOG_TIMER_PERIOD (300) // 300 secs
+#else
+#define WATCHDOG_TIMER_PERIOD (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)
// 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 )
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
+ 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;
-#if NOT_READY
IOPMCompletionAction fCompletionAction;
void * fCompletionTarget;
void * fCompletionParam;
- IOReturn fCompletionStatus;
-#endif
public:
uint32_t fRequestTag;
inline uint32_t getType( void ) const
{
- return fType;
+ return fRequestType;
}
inline bool isReplyType( void ) const
{
- return (fType > kIOPMRequestTypeReplyStart);
+ return (fRequestType > kIOPMRequestTypeReplyStart);
}
inline IOService * getTarget( void ) const
return fTarget;
}
-#if NOT_READY
- inline bool isCompletionInstalled( void )
+ inline bool isQuiesceBlocker( void ) const
+ {
+ return fIsQuiesceBlocker;
+ }
+
+ inline bool isQuiesceType( void ) const
{
- return (fCompletionAction != 0);
+ return ((kIOPMRequestTypeQuiescePowerTree == fRequestType) &&
+ (fCompletionAction != 0) && (fCompletionTarget != 0));
}
inline void installCompletionAction(
- IOPMCompletionAction action,
void * target,
+ IOPMCompletionAction action,
void * param )
{
- fCompletionAction = action;
fCompletionTarget = target;
+ fCompletionAction = action;
fCompletionParam = param;
}
-#endif /* NOT_READY */
static IOPMRequest * create( void );
bool init( IOService * owner, IOOptionBits type );
queue_head_t fQueue;
IOLock * fLock;
- virtual bool checkForWork( void );
- virtual void free( void );
+ 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:
protected:
queue_head_t fWorkQueue;
- Action fWorkAction;
+ Action fInvokeAction;
Action fRetireAction;
uint32_t fQueueLength;
uint32_t fConsumerCount;
volatile uint32_t fProducerCount;
+ IOPMRequest * fQuiesceRequest;
+ AbsoluteTime fQuiesceStartTime;
+ AbsoluteTime fQuiesceFinishTime;
- virtual bool checkForWork( void );
- virtual bool init( IOService * inOwner, Action work, Action retire );
+ 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 );
+ 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 );
};
//******************************************************************************
protected:
queue_head_t fQueue;
- virtual bool checkForWork( void );
+ virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
virtual bool init( IOService * inOwner, Action inAction );
public: