]> git.saurik.com Git - apple/xnu.git/blame - iokit/Kernel/IOServicePMPrivate.h
xnu-1504.15.3.tar.gz
[apple/xnu.git] / iokit / Kernel / IOServicePMPrivate.h
CommitLineData
2d21ac55
A
1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30#define _IOKIT_IOSERVICEPMPRIVATE_H
31
2d21ac55
A
32/*! @class IOServicePM
33 @abstract Power management class.
34*/
35class IOServicePM : public OSObject
36{
37 friend class IOService;
38
39 OSDeclareDefaultStructors( IOServicePM )
40
41private:
b0d623f7 42 // List of interested drivers.
2d21ac55
A
43 IOPMinformeeList * InterestedDrivers;
44
b0d623f7 45 // How long to wait for controlling driver to acknowledge.
2d21ac55
A
46 IOReturn DriverTimer;
47
b0d623f7
A
48 // Current power management machine state.
49 uint32_t MachineState;
2d21ac55 50
b0d623f7 51 thread_call_t AckTimer;
2d21ac55
A
52 thread_call_t SettleTimer;
53
b0d623f7 54 // Settle time after changing power state.
2d21ac55
A
55 unsigned long SettleTimeUS;
56
b0d623f7 57 // The flags describing current change note.
2d21ac55
A
58 unsigned long HeadNoteFlags;
59
b0d623f7
A
60 // The new power state number being changed to.
61 unsigned long HeadNotePowerState;
62
63 // Points to the entry in the power state array.
64 IOPMPowerState * HeadNotePowerArrayEntry;
65
66 // Power flags supplied by all parents (domain).
67 unsigned long HeadNoteDomainFlags;
68
7e4a7d39
A
69 // Power flags supplied by domain accounting for parent changes.
70 IOPMPowerFlags HeadNoteDomainTargetFlags;
71
b0d623f7
A
72 // Connection attached to the changing parent.
73 IOPowerConnection * HeadNoteParentConnection;
2d21ac55 74
b0d623f7
A
75 // Power flags supplied by the changing parent.
76 unsigned long HeadNoteParentFlags;
77
78 // Number of acks still outstanding.
2d21ac55
A
79 unsigned long HeadNotePendingAcks;
80
b0d623f7 81 // PM state lock.
2d21ac55
A
82 IOLock * PMLock;
83
b0d623f7 84 // Initialized to true, then set to false after the initial power change.
2d21ac55
A
85 bool InitialChange;
86
b0d623f7 87 // Ignore children and driver desires if true.
2d21ac55
A
88 bool DeviceOverrides;
89
b0d623f7 90 // True if device was active since last idle timer expiration.
2d21ac55
A
91 bool DeviceActive;
92
b0d623f7 93 // Keeps track of any negative responses from notified apps and clients.
2d21ac55
A
94 bool DoNotPowerDown;
95
b0d623f7 96 // True if all our parents know the state of their power domain.
2d21ac55
A
97 bool ParentsKnowState;
98
b0d623f7
A
99 bool StrictTreeOrder;
100 bool IdleTimerStopped;
101 bool AdjustPowerScheduled;
102
103 // Time of last device activity.
2d21ac55
A
104 AbsoluteTime DeviceActiveTimestamp;
105
b0d623f7 106 // Used to protect activity flag.
2d21ac55
A
107 IOLock * ActivityLock;
108
b0d623f7 109 // Idle timer event source.
2d21ac55
A
110 IOTimerEventSource * IdleTimerEventSource;
111
b0d623f7 112 // Idle timer's period in seconds.
2d21ac55 113 unsigned long IdleTimerPeriod;
cf7d32b8 114 unsigned long IdleTimerMinPowerState;
b0d623f7 115 AbsoluteTime IdleTimerStartTime;
2d21ac55 116
b0d623f7 117 // Power state desired by a subclassed device object.
2d21ac55
A
118 unsigned long DeviceDesire;
119
b0d623f7 120 // This is the power state we desire currently.
2d21ac55
A
121 unsigned long DesiredPowerState;
122
b0d623f7 123 // This is what our parent thinks our need is.
2d21ac55
A
124 unsigned long PreviousRequest;
125
b0d623f7 126 // Cache result from getName(), used in logging.
2d21ac55
A
127 const char * Name;
128
b0d623f7 129 // Number of power states in the power array.
2d21ac55
A
130 unsigned long NumberOfPowerStates;
131
b0d623f7 132 // Power state array.
2d21ac55
A
133 IOPMPowerState * PowerStates;
134
b0d623f7 135 // The controlling driver.
2d21ac55
A
136 IOService * ControllingDriver;
137
b0d623f7 138 // Our current power state.
2d21ac55
A
139 unsigned long CurrentPowerState;
140
b0d623f7 141 // Logical OR of power flags for each power domain parent.
2d21ac55
A
142 IOPMPowerFlags ParentsCurrentPowerFlags;
143
b0d623f7 144 // The highest power state we can achieve in current power domain.
2d21ac55
A
145 unsigned long MaxCapability;
146
b0d623f7 147 // Logical OR of all output power character flags in the array.
2d21ac55
A
148 IOPMPowerFlags OutputPowerCharacterFlags;
149
b0d623f7 150 // OSArray which manages responses from notified apps and clients.
2d21ac55 151 OSArray * ResponseArray;
b0d623f7
A
152 OSArray * NotifyClientArray;
153
154 // Used to uniquely identify power management notification to apps and clients.
155 UInt16 SerialNumber;
2d21ac55 156
b0d623f7
A
157 // Used to communicate desired function to tellClientsWithResponse().
158 // This is used because it avoids changing the signatures of the affected virtual methods.
2d21ac55
A
159 int OutOfBandParameter;
160
161 AbsoluteTime DriverCallStartTime;
162 IOPMPowerFlags CurrentCapabilityFlags;
b0d623f7 163 long ActivityTicklePowerState;
2d21ac55
A
164 unsigned long CurrentPowerConsumption;
165 unsigned long TempClampPowerState;
2d21ac55 166 IOPMWorkQueue * PMWorkQueue;
2d21ac55
A
167 OSSet * InsertInterestSet;
168 OSSet * RemoveInterestSet;
169 OSArray * NotifyChildArray;
b0d623f7 170 OSDictionary * PowerClients;
2d21ac55
A
171 thread_call_t DriverCallEntry;
172 void * DriverCallParamPtr;
173 IOItemCount DriverCallParamCount;
174 IOItemCount DriverCallParamSlots;
b0d623f7
A
175 uint32_t DriverCallReason;
176 uint32_t TempClampCount;
177 uint32_t OverrideMaxPowerState;
178 uint32_t ActivityTickleCount;
179 uint32_t WaitReason;
180 uint32_t NextMachineState;
181 uint32_t RootDomainState;
182 uint32_t ThreadAssertionCount;
183
184 // Protected by PMLock
185 struct {
186 uint32_t DriverCallBusy : 1;
187 uint32_t PMStop : 1;
188 } LockedFlags;
189
190 thread_t ThreadAssertionThread;
2d21ac55
A
191
192#if PM_VARS_SUPPORT
193 IOPMprot * PMVars;
194#endif
195
b0d623f7
A
196 // Serialize IOServicePM state for debug output.
197 IOReturn gatedSerialize( OSSerialize * s );
2d21ac55
A
198 virtual bool serialize( OSSerialize * s ) const;
199};
200
2d21ac55
A
201#define fInterestedDrivers pwrMgt->InterestedDrivers
202#define fDriverTimer pwrMgt->DriverTimer
203#define fAckTimer pwrMgt->AckTimer
204#define fSettleTimer pwrMgt->SettleTimer
205#define fMachineState pwrMgt->MachineState
206#define fSettleTimeUS pwrMgt->SettleTimeUS
207#define fHeadNoteFlags pwrMgt->HeadNoteFlags
b0d623f7
A
208#define fHeadNotePowerState pwrMgt->HeadNotePowerState
209#define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry
210#define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags
7e4a7d39 211#define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags
b0d623f7
A
212#define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection
213#define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags
2d21ac55
A
214#define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
215#define fPMLock pwrMgt->PMLock
216#define fInitialChange pwrMgt->InitialChange
2d21ac55 217#define fDeviceOverrides pwrMgt->DeviceOverrides
2d21ac55
A
218#define fActivityLock pwrMgt->ActivityLock
219#define fIdleTimerEventSource pwrMgt->IdleTimerEventSource
220#define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
cf7d32b8 221#define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState
2d21ac55 222#define fDeviceActive pwrMgt->DeviceActive
b0d623f7 223#define fIdleTimerStartTime pwrMgt->IdleTimerStartTime
2d21ac55 224#define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
b0d623f7 225#define fActivityTickleCount pwrMgt->ActivityTickleCount
2d21ac55 226#define fDeviceDesire pwrMgt->DeviceDesire
2d21ac55
A
227#define fDesiredPowerState pwrMgt->DesiredPowerState
228#define fPreviousRequest pwrMgt->PreviousRequest
229#define fName pwrMgt->Name
2d21ac55
A
230#define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
231#define fPowerStates pwrMgt->PowerStates
232#define fControllingDriver pwrMgt->ControllingDriver
233#define fAggressivenessValue pwrMgt->AggressivenessValue
234#define fAggressivenessValid pwrMgt->AggressivenessValid
235#define fCurrentPowerState pwrMgt->CurrentPowerState
236#define fParentsKnowState pwrMgt->ParentsKnowState
237#define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
238#define fMaxCapability pwrMgt->MaxCapability
239#define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags
240#define fSerialNumber pwrMgt->SerialNumber
241#define fResponseArray pwrMgt->ResponseArray
b0d623f7 242#define fNotifyClientArray pwrMgt->NotifyClientArray
2d21ac55
A
243#define fDoNotPowerDown pwrMgt->DoNotPowerDown
244#define fOutOfBandParameter pwrMgt->OutOfBandParameter
245#define fDriverCallStartTime pwrMgt->DriverCallStartTime
246#define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
247#define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
248#define fTempClampPowerState pwrMgt->TempClampPowerState
249#define fTempClampCount pwrMgt->TempClampCount
b0d623f7 250#define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState
2d21ac55 251#define fPMWorkQueue pwrMgt->PMWorkQueue
2d21ac55
A
252#define fWaitReason pwrMgt->WaitReason
253#define fNextMachineState pwrMgt->NextMachineState
254#define fDriverCallReason pwrMgt->DriverCallReason
255#define fDriverCallEntry pwrMgt->DriverCallEntry
256#define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
257#define fDriverCallParamCount pwrMgt->DriverCallParamCount
258#define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
2d21ac55
A
259#define fActivityTickled pwrMgt->ActivityTickled
260#define fInsertInterestSet pwrMgt->InsertInterestSet
261#define fRemoveInterestSet pwrMgt->RemoveInterestSet
262#define fStrictTreeOrder pwrMgt->StrictTreeOrder
263#define fNotifyChildArray pwrMgt->NotifyChildArray
7e4a7d39 264#define fIdleTimerStopped pwrMgt->IdleTimerStopped
b0d623f7 265#define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled
2d21ac55
A
266#define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
267#define fPMVars pwrMgt->PMVars
b0d623f7
A
268#define fPowerClients pwrMgt->PowerClients
269#define fRootDomainState pwrMgt->RootDomainState
270#define fThreadAssertionCount pwrMgt->ThreadAssertionCount
271#define fThreadAssertionThread pwrMgt->ThreadAssertionThread
272#define fLockedFlags pwrMgt->LockedFlags
2d21ac55 273
b0d623f7
A
274/*
275When an IOService is waiting for acknowledgement to a power change
276notification from an interested driver or the controlling driver,
277the ack timer is ticking every tenth of a second.
2d21ac55
A
278(100000000 nanoseconds are one tenth of a second).
279*/
b0d623f7
A
280#define ACK_TIMER_PERIOD 100000000
281
282#define kIOPMParentInitiated 0x01 // this power change initiated by our parent
283#define kIOPMWeInitiated 0x02 // this power change initiated by this device
284#define kIOPMNotDone 0x04 // we couldn't make this change
285#define kIOPMDomainWillChange 0x08 // change started by PowerDomainWillChangeTo
286#define kIOPMDomainDidChange 0x10 // change started by PowerDomainDidChangeTo
287#define kIOPMDomainPowerDrop 0x20 // Domain is lowering power
288#define kIOPMSynchronize 0x40 // change triggered by power tree re-sync
2d21ac55
A
289
290enum {
291 kDriverCallInformPreChange,
292 kDriverCallInformPostChange,
293 kDriverCallSetPowerState
294};
295
296struct DriverCallParam {
297 OSObject * Target;
298 IOReturn Result;
299};
300
301// values of outofbandparameter
302enum {
303 kNotifyApps,
304 kNotifyPriority
305};
306
b0d623f7
A
307typedef bool (*IOPMMessageFilter)(OSObject * object, void * context);
308
2d21ac55 309// used for applyToInterested
b0d623f7
A
310struct IOPMInterestContext {
311 OSArray * responseFlags;
312 OSArray * notifyClients;
313 UInt16 serialNumber;
314 UInt16 counter;
315 UInt32 maxTimeRequested;
316 int msgType;
317 IOService * us;
318 unsigned long stateNumber;
319 IOPMPowerFlags stateFlags;
320 const char * errorLog;
321 IOPMMessageFilter filterFunc;
2d21ac55
A
322};
323
b0d623f7
A
324//*********************************************************************************
325// PM Statistics & Diagnostics
326//*********************************************************************************
327
328extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut;
329extern const OSSymbol *gIOPMStatsApplicationResponseCancel;
330extern const OSSymbol *gIOPMStatsApplicationResponseSlow;
331
2d21ac55
A
332//*********************************************************************************
333// PM command types
334//*********************************************************************************
335
336enum {
337 /* Command Types */
b0d623f7
A
338 kIOPMRequestTypeInvalid = 0x00,
339 kIOPMRequestTypePMStop = 0x01,
340 kIOPMRequestTypeAddPowerChild1 = 0x02,
341 kIOPMRequestTypeAddPowerChild2 = 0x03,
342 kIOPMRequestTypeAddPowerChild3 = 0x04,
343 kIOPMRequestTypeRegisterPowerDriver = 0x05,
344 kIOPMRequestTypeAdjustPowerState = 0x06,
345 kIOPMRequestTypePowerDomainWillChange = 0x07,
346 kIOPMRequestTypePowerDomainDidChange = 0x08,
347 kIOPMRequestTypePowerOverrideOnPriv = 0x09,
348 kIOPMRequestTypePowerOverrideOffPriv = 0x0A,
349 kIOPMRequestTypeActivityTickle = 0x0B,
350 kIOPMRequestTypeRequestPowerState = 0x0C,
351 kIOPMRequestTypeSynchronizePowerTree = 0x0D,
352 kIOPMRequestTypeRequestPowerStateOverride = 0x0E,
353 kIOPMRequestTypeSetIdleTimerPeriod = 0x0F,
354
2d21ac55 355 /* Reply Types */
b0d623f7
A
356 kIOPMRequestTypeReplyStart = 0x80,
357 kIOPMRequestTypeAckPowerChange = 0x81,
358 kIOPMRequestTypeAckSetPowerState = 0x82,
359 kIOPMRequestTypeAllowPowerChange = 0x83,
360 kIOPMRequestTypeCancelPowerChange = 0x84,
361 kIOPMRequestTypeInterestChanged = 0x85,
362 kIOPMRequestTypeIdleCancel = 0x86
2d21ac55
A
363};
364
365//*********************************************************************************
b0d623f7 366// IOServicePM internal helper classes
2d21ac55
A
367//*********************************************************************************
368
b0d623f7
A
369typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status);
370
2d21ac55
A
371class IOPMRequest : public IOCommand
372{
373 OSDeclareDefaultStructors( IOPMRequest )
374
375protected:
b0d623f7
A
376 IOService * fTarget; // request target
377 IOPMRequest * fRequestNext; // the next request in the chain
7e4a7d39 378 IOPMRequest * fRequestRoot; // the root request in the issue tree
b0d623f7 379 IOItemCount fWorkWaitCount; // execution blocked if non-zero
7e4a7d39 380 IOItemCount fFreeWaitCount; // completion blocked if non-zero
b0d623f7
A
381 uint32_t fType; // request type
382
383 IOPMCompletionAction fCompletionAction;
384 void * fCompletionTarget;
385 void * fCompletionParam;
386 IOReturn fCompletionStatus;
2d21ac55
A
387
388public:
b0d623f7
A
389 void * fArg0;
390 void * fArg1;
391 void * fArg2;
2d21ac55 392
b0d623f7 393 inline bool isWorkBlocked( void ) const
2d21ac55 394 {
b0d623f7 395 return (fWorkWaitCount != 0);
2d21ac55
A
396 }
397
b0d623f7 398 inline bool isFreeBlocked( void ) const
2d21ac55 399 {
b0d623f7 400 return (fFreeWaitCount != 0);
2d21ac55
A
401 }
402
b0d623f7 403 inline IOPMRequest * getNextRequest( void ) const
2d21ac55 404 {
b0d623f7 405 return fRequestNext;
2d21ac55
A
406 }
407
7e4a7d39
A
408 inline IOPMRequest * getRootRequest( void ) const
409 {
b0d623f7
A
410 if (fRequestRoot) return fRequestRoot;
411 if (fCompletionAction) return (IOPMRequest *) this;
7e4a7d39
A
412 return 0;
413 }
b0d623f7
A
414
415 inline uint32_t getType( void ) const
2d21ac55
A
416 {
417 return fType;
418 }
419
b0d623f7 420 inline bool isReplyType( void ) const
2d21ac55
A
421 {
422 return (fType > kIOPMRequestTypeReplyStart);
423 }
424
b0d623f7 425 inline IOService * getTarget( void ) const
2d21ac55
A
426 {
427 return fTarget;
428 }
429
b0d623f7
A
430 inline bool isCompletionInstalled( void )
431 {
432 return (fCompletionAction != 0);
433 }
2d21ac55 434
b0d623f7
A
435 inline void installCompletionAction(
436 IOPMCompletionAction action,
437 void * target,
438 void * param )
439 {
440 fCompletionAction = action;
441 fCompletionTarget = target;
442 fCompletionParam = param;
443 }
2d21ac55 444
b0d623f7
A
445 static IOPMRequest * create( void );
446 bool init( IOService * owner, IOOptionBits type );
447 void reset( void );
448 void attachNextRequest( IOPMRequest * next );
449 void detachNextRequest( void );
450 void attachRootRequest( IOPMRequest * root );
451 void detachRootRequest( void );
2d21ac55
A
452};
453
454class IOPMRequestQueue : public IOEventSource
455{
456 OSDeclareDefaultStructors( IOPMRequestQueue )
457
458public:
459 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
460
461protected:
462 queue_head_t fQueue;
463 IOLock * fLock;
464
465 virtual bool checkForWork( void );
466 virtual void free( void );
467 virtual bool init( IOService * inOwner, Action inAction );
468
469public:
470 static IOPMRequestQueue * create( IOService * inOwner, Action inAction );
471 void queuePMRequest( IOPMRequest * request );
472 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
473 void signalWorkAvailable( void );
474};
475
476class IOPMWorkQueue : public IOEventSource
477{
478 OSDeclareDefaultStructors( IOPMWorkQueue )
479
480public:
481 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
482
483protected:
484 queue_head_t fWorkQueue;
485 Action fWorkAction;
486 Action fRetireAction;
487
488 virtual bool checkForWork( void );
489 virtual bool init( IOService * inOwner, Action work, Action retire );
490
491public:
b0d623f7
A
492 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
493 void queuePMRequest( IOPMRequest * request );
060df5ea
A
494
495 inline boolean_t isEmpty( void )
496 {
497 return queue_empty(&fWorkQueue);
498 }
b0d623f7
A
499};
500
501class IOPMCompletionQueue : public IOEventSource
502{
503 OSDeclareDefaultStructors( IOPMCompletionQueue )
504
505public:
506 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * );
507
508protected:
509 queue_head_t fQueue;
510
511 virtual bool checkForWork( void );
512 virtual bool init( IOService * inOwner, Action inAction );
513
514public:
515 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction );
516 void queuePMRequest( IOPMRequest * request );
2d21ac55
A
517};
518
519#endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */