2 * Copyright (c) 2007 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #ifndef _IOKIT_IOSERVICEPMPRIVATE_H
30 #define _IOKIT_IOSERVICEPMPRIVATE_H
32 /*! @class IOServicePM
33 @abstract Power management class.
35 class IOServicePM
: public OSObject
37 friend class IOService
;
39 OSDeclareDefaultStructors( IOServicePM
)
42 // List of interested drivers.
43 IOPMinformeeList
* InterestedDrivers
;
45 // How long to wait for controlling driver to acknowledge.
48 // Current power management machine state.
49 uint32_t MachineState
;
51 thread_call_t AckTimer
;
52 thread_call_t SettleTimer
;
54 // Settle time after changing power state.
55 unsigned long SettleTimeUS
;
57 // The flags describing current change note.
58 unsigned long HeadNoteFlags
;
60 // The new power state number being changed to.
61 unsigned long HeadNotePowerState
;
63 // Points to the entry in the power state array.
64 IOPMPowerState
* HeadNotePowerArrayEntry
;
66 // Power flags supplied by all parents (domain).
67 unsigned long HeadNoteDomainFlags
;
69 // Connection attached to the changing parent.
70 IOPowerConnection
* HeadNoteParentConnection
;
72 // Power flags supplied by the changing parent.
73 unsigned long HeadNoteParentFlags
;
75 // Number of acks still outstanding.
76 unsigned long HeadNotePendingAcks
;
81 // Initialized to true, then set to false after the initial power change.
84 // Ignore children and driver desires if true.
87 // True if device was active since last idle timer expiration.
90 // Keeps track of any negative responses from notified apps and clients.
93 // True if all our parents know the state of their power domain.
94 bool ParentsKnowState
;
97 bool IdleTimerStopped
;
98 bool AdjustPowerScheduled
;
100 // Time of last device activity.
101 AbsoluteTime DeviceActiveTimestamp
;
103 // Used to protect activity flag.
104 IOLock
* ActivityLock
;
106 // Idle timer event source.
107 IOTimerEventSource
* IdleTimerEventSource
;
109 // Idle timer's period in seconds.
110 unsigned long IdleTimerPeriod
;
111 unsigned long IdleTimerMinPowerState
;
112 AbsoluteTime IdleTimerStartTime
;
114 // Power state desired by a subclassed device object.
115 unsigned long DeviceDesire
;
117 // This is the power state we desire currently.
118 unsigned long DesiredPowerState
;
120 // This is what our parent thinks our need is.
121 unsigned long PreviousRequest
;
123 // Cache result from getName(), used in logging.
126 // Number of power states in the power array.
127 unsigned long NumberOfPowerStates
;
129 // Power state array.
130 IOPMPowerState
* PowerStates
;
132 // The controlling driver.
133 IOService
* ControllingDriver
;
135 // Our current power state.
136 unsigned long CurrentPowerState
;
138 // Logical OR of power flags for each power domain parent.
139 IOPMPowerFlags ParentsCurrentPowerFlags
;
141 // The highest power state we can achieve in current power domain.
142 unsigned long MaxCapability
;
144 // Logical OR of all output power character flags in the array.
145 IOPMPowerFlags OutputPowerCharacterFlags
;
147 // OSArray which manages responses from notified apps and clients.
148 OSArray
* ResponseArray
;
149 OSArray
* NotifyClientArray
;
151 // Used to uniquely identify power management notification to apps and clients.
154 // Used to communicate desired function to tellClientsWithResponse().
155 // This is used because it avoids changing the signatures of the affected virtual methods.
156 int OutOfBandParameter
;
158 AbsoluteTime DriverCallStartTime
;
159 IOPMPowerFlags CurrentCapabilityFlags
;
160 long ActivityTicklePowerState
;
161 unsigned long CurrentPowerConsumption
;
162 unsigned long TempClampPowerState
;
163 IOPMWorkQueue
* PMWorkQueue
;
164 OSSet
* InsertInterestSet
;
165 OSSet
* RemoveInterestSet
;
166 OSArray
* NotifyChildArray
;
167 OSDictionary
* PowerClients
;
168 thread_call_t DriverCallEntry
;
169 void * DriverCallParamPtr
;
170 IOItemCount DriverCallParamCount
;
171 IOItemCount DriverCallParamSlots
;
172 uint32_t DriverCallReason
;
173 uint32_t TempClampCount
;
174 uint32_t OverrideMaxPowerState
;
175 uint32_t ActivityTickleCount
;
177 uint32_t NextMachineState
;
178 uint32_t RootDomainState
;
179 uint32_t ThreadAssertionCount
;
181 // Protected by PMLock
183 uint32_t DriverCallBusy
: 1;
187 thread_t ThreadAssertionThread
;
193 // Serialize IOServicePM state for debug output.
194 IOReturn
gatedSerialize( OSSerialize
* s
);
195 virtual bool serialize( OSSerialize
* s
) const;
198 #define fInterestedDrivers pwrMgt->InterestedDrivers
199 #define fDriverTimer pwrMgt->DriverTimer
200 #define fAckTimer pwrMgt->AckTimer
201 #define fSettleTimer pwrMgt->SettleTimer
202 #define fMachineState pwrMgt->MachineState
203 #define fSettleTimeUS pwrMgt->SettleTimeUS
204 #define fHeadNoteFlags pwrMgt->HeadNoteFlags
205 #define fHeadNotePowerState pwrMgt->HeadNotePowerState
206 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry
207 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags
208 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection
209 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags
210 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
211 #define fPMLock pwrMgt->PMLock
212 #define fInitialChange pwrMgt->InitialChange
213 #define fDeviceOverrides pwrMgt->DeviceOverrides
214 #define fActivityLock pwrMgt->ActivityLock
215 #define fIdleTimerEventSource pwrMgt->IdleTimerEventSource
216 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
217 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState
218 #define fDeviceActive pwrMgt->DeviceActive
219 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime
220 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
221 #define fActivityTickleCount pwrMgt->ActivityTickleCount
222 #define fDeviceDesire pwrMgt->DeviceDesire
223 #define fDesiredPowerState pwrMgt->DesiredPowerState
224 #define fPreviousRequest pwrMgt->PreviousRequest
225 #define fName pwrMgt->Name
226 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
227 #define fPowerStates pwrMgt->PowerStates
228 #define fControllingDriver pwrMgt->ControllingDriver
229 #define fAggressivenessValue pwrMgt->AggressivenessValue
230 #define fAggressivenessValid pwrMgt->AggressivenessValid
231 #define fCurrentPowerState pwrMgt->CurrentPowerState
232 #define fParentsKnowState pwrMgt->ParentsKnowState
233 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
234 #define fMaxCapability pwrMgt->MaxCapability
235 #define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags
236 #define fSerialNumber pwrMgt->SerialNumber
237 #define fResponseArray pwrMgt->ResponseArray
238 #define fNotifyClientArray pwrMgt->NotifyClientArray
239 #define fDoNotPowerDown pwrMgt->DoNotPowerDown
240 #define fOutOfBandParameter pwrMgt->OutOfBandParameter
241 #define fDriverCallStartTime pwrMgt->DriverCallStartTime
242 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
243 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
244 #define fTempClampPowerState pwrMgt->TempClampPowerState
245 #define fTempClampCount pwrMgt->TempClampCount
246 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState
247 #define fPMWorkQueue pwrMgt->PMWorkQueue
248 #define fWaitReason pwrMgt->WaitReason
249 #define fNextMachineState pwrMgt->NextMachineState
250 #define fDriverCallReason pwrMgt->DriverCallReason
251 #define fDriverCallEntry pwrMgt->DriverCallEntry
252 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
253 #define fDriverCallParamCount pwrMgt->DriverCallParamCount
254 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
255 #define fActivityTickled pwrMgt->ActivityTickled
256 #define fInsertInterestSet pwrMgt->InsertInterestSet
257 #define fRemoveInterestSet pwrMgt->RemoveInterestSet
258 #define fStrictTreeOrder pwrMgt->StrictTreeOrder
259 #define fNotifyChildArray pwrMgt->NotifyChildArray
260 #define fIdleTimerStopped pwrMgt->IdleTimerStopped
261 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled
262 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
263 #define fPMVars pwrMgt->PMVars
264 #define fPowerClients pwrMgt->PowerClients
265 #define fRootDomainState pwrMgt->RootDomainState
266 #define fThreadAssertionCount pwrMgt->ThreadAssertionCount
267 #define fThreadAssertionThread pwrMgt->ThreadAssertionThread
268 #define fLockedFlags pwrMgt->LockedFlags
271 When an IOService is waiting for acknowledgement to a power change
272 notification from an interested driver or the controlling driver,
273 the ack timer is ticking every tenth of a second.
274 (100000000 nanoseconds are one tenth of a second).
276 #define ACK_TIMER_PERIOD 100000000
278 #define kIOPMParentInitiated 0x01 // this power change initiated by our parent
279 #define kIOPMWeInitiated 0x02 // this power change initiated by this device
280 #define kIOPMNotDone 0x04 // we couldn't make this change
281 #define kIOPMDomainWillChange 0x08 // change started by PowerDomainWillChangeTo
282 #define kIOPMDomainDidChange 0x10 // change started by PowerDomainDidChangeTo
283 #define kIOPMDomainPowerDrop 0x20 // Domain is lowering power
284 #define kIOPMSynchronize 0x40 // change triggered by power tree re-sync
287 kDriverCallInformPreChange
,
288 kDriverCallInformPostChange
,
289 kDriverCallSetPowerState
292 struct DriverCallParam
{
297 // values of outofbandparameter
303 typedef bool (*IOPMMessageFilter
)(OSObject
* object
, void * context
);
305 // used for applyToInterested
306 struct IOPMInterestContext
{
307 OSArray
* responseFlags
;
308 OSArray
* notifyClients
;
311 UInt32 maxTimeRequested
;
314 unsigned long stateNumber
;
315 IOPMPowerFlags stateFlags
;
316 const char * errorLog
;
317 IOPMMessageFilter filterFunc
;
320 //*********************************************************************************
321 // PM Statistics & Diagnostics
322 //*********************************************************************************
324 extern const OSSymbol
*gIOPMStatsApplicationResponseTimedOut
;
325 extern const OSSymbol
*gIOPMStatsApplicationResponseCancel
;
326 extern const OSSymbol
*gIOPMStatsApplicationResponseSlow
;
328 //*********************************************************************************
330 //*********************************************************************************
334 kIOPMRequestTypeInvalid
= 0x00,
335 kIOPMRequestTypePMStop
= 0x01,
336 kIOPMRequestTypeAddPowerChild1
= 0x02,
337 kIOPMRequestTypeAddPowerChild2
= 0x03,
338 kIOPMRequestTypeAddPowerChild3
= 0x04,
339 kIOPMRequestTypeRegisterPowerDriver
= 0x05,
340 kIOPMRequestTypeAdjustPowerState
= 0x06,
341 kIOPMRequestTypePowerDomainWillChange
= 0x07,
342 kIOPMRequestTypePowerDomainDidChange
= 0x08,
343 kIOPMRequestTypePowerOverrideOnPriv
= 0x09,
344 kIOPMRequestTypePowerOverrideOffPriv
= 0x0A,
345 kIOPMRequestTypeActivityTickle
= 0x0B,
346 kIOPMRequestTypeRequestPowerState
= 0x0C,
347 kIOPMRequestTypeSynchronizePowerTree
= 0x0D,
348 kIOPMRequestTypeRequestPowerStateOverride
= 0x0E,
349 kIOPMRequestTypeSetIdleTimerPeriod
= 0x0F,
352 kIOPMRequestTypeReplyStart
= 0x80,
353 kIOPMRequestTypeAckPowerChange
= 0x81,
354 kIOPMRequestTypeAckSetPowerState
= 0x82,
355 kIOPMRequestTypeAllowPowerChange
= 0x83,
356 kIOPMRequestTypeCancelPowerChange
= 0x84,
357 kIOPMRequestTypeInterestChanged
= 0x85,
358 kIOPMRequestTypeIdleCancel
= 0x86
361 //*********************************************************************************
362 // IOServicePM internal helper classes
363 //*********************************************************************************
365 typedef void (*IOPMCompletionAction
)(void * target
, void * param
, IOReturn status
);
367 class IOPMRequest
: public IOCommand
369 OSDeclareDefaultStructors( IOPMRequest
)
372 IOService
* fTarget
; // request target
373 IOPMRequest
* fRequestNext
; // the next request in the chain
374 IOPMRequest
* fRequestRoot
; // the root request in the issue tree
375 IOItemCount fWorkWaitCount
; // execution blocked if non-zero
376 IOItemCount fFreeWaitCount
; // completion blocked if non-zero
377 uint32_t fType
; // request type
379 IOPMCompletionAction fCompletionAction
;
380 void * fCompletionTarget
;
381 void * fCompletionParam
;
382 IOReturn fCompletionStatus
;
389 inline bool isWorkBlocked( void ) const
391 return (fWorkWaitCount
!= 0);
394 inline bool isFreeBlocked( void ) const
396 return (fFreeWaitCount
!= 0);
399 inline IOPMRequest
* getNextRequest( void ) const
404 inline IOPMRequest
* getRootRequest( void ) const
406 if (fRequestRoot
) return fRequestRoot
;
407 if (fCompletionAction
) return (IOPMRequest
*) this;
411 inline uint32_t getType( void ) const
416 inline bool isReplyType( void ) const
418 return (fType
> kIOPMRequestTypeReplyStart
);
421 inline IOService
* getTarget( void ) const
426 inline bool isCompletionInstalled( void )
428 return (fCompletionAction
!= 0);
431 inline void installCompletionAction(
432 IOPMCompletionAction action
,
436 fCompletionAction
= action
;
437 fCompletionTarget
= target
;
438 fCompletionParam
= param
;
441 static IOPMRequest
* create( void );
442 bool init( IOService
* owner
, IOOptionBits type
);
444 void attachNextRequest( IOPMRequest
* next
);
445 void detachNextRequest( void );
446 void attachRootRequest( IOPMRequest
* root
);
447 void detachRootRequest( void );
450 class IOPMRequestQueue
: public IOEventSource
452 OSDeclareDefaultStructors( IOPMRequestQueue
)
455 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMRequestQueue
* );
461 virtual bool checkForWork( void );
462 virtual void free( void );
463 virtual bool init( IOService
* inOwner
, Action inAction
);
466 static IOPMRequestQueue
* create( IOService
* inOwner
, Action inAction
);
467 void queuePMRequest( IOPMRequest
* request
);
468 void queuePMRequestChain( IOPMRequest
** requests
, IOItemCount count
);
469 void signalWorkAvailable( void );
472 class IOPMWorkQueue
: public IOEventSource
474 OSDeclareDefaultStructors( IOPMWorkQueue
)
477 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMWorkQueue
* );
480 queue_head_t fWorkQueue
;
482 Action fRetireAction
;
484 virtual bool checkForWork( void );
485 virtual bool init( IOService
* inOwner
, Action work
, Action retire
);
488 static IOPMWorkQueue
* create( IOService
* inOwner
, Action work
, Action retire
);
489 void queuePMRequest( IOPMRequest
* request
);
492 class IOPMCompletionQueue
: public IOEventSource
494 OSDeclareDefaultStructors( IOPMCompletionQueue
)
497 typedef bool (*Action
)( IOService
*, IOPMRequest
*, IOPMCompletionQueue
* );
502 virtual bool checkForWork( void );
503 virtual bool init( IOService
* inOwner
, Action inAction
);
506 static IOPMCompletionQueue
* create( IOService
* inOwner
, Action inAction
);
507 void queuePMRequest( IOPMRequest
* request
);
510 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */