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