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