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