]> git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOServicePMPrivate.h
xnu-1228.tar.gz
[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
176 /*! @var DriverDesire
177 Power state desired by our controlling driver.
178 */
179 unsigned long DriverDesire;
180
181 /*! @var DeviceDesire
182 Power state desired by a subclassed device object.
183 */
184 unsigned long DeviceDesire;
185
186 /*! @var ChildrenDesire
187 Power state desired by all children.
188 */
189 unsigned long ChildrenDesire;
190
191 /*! @var DesiredPowerState
192 This is the power state we desire currently.
193 */
194 unsigned long DesiredPowerState;
195
196 /*! @var PreviousRequest
197 This is what our parent thinks our need is.
198 */
199 unsigned long PreviousRequest;
200
201 /*! @var Name
202 Cache result from getName(), used in logging.
203 */
204 const char * Name;
205
206 /*! @var Platform
207 Cache result from getPlatform(), used in logging and registering.
208 */
209 IOPlatformExpert * Platform;
210
211 /*! @var NumberOfPowerStates
212 Number of power states in the power array.
213 */
214 unsigned long NumberOfPowerStates;
215
216 /*! @var PowerStates
217 Power state array.
218 */
219 IOPMPowerState * PowerStates;
220
221 /*! @var ControllingDriver
222 The controlling driver.
223 */
224 IOService * ControllingDriver;
225
226 /*! @var AggressivenessValues
227 Array of aggressiveness values.
228 */
229 unsigned long AggressivenessValue[ kMaxType + 1 ];
230
231 /*! @var AggressivenessValid
232 True for aggressiveness values that are currently valid.
233 */
234 bool AggressivenessValid[ kMaxType + 1 ];
235
236 /*! @var CurrentPowerState
237 The ordinal of our current power state.
238 */
239 unsigned long CurrentPowerState;
240
241 /*! @var ParentsCurrentPowerFlags
242 Logical OR of power flags for each power domain parent.
243 */
244 IOPMPowerFlags ParentsCurrentPowerFlags;
245
246 /*! @var MaxCapability
247 Ordinal of highest power state we can achieve in current power domain.
248 */
249 unsigned long MaxCapability;
250
251 /*! @var OutputPowerCharacterFlags
252 Logical OR of all output power character flags in the array.
253 */
254 IOPMPowerFlags OutputPowerCharacterFlags;
255
256 /*! @var SerialNumber
257 Used to uniquely identify power management notification to apps and clients.
258 */
259 UInt16 SerialNumber;
260
261 /*! @var ResponseArray
262 OSArray which manages responses from notified apps and clients.
263 */
264 OSArray * ResponseArray;
265
266 /*! @var OutOfBandParameter
267 Used to communicate desired function to tellClientsWithResponse().
268 This is used because it avoids changing the signatures of the affected virtual methods.
269 */
270 int OutOfBandParameter;
271
272 AbsoluteTime DriverCallStartTime;
273 IOPMPowerFlags CurrentCapabilityFlags;
274 unsigned long CurrentPowerConsumption;
275 unsigned long TempClampPowerState;
276 unsigned long TempClampCount;
277 IOPMWorkQueue * PMWorkQueue;
278 IOPMRequest * PMRequest;
279 OSSet * InsertInterestSet;
280 OSSet * RemoveInterestSet;
281 OSArray * NotifyChildArray;
282 unsigned long WaitReason;
283 unsigned long NextMachineState;
284 thread_call_t DriverCallEntry;
285 void * DriverCallParamPtr;
286 IOItemCount DriverCallParamCount;
287 IOItemCount DriverCallParamSlots;
288 IOOptionBits DriverCallReason;
289 long ActivityTicklePowerState;
290 bool StrictTreeOrder;
291 bool DriverCallBusy;
292 bool ActivityTimerStopped;
293 bool WillAdjustPowerState;
294 bool WillPMStop;
295
296 #if PM_VARS_SUPPORT
297 IOPMprot * PMVars;
298 #endif
299
300 /*! @function serialize
301 Serialize IOServicePM state for debug output.
302 */
303 virtual bool serialize( OSSerialize * s ) const;
304 };
305
306 #define fWeAreRoot pwrMgt->WeAreRoot
307 #define fInterestedDrivers pwrMgt->InterestedDrivers
308 #define fDriverTimer pwrMgt->DriverTimer
309 #define fAckTimer pwrMgt->AckTimer
310 #define fSettleTimer pwrMgt->SettleTimer
311 #define fMachineState pwrMgt->MachineState
312 #define fSettleTimeUS pwrMgt->SettleTimeUS
313 #define fHeadNoteFlags pwrMgt->HeadNoteFlags
314 #define fHeadNoteState pwrMgt->HeadNoteState
315 #define fHeadNoteOutputFlags pwrMgt->HeadNoteOutputFlags
316 #define fHeadNoteDomainState pwrMgt->HeadNoteDomainState
317 #define fHeadNoteParent pwrMgt->HeadNoteParent
318 #define fHeadNoteCapabilityFlags pwrMgt->HeadNoteCapabilityFlags
319 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks
320 #define fPMLock pwrMgt->PMLock
321 #define fInitialChange pwrMgt->InitialChange
322 #define fNeedToBecomeUsable pwrMgt->NeedToBecomeUsable
323 #define fDeviceOverrides pwrMgt->DeviceOverrides
324 #define fClampOn pwrMgt->ClampOn
325 #define fOwner pwrMgt->Owner
326 #define fActivityLock pwrMgt->ActivityLock
327 #define fIdleTimerEventSource pwrMgt->IdleTimerEventSource
328 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod
329 #define fDeviceActive pwrMgt->DeviceActive
330 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp
331 #define fDriverDesire pwrMgt->DriverDesire
332 #define fDeviceDesire pwrMgt->DeviceDesire
333 #define fChildrenDesire pwrMgt->ChildrenDesire
334 #define fDesiredPowerState pwrMgt->DesiredPowerState
335 #define fPreviousRequest pwrMgt->PreviousRequest
336 #define fName pwrMgt->Name
337 #define fPlatform pwrMgt->Platform
338 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates
339 #define fPowerStates pwrMgt->PowerStates
340 #define fControllingDriver pwrMgt->ControllingDriver
341 #define fAggressivenessValue pwrMgt->AggressivenessValue
342 #define fAggressivenessValid pwrMgt->AggressivenessValid
343 #define fCurrentPowerState pwrMgt->CurrentPowerState
344 #define fParentsKnowState pwrMgt->ParentsKnowState
345 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags
346 #define fMaxCapability pwrMgt->MaxCapability
347 #define fOutputPowerCharacterFlags pwrMgt->OutputPowerCharacterFlags
348 #define fSerialNumber pwrMgt->SerialNumber
349 #define fResponseArray pwrMgt->ResponseArray
350 #define fDoNotPowerDown pwrMgt->DoNotPowerDown
351 #define fOutOfBandParameter pwrMgt->OutOfBandParameter
352 #define fDriverCallStartTime pwrMgt->DriverCallStartTime
353 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags
354 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption
355 #define fTempClampPowerState pwrMgt->TempClampPowerState
356 #define fTempClampCount pwrMgt->TempClampCount
357 #define fPMWorkQueue pwrMgt->PMWorkQueue
358 #define fPMRequest pwrMgt->PMRequest
359 #define fWaitReason pwrMgt->WaitReason
360 #define fNextMachineState pwrMgt->NextMachineState
361 #define fDriverCallReason pwrMgt->DriverCallReason
362 #define fDriverCallEntry pwrMgt->DriverCallEntry
363 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr
364 #define fDriverCallParamCount pwrMgt->DriverCallParamCount
365 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots
366 #define fDriverCallBusy pwrMgt->DriverCallBusy
367 #define fWillPMStop pwrMgt->WillPMStop
368 #define fActivityTickled pwrMgt->ActivityTickled
369 #define fInsertInterestSet pwrMgt->InsertInterestSet
370 #define fRemoveInterestSet pwrMgt->RemoveInterestSet
371 #define fStrictTreeOrder pwrMgt->StrictTreeOrder
372 #define fNotifyChildArray pwrMgt->NotifyChildArray
373 #define fWillAdjustPowerState pwrMgt->WillAdjustPowerState
374 #define fActivityTimerStopped pwrMgt->ActivityTimerStopped
375 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState
376 #define fPMVars pwrMgt->PMVars
377
378 /*!
379 @defined ACK_TIMER_PERIOD
380 @discussion When an IOService is waiting for acknowledgement to a power change
381 notification from an interested driver or the controlling driver its ack timer
382 is ticking every tenth of a second.
383 (100000000 nanoseconds are one tenth of a second).
384 */
385 #define ACK_TIMER_PERIOD 100000000
386
387 #define IOPMParentInitiated 1 // this power change initiated by our parent
388 #define IOPMWeInitiated 2 // this power change initiated by this device
389 #define IOPMNotDone 4 // we couldn't make this change
390 #define IOPMNotInUse 8 // this list element not currently in use
391 #define IOPMDomainWillChange 16 // change started by PowerDomainWillChangeTo
392 #define IOPMDomainDidChange 32 // change started by PowerDomainDidChangeTo
393
394 struct changeNoteItem {
395 unsigned long flags;
396 unsigned long newStateNumber;
397 IOPMPowerFlags outputPowerCharacter;
398 IOPMPowerFlags inputPowerRequirement;
399 IOPMPowerFlags domainState;
400 IOPowerConnection * parent;
401 IOPMPowerFlags singleParentState;
402 IOPMPowerFlags capabilityFlags;
403 };
404
405 enum {
406 kDriverCallInformPreChange,
407 kDriverCallInformPostChange,
408 kDriverCallSetPowerState
409 };
410
411 struct DriverCallParam {
412 OSObject * Target;
413 IOReturn Result;
414 };
415
416 // values of outofbandparameter
417 enum {
418 kNotifyApps,
419 kNotifyPriority
420 };
421
422 // used for applyToInterested
423 struct context {
424 OSArray * responseFlags;
425 UInt16 serialNumber;
426 UInt16 counter;
427 UInt32 maxTimeRequested;
428 int msgType;
429 IOService * us;
430 unsigned long stateNumber;
431 IOPMPowerFlags stateFlags;
432 const char * errorLog;
433 };
434
435 //*********************************************************************************
436 // PM command types
437 //*********************************************************************************
438
439 enum {
440 /* Command Types */
441 kIOPMRequestTypeInvalid = 0x00,
442 kIOPMRequestTypePMStop = 0x01,
443 kIOPMRequestTypeAddPowerChild1 = 0x02,
444 kIOPMRequestTypeAddPowerChild2 = 0x03,
445 kIOPMRequestTypeAddPowerChild3 = 0x04,
446 kIOPMRequestTypeRegisterPowerDriver = 0x05,
447 kIOPMRequestTypeAdjustPowerState = 0x06,
448 kIOPMRequestTypeMakeUsable = 0x07,
449 kIOPMRequestTypeTemporaryPowerClamp = 0x08,
450 kIOPMRequestTypePowerDomainWillChange = 0x09,
451 kIOPMRequestTypePowerDomainDidChange = 0x0A,
452 kIOPMRequestTypeChangePowerStateTo = 0x0B,
453 kIOPMRequestTypeChangePowerStateToPriv = 0x0C,
454 kIOPMRequestTypePowerOverrideOnPriv = 0x0D,
455 kIOPMRequestTypePowerOverrideOffPriv = 0x0E,
456 kIOPMRequestTypeActivityTickle = 0x0F,
457 /* Reply Types */
458 kIOPMRequestTypeReplyStart = 0x80,
459 kIOPMRequestTypeAckPowerChange = 0x81,
460 kIOPMRequestTypeAckSetPowerState = 0x82,
461 kIOPMRequestTypeAllowPowerChange = 0x83,
462 kIOPMRequestTypeCancelPowerChange = 0x84,
463 kIOPMRequestTypeInterestChanged = 0x85
464 };
465
466 //*********************************************************************************
467 // PM Helper Classes
468 //*********************************************************************************
469
470 class IOPMRequest : public IOCommand
471 {
472 OSDeclareDefaultStructors( IOPMRequest )
473
474 protected:
475 IOOptionBits fType; // request type
476 IOService * fTarget; // request target
477 IOPMRequest * fParent; // parent request
478 IOItemCount fChildCount; // wait if non-zero
479
480 public:
481 void * fArg0;
482 void * fArg1;
483 void * fArg2;
484
485 inline bool hasChildRequest( void ) const
486 {
487 return (fChildCount != 0);
488 }
489
490 inline bool hasParentRequest( void ) const
491 {
492 return (fParent != 0);
493 }
494
495 inline void setParentRequest( IOPMRequest * parent )
496 {
497 if (!fParent)
498 {
499 fParent = parent;
500 fParent->fChildCount++;
501 }
502 }
503
504 inline IOOptionBits getType( void ) const
505 {
506 return fType;
507 }
508
509 inline bool isReply( void ) const
510 {
511 return (fType > kIOPMRequestTypeReplyStart);
512 }
513
514 inline IOService * getTarget( void ) const
515 {
516 return fTarget;
517 }
518
519 static IOPMRequest *create( void );
520
521 void reset( void );
522
523 bool init( IOService * owner, IOOptionBits type );
524 };
525
526 class IOPMRequestQueue : public IOEventSource
527 {
528 OSDeclareDefaultStructors( IOPMRequestQueue )
529
530 public:
531 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * );
532
533 protected:
534 queue_head_t fQueue;
535 IOLock * fLock;
536
537 virtual bool checkForWork( void );
538 virtual void free( void );
539 virtual bool init( IOService * inOwner, Action inAction );
540
541 public:
542 static IOPMRequestQueue * create( IOService * inOwner, Action inAction );
543 void queuePMRequest( IOPMRequest * request );
544 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count );
545 void signalWorkAvailable( void );
546 };
547
548 class IOPMWorkQueue : public IOEventSource
549 {
550 OSDeclareDefaultStructors( IOPMWorkQueue )
551
552 public:
553 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * );
554
555 protected:
556 queue_head_t fWorkQueue;
557 Action fWorkAction;
558 Action fRetireAction;
559
560 virtual bool checkForWork( void );
561 virtual bool init( IOService * inOwner, Action work, Action retire );
562
563 public:
564 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire );
565 void queuePMRequest( IOPMRequest * request );
566 };
567
568 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */