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    IOPMPowerStateIndex     powerState,
82    IOPMPowerChangeFlags *  changeFlags,
83    IOPMRequestTag          requestTag );
84
85typedef void
86(*IOPMActionPowerChangeDone)(
87    void *                  target,
88    IOService *             service,
89    IOPMActions *           actions,
90    IOPMPowerStateIndex     powerState,
91    IOPMPowerChangeFlags    changeFlags,
92    IOPMRequestTag          requestTag );
93
94typedef void
95(*IOPMActionPowerChangeOverride)(
96    void *                  target,
97    IOService *             service,
98    IOPMActions *           actions,
99    IOPMPowerStateIndex *   powerState,
100    IOPMPowerChangeFlags *  changeFlags,
101    IOPMRequestTag          requestTag );
102
103typedef void
104(*IOPMActionActivityTickle)(
105    void *                  target,
106    IOService *             service,
107    IOPMActions *           actions );
108
109typedef void
110(*IOPMActionUpdatePowerClient)(
111    void *                  target,
112    IOService *             service,
113    IOPMActions *           actions,
114    const OSSymbol *        powerClient,
115    IOPMPowerStateIndex     oldPowerState,
116    IOPMPowerStateIndex     newPowerState
117);
118
119struct IOPMActions {
120    void *                          target;
121    uint32_t                        parameter;
122    IOPMActionPowerChangeStart      actionPowerChangeStart;
123    IOPMActionPowerChangeDone       actionPowerChangeDone;
124    IOPMActionPowerChangeOverride   actionPowerChangeOverride;
125    IOPMActionActivityTickle        actionActivityTickle;
126    IOPMActionUpdatePowerClient     actionUpdatePowerClient;
127};
128
129// IOPMActions parameter flags
130enum {
131    kPMActionsFlagIsDisplayWrangler = 0x00000100,
132    kPMActionsFlagIsGraphicsDevice  = 0x00000200,
133    kPMActionsFlagIsAudioDevice     = 0x00000400,
134    kPMActionsFlagLimitPower        = 0x00000800,
135    kPMActionsPCIBitNumberMask      = 0x000000ff
136};
137
138//******************************************************************************
139// Internal concise representation of IOPMPowerState
140struct IOPMPSEntry
141{
142    IOPMPowerFlags      capabilityFlags;
143    IOPMPowerFlags      outputPowerFlags;
144    IOPMPowerFlags      inputPowerFlags;
145    uint32_t            staticPower;
146    uint32_t            settleUpTime;
147    uint32_t            settleDownTime;
148    IOPMPowerStateIndex stateOrder;
149    IOPMPowerStateIndex stateOrderToIndex;
150};
151
152//******************************************************************************
153// IOServicePM
154//******************************************************************************
155
156class IOServicePM : public OSObject
157{
158    friend class IOService;
159    friend class IOPMWorkQueue;
160
161    OSDeclareDefaultStructors( IOServicePM )
162
163private:
164    // Link IOServicePM objects on IOPMWorkQueue.
165    queue_chain_t           WorkChain;
166
167    // Queue of IOPMRequest objects.
168    queue_head_t            RequestHead;
169
170    // IOService creator and owner.
171    IOService *             Owner;
172
173    // List of interested drivers (protected by PMLock).
174    IOPMinformeeList *      InterestedDrivers;
175
176    // How long to wait for controlling driver to acknowledge.
177    IOReturn                DriverTimer;
178
179    // Current power management machine state.
180    uint32_t                MachineState;
181
182    thread_call_t           AckTimer;
183    thread_call_t           SettleTimer;
184    thread_call_t           IdleTimer;
185    thread_call_t           WatchdogTimer;
186
187    // Settle time after changing power state.
188    uint32_t                SettleTimeUS;
189    uint32_t                IdleTimerGeneration;
190
191    // The flags describing current change note.
192    IOPMPowerChangeFlags    HeadNoteChangeFlags;
193
194    // The new power state number being changed to.
195    IOPMPowerStateIndex     HeadNotePowerState;
196
197    // Points to the entry in the power state array.
198    IOPMPSEntry *           HeadNotePowerArrayEntry;
199
200    // Power flags supplied by all parents (domain).
201    IOPMPowerFlags          HeadNoteDomainFlags;
202
203    // Power flags supplied by domain accounting for parent changes.
204    IOPMPowerFlags          HeadNoteDomainTargetFlags;
205
206    // Connection attached to the changing parent.
207    IOPowerConnection *     HeadNoteParentConnection;
208
209    // Power flags supplied by the changing parent.
210    IOPMPowerFlags          HeadNoteParentFlags;
211
212    // Number of acks still outstanding.
213    uint32_t                HeadNotePendingAcks;
214
215    // PM state lock.
216    IOLock *                PMLock;
217
218    unsigned int            InitialPowerChange          :1;
219    unsigned int            InitialSetPowerState        :1;
220    unsigned int            DeviceOverrideEnabled       :1;
221    unsigned int            DoNotPowerDown              :1;
222    unsigned int            ParentsKnowState            :1;
223    unsigned int            StrictTreeOrder             :1;
224    unsigned int            IdleTimerStopped            :1;
225    unsigned int            AdjustPowerScheduled        :1;
226
227    unsigned int            IsPreChange                 :1;
228    unsigned int            DriverCallBusy              :1;
229    unsigned int            PCDFunctionOverride         :1;
230    unsigned int            IdleTimerIgnored            :1;
231    unsigned int            HasAdvisoryDesire           :1;
232    unsigned int            AdvisoryTickleUsed          :1;
233    unsigned int            ResetPowerStateOnWake       :1;
234
235    // Time of last device activity.
236    AbsoluteTime            DeviceActiveTimestamp;
237    AbsoluteTime            MaxPowerStateEntryTime;
238    AbsoluteTime            MaxPowerStateExitTime;
239
240    // Used to protect activity flag.
241    IOLock *                ActivityLock;
242
243    // Idle timer's period in seconds.
244    unsigned long           IdleTimerPeriod;
245    unsigned long           IdleTimerMinPowerState;
246    unsigned long           NextIdleTimerPeriod;
247    AbsoluteTime            IdleTimerStartTime;
248
249    // Power state desired by a subclassed device object.
250    IOPMPowerStateIndex     DeviceDesire;
251
252    // This is the power state we desire currently.
253    IOPMPowerStateIndex     DesiredPowerState;
254
255    // This is what our parent thinks our need is.
256    IOPMPowerFlags          PreviousRequestPowerFlags;
257
258    // Cache result from getName(), used in logging.
259    const char *            Name;
260
261    // Number of power states in the power array.
262    IOPMPowerStateIndex     NumberOfPowerStates;
263
264    // Ordered highest power state in the power array.
265    IOPMPowerStateIndex     HighestPowerState;
266
267    // Power state array.
268    IOPMPSEntry *           PowerStates;
269
270    // The controlling driver.
271    IOService *             ControllingDriver;
272
273    // Our current power state.
274    IOPMPowerStateIndex     CurrentPowerState;
275
276    // Logical OR of power flags for each power domain parent.
277    IOPMPowerFlags          ParentsCurrentPowerFlags;
278
279    // The highest power state we can achieve in current power domain.
280    IOPMPowerStateIndex     MaxPowerState;
281
282    // Logical OR of all output power flags in the power state array.
283    IOPMPowerFlags          MergedOutputPowerFlags;
284
285    // OSArray which manages responses from notified apps and clients.
286    OSArray *               ResponseArray;
287    OSArray *               NotifyClientArray;
288
289    // Used to uniquely identify power management notification to apps and clients.
290    UInt16                  SerialNumber;
291
292    // Used to communicate desired function to tellClientsWithResponse().
293    // This is used because it avoids changing the signatures of the affected virtual methods.
294    int                     OutOfBandParameter;
295
296    AbsoluteTime            DriverCallStartTime;
297    IOPMPowerFlags          CurrentCapabilityFlags;
298    unsigned long           CurrentPowerConsumption;
299    IOPMPowerStateIndex     TempClampPowerState;
300    OSArray *               NotifyChildArray;
301    OSDictionary *          PowerClients;
302    thread_call_t           DriverCallEntry;
303    void *                  DriverCallParamPtr;
304    IOItemCount             DriverCallParamCount;
305    IOItemCount             DriverCallParamSlots;
306    uint32_t                DriverCallReason;
307    uint32_t                OutOfBandMessage;
308    uint32_t                TempClampCount;
309    uint32_t                OverrideMaxPowerState;
310    uint32_t                DeviceUsablePowerState;
311
312    // Protected by ActivityLock - BEGIN
313    IOPMPowerStateIndex     ActivityTicklePowerState;
314    IOPMPowerStateIndex     AdvisoryTicklePowerState;
315    uint32_t                ActivityTickleCount;
316    uint32_t                DeviceWasActive     : 1;
317    uint32_t                AdvisoryTickled     : 1;
318    // Protected by ActivityLock - END
319
320    uint32_t                WaitReason;
321    uint32_t                SavedMachineState;
322
323    // Protected by PMLock - BEGIN
324    struct {
325        uint32_t            PMStop              : 1;
326        uint32_t            PMDriverCallWait    : 1;
327    } LockedFlags;
328
329    queue_head_t            PMDriverCallQueue;
330    OSSet *                 InsertInterestSet;
331    OSSet *                 RemoveInterestSet;
332
333    // IOReporter Data
334    uint32_t                ReportClientCnt;
335    void *                  ReportBuf;
336    // Protected by PMLock - END
337
338#if PM_VARS_SUPPORT
339    IOPMprot *              PMVars;
340#endif
341
342    IOPMActions             PMActions;
343
344    // Serialize IOServicePM state for debug output.
345    IOReturn gatedSerialize( OSSerialize * s ) const;
346    virtual bool serialize( OSSerialize * s ) const;
347
348    // PM log and trace
349    void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
350    void pmTrace( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
351};
352
353#define fOwner                      pwrMgt->Owner
354#define fInterestedDrivers          pwrMgt->InterestedDrivers
355#define fDriverTimer                pwrMgt->DriverTimer
356#define fMachineState               pwrMgt->MachineState
357#define fAckTimer                   pwrMgt->AckTimer
358#define fSettleTimer                pwrMgt->SettleTimer
359#define fIdleTimer                  pwrMgt->IdleTimer
360#define fWatchdogTimer              pwrMgt->WatchdogTimer
361#define fSettleTimeUS               pwrMgt->SettleTimeUS
362#define fIdleTimerGeneration        pwrMgt->IdleTimerGeneration
363#define fHeadNoteChangeFlags        pwrMgt->HeadNoteChangeFlags
364#define fHeadNotePowerState         pwrMgt->HeadNotePowerState
365#define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
366#define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
367#define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
368#define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
369#define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
370#define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
371#define fPMLock                     pwrMgt->PMLock
372#define fInitialPowerChange         pwrMgt->InitialPowerChange
373#define fInitialSetPowerState       pwrMgt->InitialSetPowerState
374#define fDeviceOverrideEnabled      pwrMgt->DeviceOverrideEnabled
375#define fDoNotPowerDown             pwrMgt->DoNotPowerDown
376#define fParentsKnowState           pwrMgt->ParentsKnowState
377#define fStrictTreeOrder            pwrMgt->StrictTreeOrder
378#define fIdleTimerStopped           pwrMgt->IdleTimerStopped
379#define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
380#define fIsPreChange                pwrMgt->IsPreChange
381#define fDriverCallBusy             pwrMgt->DriverCallBusy
382#define fPCDFunctionOverride        pwrMgt->PCDFunctionOverride
383#define fIdleTimerIgnored           pwrMgt->IdleTimerIgnored
384#define fHasAdvisoryDesire          pwrMgt->HasAdvisoryDesire
385#define fAdvisoryTickleUsed         pwrMgt->AdvisoryTickleUsed
386#define fResetPowerStateOnWake      pwrMgt->ResetPowerStateOnWake
387#define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
388#define fMaxPowerStateEntryTime     pwrMgt->MaxPowerStateEntryTime
389#define fMaxPowerStateExitTime      pwrMgt->MaxPowerStateExitTime
390#define fActivityLock               pwrMgt->ActivityLock
391#define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
392#define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
393#define fNextIdleTimerPeriod        pwrMgt->NextIdleTimerPeriod
394#define fIdleTimerStartTime         pwrMgt->IdleTimerStartTime
395#define fDeviceDesire               pwrMgt->DeviceDesire
396#define fDesiredPowerState          pwrMgt->DesiredPowerState
397#define fPreviousRequestPowerFlags  pwrMgt->PreviousRequestPowerFlags
398#define fName                       pwrMgt->Name
399#define fNumberOfPowerStates        pwrMgt->NumberOfPowerStates
400#define fHighestPowerState          pwrMgt->HighestPowerState
401#define fPowerStates                pwrMgt->PowerStates
402#define fControllingDriver          pwrMgt->ControllingDriver
403#define fCurrentPowerState          pwrMgt->CurrentPowerState
404#define fParentsCurrentPowerFlags   pwrMgt->ParentsCurrentPowerFlags
405#define fMaxPowerState              pwrMgt->MaxPowerState
406#define fMergedOutputPowerFlags     pwrMgt->MergedOutputPowerFlags
407#define fResponseArray              pwrMgt->ResponseArray
408#define fNotifyClientArray          pwrMgt->NotifyClientArray
409#define fSerialNumber               pwrMgt->SerialNumber
410#define fOutOfBandParameter         pwrMgt->OutOfBandParameter
411#define fDriverCallStartTime        pwrMgt->DriverCallStartTime
412#define fCurrentCapabilityFlags     pwrMgt->CurrentCapabilityFlags
413#define fCurrentPowerConsumption    pwrMgt->CurrentPowerConsumption
414#define fTempClampPowerState        pwrMgt->TempClampPowerState
415#define fNotifyChildArray           pwrMgt->NotifyChildArray
416#define fPowerClients               pwrMgt->PowerClients
417#define fDriverCallEntry            pwrMgt->DriverCallEntry
418#define fDriverCallParamPtr         pwrMgt->DriverCallParamPtr
419#define fDriverCallParamCount       pwrMgt->DriverCallParamCount
420#define fDriverCallParamSlots       pwrMgt->DriverCallParamSlots
421#define fDriverCallReason           pwrMgt->DriverCallReason
422#define fOutOfBandMessage           pwrMgt->OutOfBandMessage
423#define fTempClampCount             pwrMgt->TempClampCount
424#define fOverrideMaxPowerState      pwrMgt->OverrideMaxPowerState
425#define fDeviceUsablePowerState     pwrMgt->DeviceUsablePowerState
426#define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
427#define fAdvisoryTicklePowerState   pwrMgt->AdvisoryTicklePowerState
428#define fActivityTickleCount        pwrMgt->ActivityTickleCount
429#define fDeviceWasActive            pwrMgt->DeviceWasActive
430#define fAdvisoryTickled            pwrMgt->AdvisoryTickled
431#define fWaitReason                 pwrMgt->WaitReason
432#define fSavedMachineState          pwrMgt->SavedMachineState
433#define fLockedFlags                pwrMgt->LockedFlags
434#define fPMDriverCallQueue          pwrMgt->PMDriverCallQueue
435#define fInsertInterestSet          pwrMgt->InsertInterestSet
436#define fRemoveInterestSet          pwrMgt->RemoveInterestSet
437#define fReportClientCnt            pwrMgt->ReportClientCnt
438#define fReportBuf                  pwrMgt->ReportBuf
439#define fPMVars                     pwrMgt->PMVars
440#define fPMActions                  pwrMgt->PMActions
441
442#define StateOrder(state)           (((state) < fNumberOfPowerStates)               \
443                                    ? pwrMgt->PowerStates[(state)].stateOrder       \
444                                    : (state))
445#define StateMax(a,b)               (StateOrder((a)) < StateOrder((b)) ? (b) : (a))
446#define StateMin(a,b)               (StateOrder((a)) < StateOrder((b)) ? (a) : (b))
447
448#define kPowerStateZero             (0)
449
450/*
451When an IOService is waiting for acknowledgement to a power change
452notification from an interested driver or the controlling driver,
453the ack timer is ticking every tenth of a second.
454(100000000 nanoseconds are one tenth of a second).
455*/
456#define ACK_TIMER_PERIOD            100000000
457
458#define WATCHDOG_TIMER_PERIOD       (300)   // 300 secs
459
460// Max wait time in microseconds for kernel priority and capability clients
461// with async message handlers to acknowledge.
462//
463#define kPriorityClientMaxWait      (90 * 1000 * 1000)
464#define kCapabilityClientMaxWait    (240 * 1000 * 1000)
465
466// Attributes describing a power state change.
467// See IOPMPowerChangeFlags data type.
468//
469#define kIOPMParentInitiated        0x0001  // power change initiated by our  parent
470#define kIOPMSelfInitiated          0x0002  // power change initiated by this device
471#define kIOPMNotDone                0x0004  // we couldn't make this change
472#define kIOPMDomainWillChange       0x0008  // change started by PowerDomainWillChangeTo
473#define kIOPMDomainDidChange        0x0010  // change started by PowerDomainDidChangeTo
474#define kIOPMDomainPowerDrop        0x0020  // Domain is lowering power
475#define kIOPMIgnoreChildren         0x0040  // Ignore children and driver power desires
476#define kIOPMSkipAskPowerDown       0x0080  // skip the ask app phase
477#define kIOPMSynchronize            0x0100  // change triggered by power tree re-sync
478#define kIOPMSyncNoChildNotify      0x0200  // sync root domain only, not entire tree
479#define kIOPMSyncTellPowerDown      0x0400  // send the ask/will power off messages
480#define kIOPMSyncCancelPowerDown    0x0800  // sleep cancel for maintenance wake
481#define kIOPMInitialPowerChange     0x1000  // set for initial power change
482#define kIOPMRootChangeUp           0x2000  // Root power domain change up
483#define kIOPMRootChangeDown         0x4000  // Root power domain change down
484#define kIOPMExpireIdleTimer        0x8000  // Accelerate idle timer expiration
485
486#define kIOPMRootBroadcastFlags     (kIOPMSynchronize  | \
487                                     kIOPMRootChangeUp | kIOPMRootChangeDown)
488
489// Activity tickle request flags
490#define kTickleTypePowerDrop        0x01
491#define kTickleTypePowerRise        0x02
492#define kTickleTypeActivity         0x04
493#define kTickleTypeAdvisory         0x08
494
495enum {
496    kDriverCallInformPreChange,
497    kDriverCallInformPostChange,
498    kDriverCallSetPowerState,
499    kRootDomainInformPreChange
500};
501
502struct DriverCallParam {
503    OSObject *  Target;
504    IOReturn    Result;
505};
506
507// values of OutOfBandParameter
508enum {
509    kNotifyApps,
510    kNotifyPriority,
511    kNotifyCapabilityChangeApps,
512    kNotifyCapabilityChangePriority
513};
514
515typedef bool (*IOPMMessageFilter)(
516        void * target, void * object, void * arg1, void * arg2, void * arg3 );
517
518// used for applyToInterested
519struct IOPMInterestContext {
520    OSArray *               responseArray;
521    OSArray *               notifyClients;
522    uint16_t                serialNumber;
523    uint8_t                 isPreChange;
524    uint8_t                 enableTracing;
525    uint32_t                maxTimeRequested;
526    uint32_t                messageType;
527    uint32_t                notifyType;
528    IOService *             us;
529    IOPMPowerStateIndex     stateNumber;
530    IOPMPowerFlags          stateFlags;
531    IOPMPowerChangeFlags    changeFlags;
532    const char *            errorLog;
533    IOPMMessageFilter       messageFilter;
534};
535
536// assertPMDriverCall() options
537enum {
538    kIOPMADC_NoInactiveCheck = 1
539};
540
541//******************************************************************************
542// PM Statistics & Diagnostics
543//******************************************************************************
544
545extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut;
546extern const OSSymbol *gIOPMStatsApplicationResponseCancel;
547extern const OSSymbol *gIOPMStatsApplicationResponseSlow;
548extern const OSSymbol *gIOPMStatsApplicationResponsePrompt;
549extern const OSSymbol *gIOPMStatsDriverPSChangeSlow;
550
551//******************************************************************************
552// IOPMRequest
553//******************************************************************************
554
555typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status);
556
557class IOPMRequest : public IOCommand
558{
559    OSDeclareDefaultStructors( IOPMRequest )
560
561protected:
562    IOService *          fTarget;        // request target
563    IOPMRequest *        fRequestNext;   // the next request in the chain
564    IOPMRequest *        fRequestRoot;   // the root request in the issue tree
565    IOItemCount          fWorkWaitCount; // execution blocked if non-zero
566    IOItemCount          fFreeWaitCount; // completion blocked if non-zero
567    uint32_t             fType;          // request type
568
569#if NOT_READY
570    IOPMCompletionAction fCompletionAction;
571    void *               fCompletionTarget;
572    void *               fCompletionParam;
573    IOReturn             fCompletionStatus;
574#endif
575
576public:
577    uint32_t             fRequestTag;
578    void *               fArg0;
579    void *               fArg1;
580    void *               fArg2;
581
582    inline bool          isWorkBlocked( void ) const
583    {
584        return (fWorkWaitCount != 0);
585    }
586
587    inline bool          isFreeBlocked( void ) const
588    {
589        return (fFreeWaitCount != 0);
590    }
591
592    inline IOPMRequest * getNextRequest( void ) const
593    {
594        return fRequestNext;
595    }
596
597    inline IOPMRequest * getRootRequest( void ) const
598    {
599        if (fRequestRoot) return fRequestRoot;
600#if NOT_READY
601        if (fCompletionAction) return (IOPMRequest *) this;
602#endif
603        return 0;
604    }
605
606    inline uint32_t      getType( void ) const
607    {
608        return fType;
609    }
610
611    inline bool          isReplyType( void ) const
612    {
613        return (fType > kIOPMRequestTypeReplyStart);
614    }
615
616    inline IOService *   getTarget( void ) const
617    {
618        return fTarget;
619    }
620
621#if NOT_READY
622    inline bool          isCompletionInstalled( void )
623    {
624        return (fCompletionAction != 0);
625    }
626
627    inline void          installCompletionAction(
628                            IOPMCompletionAction action,
629                            void *               target,
630                            void *               param )
631    {
632        fCompletionAction = action;
633        fCompletionTarget = target;
634        fCompletionParam  = param;
635    }
636#endif /* NOT_READY */
637
638    static IOPMRequest * create( void );
639    bool   init( IOService * owner, IOOptionBits type );
640    void   reset( void );
641    bool   attachNextRequest( IOPMRequest * next );
642    bool   detachNextRequest( void );
643    bool   attachRootRequest( IOPMRequest * root );
644    bool   detachRootRequest( void );
645};
646
647//******************************************************************************
648// IOPMRequestQueue
649//******************************************************************************
650
651class IOPMRequestQueue : public IOEventSource
652{
653    OSDeclareDefaultStructors( IOPMRequestQueue )
654
655public:
656    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
657
658protected:
659    queue_head_t    fQueue;
660    IOLock *        fLock;
661
662    virtual bool checkForWork( void );
663    virtual void free( void );
664    virtual bool init( IOService * inOwner, Action inAction );
665
666public:
667    static  IOPMRequestQueue * create( IOService * inOwner, Action inAction );
668    void    queuePMRequest( IOPMRequest * request );
669    void    queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
670};
671
672//******************************************************************************
673// IOPMWorkQueue
674//******************************************************************************
675
676#define WORK_QUEUE_STATS    1
677
678class IOPMWorkQueue : public IOEventSource
679{
680    OSDeclareDefaultStructors( IOPMWorkQueue )
681
682public:
683    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
684
685#if WORK_QUEUE_STATS
686    uint64_t            fStatCheckForWork;
687    uint64_t            fStatScanEntries;
688    uint64_t            fStatQueueEmpty;
689    uint64_t            fStatNoWorkDone;
690#endif
691
692protected:
693    queue_head_t        fWorkQueue;
694    Action              fWorkAction;
695    Action              fRetireAction;
696    uint32_t            fQueueLength;
697    uint32_t            fConsumerCount;
698    volatile uint32_t   fProducerCount;
699
700    virtual bool checkForWork( void );
701    virtual bool init( IOService * inOwner, Action work, Action retire );
702    bool    checkRequestQueue( queue_head_t * queue, bool * empty );
703
704public:
705    static  IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
706    bool    queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
707    void    signalWorkAvailable( void );
708    void    incrementProducerCount( void );
709};
710
711//******************************************************************************
712// IOPMCompletionQueue
713//******************************************************************************
714
715class IOPMCompletionQueue : public IOEventSource
716{
717    OSDeclareDefaultStructors( IOPMCompletionQueue )
718
719public:
720    typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
721
722protected:
723    queue_head_t    fQueue;
724
725    virtual bool checkForWork( void );
726    virtual bool init( IOService * inOwner, Action inAction );
727
728public:
729    static  IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
730    bool    queuePMRequest( IOPMRequest * request );
731};
732
733#endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */
734