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