1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30#define _IOKIT_IOSERVICEPMPRIVATE_H
31
32#include <IOKit/IOCommand.h>
33#include <IOKit/IOEventSource.h>
34
35//******************************************************************************
36// PM command types
37//******************************************************************************
38
39enum {
40    /* Command Types */
41    kIOPMRequestTypeInvalid                     = 0x00,
42    kIOPMRequestTypePMStop                      = 0x01,
43    kIOPMRequestTypeAddPowerChild1              = 0x02,
44    kIOPMRequestTypeAddPowerChild2              = 0x03,
45    kIOPMRequestTypeAddPowerChild3              = 0x04,
46    kIOPMRequestTypeRegisterPowerDriver         = 0x05,
47    kIOPMRequestTypeAdjustPowerState            = 0x06,
48    kIOPMRequestTypePowerDomainWillChange       = 0x07,
49    kIOPMRequestTypePowerDomainDidChange        = 0x08,
50    kIOPMRequestTypePowerOverrideOnPriv         = 0x09,
51    kIOPMRequestTypePowerOverrideOffPriv        = 0x0A,
52    kIOPMRequestTypeActivityTickle              = 0x0B,
53    kIOPMRequestTypeRequestPowerState           = 0x0C,
54    kIOPMRequestTypeSynchronizePowerTree        = 0x0D,
55    kIOPMRequestTypeRequestPowerStateOverride   = 0x0E,
56    kIOPMRequestTypeSetIdleTimerPeriod          = 0x0F,
57    kIOPMRequestTypeIgnoreIdleTimer             = 0x10,
58
59    /* Reply Types */
60    kIOPMRequestTypeReplyStart                  = 0x80,
61    kIOPMRequestTypeAckPowerChange              = 0x81,
62    kIOPMRequestTypeAckSetPowerState            = 0x82,
63    kIOPMRequestTypeAllowPowerChange            = 0x83,
64    kIOPMRequestTypeCancelPowerChange           = 0x84,
65    kIOPMRequestTypeInterestChanged             = 0x85,
66    kIOPMRequestTypeIdleCancel                  = 0x86,
67    kIOPMRequestTypeChildNotifyDelayCancel      = 0x87
68};
69
70//******************************************************************************
71// PM actions - For root domain only
72//******************************************************************************
73
74struct IOPMActions;
75
76typedef void
77(*IOPMActionPowerChangeStart)(
78    void *          target,
79    IOService *     service,
80    IOPMActions *   actions,
81    uint32_t        powerState,
82    uint32_t *      changeFlags );
83
84typedef void
85(*IOPMActionPowerChangeDone)(
86    void *          target,
87    IOService *     service,
88    IOPMActions *   actions,
89    uint32_t        powerState,
90    uint32_t        changeFlags );
91
92typedef void
93(*IOPMActionPowerChangeOverride)(
94    void *          target,
95    IOService *     service,
96    IOPMActions *   actions,
97    unsigned long * powerState,
98    uint32_t *      changeFlags );
99
100typedef void
101(*IOPMActionActivityTickle)(
102    void *          target,
103    IOService *     service,
104    IOPMActions *   actions );
105
106struct IOPMActions {
107    void *                          target;
108    uint32_t                        parameter;
109    IOPMActionPowerChangeStart      actionPowerChangeStart;
110    IOPMActionPowerChangeDone       actionPowerChangeDone;
111    IOPMActionPowerChangeOverride   actionPowerChangeOverride;
112    IOPMActionActivityTickle        actionActivityTickle;
113};
114
115//******************************************************************************
116
117enum {
118	kIOPMEventClassSystemEvent			= 0x00,
119	kIOPMEventClassDriverEvent			= 0x1
120};
121
122class PMEventDetails : public OSObject
123{
124    OSDeclareDefaultStructors( PMEventDetails );
125    friend class IOServicePM;
126    friend class IOPMrootDomain;
127    friend class IOPMTimeline;
128public:
129  static PMEventDetails *eventDetails(uint32_t   type,
130                                      const char *ownerName,
131                                      uintptr_t  ownerUnique,
132                                      const char *interestName,
133                                      uint8_t    oldState,
134                                      uint8_t    newState,
135                                      uint32_t   result,
136                                      uint32_t   elapsedTimeUS);
137
138  static PMEventDetails *eventDetails(uint32_t   type,
139                                      const char *uuid,
140                                      uint32_t   reason,
141                                      uint32_t   result);
142private:
143  uint8_t		  eventClassifier;
144  uint32_t        eventType;
145  const char      *ownerName;
146  uintptr_t       ownerUnique;
147  const char      *interestName;
148  uint8_t         oldState;
149  uint8_t         newState;
150  uint32_t        result;
151  uint32_t        elapsedTimeUS;
152
153  const char      *uuid;
154  uint32_t        reason;
155};
156
157// Internal concise representation of IOPMPowerState
158struct IOPMPSEntry
159{
160    IOPMPowerFlags	capabilityFlags;
161    IOPMPowerFlags	outputPowerFlags;
162    IOPMPowerFlags	inputPowerFlags;
163    uint32_t        staticPower;
164    uint32_t        settleUpTime;
165    uint32_t        settleDownTime;
166};
167
168//******************************************************************************
169// IOServicePM
170//******************************************************************************
171
172class IOServicePM : public OSObject
173{
174    friend class IOService;
175    friend class IOPMWorkQueue;
176
177    OSDeclareDefaultStructors( IOServicePM )
178
179private:
180    // Link IOServicePM objects on IOPMWorkQueue.
181    queue_chain_t           WorkChain;
182
183    // Queue of IOPMRequest objects.
184    queue_head_t            RequestHead;
185
186    // IOService creator and owner.
187    IOService *             Owner;
188
189    // List of interested drivers (protected by PMLock).
190    IOPMinformeeList *      InterestedDrivers;
191
192    // How long to wait for controlling driver to acknowledge.
193    IOReturn                DriverTimer;
194
195    // Current power management machine state.
196    uint32_t                MachineState;
197
198    thread_call_t           AckTimer;
199    thread_call_t           SettleTimer;
200    thread_call_t           IdleTimer;
201
202    // Settle time after changing power state.
203    uint32_t                SettleTimeUS;
204
205    // The flags describing current change note.
206    IOPMPowerChangeFlags    HeadNoteChangeFlags;
207
208    // The new power state number being changed to.
209    IOPMPowerStateIndex     HeadNotePowerState;
210
211    // Points to the entry in the power state array.
212    IOPMPSEntry *           HeadNotePowerArrayEntry;
213
214    // Power flags supplied by all parents (domain).
215    IOPMPowerFlags          HeadNoteDomainFlags;
216
217    // Power flags supplied by domain accounting for parent changes.
218    IOPMPowerFlags          HeadNoteDomainTargetFlags;
219
220    // Connection attached to the changing parent.
221    IOPowerConnection *     HeadNoteParentConnection;
222
223    // Power flags supplied by the changing parent.
224    IOPMPowerFlags          HeadNoteParentFlags;
225
226    // Number of acks still outstanding.
227    uint32_t                HeadNotePendingAcks;
228
229    // PM state lock.
230    IOLock *                PMLock;
231
232    unsigned int            InitialPowerChange:1;
233    unsigned int            InitialSetPowerState:1;
234    unsigned int            DeviceOverrideEnabled:1;
235    unsigned int            DoNotPowerDown:1;
236    unsigned int            ParentsKnowState:1;
237    unsigned int            StrictTreeOrder:1;
238    unsigned int            IdleTimerStopped:1;
239    unsigned int            AdjustPowerScheduled:1;
240    unsigned int            IsPreChange:1;
241    unsigned int            DriverCallBusy:1;
242    unsigned int            PCDFunctionOverride:1;
243    unsigned int            IdleTimerIgnored:1;
244    unsigned int            HasAdvisoryDesire:1;
245    unsigned int            AdvisoryTickleUsed:1;
246
247    // Time of last device activity.
248    AbsoluteTime            DeviceActiveTimestamp;
249
250    // Used to protect activity flag.
251    IOLock *                ActivityLock;
252
253    // Idle timer's period in seconds.
254    unsigned long           IdleTimerPeriod;
255    unsigned long           IdleTimerMinPowerState;
256    AbsoluteTime            IdleTimerStartTime;
257
258    // Power state desired by a subclassed device object.
259    IOPMPowerStateIndex     DeviceDesire;
260
261    // This is the power state we desire currently.
262    IOPMPowerStateIndex     DesiredPowerState;
263
264    // This is what our parent thinks our need is.
265    IOPMPowerFlags          PreviousRequestPowerFlags;
266
267    // Cache result from getName(), used in logging.
268    const char *            Name;
269
270    // Number of power states in the power array.
271    IOPMPowerStateIndex     NumberOfPowerStates;
272
273    // Power state array.
274    IOPMPSEntry *           PowerStates;
275
276    // The controlling driver.
277    IOService *             ControllingDriver;
278
279    // Our current power state.
280    IOPMPowerStateIndex     CurrentPowerState;
281
282    // Logical OR of power flags for each power domain parent.
283    IOPMPowerFlags          ParentsCurrentPowerFlags;
284
285    // The highest power state we can achieve in current power domain.
286    IOPMPowerStateIndex     MaxPowerState;
287
288    // Logical OR of all output power character flags in the array.
289    IOPMPowerFlags          OutputPowerCharacterFlags;
290
291    // OSArray which manages responses from notified apps and clients.
292    OSArray *               ResponseArray;
293    OSArray *               NotifyClientArray;
294
295    // Used to uniquely identify power management notification to apps and clients.
296    UInt16                  SerialNumber;
297
298    // Used to communicate desired function to tellClientsWithResponse().
299    // This is used because it avoids changing the signatures of the affected virtual methods.
300    int                     OutOfBandParameter;
301
302    AbsoluteTime            DriverCallStartTime;
303    IOPMPowerFlags          CurrentCapabilityFlags;
304    unsigned long           CurrentPowerConsumption;
305    IOPMPowerStateIndex     TempClampPowerState;
306    OSArray *               NotifyChildArray;
307    OSDictionary *          PowerClients;
308    thread_call_t           DriverCallEntry;
309    void *                  DriverCallParamPtr;
310    IOItemCount             DriverCallParamCount;
311    IOItemCount             DriverCallParamSlots;
312    uint32_t                DriverCallReason;
313    uint32_t                OutOfBandMessage;
314    uint32_t                TempClampCount;
315    uint32_t                OverrideMaxPowerState;
316    uint32_t                DeviceUsablePowerState;
317
318    // Protected by ActivityLock - BEGIN
319    int                     ActivityTicklePowerState;
320    int                     AdvisoryTicklePowerState;
321    uint32_t                ActivityTickleCount;
322    uint32_t                DeviceWasActive     : 1;
323    uint32_t                AdvisoryTickled     : 1;
324    // Protected by ActivityLock - END
325
326    uint32_t                WaitReason;
327    uint32_t                SavedMachineState;
328    uint32_t                RootDomainState;
329
330    // Protected by PMLock - BEGIN
331    struct {
332        uint32_t            PMStop              : 1;
333        uint32_t            PMDriverCallWait    : 1;
334    } LockedFlags;
335
336    queue_head_t            PMDriverCallQueue;
337    OSSet *                 InsertInterestSet;
338    OSSet *                 RemoveInterestSet;
339    // Protected by PMLock - END
340
341#if PM_VARS_SUPPORT
342    IOPMprot *              PMVars;
343#endif
344
345    IOPMActions             PMActions;
346
347    // Serialize IOServicePM state for debug output.
348    IOReturn gatedSerialize( OSSerialize * s );
349    virtual bool serialize( OSSerialize * s ) const;
350
351    // PM log and trace
352    void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
353    void pmTrace( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
354};
355
356#define fOwner                      pwrMgt->Owner
357#define fInterestedDrivers          pwrMgt->InterestedDrivers
358#define fDriverTimer                pwrMgt->DriverTimer
359#define fMachineState               pwrMgt->MachineState
360#define fAckTimer                   pwrMgt->AckTimer
361#define fSettleTimer                pwrMgt->SettleTimer
362#define fIdleTimer                  pwrMgt->IdleTimer
363#define fSettleTimeUS               pwrMgt->SettleTimeUS
364#define fHeadNoteChangeFlags        pwrMgt->HeadNoteChangeFlags
365#define fHeadNotePowerState         pwrMgt->HeadNotePowerState
366#define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
367#define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
368#define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
369#define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
370#define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
371#define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
372#define fPMLock                     pwrMgt->PMLock
373#define fInitialPowerChange         pwrMgt->InitialPowerChange
374#define fInitialSetPowerState       pwrMgt->InitialSetPowerState
375#define fDeviceOverrideEnabled      pwrMgt->DeviceOverrideEnabled
376#define fDoNotPowerDown             pwrMgt->DoNotPowerDown
377#define fParentsKnowState           pwrMgt->ParentsKnowState
378#define fStrictTreeOrder            pwrMgt->StrictTreeOrder
379#define fIdleTimerStopped           pwrMgt->IdleTimerStopped
380#define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
381#define fIsPreChange                pwrMgt->IsPreChange
382#define fDriverCallBusy             pwrMgt->DriverCallBusy
383#define fPCDFunctionOverride        pwrMgt->PCDFunctionOverride
384#define fIdleTimerIgnored           pwrMgt->IdleTimerIgnored
385#define fHasAdvisoryDesire          pwrMgt->HasAdvisoryDesire
386#define fAdvisoryTickleUsed         pwrMgt->AdvisoryTickleUsed
387#define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
388#define fActivityLock               pwrMgt->ActivityLock
389#define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
390#define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
391#define fIdleTimerStartTime         pwrMgt->IdleTimerStartTime
392#define fDeviceDesire               pwrMgt->DeviceDesire
393#define fDesiredPowerState          pwrMgt->DesiredPowerState
394#define fPreviousRequestPowerFlags  pwrMgt->PreviousRequestPowerFlags
395#define fName                       pwrMgt->Name
396#define fNumberOfPowerStates        pwrMgt->NumberOfPowerStates
397#define fPowerStates                pwrMgt->PowerStates
398#define fControllingDriver          pwrMgt->ControllingDriver
399#define fCurrentPowerState          pwrMgt->CurrentPowerState
400#define fParentsCurrentPowerFlags   pwrMgt->ParentsCurrentPowerFlags
401#define fMaxPowerState              pwrMgt->MaxPowerState
402#define fOutputPowerCharacterFlags  pwrMgt->OutputPowerCharacterFlags
403#define fResponseArray              pwrMgt->ResponseArray
404#define fNotifyClientArray          pwrMgt->NotifyClientArray
405#define fSerialNumber               pwrMgt->SerialNumber
406#define fOutOfBandParameter         pwrMgt->OutOfBandParameter
407#define fDriverCallStartTime        pwrMgt->DriverCallStartTime
408#define fCurrentCapabilityFlags     pwrMgt->CurrentCapabilityFlags
409#define fCurrentPowerConsumption    pwrMgt->CurrentPowerConsumption
410#define fTempClampPowerState        pwrMgt->TempClampPowerState
411#define fNotifyChildArray           pwrMgt->NotifyChildArray
412#define fPowerClients               pwrMgt->PowerClients
413#define fDriverCallEntry            pwrMgt->DriverCallEntry
414#define fDriverCallParamPtr         pwrMgt->DriverCallParamPtr
415#define fDriverCallParamCount       pwrMgt->DriverCallParamCount
416#define fDriverCallParamSlots       pwrMgt->DriverCallParamSlots
417#define fDriverCallReason           pwrMgt->DriverCallReason
418#define fOutOfBandMessage           pwrMgt->OutOfBandMessage
419#define fTempClampCount             pwrMgt->TempClampCount
420#define fOverrideMaxPowerState      pwrMgt->OverrideMaxPowerState
421#define fDeviceUsablePowerState     pwrMgt->DeviceUsablePowerState
422#define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
423#define fAdvisoryTicklePowerState   pwrMgt->AdvisoryTicklePowerState
424#define fActivityTickleCount        pwrMgt->ActivityTickleCount
425#define fDeviceWasActive            pwrMgt->DeviceWasActive
426#define fAdvisoryTickled            pwrMgt->AdvisoryTickled
427#define fWaitReason                 pwrMgt->WaitReason
428#define fSavedMachineState          pwrMgt->SavedMachineState
429#define fRootDomainState            pwrMgt->RootDomainState
430#define fLockedFlags                pwrMgt->LockedFlags
431#define fPMDriverCallQueue          pwrMgt->PMDriverCallQueue
432#define fInsertInterestSet          pwrMgt->InsertInterestSet
433#define fRemoveInterestSet          pwrMgt->RemoveInterestSet
434#define fPMVars                     pwrMgt->PMVars
435#define fPMActions                  pwrMgt->PMActions
436
437/*
438When an IOService is waiting for acknowledgement to a power change
439notification from an interested driver or the controlling driver,
440the ack timer is ticking every tenth of a second.
441(100000000 nanoseconds are one tenth of a second).
442*/
443#define ACK_TIMER_PERIOD            100000000
444
445// Max wait time in microseconds for kernel priority and capability clients
446// with async message handlers to acknowledge.
447//
448#define kPriorityClientMaxWait      (90 * 1000 * 1000)
449#define kCapabilityClientMaxWait    (240 * 1000 * 1000)
450
451// Attributes describing a power state change.
452// See IOPMPowerChangeFlags data type.
453//
454#define kIOPMParentInitiated        0x0001  // this power change initiated by our  parent
455#define kIOPMSelfInitiated          0x0002  // this power change initiated by this device
456#define kIOPMNotDone                0x0004  // we couldn't make this change
457#define kIOPMDomainWillChange       0x0008  // change started by PowerDomainWillChangeTo
458#define kIOPMDomainDidChange        0x0010  // change started by PowerDomainDidChangeTo
459#define kIOPMDomainPowerDrop        0x0020  // Domain is lowering power
460#define kIOPMIgnoreChildren         0x0040  // Ignore children and driver power desires
461#define kIOPMSkipAskPowerDown       0x0080  // skip the ask app phase
462#define kIOPMSynchronize            0x0100  // change triggered by power tree re-sync
463#define kIOPMSyncNoChildNotify      0x0200  // sync root domain only, not entire tree
464#define kIOPMSyncTellPowerDown      0x0400  // send the ask/will power off messages
465#define kIOPMSyncCancelPowerDown    0x0800  // sleep cancel for maintenance wake
466#define kIOPMInitialPowerChange     0x1000  // set for initial power change
467
468enum {
469    kDriverCallInformPreChange,
470    kDriverCallInformPostChange,
471    kDriverCallSetPowerState
472};
473
474struct DriverCallParam {
475    OSObject *  Target;
476    IOReturn    Result;
477};
478
479// values of OutOfBandParameter
480enum {
481    kNotifyApps,
482    kNotifyPriority,
483    kNotifyCapabilityChangeApps,
484    kNotifyCapabilityChangePriority
485};
486
487typedef bool (*IOPMMessageFilter)(
488        void * target, void * object, void * arg1, void * arg2, void * arg3 );
489
490// used for applyToInterested
491struct IOPMInterestContext {
492    OSArray *               responseArray;
493    OSArray *               notifyClients;
494    uint16_t                serialNumber;
495    uint8_t                 isPreChange;
496    uint8_t                 enableTracing;
497    uint32_t                maxTimeRequested;
498    uint32_t                messageType;
499    uint32_t                notifyType;
500    IOService *             us;
501    IOPMPowerStateIndex     stateNumber;
502    IOPMPowerFlags          stateFlags;
503    IOPMPowerChangeFlags    changeFlags;
504    const char *            errorLog;
505    IOPMMessageFilter       messageFilter;
506};
507
508// assertPMDriverCall() options
509enum {
510    kIOPMADC_NoInactiveCheck = 1
511};
512
513//******************************************************************************
514// PM Statistics & Diagnostics
515//******************************************************************************
516
517extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut;
518extern const OSSymbol *gIOPMStatsApplicationResponseCancel;
519extern const OSSymbol *gIOPMStatsApplicationResponseSlow;
520
521//******************************************************************************
522// IOPMRequest
523//******************************************************************************
524
525typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status);
526
527class IOPMRequest : public IOCommand
528{
529    OSDeclareDefaultStructors( IOPMRequest )
530
531protected:
532    IOService *          fTarget;        // request target
533    IOPMRequest *        fRequestNext;   // the next request in the chain
534    IOPMRequest *        fRequestRoot;   // the root request in the issue tree
535    IOItemCount          fWorkWaitCount; // execution blocked if non-zero
536    IOItemCount          fFreeWaitCount; // completion blocked if non-zero
537    uint32_t             fType;          // request type
538
539    IOPMCompletionAction fCompletionAction;
540    void *               fCompletionTarget;
541    void *               fCompletionParam;
542    IOReturn             fCompletionStatus;
543
544public:
545    void *               fArg0;
546    void *               fArg1;
547    void *               fArg2;
548
549    inline bool          isWorkBlocked( void ) const
550    {
551        return (fWorkWaitCount != 0);
552    }
553
554    inline bool          isFreeBlocked( void ) const
555    {
556        return (fFreeWaitCount != 0);
557    }
558
559    inline IOPMRequest * getNextRequest( void ) const
560    {
561        return fRequestNext;
562    }
563
564    inline IOPMRequest * getRootRequest( void ) const
565    {
566        if (fRequestRoot) return fRequestRoot;
567        if (fCompletionAction) return (IOPMRequest *) this;
568        return 0;
569    }
570
571    inline uint32_t      getType( void ) const
572    {
573        return fType;
574    }
575
576    inline bool          isReplyType( void ) const
577    {
578        return (fType > kIOPMRequestTypeReplyStart);
579    }
580
581    inline IOService *   getTarget( void ) const
582    {
583        return fTarget;
584    }
585
586    inline bool          isCompletionInstalled( void )
587    {
588        return (fCompletionAction != 0);
589    }
590
591    inline void          installCompletionAction(
592                            IOPMCompletionAction action,
593                            void *               target,
594                            void *               param )
595    {
596        fCompletionAction = action;
597        fCompletionTarget = target;
598        fCompletionParam  = param;
599    }
600
601    static IOPMRequest * create( void );
602    bool   init( IOService * owner, IOOptionBits type );
603    void   reset( void );
604    bool   attachNextRequest( IOPMRequest * next );
605    bool   detachNextRequest( void );
606    bool   attachRootRequest( IOPMRequest * root );
607    bool   detachRootRequest( void );
608};
609
610//******************************************************************************
611// IOPMRequestQueue
612//******************************************************************************
613
614class IOPMRequestQueue : public IOEventSource
615{
616    OSDeclareDefaultStructors( IOPMRequestQueue )
617
618public:
619    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
620
621protected:
622    queue_head_t    fQueue;
623    IOLock *        fLock;
624
625    virtual bool checkForWork( void );
626    virtual void free( void );
627    virtual bool init( IOService * inOwner, Action inAction );
628
629public:
630    static  IOPMRequestQueue * create( IOService * inOwner, Action inAction );
631    void    queuePMRequest( IOPMRequest * request );
632    void    queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
633};
634
635//******************************************************************************
636// IOPMWorkQueue
637//******************************************************************************
638
639#define WORK_QUEUE_STATS    1
640
641class IOPMWorkQueue : public IOEventSource
642{
643    OSDeclareDefaultStructors( IOPMWorkQueue )
644
645public:
646    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
647
648#if WORK_QUEUE_STATS
649    uint64_t            fStatCheckForWork;
650    uint64_t            fStatScanEntries;
651    uint64_t            fStatQueueEmpty;
652    uint64_t            fStatNoWorkDone;
653#endif
654
655protected:
656    queue_head_t        fWorkQueue;
657    Action              fWorkAction;
658    Action              fRetireAction;
659    uint32_t            fQueueLength;
660    uint32_t            fConsumerCount;
661    volatile uint32_t   fProducerCount;
662
663    virtual bool checkForWork( void );
664    virtual bool init( IOService * inOwner, Action work, Action retire );
665    bool    checkRequestQueue( queue_head_t * queue, bool * empty );
666
667public:
668    static  IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
669    bool    queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
670    void    signalWorkAvailable( void );
671    void    incrementProducerCount( void );
672};
673
674//******************************************************************************
675// IOPMCompletionQueue
676//******************************************************************************
677
678class IOPMCompletionQueue : public IOEventSource
679{
680    OSDeclareDefaultStructors( IOPMCompletionQueue )
681
682public:
683    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
684
685protected:
686    queue_head_t    fQueue;
687
688    virtual bool checkForWork( void );
689    virtual bool init( IOService * inOwner, Action inAction );
690
691public:
692    static  IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
693    bool    queuePMRequest( IOPMRequest * request );
694};
695
696#endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */
697