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*/ 38class IOServicePM : public OSObject 39{ 40 friend class IOService; 41 42 OSDeclareDefaultStructors( IOServicePM ) 43 44private: 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 383notification from an interested driver or the controlling driver its ack timer 384is 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 396struct 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 407enum { 408 kDriverCallInformPreChange, 409 kDriverCallInformPostChange, 410 kDriverCallSetPowerState 411}; 412 413struct DriverCallParam { 414 OSObject * Target; 415 IOReturn Result; 416}; 417 418// values of outofbandparameter 419enum { 420 kNotifyApps, 421 kNotifyPriority 422}; 423 424// used for applyToInterested 425struct 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 441enum { 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 kIOPMRequestTypeIdleCancel = 0x86 467}; 468 469//********************************************************************************* 470// PM Helper Classes 471//********************************************************************************* 472 473class IOPMRequest : public IOCommand 474{ 475 OSDeclareDefaultStructors( IOPMRequest ) 476 477protected: 478 IOOptionBits fType; // request type 479 IOService * fTarget; // request target 480 IOPMRequest * fParent; // parent request 481 IOItemCount fChildCount; // wait if non-zero 482 483public: 484 void * fArg0; 485 void * fArg1; 486 void * fArg2; 487 488 inline bool hasChildRequest( void ) const 489 { 490 return (fChildCount != 0); 491 } 492 493 inline bool hasParentRequest( void ) const 494 { 495 return (fParent != 0); 496 } 497 498 inline void setParentRequest( IOPMRequest * parent ) 499 { 500 if (!fParent) 501 { 502 fParent = parent; 503 fParent->fChildCount++; 504 } 505 } 506 507 inline IOOptionBits getType( void ) const 508 { 509 return fType; 510 } 511 512 inline bool isReply( void ) const 513 { 514 return (fType > kIOPMRequestTypeReplyStart); 515 } 516 517 inline IOService * getTarget( void ) const 518 { 519 return fTarget; 520 } 521 522 static IOPMRequest *create( void ); 523 524 void reset( void ); 525 526 bool init( IOService * owner, IOOptionBits type ); 527}; 528 529class IOPMRequestQueue : public IOEventSource 530{ 531 OSDeclareDefaultStructors( IOPMRequestQueue ) 532 533public: 534 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 535 536protected: 537 queue_head_t fQueue; 538 IOLock * fLock; 539 540 virtual bool checkForWork( void ); 541 virtual void free( void ); 542 virtual bool init( IOService * inOwner, Action inAction ); 543 544public: 545 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 546 void queuePMRequest( IOPMRequest * request ); 547 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 548 void signalWorkAvailable( void ); 549}; 550 551class IOPMWorkQueue : public IOEventSource 552{ 553 OSDeclareDefaultStructors( IOPMWorkQueue ) 554 555public: 556 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 557 558protected: 559 queue_head_t fWorkQueue; 560 Action fWorkAction; 561 Action fRetireAction; 562 563 virtual bool checkForWork( void ); 564 virtual bool init( IOService * inOwner, Action work, Action retire ); 565 566public: 567 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire ); 568 void queuePMRequest( IOPMRequest * request ); 569}; 570 571#endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 572