/* * Copyright (c) 2007 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 * compliance with the License. The rights granted to you under the License * may not be used to create, or enable the creation or redistribution of, * 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, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * 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@ */ #ifndef _IOKIT_IOSERVICEPMPRIVATE_H #define _IOKIT_IOSERVICEPMPRIVATE_H #include #include //****************************************************************************** // 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, /* Reply Types */ kIOPMRequestTypeReplyStart = 0x80, kIOPMRequestTypeAckPowerChange = 0x81, kIOPMRequestTypeAckSetPowerState = 0x82, kIOPMRequestTypeAllowPowerChange = 0x83, kIOPMRequestTypeCancelPowerChange = 0x84, kIOPMRequestTypeInterestChanged = 0x85, kIOPMRequestTypeIdleCancel = 0x86, kIOPMRequestTypeChildNotifyDelayCancel = 0x87 }; //****************************************************************************** // PM actions - For root domain only //****************************************************************************** struct IOPMActions; typedef void (*IOPMActionPowerChangeStart)( 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 ); typedef void (*IOPMActionPowerChangeOverride)( void * target, IOService * service, IOPMActions * actions, IOPMPowerStateIndex * powerState, IOPMPowerChangeFlags * changeFlags, IOPMRequestTag requestTag ); typedef void (*IOPMActionActivityTickle)( void * target, IOService * service, IOPMActions * actions ); typedef void (*IOPMActionUpdatePowerClient)( 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; }; // IOPMActions parameter flags enum { kPMActionsFlagIsDisplayWrangler = 0x00000100, kPMActionsFlagIsGraphicsDevice = 0x00000200, kPMActionsFlagIsAudioDevice = 0x00000400, kPMActionsFlagLimitPower = 0x00000800, kPMActionsPCIBitNumberMask = 0x000000ff }; //****************************************************************************** // 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; }; //****************************************************************************** // IOServicePM //****************************************************************************** class IOServicePM : public OSObject { friend class IOService; friend class IOPMWorkQueue; OSDeclareDefaultStructors( IOServicePM ) private: // 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; // 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; // Points to the entry in the power state array. IOPMPSEntry * HeadNotePowerArrayEntry; // Power flags supplied by all parents (domain). IOPMPowerFlags HeadNoteDomainFlags; // 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; 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; #endif IOPMActions PMActions; // 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; }; #define fOwner pwrMgt->Owner #define fInterestedDrivers pwrMgt->InterestedDrivers #define fDriverTimer pwrMgt->DriverTimer #define fMachineState pwrMgt->MachineState #define fAckTimer pwrMgt->AckTimer #define fSettleTimer pwrMgt->SettleTimer #define fIdleTimer pwrMgt->IdleTimer #define fWatchdogTimer pwrMgt->WatchdogTimer #define fSettleTimeUS pwrMgt->SettleTimeUS #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags #define fHeadNotePowerState pwrMgt->HeadNotePowerState #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks #define fPMLock pwrMgt->PMLock #define fInitialPowerChange pwrMgt->InitialPowerChange #define fInitialSetPowerState pwrMgt->InitialSetPowerState #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled #define fDoNotPowerDown pwrMgt->DoNotPowerDown #define fParentsKnowState pwrMgt->ParentsKnowState #define fStrictTreeOrder pwrMgt->StrictTreeOrder #define fIdleTimerStopped pwrMgt->IdleTimerStopped #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled #define fIsPreChange pwrMgt->IsPreChange #define fDriverCallBusy pwrMgt->DriverCallBusy #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire #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 fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags #define fName pwrMgt->Name #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates #define fHighestPowerState pwrMgt->HighestPowerState #define fPowerStates pwrMgt->PowerStates #define fControllingDriver pwrMgt->ControllingDriver #define fCurrentPowerState pwrMgt->CurrentPowerState #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags #define fMaxPowerState pwrMgt->MaxPowerState #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags #define fResponseArray pwrMgt->ResponseArray #define fNotifyClientArray pwrMgt->NotifyClientArray #define fSerialNumber pwrMgt->SerialNumber #define fOutOfBandParameter pwrMgt->OutOfBandParameter #define fDriverCallStartTime pwrMgt->DriverCallStartTime #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption #define fTempClampPowerState pwrMgt->TempClampPowerState #define fNotifyChildArray pwrMgt->NotifyChildArray #define fPowerClients pwrMgt->PowerClients #define fDriverCallEntry pwrMgt->DriverCallEntry #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr #define fDriverCallParamCount pwrMgt->DriverCallParamCount #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots #define fDriverCallReason pwrMgt->DriverCallReason #define fOutOfBandMessage pwrMgt->OutOfBandMessage #define fTempClampCount pwrMgt->TempClampCount #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState #define fActivityTickleCount pwrMgt->ActivityTickleCount #define fDeviceWasActive pwrMgt->DeviceWasActive #define fAdvisoryTickled pwrMgt->AdvisoryTickled #define fWaitReason pwrMgt->WaitReason #define fSavedMachineState pwrMgt->SavedMachineState #define fLockedFlags pwrMgt->LockedFlags #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue #define fInsertInterestSet pwrMgt->InsertInterestSet #define fRemoveInterestSet pwrMgt->RemoveInterestSet #define fReportClientCnt pwrMgt->ReportClientCnt #define fReportBuf pwrMgt->ReportBuf #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 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). */ #define ACK_TIMER_PERIOD 100000000 #define WATCHDOG_TIMER_PERIOD (300) // 300 secs // 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) // Attributes describing a power state change. // See IOPMPowerChangeFlags data type. // #define kIOPMParentInitiated 0x0001 // power change initiated by our parent #define kIOPMSelfInitiated 0x0002 // power change initiated by this device #define kIOPMNotDone 0x0004 // we couldn't make this change #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake #define kIOPMInitialPowerChange 0x1000 // set for initial power change #define kIOPMRootChangeUp 0x2000 // Root power domain change up #define kIOPMRootChangeDown 0x4000 // Root power domain change down #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ kIOPMRootChangeUp | kIOPMRootChangeDown) // Activity tickle request flags #define kTickleTypePowerDrop 0x01 #define kTickleTypePowerRise 0x02 #define kTickleTypeActivity 0x04 #define kTickleTypeAdvisory 0x08 enum { kDriverCallInformPreChange, kDriverCallInformPostChange, kDriverCallSetPowerState, kRootDomainInformPreChange }; struct DriverCallParam { OSObject * Target; IOReturn Result; }; // values of OutOfBandParameter enum { kNotifyApps, kNotifyPriority, kNotifyCapabilityChangeApps, kNotifyCapabilityChangePriority }; typedef bool (*IOPMMessageFilter)( 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; }; // assertPMDriverCall() options enum { kIOPMADC_NoInactiveCheck = 1 }; //****************************************************************************** // PM Statistics & Diagnostics //****************************************************************************** extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut; extern const OSSymbol *gIOPMStatsApplicationResponseCancel; extern const OSSymbol *gIOPMStatsApplicationResponseSlow; extern const OSSymbol *gIOPMStatsApplicationResponsePrompt; 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 #if NOT_READY IOPMCompletionAction fCompletionAction; void * fCompletionTarget; void * fCompletionParam; IOReturn fCompletionStatus; #endif 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; #if NOT_READY 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 ); }; //****************************************************************************** // IOPMRequestQueue //****************************************************************************** class IOPMRequestQueue : public IOEventSource { OSDeclareDefaultStructors( IOPMRequestQueue ) public: typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); protected: queue_head_t fQueue; IOLock * fLock; virtual bool checkForWork( void ); virtual void free( void ); 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 ); }; //****************************************************************************** // IOPMWorkQueue //****************************************************************************** #define WORK_QUEUE_STATS 1 class IOPMWorkQueue : public IOEventSource { OSDeclareDefaultStructors( IOPMWorkQueue ) public: typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); #if WORK_QUEUE_STATS 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 ); public: static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire ); bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); void signalWorkAvailable( void ); void incrementProducerCount( void ); }; //****************************************************************************** // IOPMCompletionQueue //****************************************************************************** class IOPMCompletionQueue : public IOEventSource { OSDeclareDefaultStructors( IOPMCompletionQueue ) public: typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); protected: queue_head_t fQueue; virtual bool checkForWork( void ); virtual bool init( IOService * inOwner, Action inAction ); public: static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); bool queuePMRequest( IOPMRequest * request ); }; #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */