38#if defined(EVENT_TRACING)
39#include "PowerPolicyStateMachine.tmh"
61 #define ASSERT_PWR_POL_STATE(_This, _State) \
62 ASSERT((_This)->m_Device->GetDevicePowerPolicyState() == (_State))
64 #define ASSERT_PWR_POL_STATE(_This, _State) (0)
67#if FX_STATE_MACHINE_VERIFY
68 #define VALIDATE_PWR_POL_STATE(_CurrentState, _NewState) \
69 ValidatePwrPolStateEntryFunctionReturnValue((_CurrentState), (_NewState))
71 #define VALIDATE_PWR_POL_STATE(_CurrentState, _NewState) (0)
2115 LONG idleTimeoutStatusSnapshot;
2116 LONG updatedIdleTimeoutStatus;
2117 LONG preInterlockedIdleTimeoutStatus;
2127 if (0 != (idleTimeoutStatusSnapshot &
Flag)) {
2146 updatedIdleTimeoutStatus = idleTimeoutStatusSnapshot |
Flag;
2150 updatedIdleTimeoutStatus,
2151 idleTimeoutStatusSnapshot
2153 if (preInterlockedIdleTimeoutStatus != idleTimeoutStatusSnapshot) {
2155 if (0 != (preInterlockedIdleTimeoutStatus &
2203 switch (statusUpdateResult) {
2212 "WDFDEVICE %p !devobj %p If the power framework is made "
2213 "responsible for determining the idle timeout, then the "
2214 "first call to assign S0-idle policy must occur before the "
2215 "first start IRP is completed. However, in this case, it "
2216 "occurred after the first start IRP was completed. "
2219 device->GetDeviceObject(),
2235 "WDFDEVICE %p !devobj %p Calls to assign S0-idle settings "
2236 "and to specify power framework settings are happening in "
2237 "parallel. The driver needs to serialize these calls with "
2238 "respect to each other. %!STATUS!.",
2240 device->GetDeviceObject(),
2254 "IdleTimeoutManagement::UseSystemManagedIdleTimeout was "
2255 "called more than once\n",
FALSE);
2272 ASSERTMSG(
"Unexpected IdleTimeoutStatusUpdateResult value\n",
2294 LONG idleTimeoutSnapshot;
2295 LONG idleTimeoutStatus;
2296 LONG idleTimeoutPreviousStatus;
2320 if (idleTimeoutPreviousStatus != idleTimeoutSnapshot) {
2327 "WDFDEVICE %p !devobj %p The driver's S0-idle settings and/or power"
2328 " framework settings did not take effect because they were supplied"
2329 " too late. The driver must ensure that the settings are provided "
2330 "before the first start IRP is completed.",
2332 device->GetDeviceObject()
2347 "WDFDEVICE %p !devobj %p The driver specified power framework "
2348 "settings, but did not opt for system-managed idle timeout.",
2350 device->GetDeviceObject()
2407 if (
NULL != oldPoxSettings) {
2416 "WDFDEVICE %p !devobj %p The driver attempted to specify power "
2417 "framework settings more than once. %!STATUS!.",
2419 device->GetDeviceObject(),
2425 settingsSuccessfullySaved =
TRUE;
2435 switch (statusUpdateResult) {
2444 "WDFDEVICE %p !devobj %p Power framework settings must be "
2445 "specified before the first start IRP is completed. %!STATUS!.",
2447 device->GetDeviceObject(),
2464 "WDFDEVICE %p !devobj %p Calls to assign S0-idle settings and "
2465 "to specify power framework settings are happening in parallel."
2466 " The driver needs to serialize these calls with respect to "
2467 "each other. %!STATUS!.",
2469 device->GetDeviceObject(),
2486 "Attempt to set the IdleTimeoutPoxSettingsSpecified flag more "
2487 "than once\n",
FALSE);
2500 ASSERTMSG(
"Unexpected IdleTimeoutStatusUpdateResult value\n",
2514 if (settingsSuccessfullySaved) {
2578 if (pInfo ==
NULL) {
2609 ) : m_PoxInterface(PkgPnp)
2925 "WDFDEVICE 0x%p !devobj 0x%p current pwr pol state "
2926 "%!WDF_DEVICE_POWER_POLICY_STATE! dropping event "
2927 "%!FxPowerPolicyEvent! because the Event is already enqueued.",
2943 ASSERT(!
"The Power queue is full. This shouldn't be able to happen.");
2950 "WDFDEVICE 0x%p !devobj 0x%p current pwr pol state "
2951 "%!WDF_DEVICE_POWER_POLICY_STATE! dropping event "
2952 "%!FxPowerPolicyEvent! because of a closed queue",
3001 ProcessOnDifferentThread
3009 if (FxWaitLockInternal::IsLockAcquired(
status)) {
3026 info.Evaluate(
this);
3060 This->m_PowerPolicyMachine.m_StateMachineLock.AcquireLock(
3061 This->GetDriverGlobals()
3067 This->PowerPolicyProcessEventInner(
Info);
3078 This->m_PowerPolicyMachine.m_StateMachineLock.ReleaseLock(
3079 This->GetDriverGlobals()
3134 if (
entry->StateInfo.Bits.QueueOpen ==
FALSE) {
3161 if (
entry->FirstTargetState.PowerPolicyEvent ==
event) {
3162 newState =
entry->FirstTargetState.TargetState;
3166 else if (
entry->OtherTargetStates !=
NULL) {
3170 if (
entry->OtherTargetStates[
i].PowerPolicyEvent ==
event) {
3171 newState =
entry->OtherTargetStates[
i].TargetState;
3185 "WDFDEVICE 0x%p !devobj 0x%p current pwr pol state "
3186 "%!WDF_DEVICE_POWER_POLICY_STATE! dropping event "
3191 if ((
entry->StateInfo.Bits.KnownDroppedEvents &
event) == 0) {
3196 "WDFDEVICE 0x%p !devobj 0x%p current state "
3197 "%!WDF_DEVICE_POWER_POLICY_STATE!, policy event "
3198 "%!FxPowerPolicyEvent! is not a known dropped "
3199 "event, known dropped events are %!FxPowerPolicyEvent!",
3202 event,
entry->StateInfo.Bits.KnownDroppedEvents);
3274#pragma prefast(suppress:__WARNING_DEREF_NULL_PTR, "The current power policy state will always be in the table so entry will never be NULL")
3331 for (
i = 0;
i <
entry->TargetStatesCount;
i++) {
3332 if (
event ==
entry->TargetStates[
i].PowerPolicyEvent) {
3339 entry->TargetStates[
i].TargetState);
3372 newState = NewState;
3377 "WDFDEVICE 0x%p !devobj 0x%p entering power policy state "
3378 "%!WDF_DEVICE_POWER_POLICY_STATE! from "
3389 data.Data.LeaveState.CurrentState = currentState;
3390 data.Data.LeaveState.NewState = newState;
3408 data.Data.EnterState.CurrentState = currentState;
3409 data.Data.EnterState.NewState = newState;
3418 currentState = newState;
3427 newState =
entry->StateFunc(
this);
3447 data.Data.PostProcessState.CurrentState = currentState;
3549 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Start();
3594 This->m_PowerPolicyMachine.m_Owner->
3595 m_IdleSettings.m_TimeoutMgmt.FreezeIdleTimeoutManagementStatus(
3596 This->GetDriverGlobals()
3599 status =
This->m_PowerPolicyMachine.m_Owner->
3600 m_PoxInterface.InitializeComponents();
3682 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Stop();
3692 Mx::MxLowerIrql(
irql);
3704 This->PowerPolicyChildrenCanPowerUp();
3715 This->m_PowerPolicyMachine.m_Owner->m_PoxInterface.UpdateIdleTimeoutHint();
3717 if (
This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.Enabled) {
3718 if (
This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.WakeFromS0Capable) {
3746 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.EnableTimer();
3772 canPowerDown =
This->m_PowerPolicyMachine.m_Owner->
3773 m_PoxInterface.DeclareComponentIdle();
3781 return (canPowerDown ?
3805 This->m_PowerPolicyMachine.m_Owner->
3806 m_PoxInterface.RequestComponentActive();
3837 This->m_PowerPolicyMachine.m_Owner->
3838 m_PoxInterface.RequestComponentActive();
3869 This->m_PowerPolicyMachine.m_Owner->
3870 m_PoxInterface.RequestComponentActive();
3889 notifyPowerDownStatus =
This->m_PowerPolicyMachine.m_Owner->
3890 m_PoxInterface.NotifyDevicePowerDown();
3901 poweredDown =
This->PowerPolicyCanIdlePowerDown(
3902 This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.DxState
3905 if (poweredDown ==
FALSE) {
3968 if (
This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.QueryReturnToIdle()) {
3988 This->m_PowerPolicyMachine.m_Owner->
3989 m_PoxInterface.RequestComponentActive();
4022 This->m_PowerPolicyMachine.m_Owner->
4023 m_PoxInterface.DeviceIsPoweredOn();
4040 systemState =
This->PowerPolicyGetPendingSystemState();
4042 if (
This->PowerPolicyIsWakeEnabled() &&
4043 This->PowerPolicyCanWakeFromSystemState(systemState)) {
4061 result =
This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer();
4075 "Failed to allocate D0 request to disarm from wake from S0 to allow "
4076 "arm for wake from Sx, %!STATUS!",
status);
4140 This->PowerPolicyCompleteSystemPowerIrp();
4209 ASSERT(
This->PowerPolicyCanWakeFromSystemState(
4210 This->PowerPolicyGetPendingSystemState()
4213 wakeReason =
This->PowerPolicyGetCurrentWakeReason();
4215 status =
This->m_PowerPolicyMachine.m_Owner->m_DeviceArmWakeFromSx.Invoke(
4216 This->m_Device->GetHandle(),
4224 "WDFDEVICE %p Failed to arm for wake from Sx, %!STATUS!",
4234 if (
This->m_Device->IsPdo()) {
4235 status =
This->PowerEnableWakeAtBusOverload();
4239 "WDFDEVICE %p Failed to Enable Wake at Bus, %!STATUS!",
4260 "reverting arm for wake from Sx due to failure to allocate wait wake "
4261 "request or wait wake request completed immeidately. Device will *NOT* "
4262 "be armed for wake from Sx");
4271 This->PowerPolicyDisarmWakeFromSx();
4276 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4277 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4290 This->PowerPolicyCompleteSystemPowerIrp();
4303 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4304 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4323 This->m_SystemWokenByWakeInterrupt =
TRUE;
4325 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4326 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4366 if (
This->m_Device->IsPdo()) {
4367 This->PowerDisableWakeAtBusOverload();
4370 This->PowerPolicyDisarmWakeFromSx();
4407 if (
This->m_Device->IsPdo()) {
4408 This->PowerDisableWakeAtBusOverload();
4411 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromSxTriggered.Invoke(
4412 This->m_Device->GetHandle()
4415 This->PowerPolicyDisarmWakeFromSx();
4445 ASSERT(
This->PowerPolicyCanWakeFromSystemState(
4446 This->PowerPolicyGetPendingSystemState()
4449 wakeReason =
This->PowerPolicyGetCurrentWakeReason();
4451 status =
This->m_PowerPolicyMachine.m_Owner->m_DeviceArmWakeFromSx.Invoke(
4452 This->m_Device->GetHandle(),
4460 "WDFDEVICE %p Failed to arm for wake from Sx, %!STATUS!",
4470 if (
This->m_Device->IsPdo()) {
4471 status =
This->PowerEnableWakeAtBusOverload();
4475 "WDFDEVICE %p Failed to Enable Wake at Bus, %!STATUS!",
4496 "reverting arm for wake from Sx due to failure to allocate wait wake "
4497 "request or wait wake request completed immeidately. Device will *NOT* "
4498 "be armed for wake from Sx");
4507 This->PowerPolicyDisarmWakeFromSx();
4512 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4513 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4542 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4543 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4571 This->PowerPolicyCompleteSystemPowerIrp();
4583 This->PowerPolicyCompleteSystemPowerIrp();
4595 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4596 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4615 This->m_SystemWokenByWakeInterrupt =
TRUE;
4617 if (
This->PowerPolicyCancelWaitWake() ==
FALSE &&
4618 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) {
4656 if (
This->m_Device->IsPdo()) {
4657 This->PowerDisableWakeAtBusOverload();
4660 This->PowerPolicyDisarmWakeFromSx();
4695 if (
This->m_Device->IsPdo()) {
4696 This->PowerDisableWakeAtBusOverload();
4699 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromSxTriggered.Invoke(
4700 This->m_Device->GetHandle()
4703 This->PowerPolicyDisarmWakeFromSx();
4736 This->m_PowerPolicyMachine.m_Owner->
4737 m_PoxInterface.SimulateDevicePowerRequired();
4742 This->m_PowerPolicyMachine.m_Owner->
4743 m_PoxInterface.DeviceIsPoweredOn();
4779 This->m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount > 0) {
4782 "WDFDEVICE %p powering down before child devices have powered down. "
4783 "This usually indicates a faulty child device that completed the Sx "
4784 "irp before sending the Dx irp",
4785 This->m_Device->GetHandle());
4788 This->m_Device->GetDriverGlobals());
4796 This->m_PowerPolicyMachine.m_Owner->
4797 m_PoxInterface.SimulateDevicePowerNotRequired();
4803 notifyPowerDownStatus =
This->m_PowerPolicyMachine.m_Owner->
4804 m_PoxInterface.NotifyDevicePowerDown();
4814 systemState =
This->PowerPolicyGetPendingSystemState();
4816 if (
This->PowerPolicyIsWakeEnabled() &&
4817 This->PowerPolicyCanWakeFromSystemState(systemState)) {
4849 This->m_PowerPolicyMachine.m_Owner->m_IdealDxStateForSx;
4859 This->PowerPolicyGetPendingSystemState(),
4860 This->m_PowerPolicyMachine.m_Owner->m_SystemToDeviceStateMap
4867 if (dxState < dxMappedState) {
4868 dxState = dxMappedState;