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