]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOServicePMPrivate.h
658730e05f47c9e95b21fd3eb2ba2c95c2d6a2b8
[apple/xnu.git] / iokit / Kernel / IOServicePMPrivate.h
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
32 /* Binary compatibility with drivers that access pm_vars */
33 #define PM_VARS_SUPPORT 1
34
35 /*! @class IOServicePM
36 @abstract Power management class.
37 */
38 class IOServicePM : public OSObject
39 {
40 friend class IOService;
41
42 OSDeclareDefaultStructors( IOServicePM )
43
44 private:
45 /*! @var Owner
46 Points to object that called PMinit(). Used only for debugging.
47 */
48 IOService * Owner;
49
50 /*! @var InterestedDrivers
51 List of interested drivers.
52 */
53 IOPMinformeeList * InterestedDrivers;
54
55 /*! @var DriverTimer
56 How long to wait for controlling driver to acknowledge.
57 */
58 IOReturn DriverTimer;
59
60 /*! @var AckTimer */
61 thread_call_t AckTimer;
62
63 /*! @var SettleTimer */
64 thread_call_t SettleTimer;
65
66 /*! @var MachineState
67 Current power management machine state.
68 */
69 unsigned long MachineState;
70
71 /*! @var SettleTimeUS
72 Settle time after changing power state.
73 */
74 unsigned long SettleTimeUS;
75
76 /*! @var HeadNoteFlags
77 The flags field for the current change note.
78 */
79 unsigned long HeadNoteFlags;
80
81 /*! @var HeadNoteState
82 The newStateNumber field for the current change note.
83 */
84 unsigned long HeadNoteState;
85
86 /*! @var HeadNoteOutputFlags
87 The outputPowerCharacter field for the current change note.
88 */
89 unsigned long HeadNoteOutputFlags;
90
91 /*! @var HeadNoteDomainState
92 Power domain flags from parent. (only on parent change).
93 */
94 unsigned long HeadNoteDomainState;
95
96 /*! @var HeadNoteParent
97 Pointer to initiating parent. (only on parent change).
98 */
99 IOPowerConnection * HeadNoteParent;
100
101 /*! @var HeadNoteCapabilityFlags
102 The capabilityFlags field for the current change note.
103 */
104 unsigned long HeadNoteCapabilityFlags;
105
106 /*! @var HeadNotePendingAcks
107 Number of acks we are waiting for.
108 */
109 unsigned long HeadNotePendingAcks;
110
111 /*! @var PMLock
112 PM state lock.
113 */
114 IOLock * PMLock;
115
116 /*! @var WeAreRoot
117 True if our owner is the root of the power tree.
118 */
119 bool WeAreRoot;
120
121 /*! @var InitialChange
122 Initialized to true, then set to false after the initial power change.
123 */
124 bool InitialChange;
125
126 /*! @var NeedToBecomeUsable
127 Someone has called makeUsable before we had a controlling driver.
128 */
129 bool NeedToBecomeUsable;
130
131 /*! @var DeviceOverrides
132 Ignore children and driver desires if true.
133 */
134 bool DeviceOverrides;
135
136 /*! @var ClampOn
137 Domain is clamped on until the first power child is added.
138 */
139 bool ClampOn;
140
141 /*! @var DeviceActive
142 True if device was active since last idle timer expiration.
143 */
144 bool DeviceActive;
145
146 /*! @var DoNotPowerDown
147 Keeps track of any negative responses from notified apps and clients.
148 */
149 bool DoNotPowerDown;
150
151 /*! @var ParentsKnowState
152 True if all our parents know the state of their power domain.
153 */
154 bool ParentsKnowState;
155
156 /*! @var DeviceActiveTimestamp
157 Time of last device activity.
158 */
159 AbsoluteTime DeviceActiveTimestamp;
160
161 /*! @var ActivityLock
162 Used to protect activity flag.
163 */
164 IOLock * ActivityLock;
165
166 /*! @var IdleTimerEventSource
167 An idle timer event source.
168 */
169 IOTimerEventSource * IdleTimerEventSource;
170
171 /*! @var IdleTimerPeriod
172 Idle timer's period in seconds.
173 */
174 unsigned long IdleTimerPeriod;
175 unsigned long IdleTimerMinPowerState;
176
177 /*! @var DriverDesire
178 Power state desired by our controlling driver.
179 */
180 unsigned long DriverDesire;
181
182 /*! @var DeviceDesire
183 Power state desired by a subclassed device object.
184 */
185 unsigned long DeviceDesire;
186
187 /*! @var ChildrenDesire
188 Power state desired by all children.
189 */
190 unsigned long ChildrenDesire;
191
192 /*! @var DesiredPowerState
193 This is the power state we desire currently.
194 */
195 unsigned long DesiredPowerState;
196
197 /*! @var PreviousRequest
198 This is what our parent thinks our need is.
199 */
200 unsigned long PreviousRequest;
201
202 /*! @var Name
203 Cache result from getName(), used in logging.
204 */
205 const char * Name;
206
207 /*! @var Platform
208 Cache result from getPlatform(), used in logging and registering.
209 */
210 IOPlatformExpert * Platform;
211
212 /*! @var NumberOfPowerStates
213 Number of power states in the power array.
214 */
215 unsigned long NumberOfPowerStates;
216
217 /*! @var PowerStates
218 Power state array.
219 */
220 IOPMPowerState * PowerStates;
221
222 /*! @var ControllingDriver
223 The controlling driver.
224 */
225 IOService * ControllingDriver;
226
227 /*! @var AggressivenessValues
228 Array of aggressiveness values.
229 */
230 unsigned long AggressivenessValue[ kMaxType + 1 ];
231
232 /*! @var AggressivenessValid
233 True for aggressiveness values that are currently valid.
234 */
235 bool AggressivenessValid[ kMaxType + 1 ];
236
237 /*! @var CurrentPowerState
238 The ordinal of our current power state.
239 */
240 unsigned long CurrentPowerState;
241
242 /*! @var ParentsCurrentPowerFlags
243 Logical OR of power flags for each power domain parent.
244 */
245 IOPMPowerFlags ParentsCurrentPowerFlags;
246
247 /*! @var MaxCapability
248 Ordinal of highest power state we can achieve in current power domain.
249 */
250 unsigned long MaxCapability;
251
252 /*! @var OutputPowerCharacterFlags
253 Logical OR of all output power character flags in the array.
254 */
255 IOPMPowerFlags OutputPowerCharacterFlags;
256
257 /*! @var SerialNumber
258 Used to uniquely identify power management notification to apps and clients.
259 */
260 UInt16 SerialNumber;
261
262 /*! @var ResponseArray
263 OSArray which manages responses from notified apps and clients.
264 */
265 OSArray * ResponseArray;
266
267 /*! @var OutOfBandParameter
268 Used to communicate desired function to tellClientsWithResponse().
269 This is used because it avoids changing the signatures of the affected virtual methods.
270 */
271 int OutOfBandParameter;
272
273 AbsoluteTime DriverCallStartTime;
274 IOPMPowerFlags CurrentCapabilityFlags;
275 unsigned long CurrentPowerConsumption;
276 unsigned long TempClampPowerState;
277 unsigned long TempClampCount;
278 IOPMWorkQueue * PMWorkQueue;
279 IOPMRequest * PMRequest;
280 OSSet * InsertInterestSet;
281 OSSet * RemoveInterestSet;
282 OSArray * NotifyChildArray;
283 unsigned long WaitReason;
284 unsigned long NextMachineState;
285 thread_call_t DriverCallEntry;
286 void * DriverCallParamPtr;
287 IOItemCount DriverCallParamCount;
288 IOItemCount DriverCallParamSlots;
289 IOOptionBits DriverCallReason;
290 long ActivityTicklePowerState;
291 bool StrictTreeOrder;
292 bool DriverCallBusy;
293 bool ActivityTimerStopped;
294 bool WillAdjustPowerState;
295 bool WillPMStop;
296
297 #if PM_VARS_SUPPORT
298 IOPMprot * PMVars;
299 #endif
300
301 /*! @function serialize
302 Serialize IOServicePM state for debug output.
303 */
304 virtual bool serialize( OSSerialize * s ) const;
305 };
306
307 #define fWeAreRoot pwrMgt->WeAreRoot
308 #define fInterestedDrivers pwrMgt->InterestedDrivers
309 #define fDriverTimer pwrMgt->DriverTimer
310 #define fAckTimer pwrMgt->AckTimer
311 #define fSettleTimer pwrMgt->SettleTimer
312 #define fMachineState pwrMgt->MachineState
313 #define fSettleTimeUS pwrMgt->SettleTimeUS
314 #define fHeadNoteFlags pwrMgt->HeadNoteFlags
315 #define fHeadNoteState pwrMgt->HeadNoteState
316 #define fHeadNoteOutputFlags pwrMgt->HeadNoteOutputFlags
317 #define fHeadNoteDomainState pwrMgt->HeadNoteDomainState
318 #define fHeadNoteParent pwrMgt->HeadNoteParent
319 #define fHeadNoteCapabilityFlags pwrMgt->HeadNoteCapabilityFlags
320 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
321 #define fPMLock pwrMgt->PMLock
322 #define fInitialChange pwrMgt->InitialChange
323 #define fNeedToBecomeUsable pwrMgt->NeedToBecomeUsable
324 #define fDeviceOverrides pwrMgt->DeviceOverrides
325 #define fClampOn pwrMgt->ClampOn
326 #define fOwner pwrMgt->Owner
327 #define fActivityLock pwrMgt->ActivityLock
328 #define fIdleTimerEventSource pwrMgt->IdleTimerEventSource
329 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
330 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState
331 #define fDeviceActive pwrMgt->DeviceActive
332 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
333 #define fDriverDesire pwrMgt->DriverDesire
334 #define fDeviceDesire pwrMgt->DeviceDesire
335 #define fChildrenDesire pwrMgt->ChildrenDesire
336 #define fDesiredPowerState pwrMgt->DesiredPowerState
337 #define fPreviousRequest pwrMgt->PreviousRequest
338 #define fName pwrMgt->Name
339 #define fPlatform pwrMgt->Platform
340 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
341 #define fPowerStates pwrMgt->PowerStates
342 #define fControllingDriver pwrMgt->ControllingDriver
343 #define fAggressivenessValue pwrMgt->AggressivenessValue
344 #define fAggressivenessValid pwrMgt->AggressivenessValid
345 #define fCurrentPowerState pwrMgt->CurrentPowerState
346 #define fParentsKnowState pwrMgt->ParentsKnowState
347 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
348 #define fMaxCapability pwrMgt->MaxCapability
349 #define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags
350 #define fSerialNumber pwrMgt->SerialNumber
351 #define fResponseArray pwrMgt->ResponseArray
352 #define fDoNotPowerDown pwrMgt->DoNotPowerDown
353 #define fOutOfBandParameter pwrMgt->OutOfBandParameter
354 #define fDriverCallStartTime pwrMgt->DriverCallStartTime
355 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
356 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
357 #define fTempClampPowerState pwrMgt->TempClampPowerState
358 #define fTempClampCount pwrMgt->TempClampCount
359 #define fPMWorkQueue pwrMgt->PMWorkQueue
360 #define fPMRequest pwrMgt->PMRequest
361 #define fWaitReason pwrMgt->WaitReason
362 #define fNextMachineState pwrMgt->NextMachineState
363 #define fDriverCallReason pwrMgt->DriverCallReason
364 #define fDriverCallEntry pwrMgt->DriverCallEntry
365 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
366 #define fDriverCallParamCount pwrMgt->DriverCallParamCount
367 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
368 #define fDriverCallBusy pwrMgt->DriverCallBusy
369 #define fWillPMStop pwrMgt->WillPMStop
370 #define fActivityTickled pwrMgt->ActivityTickled
371 #define fInsertInterestSet pwrMgt->InsertInterestSet
372 #define fRemoveInterestSet pwrMgt->RemoveInterestSet
373 #define fStrictTreeOrder pwrMgt->StrictTreeOrder
374 #define fNotifyChildArray pwrMgt->NotifyChildArray
375 #define fWillAdjustPowerState pwrMgt->WillAdjustPowerState
376 #define fActivityTimerStopped pwrMgt->ActivityTimerStopped
377 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
378 #define fPMVars pwrMgt->PMVars
379
380 /*!
381 @defined ACK_TIMER_PERIOD
382 @discussion When an IOService is waiting for acknowledgement to a power change
383 notification from an interested driver or the controlling driver its ack timer
384 is ticking every tenth of a second.
385 (100000000 nanoseconds are one tenth of a second).
386 */
387 #define ACK_TIMER_PERIOD 100000000
388
389 #define IOPMParentInitiated 1 // this power change initiated by our parent
390 #define IOPMWeInitiated 2 // this power change initiated by this device
391 #define IOPMNotDone 4 // we couldn't make this change
392 #define IOPMNotInUse 8 // this list element not currently in use
393 #define IOPMDomainWillChange 16 // change started by PowerDomainWillChangeTo
394 #define IOPMDomainDidChange 32 // change started by PowerDomainDidChangeTo
395
396 struct changeNoteItem {
397 unsigned long flags;
398 unsigned long newStateNumber;
399 IOPMPowerFlags outputPowerCharacter;
400 IOPMPowerFlags inputPowerRequirement;
401 IOPMPowerFlags domainState;
402 IOPowerConnection * parent;
403 IOPMPowerFlags singleParentState;
404 IOPMPowerFlags capabilityFlags;
405 };
406
407 enum {
408 kDriverCallInformPreChange,
409 kDriverCallInformPostChange,
410 kDriverCallSetPowerState
411 };
412
413 struct DriverCallParam {
414 OSObject * Target;
415 IOReturn Result;
416 };
417
418 // values of outofbandparameter
419 enum {
420 kNotifyApps,
421 kNotifyPriority
422 };
423
424 // used for applyToInterested
425 struct context {
426 OSArray * responseFlags;
427 UInt16 serialNumber;
428 UInt16 counter;
429 UInt32 maxTimeRequested;
430 int msgType;
431 IOService * us;
432 unsigned long stateNumber;
433 IOPMPowerFlags stateFlags;
434 const char * errorLog;
435 };
436
437 //*********************************************************************************
438 // PM command types
439 //*********************************************************************************
440
441 enum {
442 /* Command Types */
443 kIOPMRequestTypeInvalid = 0x00,
444 kIOPMRequestTypePMStop = 0x01,
445 kIOPMRequestTypeAddPowerChild1 = 0x02,
446 kIOPMRequestTypeAddPowerChild2 = 0x03,
447 kIOPMRequestTypeAddPowerChild3 = 0x04,
448 kIOPMRequestTypeRegisterPowerDriver = 0x05,
449 kIOPMRequestTypeAdjustPowerState = 0x06,
450 kIOPMRequestTypeMakeUsable = 0x07,
451 kIOPMRequestTypeTemporaryPowerClamp = 0x08,
452 kIOPMRequestTypePowerDomainWillChange = 0x09,
453 kIOPMRequestTypePowerDomainDidChange = 0x0A,
454 kIOPMRequestTypeChangePowerStateTo = 0x0B,
455 kIOPMRequestTypeChangePowerStateToPriv = 0x0C,
456 kIOPMRequestTypePowerOverrideOnPriv = 0x0D,
457 kIOPMRequestTypePowerOverrideOffPriv = 0x0E,
458 kIOPMRequestTypeActivityTickle = 0x0F,
459 /* Reply Types */
460 kIOPMRequestTypeReplyStart = 0x80,
461 kIOPMRequestTypeAckPowerChange = 0x81,
462 kIOPMRequestTypeAckSetPowerState = 0x82,
463 kIOPMRequestTypeAllowPowerChange = 0x83,
464 kIOPMRequestTypeCancelPowerChange = 0x84,
465 kIOPMRequestTypeInterestChanged = 0x85
466 };
467
468 //*********************************************************************************
469 // PM Helper Classes
470 //*********************************************************************************
471
472 class IOPMRequest : public IOCommand
473 {
474 OSDeclareDefaultStructors( IOPMRequest )
475
476 protected:
477 IOOptionBits fType; // request type
478 IOService * fTarget; // request target
479 IOPMRequest * fParent; // parent request
480 IOItemCount fChildCount; // wait if non-zero
481
482 public:
483 void * fArg0;
484 void * fArg1;
485 void * fArg2;
486
487 inline bool hasChildRequest( void ) const
488 {
489 return (fChildCount != 0);
490 }
491
492 inline bool hasParentRequest( void ) const
493 {
494 return (fParent != 0);
495 }
496
497 inline void setParentRequest( IOPMRequest * parent )
498 {
499 if (!fParent)
500 {
501 fParent = parent;
502 fParent->fChildCount++;
503 }
504 }
505
506 inline IOOptionBits getType( void ) const
507 {
508 return fType;
509 }
510
511 inline bool isReply( void ) const
512 {
513 return (fType > kIOPMRequestTypeReplyStart);
514 }
515
516 inline IOService * getTarget( void ) const
517 {
518 return fTarget;
519 }
520
521 static IOPMRequest *create( void );
522
523 void reset( void );
524
525 bool init( IOService * owner, IOOptionBits type );
526 };
527
528 class IOPMRequestQueue : public IOEventSource
529 {
530 OSDeclareDefaultStructors( IOPMRequestQueue )
531
532 public:
533 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
534
535 protected:
536 queue_head_t fQueue;
537 IOLock * fLock;
538
539 virtual bool checkForWork( void );
540 virtual void free( void );
541 virtual bool init( IOService * inOwner, Action inAction );
542
543 public:
544 static IOPMRequestQueue * create( IOService * inOwner, Action inAction );
545 void queuePMRequest( IOPMRequest * request );
546 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
547 void signalWorkAvailable( void );
548 };
549
550 class IOPMWorkQueue : public IOEventSource
551 {
552 OSDeclareDefaultStructors( IOPMWorkQueue )
553
554 public:
555 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
556
557 protected:
558 queue_head_t fWorkQueue;
559 Action fWorkAction;
560 Action fRetireAction;
561
562 virtual bool checkForWork( void );
563 virtual bool init( IOService * inOwner, Action work, Action retire );
564
565 public:
566 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
567 void queuePMRequest( IOPMRequest * request );
568 };
569
570 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */