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