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 IOPMMessageFilter messageFilter; 566 }; 567 568 // assertPMDriverCall() options 569 enum { 570 kIOPMDriverCallNoInactiveCheck = 1 571 }; 572 573 // assertPMDriverCall() method 574 enum { 575 kIOPMDriverCallMethodUnknown = 0, 576 kIOPMDriverCallMethodSetPowerState = 1, 577 kIOPMDriverCallMethodWillChange = 2, 578 kIOPMDriverCallMethodDidChange = 3, 579 kIOPMDriverCallMethodChangeDone = 4, 580 kIOPMDriverCallMethodSetAggressive = 5 581 }; 582 583 //****************************************************************************** 584 // PM Statistics & Diagnostics 585 //****************************************************************************** 586 587 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut; 588 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel; 589 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow; 590 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt; 591 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow; 592 593 //****************************************************************************** 594 // IOPMRequest 595 //****************************************************************************** 596 597 class IOPMRequest : public IOCommand 598 { 599 OSDeclareDefaultStructors( IOPMRequest ); 600 601 protected: 602 IOService * fTarget; // request target 603 IOPMRequest * fRequestNext; // the next request in the chain 604 IOPMRequest * fRequestRoot; // the root request in the call tree 605 uint32_t fWorkWaitCount; // execution blocked if non-zero 606 uint32_t fFreeWaitCount; // completion blocked if non-zero 607 uint64_t fTimestamp; // MCTU 608 uint32_t fRequestType; // request type 609 bool fIsQuiesceBlocker; 610 611 IOPMCompletionAction fCompletionAction; 612 void * fCompletionTarget; 613 void * fCompletionParam; 614 615 public: 616 uint32_t fTag; 617 void * fArg0; 618 void * fArg1; 619 void * fArg2; 620 621 inline bool isWorkBlocked(void)622 isWorkBlocked( void ) const 623 { 624 return fWorkWaitCount != 0; 625 } 626 627 inline bool isFreeBlocked(void)628 isFreeBlocked( void ) const 629 { 630 return fFreeWaitCount != 0; 631 } 632 633 inline IOPMRequest * getNextRequest(void)634 getNextRequest( void ) const 635 { 636 return fRequestNext; 637 } 638 639 inline IOPMRequest * getRootRequest(void)640 getRootRequest( void ) const 641 { 642 if (fRequestRoot) { 643 return fRequestRoot; 644 } 645 #if NOT_READY 646 if (fCompletionAction) { 647 return (IOPMRequest *) this; 648 } 649 #endif 650 return NULL; 651 } 652 653 inline uint32_t getType(void)654 getType( void ) const 655 { 656 return fRequestType; 657 } 658 659 inline uint32_t getTag(void)660 getTag( void ) const 661 { 662 return fTag; 663 } 664 665 inline bool isReplyType(void)666 isReplyType( void ) const 667 { 668 return fRequestType > kIOPMRequestTypeReplyStart; 669 } 670 671 inline IOService * getTarget(void)672 getTarget( void ) const 673 { 674 return fTarget; 675 } 676 677 inline bool isQuiesceBlocker(void)678 isQuiesceBlocker( void ) const 679 { 680 return fIsQuiesceBlocker; 681 } 682 683 inline bool isQuiesceType(void)684 isQuiesceType( void ) const 685 { 686 return (kIOPMRequestTypeQuiescePowerTree == fRequestType) && 687 (fCompletionAction != NULL) && (fCompletionTarget != NULL); 688 } 689 690 inline void installCompletionAction(void * target,IOPMCompletionAction action,void * param)691 installCompletionAction( 692 void * target, 693 IOPMCompletionAction action, 694 void * param ) 695 { 696 fCompletionTarget = target; 697 fCompletionAction = action; 698 fCompletionParam = param; 699 } 700 701 inline void setTimestamp(uint64_t time)702 setTimestamp( uint64_t time ) 703 { 704 fTimestamp = time; 705 } 706 707 inline uint64_t getTimestamp(void)708 getTimestamp( void ) const 709 { 710 return fTimestamp; 711 } 712 713 static IOPMRequest * create( void ); 714 bool init( IOService * owner, IOOptionBits type ); 715 void reset( void ); 716 bool attachNextRequest( IOPMRequest * next ); 717 bool detachNextRequest( void ); 718 bool attachRootRequest( IOPMRequest * root ); 719 bool detachRootRequest( void ); 720 }; 721 722 //****************************************************************************** 723 // IOPMRequestQueue 724 //****************************************************************************** 725 726 class IOPMRequestQueue : public IOEventSource 727 { 728 OSDeclareDefaultStructors( IOPMRequestQueue ); 729 730 public: 731 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 732 733 protected: 734 queue_head_t fQueue; 735 IOLock * fLock; 736 737 enum { kMaxDequeueCount = 256 }; 738 739 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 740 virtual void free( void ) APPLE_KEXT_OVERRIDE; 741 virtual bool init( IOService * inOwner, Action inAction ); 742 743 public: 744 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 745 void queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request ); 746 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 747 }; 748 749 //****************************************************************************** 750 // IOPMWorkQueue 751 //****************************************************************************** 752 753 #define WORK_QUEUE_STATS 1 754 755 class IOPMWorkQueue : public IOEventSource 756 { 757 OSDeclareDefaultStructors( IOPMWorkQueue ); 758 759 public: 760 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 761 762 #if WORK_QUEUE_STATS 763 uint64_t fStatCheckForWork; 764 uint64_t fStatScanEntries; 765 uint64_t fStatQueueEmpty; 766 uint64_t fStatNoWorkDone; 767 #endif 768 769 protected: 770 queue_head_t fWorkQueue; 771 Action fInvokeAction; 772 Action fRetireAction; 773 uint32_t fQueueLength; 774 uint32_t fConsumerCount; 775 volatile uint32_t fProducerCount; 776 IOPMRequest * fQuiesceRequest; 777 AbsoluteTime fQuiesceStartTime; 778 AbsoluteTime fQuiesceFinishTime; 779 780 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 781 virtual bool init( IOService * inOwner, Action invoke, Action retire ); 782 bool checkRequestQueue( queue_head_t * queue, bool * empty ); 783 784 public: 785 static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); 786 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); 787 void signalWorkAvailable( void ); 788 void incrementProducerCount( void ); 789 void attachQuiesceRequest( IOPMRequest * quiesceRequest ); 790 void finishQuiesceRequest( IOPMRequest * quiesceRequest ); 791 }; 792 793 //****************************************************************************** 794 // IOPMCompletionQueue 795 //****************************************************************************** 796 797 class IOPMCompletionQueue : public IOEventSource 798 { 799 OSDeclareDefaultStructors( IOPMCompletionQueue ); 800 801 public: 802 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); 803 804 protected: 805 queue_head_t fQueue; 806 807 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 808 virtual bool init( IOService * inOwner, Action inAction ); 809 810 public: 811 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); 812 bool queuePMRequest( IOPMRequest * request ); 813 }; 814 815 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 816