xref: /xnu-10002.41.9/iokit/Kernel/IOServicePMPrivate.h (revision 699cd48037512bf4380799317ca44ca453c82f57)
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 // Thread to be run alongside DriverCallEntry to provide logging.
334 	thread_call_t           DriverCallTimer;
335 
336 // Protected by ActivityLock - BEGIN
337 	IOPMPowerStateIndex     ActivityTicklePowerState;
338 	IOPMPowerStateIndex     AdvisoryTicklePowerState;
339 	uint32_t                ActivityTickleCount;
340 	uint32_t                DeviceWasActive     : 1;
341 	uint32_t                AdvisoryTickled     : 1;
342 // Protected by ActivityLock - END
343 
344 	uint32_t                WaitReason;
345 	uint32_t                SavedMachineState;
346 
347 // Protected by PMLock - BEGIN
348 	struct {
349 		uint32_t            PMStop              : 1;
350 		uint32_t            PMDriverCallWait    : 1;
351 	} LockedFlags;
352 
353 	queue_head_t            PMDriverCallQueue;
354 	OSSet *                 InsertInterestSet;
355 	OSSet *                 RemoveInterestSet;
356 
357 // IOReporter Data
358 	uint32_t                ReportClientCnt;
359 	void *                  ReportBuf;
360 // Protected by PMLock - END
361 
362 #if PM_VARS_SUPPORT
363 	IOPMprot *              PMVars;
364 #endif
365 
366 	IOPMActions             PMActions;
367 
368 // Serialize IOServicePM state for debug output.
369 	IOReturn gatedSerialize( OSSerialize * s ) const;
370 	virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE;
371 
372 // PM log and trace
373 	void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const;
374 	void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const;
375 };
376 
377 #define fOwner                      pwrMgt->Owner
378 #define fInterestedDrivers          pwrMgt->InterestedDrivers
379 #define fDriverTimer                pwrMgt->DriverTimer
380 #define fMachineState               pwrMgt->MachineState
381 #define fAckTimer                   pwrMgt->AckTimer
382 #define fSettleTimer                pwrMgt->SettleTimer
383 #define fIdleTimer                  pwrMgt->IdleTimer
384 #define fWatchdogTimer              pwrMgt->WatchdogTimer
385 #define fWatchdogDeadline           pwrMgt->WatchdogDeadline
386 #define fWatchdogLock               pwrMgt->WatchdogLock
387 #define fBlockedArray               pwrMgt->BlockedArray
388 #define fPendingResponseDeadline    pwrMgt->PendingResponseDeadline
389 #define fSettleTimeUS               pwrMgt->SettleTimeUS
390 #define fIdleTimerGeneration        pwrMgt->IdleTimerGeneration
391 #define fHeadNoteChangeFlags        pwrMgt->HeadNoteChangeFlags
392 #define fHeadNotePowerState         pwrMgt->HeadNotePowerState
393 #define fHeadNotePowerArrayEntry    pwrMgt->HeadNotePowerArrayEntry
394 #define fHeadNoteDomainFlags        pwrMgt->HeadNoteDomainFlags
395 #define fHeadNoteDomainTargetFlags  pwrMgt->HeadNoteDomainTargetFlags
396 #define fHeadNoteParentConnection   pwrMgt->HeadNoteParentConnection
397 #define fHeadNoteParentFlags        pwrMgt->HeadNoteParentFlags
398 #define fHeadNotePendingAcks        pwrMgt->HeadNotePendingAcks
399 #define fPMLock                     pwrMgt->PMLock
400 #define fInitialPowerChange         pwrMgt->InitialPowerChange
401 #define fInitialSetPowerState       pwrMgt->InitialSetPowerState
402 #define fDeviceOverrideEnabled      pwrMgt->DeviceOverrideEnabled
403 #define fDoNotPowerDown             pwrMgt->DoNotPowerDown
404 #define fParentsKnowState           pwrMgt->ParentsKnowState
405 #define fStrictTreeOrder            pwrMgt->StrictTreeOrder
406 #define fIdleTimerStopped           pwrMgt->IdleTimerStopped
407 #define fAdjustPowerScheduled       pwrMgt->AdjustPowerScheduled
408 #define fIsPreChange                pwrMgt->IsPreChange
409 #define fDriverCallBusy             pwrMgt->DriverCallBusy
410 #define fPCDFunctionOverride        pwrMgt->PCDFunctionOverride
411 #define fIdleTimerIgnored           pwrMgt->IdleTimerIgnored
412 #define fHasAdvisoryDesire          pwrMgt->HasAdvisoryDesire
413 #define fAdvisoryTickleUsed         pwrMgt->AdvisoryTickleUsed
414 #define fResetPowerStateOnWake      pwrMgt->ResetPowerStateOnWake
415 #define fDeviceActiveTimestamp      pwrMgt->DeviceActiveTimestamp
416 #define fMaxPowerStateEntryTime     pwrMgt->MaxPowerStateEntryTime
417 #define fMaxPowerStateExitTime      pwrMgt->MaxPowerStateExitTime
418 #define fActivityLock               pwrMgt->ActivityLock
419 #define fIdleTimerPeriod            pwrMgt->IdleTimerPeriod
420 #define fIdleTimerMinPowerState     pwrMgt->IdleTimerMinPowerState
421 #define fNextIdleTimerPeriod        pwrMgt->NextIdleTimerPeriod
422 #define fIdleTimerStartTime         pwrMgt->IdleTimerStartTime
423 #define fDeviceDesire               pwrMgt->DeviceDesire
424 #define fDesiredPowerState          pwrMgt->DesiredPowerState
425 #define fPreviousRequestPowerFlags  pwrMgt->PreviousRequestPowerFlags
426 #define fName                       pwrMgt->Name
427 #define fNumberOfPowerStates        pwrMgt->NumberOfPowerStates
428 #define fHighestPowerState          pwrMgt->HighestPowerState
429 #define fPowerStates                pwrMgt->PowerStates
430 #define fControllingDriver          pwrMgt->ControllingDriver
431 #define fCurrentPowerState          pwrMgt->CurrentPowerState
432 #define fParentsCurrentPowerFlags   pwrMgt->ParentsCurrentPowerFlags
433 #define fMaxPowerState              pwrMgt->MaxPowerState
434 #define fMergedOutputPowerFlags     pwrMgt->MergedOutputPowerFlags
435 #define fResponseArray              pwrMgt->ResponseArray
436 #define fNotifyClientArray          pwrMgt->NotifyClientArray
437 #define fSerialNumber               pwrMgt->SerialNumber
438 #define fOutOfBandParameter         pwrMgt->OutOfBandParameter
439 #define fDriverCallStartTime        pwrMgt->DriverCallStartTime
440 #define fCurrentCapabilityFlags     pwrMgt->CurrentCapabilityFlags
441 #define fCurrentPowerConsumption    pwrMgt->CurrentPowerConsumption
442 #define fTempClampPowerState        pwrMgt->TempClampPowerState
443 #define fNotifyChildArray           pwrMgt->NotifyChildArray
444 #define fPowerClients               pwrMgt->PowerClients
445 #define fDriverCallEntry            pwrMgt->DriverCallEntry
446 #define fDriverCallParamPtr         pwrMgt->DriverCallParamPtr
447 #define fDriverCallParamCount       pwrMgt->DriverCallParamCount
448 #define fDriverCallParamSlots       pwrMgt->DriverCallParamSlots
449 #define fDriverCallReason           pwrMgt->DriverCallReason
450 #define fOutOfBandMessage           pwrMgt->OutOfBandMessage
451 #define fTempClampCount             pwrMgt->TempClampCount
452 #define fOverrideMaxPowerState      pwrMgt->OverrideMaxPowerState
453 #define fDeviceUsablePowerState     pwrMgt->DeviceUsablePowerState
454 #define fDriverCallTimer            pwrMgt->DriverCallTimer
455 #define fActivityTicklePowerState   pwrMgt->ActivityTicklePowerState
456 #define fAdvisoryTicklePowerState   pwrMgt->AdvisoryTicklePowerState
457 #define fActivityTickleCount        pwrMgt->ActivityTickleCount
458 #define fDeviceWasActive            pwrMgt->DeviceWasActive
459 #define fAdvisoryTickled            pwrMgt->AdvisoryTickled
460 #define fWaitReason                 pwrMgt->WaitReason
461 #define fSavedMachineState          pwrMgt->SavedMachineState
462 #define fLockedFlags                pwrMgt->LockedFlags
463 #define fPMDriverCallQueue          pwrMgt->PMDriverCallQueue
464 #define fInsertInterestSet          pwrMgt->InsertInterestSet
465 #define fRemoveInterestSet          pwrMgt->RemoveInterestSet
466 #define fReportClientCnt            pwrMgt->ReportClientCnt
467 #define fReportBuf                  pwrMgt->ReportBuf
468 #define fPMVars                     pwrMgt->PMVars
469 #define fPMActions                  pwrMgt->PMActions
470 
471 #define StateOrder(state)           (((state) < fNumberOfPowerStates)               \
472 	                            ? pwrMgt->PowerStates[(state)].stateOrder       \
473 	                            : (state))
474 #define StateMax(a, b)               (StateOrder((a)) < StateOrder((b)) ? (b) : (a))
475 #define StateMin(a, b)               (StateOrder((a)) < StateOrder((b)) ? (a) : (b))
476 
477 #define kPowerStateZero             (0)
478 
479 /*
480  *  When an IOService is waiting for acknowledgement to a power change
481  *  notification from an interested driver or the controlling driver,
482  *  the ack timer is ticking every tenth of a second.
483  *  (100000000 nanoseconds are one tenth of a second).
484  */
485 #define ACK_TIMER_PERIOD            100000000
486 
487 #if defined(__i386__) || defined(__x86_64__)
488 #define WATCHDOG_SLEEP_TIMEOUT      (180)   // 180 secs
489 #define WATCHDOG_WAKE_TIMEOUT       (180)   // 180  secs
490 #else
491 #define WATCHDOG_SLEEP_TIMEOUT      (35)   // 35 secs (kMaxTimeRequested + 5s)
492 #define WATCHDOG_WAKE_TIMEOUT       (35)   // 35 secs (kMaxTimeRequested + 5s)
493 #endif
494 
495 // Max wait time in microseconds for kernel priority and capability clients
496 // with async message handlers to acknowledge.
497 //
498 #define kPriorityClientMaxWait      (90 * 1000 * 1000)
499 #define kCapabilityClientMaxWait    (240 * 1000 * 1000)
500 
501 // Attributes describing a power state change.
502 // See IOPMPowerChangeFlags data type.
503 //
504 #define kIOPMParentInitiated        0x0001  // power change initiated by our  parent
505 #define kIOPMSelfInitiated          0x0002  // power change initiated by this device
506 #define kIOPMNotDone                0x0004  // we couldn't make this change
507 #define kIOPMDomainWillChange       0x0008  // change started by PowerDomainWillChangeTo
508 #define kIOPMDomainDidChange        0x0010  // change started by PowerDomainDidChangeTo
509 #define kIOPMDomainPowerDrop        0x0020  // Domain is lowering power
510 #define kIOPMIgnoreChildren         0x0040  // Ignore children and driver power desires
511 #define kIOPMSkipAskPowerDown       0x0080  // skip the ask app phase
512 #define kIOPMSynchronize            0x0100  // change triggered by power tree re-sync
513 #define kIOPMSyncNoChildNotify      0x0200  // sync root domain only, not entire tree
514 #define kIOPMSyncTellPowerDown      0x0400  // send the ask/will power off messages
515 #define kIOPMSyncCancelPowerDown    0x0800  // sleep cancel for maintenance wake
516 #define kIOPMInitialPowerChange     0x1000  // set for initial power change
517 #define kIOPMRootChangeUp           0x2000  // Root power domain change up
518 #define kIOPMRootChangeDown         0x4000  // Root power domain change down
519 #define kIOPMExpireIdleTimer        0x8000  // Accelerate idle timer expiration
520 
521 #define kIOPMRootBroadcastFlags     (kIOPMSynchronize  | \
522 	                             kIOPMRootChangeUp | kIOPMRootChangeDown)
523 
524 // Activity tickle request flags
525 #define kTickleTypePowerDrop        0x01
526 #define kTickleTypePowerRise        0x02
527 #define kTickleTypeActivity         0x04
528 #define kTickleTypeAdvisory         0x08
529 
530 enum {
531 	kDriverCallInformPreChange,
532 	kDriverCallInformPostChange,
533 	kDriverCallSetPowerState,
534 	kRootDomainInformPreChange
535 };
536 
537 struct DriverCallParam {
538 	OSObject *  Target;
539 	IOReturn    Result;
540 };
541 
542 // values of OutOfBandParameter
543 enum {
544 	kNotifyApps,
545 	kNotifyPriority,
546 	kNotifyCapabilityChangeApps,
547 	kNotifyCapabilityChangePriority
548 };
549 
550 typedef bool (*IOPMMessageFilter)(
551 	void * target, void * object, void * arg1, void * arg2, void * arg3 );
552 
553 // used for applyToInterested
554 struct IOPMInterestContext {
555 	OSArray *               responseArray;
556 	OSArray *               notifyClients;
557 	uint16_t                serialNumber;
558 	uint8_t                 isPreChange;
559 	uint8_t                 enableTracing;
560 	uint32_t                maxTimeRequested;
561 	uint32_t                messageType;
562 	uint32_t                notifyType;
563 	uint32_t                skippedInDark;
564 	uint32_t                notSkippedInDark;
565 	IOService *             us;
566 	IOPMPowerStateIndex     stateNumber;
567 	IOPMPowerFlags          stateFlags;
568 	IOPMPowerChangeFlags    changeFlags;
569 	IOPMMessageFilter       messageFilter;
570 };
571 
572 // assertPMDriverCall() options
573 enum {
574 	kIOPMDriverCallNoInactiveCheck = 1
575 };
576 
577 // assertPMDriverCall() method
578 enum {
579 	kIOPMDriverCallMethodUnknown       = 0,
580 	kIOPMDriverCallMethodSetPowerState = 1,
581 	kIOPMDriverCallMethodWillChange    = 2,
582 	kIOPMDriverCallMethodDidChange     = 3,
583 	kIOPMDriverCallMethodChangeDone    = 4,
584 	kIOPMDriverCallMethodSetAggressive = 5
585 };
586 
587 //******************************************************************************
588 // PM Statistics & Diagnostics
589 //******************************************************************************
590 
591 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut;
592 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel;
593 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow;
594 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt;
595 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow;
596 
597 //******************************************************************************
598 // IOPMRequest
599 //******************************************************************************
600 
601 class IOPMRequest : public IOCommand
602 {
603 	OSDeclareDefaultStructors( IOPMRequest );
604 
605 protected:
606 	IOService *          fTarget;           // request target
607 	IOPMRequest *        fRequestNext;      // the next request in the chain
608 	IOPMRequest *        fRequestRoot;      // the root request in the call tree
609 	uint32_t             fWorkWaitCount;    // execution blocked if non-zero
610 	uint32_t             fFreeWaitCount;    // completion blocked if non-zero
611 	uint64_t             fTimestamp;        // MCTU
612 	uint32_t             fRequestType;      // request type
613 	bool                 fIsQuiesceBlocker;
614 
615 	IOPMCompletionAction fCompletionAction;
616 	void *               fCompletionTarget;
617 	void *               fCompletionParam;
618 
619 public:
620 	uint32_t             fTag;
621 	void *               fArg0;
622 	void *               fArg1;
623 	void *               fArg2;
624 
625 	inline bool
isWorkBlocked(void)626 	isWorkBlocked( void ) const
627 	{
628 		return fWorkWaitCount != 0;
629 	}
630 
631 	inline bool
isFreeBlocked(void)632 	isFreeBlocked( void ) const
633 	{
634 		return fFreeWaitCount != 0;
635 	}
636 
637 	inline IOPMRequest *
getNextRequest(void)638 	getNextRequest( void ) const
639 	{
640 		return fRequestNext;
641 	}
642 
643 	inline IOPMRequest *
getRootRequest(void)644 	getRootRequest( void ) const
645 	{
646 		if (fRequestRoot) {
647 			return fRequestRoot;
648 		}
649 #if NOT_READY
650 		if (fCompletionAction) {
651 			return (IOPMRequest *) this;
652 		}
653 #endif
654 		return NULL;
655 	}
656 
657 	inline uint32_t
getType(void)658 	getType( void ) const
659 	{
660 		return fRequestType;
661 	}
662 
663 	inline uint32_t
getTag(void)664 	getTag( void ) const
665 	{
666 		return fTag;
667 	}
668 
669 	inline bool
isReplyType(void)670 	isReplyType( void ) const
671 	{
672 		return fRequestType > kIOPMRequestTypeReplyStart;
673 	}
674 
675 	inline IOService *
getTarget(void)676 	getTarget( void ) const
677 	{
678 		return fTarget;
679 	}
680 
681 	inline bool
isQuiesceBlocker(void)682 	isQuiesceBlocker( void ) const
683 	{
684 		return fIsQuiesceBlocker;
685 	}
686 
687 	inline bool
isQuiesceType(void)688 	isQuiesceType( void ) const
689 	{
690 		return (kIOPMRequestTypeQuiescePowerTree == fRequestType) &&
691 		       (fCompletionAction != NULL) && (fCompletionTarget != NULL);
692 	}
693 
694 	inline void
installCompletionAction(void * target,IOPMCompletionAction action,void * param)695 	installCompletionAction(
696 		void *               target,
697 		IOPMCompletionAction action,
698 		void *               param )
699 	{
700 		fCompletionTarget = target;
701 		fCompletionAction = action;
702 		fCompletionParam  = param;
703 	}
704 
705 	inline void
setTimestamp(uint64_t time)706 	setTimestamp( uint64_t time )
707 	{
708 		fTimestamp = time;
709 	}
710 
711 	inline uint64_t
getTimestamp(void)712 	getTimestamp( void ) const
713 	{
714 		return fTimestamp;
715 	}
716 
717 	static IOPMRequest * create( void );
718 	bool   init( IOService * owner, IOOptionBits type );
719 	void   reset( void );
720 	bool   attachNextRequest( IOPMRequest * next );
721 	bool   detachNextRequest( void );
722 	bool   attachRootRequest( IOPMRequest * root );
723 	bool   detachRootRequest( void );
724 };
725 
726 //******************************************************************************
727 // IOPMRequestQueue
728 //******************************************************************************
729 
730 class IOPMRequestQueue : public IOEventSource
731 {
732 	OSDeclareDefaultStructors( IOPMRequestQueue );
733 
734 public:
735 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
736 
737 protected:
738 	queue_head_t    fQueue;
739 	IOLock *        fLock;
740 
741 	enum { kMaxDequeueCount = 256 };
742 
743 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
744 	virtual void free( void ) APPLE_KEXT_OVERRIDE;
745 	virtual bool init( IOService * inOwner, Action inAction );
746 
747 public:
748 	static  IOPMRequestQueue * create( IOService * inOwner, Action inAction );
749 	void    queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request );
750 	void    queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
751 };
752 
753 //******************************************************************************
754 // IOPMWorkQueue
755 //******************************************************************************
756 
757 #define WORK_QUEUE_STATS    1
758 
759 class IOPMWorkQueue : public IOEventSource
760 {
761 	OSDeclareDefaultStructors( IOPMWorkQueue );
762 
763 public:
764 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
765 
766 #if WORK_QUEUE_STATS
767 	uint64_t            fStatCheckForWork;
768 	uint64_t            fStatScanEntries;
769 	uint64_t            fStatQueueEmpty;
770 	uint64_t            fStatNoWorkDone;
771 #endif
772 
773 protected:
774 	queue_head_t        fWorkQueue;
775 	Action              fInvokeAction;
776 	Action              fRetireAction;
777 	uint32_t            fQueueLength;
778 	uint32_t            fConsumerCount;
779 	volatile uint32_t   fProducerCount;
780 	IOPMRequest *       fQuiesceRequest;
781 	AbsoluteTime        fQuiesceStartTime;
782 	AbsoluteTime        fQuiesceFinishTime;
783 
784 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
785 	virtual bool init( IOService * inOwner, Action invoke, Action retire );
786 	bool    checkRequestQueue( queue_head_t * queue, bool * empty );
787 
788 public:
789 	static  IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire );
790 	bool    queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt );
791 	void    signalWorkAvailable( void );
792 	void    incrementProducerCount( void );
793 	void    attachQuiesceRequest( IOPMRequest * quiesceRequest );
794 	void    finishQuiesceRequest( IOPMRequest * quiesceRequest );
795 };
796 
797 //******************************************************************************
798 // IOPMCompletionQueue
799 //******************************************************************************
800 
801 class IOPMCompletionQueue : public IOEventSource
802 {
803 	OSDeclareDefaultStructors( IOPMCompletionQueue );
804 
805 public:
806 	typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
807 
808 protected:
809 	queue_head_t    fQueue;
810 
811 	virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE;
812 	virtual bool init( IOService * inOwner, Action inAction );
813 
814 public:
815 	static  IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
816 	bool    queuePMRequest( IOPMRequest * request );
817 };
818 
819 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */
820