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 // Thread to be run alongside DriverCallEntry to provide logging. 334 thread_call_t DriverCallTimer; 335 336 // Protected by ActivityLock - BEGIN 337 IOPMPowerStateIndex ActivityTicklePowerState; 338 IOPMPowerStateIndex AdvisoryTicklePowerState; 339 uint32_t ActivityTickleCount; 340 uint32_t DeviceWasActive : 1; 341 uint32_t AdvisoryTickled : 1; 342 // Protected by ActivityLock - END 343 344 uint32_t WaitReason; 345 uint32_t SavedMachineState; 346 347 // Protected by PMLock - BEGIN 348 struct { 349 uint32_t PMStop : 1; 350 uint32_t PMDriverCallWait : 1; 351 } LockedFlags; 352 353 queue_head_t PMDriverCallQueue; 354 OSSet * InsertInterestSet; 355 OSSet * RemoveInterestSet; 356 357 // IOReporter Data 358 uint32_t ReportClientCnt; 359 void * ReportBuf; 360 // Protected by PMLock - END 361 362 #if PM_VARS_SUPPORT 363 IOPMprot * PMVars; 364 #endif 365 366 IOPMActions PMActions; 367 368 // Serialize IOServicePM state for debug output. 369 IOReturn gatedSerialize( OSSerialize * s ) const; 370 virtual bool serialize( OSSerialize * s ) const APPLE_KEXT_OVERRIDE; 371 372 // PM log and trace 373 void pmPrint( uint32_t event, uintptr_t param1, uintptr_t param2 ) const; 374 void pmTrace( uint32_t event, uint32_t eventFunc, uintptr_t param1, uintptr_t param2 ) const; 375 }; 376 377 #define fOwner pwrMgt->Owner 378 #define fInterestedDrivers pwrMgt->InterestedDrivers 379 #define fDriverTimer pwrMgt->DriverTimer 380 #define fMachineState pwrMgt->MachineState 381 #define fAckTimer pwrMgt->AckTimer 382 #define fSettleTimer pwrMgt->SettleTimer 383 #define fIdleTimer pwrMgt->IdleTimer 384 #define fWatchdogTimer pwrMgt->WatchdogTimer 385 #define fWatchdogDeadline pwrMgt->WatchdogDeadline 386 #define fWatchdogLock pwrMgt->WatchdogLock 387 #define fBlockedArray pwrMgt->BlockedArray 388 #define fPendingResponseDeadline pwrMgt->PendingResponseDeadline 389 #define fSettleTimeUS pwrMgt->SettleTimeUS 390 #define fIdleTimerGeneration pwrMgt->IdleTimerGeneration 391 #define fHeadNoteChangeFlags pwrMgt->HeadNoteChangeFlags 392 #define fHeadNotePowerState pwrMgt->HeadNotePowerState 393 #define fHeadNotePowerArrayEntry pwrMgt->HeadNotePowerArrayEntry 394 #define fHeadNoteDomainFlags pwrMgt->HeadNoteDomainFlags 395 #define fHeadNoteDomainTargetFlags pwrMgt->HeadNoteDomainTargetFlags 396 #define fHeadNoteParentConnection pwrMgt->HeadNoteParentConnection 397 #define fHeadNoteParentFlags pwrMgt->HeadNoteParentFlags 398 #define fHeadNotePendingAcks pwrMgt->HeadNotePendingAcks 399 #define fPMLock pwrMgt->PMLock 400 #define fInitialPowerChange pwrMgt->InitialPowerChange 401 #define fInitialSetPowerState pwrMgt->InitialSetPowerState 402 #define fDeviceOverrideEnabled pwrMgt->DeviceOverrideEnabled 403 #define fDoNotPowerDown pwrMgt->DoNotPowerDown 404 #define fParentsKnowState pwrMgt->ParentsKnowState 405 #define fStrictTreeOrder pwrMgt->StrictTreeOrder 406 #define fIdleTimerStopped pwrMgt->IdleTimerStopped 407 #define fAdjustPowerScheduled pwrMgt->AdjustPowerScheduled 408 #define fIsPreChange pwrMgt->IsPreChange 409 #define fDriverCallBusy pwrMgt->DriverCallBusy 410 #define fPCDFunctionOverride pwrMgt->PCDFunctionOverride 411 #define fIdleTimerIgnored pwrMgt->IdleTimerIgnored 412 #define fHasAdvisoryDesire pwrMgt->HasAdvisoryDesire 413 #define fAdvisoryTickleUsed pwrMgt->AdvisoryTickleUsed 414 #define fResetPowerStateOnWake pwrMgt->ResetPowerStateOnWake 415 #define fDeviceActiveTimestamp pwrMgt->DeviceActiveTimestamp 416 #define fMaxPowerStateEntryTime pwrMgt->MaxPowerStateEntryTime 417 #define fMaxPowerStateExitTime pwrMgt->MaxPowerStateExitTime 418 #define fActivityLock pwrMgt->ActivityLock 419 #define fIdleTimerPeriod pwrMgt->IdleTimerPeriod 420 #define fIdleTimerMinPowerState pwrMgt->IdleTimerMinPowerState 421 #define fNextIdleTimerPeriod pwrMgt->NextIdleTimerPeriod 422 #define fIdleTimerStartTime pwrMgt->IdleTimerStartTime 423 #define fDeviceDesire pwrMgt->DeviceDesire 424 #define fDesiredPowerState pwrMgt->DesiredPowerState 425 #define fPreviousRequestPowerFlags pwrMgt->PreviousRequestPowerFlags 426 #define fName pwrMgt->Name 427 #define fNumberOfPowerStates pwrMgt->NumberOfPowerStates 428 #define fHighestPowerState pwrMgt->HighestPowerState 429 #define fPowerStates pwrMgt->PowerStates 430 #define fControllingDriver pwrMgt->ControllingDriver 431 #define fCurrentPowerState pwrMgt->CurrentPowerState 432 #define fParentsCurrentPowerFlags pwrMgt->ParentsCurrentPowerFlags 433 #define fMaxPowerState pwrMgt->MaxPowerState 434 #define fMergedOutputPowerFlags pwrMgt->MergedOutputPowerFlags 435 #define fResponseArray pwrMgt->ResponseArray 436 #define fNotifyClientArray pwrMgt->NotifyClientArray 437 #define fSerialNumber pwrMgt->SerialNumber 438 #define fOutOfBandParameter pwrMgt->OutOfBandParameter 439 #define fDriverCallStartTime pwrMgt->DriverCallStartTime 440 #define fCurrentCapabilityFlags pwrMgt->CurrentCapabilityFlags 441 #define fCurrentPowerConsumption pwrMgt->CurrentPowerConsumption 442 #define fTempClampPowerState pwrMgt->TempClampPowerState 443 #define fNotifyChildArray pwrMgt->NotifyChildArray 444 #define fPowerClients pwrMgt->PowerClients 445 #define fDriverCallEntry pwrMgt->DriverCallEntry 446 #define fDriverCallParamPtr pwrMgt->DriverCallParamPtr 447 #define fDriverCallParamCount pwrMgt->DriverCallParamCount 448 #define fDriverCallParamSlots pwrMgt->DriverCallParamSlots 449 #define fDriverCallReason pwrMgt->DriverCallReason 450 #define fOutOfBandMessage pwrMgt->OutOfBandMessage 451 #define fTempClampCount pwrMgt->TempClampCount 452 #define fOverrideMaxPowerState pwrMgt->OverrideMaxPowerState 453 #define fDeviceUsablePowerState pwrMgt->DeviceUsablePowerState 454 #define fDriverCallTimer pwrMgt->DriverCallTimer 455 #define fActivityTicklePowerState pwrMgt->ActivityTicklePowerState 456 #define fAdvisoryTicklePowerState pwrMgt->AdvisoryTicklePowerState 457 #define fActivityTickleCount pwrMgt->ActivityTickleCount 458 #define fDeviceWasActive pwrMgt->DeviceWasActive 459 #define fAdvisoryTickled pwrMgt->AdvisoryTickled 460 #define fWaitReason pwrMgt->WaitReason 461 #define fSavedMachineState pwrMgt->SavedMachineState 462 #define fLockedFlags pwrMgt->LockedFlags 463 #define fPMDriverCallQueue pwrMgt->PMDriverCallQueue 464 #define fInsertInterestSet pwrMgt->InsertInterestSet 465 #define fRemoveInterestSet pwrMgt->RemoveInterestSet 466 #define fReportClientCnt pwrMgt->ReportClientCnt 467 #define fReportBuf pwrMgt->ReportBuf 468 #define fPMVars pwrMgt->PMVars 469 #define fPMActions pwrMgt->PMActions 470 471 #define StateOrder(state) (((state) < fNumberOfPowerStates) \ 472 ? pwrMgt->PowerStates[(state)].stateOrder \ 473 : (state)) 474 #define StateMax(a, b) (StateOrder((a)) < StateOrder((b)) ? (b) : (a)) 475 #define StateMin(a, b) (StateOrder((a)) < StateOrder((b)) ? (a) : (b)) 476 477 #define kPowerStateZero (0) 478 479 /* 480 * When an IOService is waiting for acknowledgement to a power change 481 * notification from an interested driver or the controlling driver, 482 * the ack timer is ticking every tenth of a second. 483 * (100000000 nanoseconds are one tenth of a second). 484 */ 485 #define ACK_TIMER_PERIOD 100000000 486 487 #if defined(__i386__) || defined(__x86_64__) 488 #define WATCHDOG_SLEEP_TIMEOUT (180) // 180 secs 489 #define WATCHDOG_WAKE_TIMEOUT (180) // 180 secs 490 #else 491 #define WATCHDOG_SLEEP_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 492 #define WATCHDOG_WAKE_TIMEOUT (35) // 35 secs (kMaxTimeRequested + 5s) 493 #endif 494 495 // Max wait time in microseconds for kernel priority and capability clients 496 // with async message handlers to acknowledge. 497 // 498 #define kPriorityClientMaxWait (90 * 1000 * 1000) 499 #define kCapabilityClientMaxWait (240 * 1000 * 1000) 500 501 // Attributes describing a power state change. 502 // See IOPMPowerChangeFlags data type. 503 // 504 #define kIOPMParentInitiated 0x0001 // power change initiated by our parent 505 #define kIOPMSelfInitiated 0x0002 // power change initiated by this device 506 #define kIOPMNotDone 0x0004 // we couldn't make this change 507 #define kIOPMDomainWillChange 0x0008 // change started by PowerDomainWillChangeTo 508 #define kIOPMDomainDidChange 0x0010 // change started by PowerDomainDidChangeTo 509 #define kIOPMDomainPowerDrop 0x0020 // Domain is lowering power 510 #define kIOPMIgnoreChildren 0x0040 // Ignore children and driver power desires 511 #define kIOPMSkipAskPowerDown 0x0080 // skip the ask app phase 512 #define kIOPMSynchronize 0x0100 // change triggered by power tree re-sync 513 #define kIOPMSyncNoChildNotify 0x0200 // sync root domain only, not entire tree 514 #define kIOPMSyncTellPowerDown 0x0400 // send the ask/will power off messages 515 #define kIOPMSyncCancelPowerDown 0x0800 // sleep cancel for maintenance wake 516 #define kIOPMInitialPowerChange 0x1000 // set for initial power change 517 #define kIOPMRootChangeUp 0x2000 // Root power domain change up 518 #define kIOPMRootChangeDown 0x4000 // Root power domain change down 519 #define kIOPMExpireIdleTimer 0x8000 // Accelerate idle timer expiration 520 521 #define kIOPMRootBroadcastFlags (kIOPMSynchronize | \ 522 kIOPMRootChangeUp | kIOPMRootChangeDown) 523 524 // Activity tickle request flags 525 #define kTickleTypePowerDrop 0x01 526 #define kTickleTypePowerRise 0x02 527 #define kTickleTypeActivity 0x04 528 #define kTickleTypeAdvisory 0x08 529 530 enum { 531 kDriverCallInformPreChange, 532 kDriverCallInformPostChange, 533 kDriverCallSetPowerState, 534 kRootDomainInformPreChange 535 }; 536 537 struct DriverCallParam { 538 OSObject * Target; 539 IOReturn Result; 540 }; 541 542 // values of OutOfBandParameter 543 enum { 544 kNotifyApps, 545 kNotifyPriority, 546 kNotifyCapabilityChangeApps, 547 kNotifyCapabilityChangePriority 548 }; 549 550 typedef bool (*IOPMMessageFilter)( 551 void * target, void * object, void * arg1, void * arg2, void * arg3 ); 552 553 // used for applyToInterested 554 struct IOPMInterestContext { 555 OSArray * responseArray; 556 OSArray * notifyClients; 557 uint16_t serialNumber; 558 uint8_t isPreChange; 559 uint8_t enableTracing; 560 uint32_t maxTimeRequested; 561 uint32_t messageType; 562 uint32_t notifyType; 563 uint32_t skippedInDark; 564 uint32_t notSkippedInDark; 565 IOService * us; 566 IOPMPowerStateIndex stateNumber; 567 IOPMPowerFlags stateFlags; 568 IOPMPowerChangeFlags changeFlags; 569 IOPMMessageFilter messageFilter; 570 }; 571 572 // track client ack requirements 573 class IOPMClientAck : public OSObject { 574 OSDeclareDefaultStructors( IOPMClientAck ); 575 public: 576 uint64_t completionTimestamp; // absolute time 577 uint32_t maxTimeRequested; // microseconds 578 }; 579 580 // assertPMDriverCall() options 581 enum { 582 kIOPMDriverCallNoInactiveCheck = 1 583 }; 584 585 // assertPMDriverCall() method 586 enum { 587 kIOPMDriverCallMethodUnknown = 0, 588 kIOPMDriverCallMethodSetPowerState = 1, 589 kIOPMDriverCallMethodWillChange = 2, 590 kIOPMDriverCallMethodDidChange = 3, 591 kIOPMDriverCallMethodChangeDone = 4, 592 kIOPMDriverCallMethodSetAggressive = 5, 593 kIOPMDriverCallMethodMaxCapabilityForDomainState = 6, 594 kIOPMDriverCallMethodInitialPowerStateForDomainState = 7 595 }; 596 597 //****************************************************************************** 598 // PM Statistics & Diagnostics 599 //****************************************************************************** 600 601 extern OSPtr<const OSSymbol> gIOPMStatsResponseTimedOut; 602 extern OSPtr<const OSSymbol> gIOPMStatsResponseCancel; 603 extern OSPtr<const OSSymbol> gIOPMStatsResponseSlow; 604 extern OSPtr<const OSSymbol> gIOPMStatsResponsePrompt; 605 extern OSPtr<const OSSymbol> gIOPMStatsDriverPSChangeSlow; 606 607 //****************************************************************************** 608 // IOPMRequest 609 //****************************************************************************** 610 611 class IOPMRequest : public IOCommand 612 { 613 OSDeclareDefaultStructors( IOPMRequest ); 614 615 protected: 616 IOService * fTarget; // request target 617 IOPMRequest * fRequestNext; // the next request in the chain 618 IOPMRequest * fRequestRoot; // the root request in the call tree 619 uint32_t fWorkWaitCount; // execution blocked if non-zero 620 uint32_t fFreeWaitCount; // completion blocked if non-zero 621 uint64_t fTimestamp; // MCTU 622 uint32_t fRequestType; // request type 623 bool fIsQuiesceBlocker; 624 625 IOPMCompletionAction fCompletionAction; 626 void * fCompletionTarget; 627 void * fCompletionParam; 628 629 public: 630 uint32_t fTag; 631 void * fArg0; 632 void * fArg1; 633 void * fArg2; 634 635 inline bool isWorkBlocked(void)636 isWorkBlocked( void ) const 637 { 638 return fWorkWaitCount != 0; 639 } 640 641 inline bool isFreeBlocked(void)642 isFreeBlocked( void ) const 643 { 644 return fFreeWaitCount != 0; 645 } 646 647 inline IOPMRequest * getNextRequest(void)648 getNextRequest( void ) const 649 { 650 return fRequestNext; 651 } 652 653 inline IOPMRequest * getRootRequest(void)654 getRootRequest( void ) const 655 { 656 if (fRequestRoot) { 657 return fRequestRoot; 658 } 659 #if NOT_READY 660 if (fCompletionAction) { 661 return (IOPMRequest *) this; 662 } 663 #endif 664 return NULL; 665 } 666 667 inline uint32_t getType(void)668 getType( void ) const 669 { 670 return fRequestType; 671 } 672 673 inline uint32_t getTag(void)674 getTag( void ) const 675 { 676 return fTag; 677 } 678 679 inline bool isReplyType(void)680 isReplyType( void ) const 681 { 682 return fRequestType > kIOPMRequestTypeReplyStart; 683 } 684 685 inline IOService * getTarget(void)686 getTarget( void ) const 687 { 688 return fTarget; 689 } 690 691 inline bool isQuiesceBlocker(void)692 isQuiesceBlocker( void ) const 693 { 694 return fIsQuiesceBlocker; 695 } 696 697 inline bool isQuiesceType(void)698 isQuiesceType( void ) const 699 { 700 return (kIOPMRequestTypeQuiescePowerTree == fRequestType) && 701 (fCompletionAction != NULL) && (fCompletionTarget != NULL); 702 } 703 704 inline void installCompletionAction(void * target,IOPMCompletionAction action,void * param)705 installCompletionAction( 706 void * target, 707 IOPMCompletionAction action, 708 void * param ) 709 { 710 fCompletionTarget = target; 711 fCompletionAction = action; 712 fCompletionParam = param; 713 } 714 715 inline void setTimestamp(uint64_t time)716 setTimestamp( uint64_t time ) 717 { 718 fTimestamp = time; 719 } 720 721 inline uint64_t getTimestamp(void)722 getTimestamp( void ) const 723 { 724 return fTimestamp; 725 } 726 727 static IOPMRequest * create( void ); 728 bool init( IOService * owner, IOOptionBits type ); 729 void reset( void ); 730 bool attachNextRequest( IOPMRequest * next ); 731 bool detachNextRequest( void ); 732 bool attachRootRequest( IOPMRequest * root ); 733 bool detachRootRequest( void ); 734 }; 735 736 //****************************************************************************** 737 // IOPMRequestQueue 738 //****************************************************************************** 739 740 class IOPMRequestQueue : public IOEventSource 741 { 742 OSDeclareDefaultStructors( IOPMRequestQueue ); 743 744 public: 745 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMRequestQueue * ); 746 747 protected: 748 queue_head_t fQueue; 749 IOLock * fLock; 750 751 enum { kMaxDequeueCount = 256 }; 752 753 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 754 virtual void free( void ) APPLE_KEXT_OVERRIDE; 755 virtual bool init( IOService * inOwner, Action inAction ); 756 757 public: 758 static IOPMRequestQueue * create( IOService * inOwner, Action inAction ); 759 void queuePMRequest( LIBKERN_CONSUMED IOPMRequest * request ); 760 void queuePMRequestChain( IOPMRequest ** requests, IOItemCount count ); 761 }; 762 763 //****************************************************************************** 764 // IOPMWorkQueue 765 //****************************************************************************** 766 767 #define WORK_QUEUE_STATS 1 768 769 class IOPMWorkQueue : public IOEventSource 770 { 771 OSDeclareDefaultStructors( IOPMWorkQueue ); 772 773 public: 774 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMWorkQueue * ); 775 776 #if WORK_QUEUE_STATS 777 uint64_t fStatCheckForWork; 778 uint64_t fStatScanEntries; 779 uint64_t fStatQueueEmpty; 780 uint64_t fStatNoWorkDone; 781 #endif 782 783 protected: 784 queue_head_t fWorkQueue; 785 Action fInvokeAction; 786 Action fRetireAction; 787 uint32_t fQueueLength; 788 uint32_t fConsumerCount; 789 volatile uint32_t fProducerCount; 790 IOPMRequest * fQuiesceRequest; 791 AbsoluteTime fQuiesceStartTime; 792 AbsoluteTime fQuiesceFinishTime; 793 794 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 795 virtual bool init( IOService * inOwner, Action invoke, Action retire ); 796 bool checkRequestQueue( queue_head_t * queue, bool * empty ); 797 798 public: 799 static IOPMWorkQueue * create( IOService * inOwner, Action invoke, Action retire ); 800 bool queuePMRequest( IOPMRequest * request, IOServicePM * pwrMgt ); 801 void signalWorkAvailable( void ); 802 void incrementProducerCount( void ); 803 void attachQuiesceRequest( IOPMRequest * quiesceRequest ); 804 void finishQuiesceRequest( IOPMRequest * quiesceRequest ); 805 }; 806 807 //****************************************************************************** 808 // IOPMCompletionQueue 809 //****************************************************************************** 810 811 class IOPMCompletionQueue : public IOEventSource 812 { 813 OSDeclareDefaultStructors( IOPMCompletionQueue ); 814 815 public: 816 typedef bool (*Action)( IOService *, IOPMRequest *, IOPMCompletionQueue * ); 817 818 protected: 819 queue_head_t fQueue; 820 821 virtual bool checkForWork( void ) APPLE_KEXT_OVERRIDE; 822 virtual bool init( IOService * inOwner, Action inAction ); 823 824 public: 825 static IOPMCompletionQueue * create( IOService * inOwner, Action inAction ); 826 bool queuePMRequest( IOPMRequest * request ); 827 }; 828 829 #endif /* !_IOKIT_IOSERVICEPMPRIVATE_H */ 830