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#include <IOKit/IOCommand.h> 33#include <IOKit/IOEventSource.h> 34 35//****************************************************************************** 36// PM command types 37//****************************************************************************** 38 39enum { 40 /* Command Types */ 41 kIOPMRequestTypeInvalid = 0x00, 42 kIOPMRequestTypePMStop = 0x01, 43 kIOPMRequestTypeAddPowerChild1 = 0x02, 44 kIOPMRequestTypeAddPowerChild2 = 0x03, 45 kIOPMRequestTypeAddPowerChild3 = 0x04, 46 kIOPMRequestTypeRegisterPowerDriver = 0x05, 47 kIOPMRequestTypeAdjustPowerState = 0x06, 48 kIOPMRequestTypePowerDomainWillChange = 0x07, 49 kIOPMRequestTypePowerDomainDidChange = 0x08, 50 kIOPMRequestTypePowerOverrideOnPriv = 0x09, 51 kIOPMRequestTypePowerOverrideOffPriv = 0x0A, 52 kIOPMRequestTypeActivityTickle = 0x0B, 53 kIOPMRequestTypeRequestPowerState = 0x0C, 54 kIOPMRequestTypeSynchronizePowerTree = 0x0D, 55 kIOPMRequestTypeRequestPowerStateOverride = 0x0E, 56 kIOPMRequestTypeSetIdleTimerPeriod = 0x0F, 57 kIOPMRequestTypeIgnoreIdleTimer = 0x10, 58 59 /* Reply Types */ 60 kIOPMRequestTypeReplyStart = 0x80, 61 kIOPMRequestTypeAckPowerChange = 0x81, 62 kIOPMRequestTypeAckSetPowerState = 0x82, 63 kIOPMRequestTypeAllowPowerChange = 0x83, 64 kIOPMRequestTypeCancelPowerChange = 0x84, 65 kIOPMRequestTypeInterestChanged = 0x85, 66 kIOPMRequestTypeIdleCancel = 0x86, 67 kIOPMRequestTypeChildNotifyDelayCancel = 0x87 68}; 69 70//****************************************************************************** 71// PM actions - For root domain only 72//****************************************************************************** 73 74struct IOPMActions; 75 76typedef void 77(*IOPMActionPowerChangeStart)( 78 void * target, 79 IOService * service, 80 IOPMActions * actions, 81 IOPMPowerStateIndex powerState, 82 IOPMPowerChangeFlags * changeFlags, 83 IOPMRequestTag requestTag ); 84 85typedef void 86(*IOPMActionPowerChangeDone)( 87 void * target, 88 IOService * service, 89 IOPMActions * actions, 90 IOPMPowerStateIndex powerState, 91 IOPMPowerChangeFlags changeFlags, 92 IOPMRequestTag requestTag ); 93 94typedef void 95(*IOPMActionPowerChangeOverride)( 96 void * target, 97 IOService * service, 98 IOPMActions * actions, 99 IOPMPowerStateIndex * powerState, 100 IOPMPowerChangeFlags * changeFlags, 101 IOPMRequestTag requestTag ); 102 103typedef void 104(*IOPMActionActivityTickle)( 105 void * target, 106 IOService * service, 107 IOPMActions * actions ); 108 109typedef void 110(*IOPMActionUpdatePowerClient)( 111 void * target, 112 IOService * service, 113 IOPMActions * actions, 114 const OSSymbol * powerClient, 115 IOPMPowerStateIndex oldPowerState, 116 IOPMPowerStateIndex newPowerState 117); 118 119struct IOPMActions { 120 void * target; 121 uint32_t parameter; 122 IOPMActionPowerChangeStart actionPowerChangeStart; 123 IOPMActionPowerChangeDone actionPowerChangeDone; 124 IOPMActionPowerChangeOverride actionPowerChangeOverride; 125 IOPMActionActivityTickle actionActivityTickle; 126 IOPMActionUpdatePowerClient actionUpdatePowerClient; 127}; 128 129// IOPMActions parameter flags 130enum { 131 kPMActionsFlagIsDisplayWrangler = 0x00000100, 132 kPMActionsFlagIsGraphicsDevice = 0x00000200, 133 kPMActionsFlagIsAudioDevice = 0x00000400, 134 kPMActionsFlagLimitPower = 0x00000800, 135 kPMActionsPCIBitNumberMask = 0x000000ff 136}; 137 138//****************************************************************************** 139 140enum { 141 kIOPMEventClassSystemEvent = 0x00, 142 kIOPMEventClassDriverEvent = 0x1 143}; 144 145class PMEventDetails : public OSObject 146{ 147 OSDeclareDefaultStructors( PMEventDetails ); 148 friend class IOServicePM; 149 friend class IOPMrootDomain; 150 friend class IOPMTimeline; 151public: 152 static PMEventDetails *eventDetails(uint32_t type, 153 const char *ownerName, 154 uintptr_t ownerUnique, 155 const char *interestName, 156 uint8_t oldState, 157 uint8_t newState, 158 uint32_t result, 159 uint32_t elapsedTimeUS); 160 161 static PMEventDetails *eventDetails(uint32_t type, 162 const char *uuid, 163 uint32_t reason, 164 uint32_t result); 165private: 166 uint8_t eventClassifier; 167 uint32_t eventType; 168 const char *ownerName; 169 uintptr_t ownerUnique; 170 const char *interestName; 171 uint8_t oldState; 172 uint8_t newState; 173 uint32_t result; 174 uint32_t elapsedTimeUS; 175 176 const char *uuid; 177 uint32_t reason; 178}; 179 180// Internal concise representation of IOPMPowerState 181struct IOPMPSEntry 182{ 183 IOPMPowerFlags capabilityFlags; 184 IOPMPowerFlags outputPowerFlags; 185 IOPMPowerFlags inputPowerFlags; 186 uint32_t staticPower; 187 uint32_t settleUpTime; 188 uint32_t settleDownTime; 189 IOPMPowerStateIndex stateOrder; 190 IOPMPowerStateIndex stateOrderToIndex; 191}; 192 193//****************************************************************************** 194// IOServicePM 195//****************************************************************************** 196 197class IOServicePM : public OSObject 198{ 199 friend class IOService; 200 friend class IOPMWorkQueue; 201 202 OSDeclareDefaultStructors( IOServicePM ) 203 204private: 205 // Link IOServicePM objects on IOPMWorkQueue. 206 queue_chain_t WorkChain; 207 208 // Queue of IOPMRequest objects. 209 queue_head_t RequestHead; 210 211 // IOService creator and owner. 212 IOService * Owner; 213 214 // List of interested drivers (protected by PMLock). 215 IOPMinformeeList * InterestedDrivers; 216 217 // How long to wait for controlling driver to acknowledge. 218 IOReturn DriverTimer; 219 220 // Current power management machine state. 221 uint32_t MachineState; 222 223 thread_call_t AckTimer; 224 thread_call_t SettleTimer; 225 thread_call_t IdleTimer; 226 thread_call_t WatchdogTimer; 227 228 // Settle time after changing power state. 229 uint32_t SettleTimeUS; 230 231 // The flags describing current change note. 232 IOPMPowerChangeFlags HeadNoteChangeFlags; 233 234 // The new power state number being changed to. 235 IOPMPowerStateIndex HeadNotePowerState; 236 237 // Points to the entry in the power state array. 238 IOPMPSEntry * HeadNotePowerArrayEntry; 239 240 // Power flags supplied by all parents (domain). 241 IOPMPowerFlags HeadNoteDomainFlags; 242 243 // Power flags supplied by domain accounting for parent changes. 244 IOPMPowerFlags HeadNoteDomainTargetFlags; 245 246 // Connection attached to the changing parent. 247 IOPowerConnection * HeadNoteParentConnection; 248 249 // Power flags supplied by the changing parent. 250 IOPMPowerFlags HeadNoteParentFlags; 251 252 // Number of acks still outstanding. 253 uint32_t HeadNotePendingAcks; 254 255 // PM state lock. 256 IOLock * PMLock; 257 258 unsigned int InitialPowerChange :1; 259 unsigned int InitialSetPowerState :1; 260 unsigned int DeviceOverrideEnabled :1; 261 unsigned int DoNotPowerDown :1; 262 unsigned int ParentsKnowState :1; 263 unsigned int StrictTreeOrder :1; 264 unsigned int IdleTimerStopped :1; 265 unsigned int AdjustPowerScheduled :1; 266 267 unsigned int IsPreChange :1; 268 unsigned int DriverCallBusy :1; 269 unsigned int PCDFunctionOverride :1; 270 unsigned int IdleTimerIgnored :1; 271 unsigned int HasAdvisoryDesire :1; 272 unsigned int AdvisoryTickleUsed :1; 273 unsigned int ResetPowerStateOnWake :1; 274 275 // Time of last device activity. 276 AbsoluteTime DeviceActiveTimestamp; 277 278 // Used to protect activity flag. 279 IOLock * ActivityLock; 280 281 // Idle timer's period in seconds. 282 unsigned long IdleTimerPeriod; 283 unsigned long IdleTimerMinPowerState; 284 AbsoluteTime IdleTimerStartTime; 285 286 // Power state desired by a subclassed device object. 287 IOPMPowerStateIndex DeviceDesire; 288 289 // This is the power state we desire currently. 290 IOPMPowerStateIndex DesiredPowerState; 291 292 // This is what our parent thinks our need is. 293 IOPMPowerFlags PreviousRequestPowerFlags; 294 295 // Cache result from getName(), used in logging. 296 const char * Name; 297 298 // Number of power states in the power array. 299 IOPMPowerStateIndex NumberOfPowerStates; 300 301 // Ordered highest power state in the power array. 302 IOPMPowerStateIndex HighestPowerState; 303 304 // Power state array. 305 IOPMPSEntry * PowerStates; 306 307 // The controlling driver. 308 IOService * ControllingDriver; 309 310 // Our current power state. 311 IOPMPowerStateIndex CurrentPowerState; 312 313 // Logical OR of power flags for each power domain parent. 314 IOPMPowerFlags ParentsCurrentPowerFlags; 315 316 // The highest power state we can achieve in current power domain. 317 IOPMPowerStateIndex MaxPowerState; 318 319 // Logical OR of all output power flags in the power state array. 320 IOPMPowerFlags MergedOutputPowerFlags; 321 322 // OSArray which manages responses from notified apps and clients. 323 OSArray * ResponseArray; 324 OSArray * NotifyClientArray; 325 326 // Used to uniquely identify power management notification to apps and clients. 327 UInt16 SerialNumber; 328 329 // Used to communicate desired function to tellClientsWithResponse(). 330 // This is used because it avoids changing the signatures of the affected virtual methods. 331 int OutOfBandParameter; 332 333 AbsoluteTime DriverCallStartTime; 334 IOPMPowerFlags CurrentCapabilityFlags; 335 unsigned long CurrentPowerConsumption; 336 IOPMPowerStateIndex TempClampPowerState; 337 OSArray * NotifyChildArray; 338 OSDictionary * PowerClients; 339 thread_call_t DriverCallEntry; 340 void * DriverCallParamPtr; 341 IOItemCount DriverCallParamCount; 342 IOItemCount DriverCallParamSlots; 343 uint32_t DriverCallReason; 344 uint32_t OutOfBandMessage; 345 uint32_t TempClampCount; 346 uint32_t OverrideMaxPowerState; 347 uint32_t DeviceUsablePowerState; 348 349 // Protected by ActivityLock - BEGIN 350 IOPMPowerStateIndex ActivityTicklePowerState; 351 IOPMPowerStateIndex AdvisoryTicklePowerState; 352 uint32_t ActivityTickleCount; 353 uint32_t DeviceWasActive : 1; 354 uint32_t AdvisoryTickled : 1; 355 // Protected by ActivityLock - END 356 357 uint32_t WaitReason; 358 uint32_t SavedMachineState; 359 uint32_t RootDomainState; 360 361 // Protected by PMLock - BEGIN 362 struct { 363 uint32_t PMStop : 1; 364 uint32_t PMDriverCallWait : 1; 365 } LockedFlags; 366 367 queue_head_t PMDriverCallQueue; 368 OSSet * InsertInterestSet; 369 OSSet * RemoveInterestSet; 370 371 372 // IOReporter Data 373 uint32_t ReportClientCnt; 374 void * ReportBuf; 375 // Protected by PMLock - END 376 377 378#if PM_VARS_SUPPORT 379 IOPMprot * PMVars; 380#endif 381 382 IOPMActions PMActions; 383 384 // Serialize IOServicePM state for debug output. 385 IOReturn gatedSerialize( OSSerialize * s ) const; 386 virtual bool serialize( OSSerialize * s ) const; 387 388 // PM log and trace 389 void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; 390 void pmTrace( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; 391}; 392 393#define fOwner pwrMgt->Owner 394#define fInterestedDrivers pwrMgt->InterestedDrivers 395#define fDriverTimer pwrMgt->DriverTimer 396#define fMachineState pwrMgt->MachineState 397#define fAckTimer pwrMgt->AckTimer 398#define fSettleTimer pwrMgt->SettleTimer 399#define fIdleTimer pwrMgt->IdleTimer 400#define fWatchdogTimer pwrMgt->WatchdogTimer 401#define fSettleTimeUS pwrMgt->SettleTimeUS 402#define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags 403#define fHeadNotePowerState pwrMgt->HeadNotePowerState 404#define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry 405#define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags 406#define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags 407#define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection 408#define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags 409#define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks 410#define fPMLock pwrMgt->PMLock 411#define fInitialPowerChange pwrMgt->InitialPowerChange 412#define fInitialSetPowerState pwrMgt->InitialSetPowerState 413#define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled 414#define fDoNotPowerDown pwrMgt->DoNotPowerDown 415#define fParentsKnowState pwrMgt->ParentsKnowState 416#define fStrictTreeOrder pwrMgt->StrictTreeOrder 417#define fIdleTimerStopped pwrMgt->IdleTimerStopped 418#define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled 419#define fIsPreChange pwrMgt->IsPreChange 420#define fDriverCallBusy pwrMgt->DriverCallBusy 421#define fPCDFunctionOverride pwrMgt->PCDFunctionOverride 422#define fIdleTimerIgnored pwrMgt->IdleTimerIgnored 423#define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire 424#define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed 425#define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake 426#define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp 427#define fActivityLock pwrMgt->ActivityLock 428#define fIdleTimerPeriod pwrMgt->IdleTimerPeriod 429#define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState 430#define fIdleTimerStartTime pwrMgt->IdleTimerStartTime 431#define fDeviceDesire pwrMgt->DeviceDesire 432#define fDesiredPowerState pwrMgt->DesiredPowerState 433#define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags 434#define fName pwrMgt->Name 435#define fNumberOfPowerStates pwrMgt->NumberOfPowerStates 436#define fHighestPowerState pwrMgt->HighestPowerState 437#define fPowerStates pwrMgt->PowerStates 438#define fControllingDriver pwrMgt->ControllingDriver 439#define fCurrentPowerState pwrMgt->CurrentPowerState 440#define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags 441#define fMaxPowerState pwrMgt->MaxPowerState 442#define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags 443#define fResponseArray pwrMgt->ResponseArray 444#define fNotifyClientArray pwrMgt->NotifyClientArray 445#define fSerialNumber pwrMgt->SerialNumber 446#define fOutOfBandParameter pwrMgt->OutOfBandParameter 447#define fDriverCallStartTime pwrMgt->DriverCallStartTime 448#define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags 449#define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption 450#define fTempClampPowerState pwrMgt->TempClampPowerState 451#define fNotifyChildArray pwrMgt->NotifyChildArray 452#define fPowerClients pwrMgt->PowerClients 453#define fDriverCallEntry pwrMgt->DriverCallEntry 454#define fDriverCallParamPtr pwrMgt->DriverCallParamPtr 455#define fDriverCallParamCount pwrMgt->DriverCallParamCount 456#define fDriverCallParamSlots pwrMgt->DriverCallParamSlots 457#define fDriverCallReason pwrMgt->DriverCallReason 458#define fOutOfBandMessage pwrMgt->OutOfBandMessage 459#define fTempClampCount pwrMgt->TempClampCount 460#define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState 461#define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState 462#define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState 463#define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState 464#define fActivityTickleCount pwrMgt->ActivityTickleCount 465#define fDeviceWasActive pwrMgt->DeviceWasActive 466#define fAdvisoryTickled pwrMgt->AdvisoryTickled 467#define fWaitReason pwrMgt->WaitReason 468#define fSavedMachineState pwrMgt->SavedMachineState 469#define fRootDomainState pwrMgt->RootDomainState 470#define fLockedFlags pwrMgt->LockedFlags 471#define fPMDriverCallQueue pwrMgt->PMDriverCallQueue 472#define fInsertInterestSet pwrMgt->InsertInterestSet 473#define fRemoveInterestSet pwrMgt->RemoveInterestSet 474#define fReportClientCnt pwrMgt->ReportClientCnt 475#define fReportBuf pwrMgt->ReportBuf 476#define fPMVars pwrMgt->PMVars 477#define fPMActions pwrMgt->PMActions 478 479#define StateOrder(state) (((state) < fNumberOfPowerStates) \ 480 ? pwrMgt->PowerStates[(state)].stateOrder \ 481 : (state)) 482#define StateMax(a,b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) 483#define StateMin(a,b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) 484 485#define kPowerStateZero (0) 486 487/* 488When an IOService is waiting for acknowledgement to a power change 489notification from an interested driver or the controlling driver, 490the ack timer is ticking every tenth of a second. 491(100000000 nanoseconds are one tenth of a second). 492*/ 493#define ACK_TIMER_PERIOD 100000000 494 495#define WATCHDOG_TIMER_PERIOD (300) // 300 secs 496 497// Max wait time in microseconds for kernel priority and capability clients 498// with async message handlers to acknowledge. 499// 500#define kPriorityClientMaxWait (90 * 1000 * 1000) 501#define kCapabilityClientMaxWait (240 * 1000 * 1000) 502 503// Attributes describing a power state change. 504// See IOPMPowerChangeFlags data type. 505// 506#define kIOPMParentInitiated 0x0001 // power change initiated by our parent 507#define kIOPMSelfInitiated 0x0002 // power change initiated by this device 508#define kIOPMNotDone 0x0004 // we couldn't make this change 509#define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo 510#define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo 511#define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power 512#define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires 513#define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase 514#define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync 515#define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree 516#define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages 517#define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake 518#define kIOPMInitialPowerChange 0x1000 // set for initial power change 519#define kIOPMRootChangeUp 0x2000 // Root power domain change up 520#define kIOPMRootChangeDown 0x4000 // Root power domain change down 521#define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration 522 523#define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ 524 kIOPMRootChangeUp | kIOPMRootChangeDown) 525 526// Activity tickle request flags 527#define kTickleTypePowerDrop 0x01 528#define kTickleTypePowerRise 0x02 529#define kTickleTypeActivity 0x04 530#define kTickleTypeAdvisory 0x08 531 532enum { 533 kDriverCallInformPreChange, 534 kDriverCallInformPostChange, 535 kDriverCallSetPowerState, 536 kRootDomainInformPreChange 537}; 538 539struct DriverCallParam { 540 OSObject * Target; 541 IOReturn Result; 542}; 543 544// values of OutOfBandParameter 545enum { 546 kNotifyApps, 547 kNotifyPriority, 548 kNotifyCapabilityChangeApps, 549 kNotifyCapabilityChangePriority 550}; 551 552typedef bool (*IOPMMessageFilter)( 553 void * target, void * object, void * arg1, void * arg2, void * arg3 ); 554 555// used for applyToInterested 556struct IOPMInterestContext { 557 OSArray * responseArray; 558 OSArray * notifyClients; 559 uint16_t serialNumber; 560 uint8_t isPreChange; 561 uint8_t enableTracing; 562 uint32_t maxTimeRequested; 563 uint32_t messageType; 564 uint32_t notifyType; 565 IOService * us; 566 IOPMPowerStateIndex stateNumber; 567 IOPMPowerFlags stateFlags; 568 IOPMPowerChangeFlags changeFlags; 569 const char * errorLog; 570 IOPMMessageFilter messageFilter; 571}; 572 573// assertPMDriverCall() options 574enum { 575 kIOPMADC_NoInactiveCheck = 1 576}; 577 578//****************************************************************************** 579// PM Statistics & Diagnostics 580//****************************************************************************** 581 582extern const OSSymbol *gIOPMStatsApplicationResponseTimedOut; 583extern const OSSymbol *gIOPMStatsApplicationResponseCancel; 584extern const OSSymbol *gIOPMStatsApplicationResponseSlow; 585 586//****************************************************************************** 587// IOPMRequest 588//****************************************************************************** 589 590typedef void (*IOPMCompletionAction)(void * target, void * param, IOReturn status); 591 592class IOPMRequest : public IOCommand 593{ 594 OSDeclareDefaultStructors( IOPMRequest ) 595 596protected: 597 IOService * fTarget; // request target 598 IOPMRequest * fRequestNext; // the next request in the chain 599 IOPMRequest * fRequestRoot; // the root request in the issue tree 600 IOItemCount fWorkWaitCount; // execution blocked if non-zero 601 IOItemCount fFreeWaitCount; // completion blocked if non-zero 602 uint32_t fType; // request type 603 604#if NOT_READY 605 IOPMCompletionAction fCompletionAction; 606 void * fCompletionTarget; 607 void * fCompletionParam; 608 IOReturn fCompletionStatus; 609#endif 610 611public: 612 uint32_t fRequestTag; 613 void * fArg0; 614 void * fArg1; 615 void * fArg2; 616 617 inline bool isWorkBlocked( void ) const 618 { 619 return (fWorkWaitCount != 0); 620 } 621 622 inline bool isFreeBlocked( void ) const 623 { 624 return (fFreeWaitCount != 0); 625 } 626 627 inline IOPMRequest * getNextRequest( void ) const 628 { 629 return fRequestNext; 630 } 631 632 inline IOPMRequest * getRootRequest( void ) const 633 { 634 if (fRequestRoot) return fRequestRoot; 635#if NOT_READY 636 if (fCompletionAction) return (IOPMRequest *) this; 637#endif 638 return 0; 639 } 640 641 inline uint32_t getType( void ) const 642 { 643 return fType; 644 } 645 646 inline bool isReplyType( void ) const 647 { 648 return (fType > kIOPMRequestTypeReplyStart); 649 } 650 651 inline IOService * getTarget( void ) const 652 { 653 return fTarget; 654 } 655 656#if NOT_READY 657 inline bool isCompletionInstalled( void ) 658 { 659 return (fCompletionAction != 0); 660 } 661 662 inline void installCompletionAction( 663 IOPMCompletionAction action, 664 void * target, 665 void * param ) 666 { 667 fCompletionAction = action; 668 fCompletionTarget = target; 669 fCompletionParam = param; 670 } 671#endif /* NOT_READY */ 672 673 static IOPMRequest * create( void ); 674 bool init( IOService * owner, IOOptionBits type ); 675 void reset( void ); 676 bool attachNextRequest( IOPMRequest * next ); 677 bool detachNextRequest( void ); 678 bool attachRootRequest( IOPMRequest * root ); 679 bool detachRootRequest( void ); 680}; 681 682//****************************************************************************** 683// IOPMRequestQueue 684//****************************************************************************** 685 686class IOPMRequestQueue : public IOEventSource 687{ 688 OSDeclareDefaultStructors( IOPMRequestQueue ) 689 690public: 691 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 692 693protected: 694 queue_head_t fQueue; 695 IOLock * fLock; 696 697 virtual bool checkForWork( void ); 698 virtual void free( void ); 699 virtual bool init( IOService * inOwner, Action inAction ); 700 701public: 702 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 703 void queuePMRequest( IOPMRequest * request ); 704 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 705}; 706 707//****************************************************************************** 708// IOPMWorkQueue 709//****************************************************************************** 710 711#define WORK_QUEUE_STATS 1 712 713class IOPMWorkQueue : public IOEventSource 714{ 715 OSDeclareDefaultStructors( IOPMWorkQueue ) 716 717public: 718 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 719 720#if WORK_QUEUE_STATS 721 uint64_t fStatCheckForWork; 722 uint64_t fStatScanEntries; 723 uint64_t fStatQueueEmpty; 724 uint64_t fStatNoWorkDone; 725#endif 726 727protected: 728 queue_head_t fWorkQueue; 729 Action fWorkAction; 730 Action fRetireAction; 731 uint32_t fQueueLength; 732 uint32_t fConsumerCount; 733 volatile uint32_t fProducerCount; 734 735 virtual bool checkForWork( void ); 736 virtual bool init( IOService * inOwner, Action work, Action retire ); 737 bool checkRequestQueue( queue_head_t * queue, bool * empty ); 738 739public: 740 static IOPMWorkQueue * create( IOService * inOwner, Action work, Action retire ); 741 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); 742 void signalWorkAvailable( void ); 743 void incrementProducerCount( void ); 744}; 745 746//****************************************************************************** 747// IOPMCompletionQueue 748//****************************************************************************** 749 750class IOPMCompletionQueue : public IOEventSource 751{ 752 OSDeclareDefaultStructors( IOPMCompletionQueue ) 753 754public: 755 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); 756 757protected: 758 queue_head_t fQueue; 759 760 virtual bool checkForWork( void ); 761 virtual bool init( IOService * inOwner, Action inAction ); 762 763public: 764 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); 765 bool queuePMRequest( IOPMRequest * request ); 766}; 767 768#endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 769