1 /*++ 2 3 Copyright (c) Microsoft. All rights reserved. 4 5 Module Name: 6 7 PowerPolicyStateMachine.cpp 8 9 Abstract: 10 11 This module implements the Power Policy state machine for the driver 12 framework. This code was split out from FxPkgPnp.cpp. 13 14 Author: 15 16 17 18 19 Environment: 20 21 Both kernel and user mode 22 23 Revision History: 24 25 26 27 --*/ 28 29 #include "pnppriv.hpp" 30 31 #if FX_IS_KERNEL_MODE 32 #include <usbdrivr.h> 33 #endif 34 35 #include "fxusbidleinfo.hpp" 36 37 extern "C" { 38 #if defined(EVENT_TRACING) 39 #include "PowerPolicyStateMachine.tmh" 40 #endif 41 } 42 43 // 44 // The Power Policy State Machine 45 // 46 // This state machine responds to the following events: 47 // 48 // PowerUp 49 // PowerDown 50 // PowerPolicyStart 51 // PowerPolicyStop 52 // IRP_MN_SET_POWER -- System State S0 53 // IRP_MN_SET_POWER -- System State Sx 54 // PowerTimeoutExpired 55 // IoPresent 56 // IRP_MN_WAIT_WAKE Complete 57 // IRP_MN_WAIT_WAKE Failed 58 // 59 60 #if FX_SUPER_DBG 61 #define ASSERT_PWR_POL_STATE(_This, _State) \ 62 ASSERT((_This)->m_Device->GetDevicePowerPolicyState() == (_State)) 63 #else 64 #define ASSERT_PWR_POL_STATE(_This, _State) (0) 65 #endif 66 67 #if FX_STATE_MACHINE_VERIFY 68 #define VALIDATE_PWR_POL_STATE(_CurrentState, _NewState) \ 69 ValidatePwrPolStateEntryFunctionReturnValue((_CurrentState), (_NewState)) 70 #else 71 #define VALIDATE_PWR_POL_STATE(_CurrentState, _NewState) (0) 72 #endif //FX_STATE_MACHINE_VERIFY 73 74 // @@SMVERIFY_SPLIT_BEGIN 75 76 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolObjectCreatedOtherStates[] = 77 { 78 { PwrPolRemove, WdfDevStatePwrPolRemoved DEBUGGED_EVENT }, 79 { PwrPolNull, WdfDevStatePwrPolNull }, 80 }; 81 82 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStartingOtherStates[] = 83 { 84 { PwrPolPowerUpFailed, WdfDevStatePwrPolStartingFailed DEBUGGED_EVENT }, 85 { PwrPolNull, WdfDevStatePwrPolNull }, 86 }; 87 88 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStartedIdleCapableOtherStates[] = 89 { 90 { PwrPolSx, WdfDevStatePwrPolStartedIdleCapableCancelTimerForSleep DEBUGGED_EVENT }, 91 { PwrPolStop, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 92 { PwrPolSurpriseRemove,WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 93 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolStartedCancelTimer DEBUGGED_EVENT }, 94 { PwrPolNull, WdfDevStatePwrPolNull }, 95 }; 96 97 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolIdleCapableDeviceIdleOtherStates[] = 98 { 99 { PwrPolSx, WdfDevStatePwrPolDeviceIdleSleeping DEBUGGED_EVENT }, 100 { PwrPolStop, WdfDevStatePwrPolDeviceIdleStopping DEBUGGED_EVENT }, 101 { PwrPolSurpriseRemove,WdfDevStatePwrPolDeviceIdleStopping DEBUGGED_EVENT }, 102 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolDeviceIdleReturnToActive TRAP_ON_EVENT }, 103 { PwrPolIoPresent, WdfDevStatePwrPolDeviceIdleReturnToActive DEBUGGED_EVENT }, 104 { PwrPolNull, WdfDevStatePwrPolNull }, 105 }; 106 107 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredNoWakeOtherStates[] = 108 { 109 { PwrPolPowerDown, WdfDevStatePwrPolTimerExpiredNoWakePowerDownNotProcessed TRAP_ON_EVENT }, 110 { PwrPolNull, WdfDevStatePwrPolNull }, 111 }; 112 113 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredNoWakeCompletePowerDownOtherStates[] = 114 { 115 { PwrPolPowerDownFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 116 { PwrPolNull, WdfDevStatePwrPolNull }, 117 }; 118 119 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWaitingUnarmedOtherStates[] = 120 { 121 { PwrPolSx, WdfDevStatePwrPolSystemSleepFromDeviceWaitingUnarmed DEBUGGED_EVENT }, 122 { PwrPolStop, WdfDevStatePwrPolStoppingResetDevice DEBUGGED_EVENT }, 123 { PwrPolSurpriseRemove, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 124 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolS0NoWakePowerUp DEBUGGED_EVENT }, 125 { PwrPolDevicePowerRequired, WdfDevStatePwrPolS0NoWakePowerUp DEBUGGED_EVENT }, 126 { PwrPolNull, WdfDevStatePwrPolNull }, 127 }; 128 129 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolS0NoWakePowerUpOtherStates[] = 130 { 131 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 132 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 133 { PwrPolNull, WdfDevStatePwrPolNull }, 134 }; 135 136 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolS0NoWakeCompletePowerUpOtherStates[] = 137 { 138 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 139 { PwrPolNull, WdfDevStatePwrPolNull }, 140 }; 141 142 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemSleepNeedWakeOtherStates[] = 143 { 144 { PwrPolPowerUpFailed, WdfDevStatePwrPolSystemSleepPowerRequestFailed DEBUGGED_EVENT }, 145 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolPowerUpForSystemSleepNotSeen TRAP_ON_EVENT }, 146 { PwrPolNull, WdfDevStatePwrPolNull }, 147 }; 148 149 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemSleepNeedWakeCompletePowerUpOtherStates[] = 150 { 151 { PwrPolPowerUpFailed, WdfDevStatePwrPolSystemSleepPowerRequestFailed DEBUGGED_EVENT }, 152 { PwrPolNull, WdfDevStatePwrPolNull }, 153 }; 154 155 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemAsleepWakeArmedOtherStates[] = 156 { 157 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeTriggered DEBUGGED_EVENT }, 158 { PwrPolWakeInterruptFired, WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFired DEBUGGED_EVENT }, 159 { PwrPolNull, WdfDevStatePwrPolNull }, 160 }; 161 162 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemAsleepWakeArmedNPOtherStates[] = 163 { 164 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredNP DEBUGGED_EVENT }, 165 { PwrPolWakeInterruptFired, WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFiredNP TRAP_ON_EVENT }, 166 { PwrPolNull, WdfDevStatePwrPolNull }, 167 }; 168 169 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceToD0OtherStates[] = 170 { 171 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 172 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 173 { PwrPolNull, WdfDevStatePwrPolNull }, 174 }; 175 176 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceToD0CompletePowerUpOtherStates[] = 177 { 178 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 179 { PwrPolNull, WdfDevStatePwrPolNull }, 180 }; 181 182 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStartedWakeCapableOtherStates[] = 183 { 184 { PwrPolSx, WdfDevStatePwrPolStartedWakeCapableCancelTimerForSleep DEBUGGED_EVENT }, 185 { PwrPolStop, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 186 { PwrPolSurpriseRemove, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 187 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolStartedCancelTimer DEBUGGED_EVENT }, 188 { PwrPolNull, WdfDevStatePwrPolNull }, 189 }; 190 191 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWakeCapableDeviceIdleOtherStates[] = 192 { 193 { PwrPolSx, WdfDevStatePwrPolDeviceIdleSleeping DEBUGGED_EVENT }, 194 { PwrPolStop, WdfDevStatePwrPolDeviceIdleStopping TRAP_ON_EVENT }, 195 { PwrPolSurpriseRemove,WdfDevStatePwrPolDeviceIdleStopping DEBUGGED_EVENT }, 196 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolDeviceIdleReturnToActive TRAP_ON_EVENT }, 197 { PwrPolIoPresent, WdfDevStatePwrPolDeviceIdleReturnToActive DEBUGGED_EVENT }, 198 { PwrPolNull, WdfDevStatePwrPolNull }, 199 }; 200 201 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakePowerDownOtherStates[] = 202 { 203 { PwrPolPowerDown, WdfDevStatePwrPolSleepingPowerDownNotProcessed TRAP_ON_EVENT }, 204 { PwrPolNull, WdfDevStatePwrPolNull }, 205 }; 206 207 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownOtherStates[] = 208 { 209 { PwrPolPowerDown, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownNotProcessed TRAP_ON_EVENT }, 210 { PwrPolNull, WdfDevStatePwrPolNull }, 211 }; 212 213 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableSendWakeOtherStates[] = 214 { 215 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCompletedDisarm DEBUGGED_EVENT }, 216 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeSucceeded DEBUGGED_EVENT }, 217 { PwrPolNull, WdfDevStatePwrPolNull }, 218 }; 219 220 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableUsbSSOtherStates[] = 221 { 222 { PwrPolSx, WdfDevStatePwrPolStartedWakeCapableSleepingUsbSS DEBUGGED_EVENT }, 223 { PwrPolStop, WdfDevStatePwrPolStoppingCancelUsbSS TRAP_ON_EVENT }, 224 { PwrPolSurpriseRemove, WdfDevStatePwrPolStoppingCancelUsbSS DEBUGGED_EVENT }, 225 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolWakeCapableUsbSSCompleted DEBUGGED_EVENT }, 226 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolCancelUsbSS DEBUGGED_EVENT }, 227 { PwrPolIoPresent, WdfDevStatePwrPolCancelUsbSS DEBUGGED_EVENT }, 228 { PwrPolDevicePowerRequired, WdfDevStatePwrPolCancelUsbSS DEBUGGED_EVENT }, 229 { PwrPolNull, WdfDevStatePwrPolNull }, 230 }; 231 232 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWaitingArmedOtherStates[] = 233 { 234 { PwrPolSx, WdfDevStatePwrPolCancelingUsbSSForSystemSleep DEBUGGED_EVENT }, 235 { PwrPolWakeSuccess, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS DEBUGGED_EVENT }, 236 { PwrPolWakeFailed, WdfDevStatePwrPolWaitingArmedWakeFailedCancelUsbSS DEBUGGED_EVENT }, 237 { PwrPolStop, WdfDevStatePwrPolStoppingD0CancelUsbSS DEBUGGED_EVENT }, 238 { PwrPolSurpriseRemove, WdfDevStatePwrPolWaitingArmedStoppingCancelUsbSS DEBUGGED_EVENT }, 239 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolWaitingArmedIoPresentCancelUsbSS DEBUGGED_EVENT }, 240 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolIoPresentArmed TRAP_ON_EVENT }, 241 { PwrPolDevicePowerRequired, WdfDevStatePwrPolWaitingArmedIoPresentCancelUsbSS DEBUGGED_EVENT }, 242 { PwrPolWakeInterruptFired, WdfDevStatePwrPolWaitingArmedWakeInterruptFired DEBUGGED_EVENT }, 243 { PwrPolNull, WdfDevStatePwrPolNull }, 244 }; 245 246 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolDisarmingWakeForSystemSleepCompletePowerUpOtherStates[] = 247 { 248 { PwrPolPowerUpFailed, WdfDevStatePwrPolPowerUpForSystemSleepFailed DEBUGGED_EVENT }, 249 { PwrPolNull, WdfDevStatePwrPolNull }, 250 }; 251 252 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolCancelingWakeForSystemSleepWakeCanceledOtherStates[] = 253 { 254 { PwrPolPowerUpFailed, WdfDevStatePwrPolPowerUpForSystemSleepFailed DEBUGGED_EVENT }, 255 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolPowerUpForSystemSleepNotSeen TRAP_ON_EVENT }, 256 { PwrPolNull, WdfDevStatePwrPolNull }, 257 }; 258 259 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWokeFromS0OtherStates[] = 260 { 261 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 262 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 263 { PwrPolNull, WdfDevStatePwrPolNull }, 264 }; 265 266 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingResetDeviceOtherStates[] = 267 { 268 { PwrPolPowerUpFailed, WdfDevStatePwrPolStoppingResetDeviceFailed DEBUGGED_EVENT }, 269 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 270 { PwrPolNull, WdfDevStatePwrPolNull }, 271 }; 272 273 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingResetDeviceCompletePowerUpOtherStates[] = 274 { 275 { PwrPolPowerUpFailed, WdfDevStatePwrPolStoppingResetDeviceFailed DEBUGGED_EVENT }, 276 { PwrPolNull, WdfDevStatePwrPolNull }, 277 }; 278 279 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingD0OtherStates[] = 280 { 281 { PwrPolPowerUpFailed, WdfDevStatePwrPolStoppingD0Failed DEBUGGED_EVENT }, 282 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 283 { PwrPolNull, WdfDevStatePwrPolNull }, 284 }; 285 286 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingDisarmWakeOtherStates[] = 287 { 288 { PwrPolPowerUpFailed, WdfDevStatePwrPolStoppingD0Failed DEBUGGED_EVENT }, 289 { PwrPolNull, WdfDevStatePwrPolNull }, 290 }; 291 292 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingDisarmWakeCancelWakeOtherStates[] = 293 { 294 { PwrPolWakeSuccess, WdfDevStatePwrPolStoppingDisarmWakeWakeCanceled DEBUGGED_EVENT }, 295 { PwrPolNull, WdfDevStatePwrPolNull }, 296 }; 297 298 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStartedOtherStates[] = 299 { 300 { PwrPolStop, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 301 { PwrPolSurpriseRemove, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 302 { PwrPolS0IdlePolicyChanged, WdfDevStatePwrPolStartingDecideS0Wake DEBUGGED_EVENT }, 303 { PwrPolNull, WdfDevStatePwrPolNull }, 304 }; 305 306 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStartedWaitForIdleTimeoutOtherStates[] = 307 { 308 { PwrPolStop, WdfDevStatePwrPolStoppingWaitForIdleTimeout TRAP_ON_EVENT }, 309 { PwrPolSurpriseRemove, WdfDevStatePwrPolStoppingWaitForIdleTimeout TRAP_ON_EVENT }, 310 { PwrPolNull, WdfDevStatePwrPolNull }, 311 }; 312 313 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolIoPresentArmedOtherStates[] = 314 { 315 { PwrPolWakeSuccess, WdfDevStatePwrPolIoPresentArmedWakeCanceled DEBUGGED_EVENT }, 316 { PwrPolNull, WdfDevStatePwrPolNull }, 317 }; 318 319 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolIoPresentArmedWakeCanceledOtherStates[] = 320 { 321 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 322 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 323 { PwrPolNull, WdfDevStatePwrPolNull }, 324 }; 325 326 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolS0WakeCompletePowerUpOtherStates[] = 327 { 328 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 329 { PwrPolNull, WdfDevStatePwrPolNull }, 330 }; 331 332 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeSucceededOtherStates[] = 333 { 334 { PwrPolPowerDownFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedUsbSS DEBUGGED_EVENT }, 335 { PwrPolNull, WdfDevStatePwrPolNull }, 336 }; 337 338 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeFailedOtherStates[] = 339 { 340 { PwrPolPowerDownFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedUsbSS DEBUGGED_EVENT }, 341 { PwrPolNull, WdfDevStatePwrPolNull }, 342 }; 343 344 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWakeOtherStates[] = 345 { 346 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled DEBUGGED_EVENT }, 347 { PwrPolNull, WdfDevStatePwrPolNull }, 348 }; 349 350 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolCancelingWakeForSystemSleepOtherStates[] = 351 { 352 { PwrPolWakeSuccess, WdfDevStatePwrPolCancelingWakeForSystemSleepWakeCanceled DEBUGGED_EVENT }, 353 { PwrPolNull, WdfDevStatePwrPolNull }, 354 }; 355 356 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeArrivedOtherStates[] = 357 { 358 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeCapableWakeSucceeded DEBUGGED_EVENT }, 359 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCapableWakeFailed DEBUGGED_EVENT }, 360 { PwrPolPowerDownFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedCancelWake DEBUGGED_EVENT }, 361 { PwrPolWakeInterruptFired, WdfDevStatePwrPolTimerExpiredWakeCapableWakeInterruptArrived }, 362 { PwrPolNull, WdfDevStatePwrPolNull }, 363 }; 364 365 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableCancelWakeOtherStates[] = 366 { 367 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCapableWakeCanceled DEBUGGED_EVENT }, 368 { PwrPolNull, WdfDevStatePwrPolNull }, 369 }; 370 371 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCompletedPowerDownOtherStates[] = 372 { 373 { PwrPolPowerDownFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 374 { PwrPolNull, WdfDevStatePwrPolNull }, 375 }; 376 377 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCompletedPowerUpOtherStates[] = 378 { 379 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 380 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 381 { PwrPolNull, WdfDevStatePwrPolNull }, 382 }; 383 384 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakeWakeArrivedOtherStates[] = 385 { 386 { PwrPolPowerDownFailed, WdfDevStatePwrPolSleepingWakePowerDownFailed DEBUGGED_EVENT }, 387 { PwrPolNull, WdfDevStatePwrPolNull }, 388 }; 389 390 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeTriggeredS0OtherStates[] = 391 { 392 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 393 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 394 { PwrPolNull, WdfDevStatePwrPolNull }, 395 }; 396 397 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeTriggeredS0NPOtherStates[] = 398 { 399 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 400 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 401 { PwrPolNull, WdfDevStatePwrPolNull }, 402 }; 403 404 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeCompletePowerUpOtherStates[] = 405 { 406 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 407 { PwrPolNull, WdfDevStatePwrPolNull }, 408 }; 409 410 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingNoWakePowerDownOtherStates[] = 411 { 412 { PwrPolPowerDown, WdfDevStatePwrPolSleepingPowerDownNotProcessed TRAP_ON_EVENT }, 413 { PwrPolNull, WdfDevStatePwrPolNull }, 414 }; 415 416 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingNoWakeCompletePowerDownOtherStates[] = 417 { 418 { PwrPolPowerDownFailed, WdfDevStatePwrPolSystemSleepPowerRequestFailed DEBUGGED_EVENT }, 419 { PwrPolNull, WdfDevStatePwrPolNull }, 420 }; 421 422 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingSendWakeOtherStates[] = 423 { 424 { PwrPolWakeSuccess, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 425 { PwrPolWakeFailed, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 426 { PwrPolNull, WdfDevStatePwrPolNull }, 427 }; 428 429 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakeWakeArrivedNPOtherStates[] = 430 { 431 { PwrPolPowerDownFailed, WdfDevStatePwrPolSleepingWakePowerDownFailed DEBUGGED_EVENT }, 432 { PwrPolNull, WdfDevStatePwrPolNull }, 433 }; 434 435 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakePowerDownFailedOtherStates[] = 436 { 437 { PwrPolWakeFailed, WdfDevStatePwrPolSleepingWakePowerDownFailedWakeCanceled DEBUGGED_EVENT }, 438 { PwrPolNull, WdfDevStatePwrPolNull }, 439 }; 440 441 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledOtherStates[] = 442 { 443 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceled DEBUGGED_EVENT }, 444 { PwrPolNull, WdfDevStatePwrPolNull }, 445 }; 446 447 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledOtherStates[] = 448 { 449 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 450 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 451 { PwrPolNull, WdfDevStatePwrPolNull }, 452 }; 453 454 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledNPOtherStates[] = 455 { 456 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceledNP DEBUGGED_EVENT }, 457 { PwrPolNull, WdfDevStatePwrPolNull }, 458 }; 459 460 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNPOtherStates[] = 461 { 462 { PwrPolPowerUpFailed, WdfDevStatePwrPolDevicePowerRequestFailed DEBUGGED_EVENT }, 463 { PwrPolPowerUpNotSeen, WdfDevStatePwrPolDeviceD0PowerRequestFailed TRAP_ON_EVENT }, 464 { PwrPolNull, WdfDevStatePwrPolNull }, 465 }; 466 467 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolDevicePowerRequestFailedOtherStates[] = 468 { 469 { PwrPolSurpriseRemove, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 470 { PwrPolNull, WdfDevStatePwrPolNull }, 471 }; 472 473 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingOtherStates[] = 474 { 475 { PwrPolPowerDownFailed, WdfDevStatePwrPolStoppingFailed DEBUGGED_EVENT }, 476 { PwrPolNull,WdfDevStatePwrPolNull }, 477 }; 478 479 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppedOtherStates[] = 480 { 481 { PwrPolRemove, WdfDevStatePwrPolStoppedRemoving DEBUGGED_EVENT }, 482 { PwrPolNull, WdfDevStatePwrPolNull }, 483 }; 484 485 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolRestartingOtherStates[] = 486 { 487 { PwrPolPowerUpFailed, WdfDevStatePwrPolRestartingFailed DEBUGGED_EVENT }, 488 { PwrPolNull, WdfDevStatePwrPolNull }, 489 }; 490 491 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolStoppingCancelWakeOtherStates[] = 492 { 493 { PwrPolWakeSuccess, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 494 { PwrPolNull, WdfDevStatePwrPolNull }, 495 }; 496 497 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolCancelUsbSSOtherStates[] = 498 { 499 { PwrPolStop, WdfDevStatePwrPolStoppingWaitForUsbSSCompletion TRAP_ON_EVENT }, 500 { PwrPolSurpriseRemove, WdfDevStatePwrPolStoppingWaitForUsbSSCompletion TRAP_ON_EVENT }, 501 { PwrPolNull, WdfDevStatePwrPolNull }, 502 }; 503 504 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakeRevertArmWakeOtherStates[] = 505 { 506 { PwrPolWakeSuccess, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 507 { PwrPolNull, WdfDevStatePwrPolNull }, 508 }; 509 510 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSleepingWakeRevertArmWakeNPOtherStates[] = 511 { 512 { PwrPolWakeSuccess, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 513 { PwrPolNull, WdfDevStatePwrPolNull }, 514 }; 515 516 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolRemovedOtherStates[] = 517 { 518 { PwrPolRemove, WdfDevStatePwrPolRemoved DEBUGGED_EVENT }, 519 { PwrPolNull, WdfDevStatePwrPolNull }, 520 }; 521 522 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWaitingArmedWakeInterruptFiredOtherStates[] = 523 { 524 { PwrPolWakeSuccess, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS TRAP_ON_EVENT }, 525 { PwrPolNull, WdfDevStatePwrPolNull }, 526 }; 527 528 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeInterruptFiredOtherStates[] = 529 { 530 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeTriggered TRAP_ON_EVENT }, 531 { PwrPolNull, WdfDevStatePwrPolNull }, 532 }; 533 534 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolSystemWakeDeviceWakeInterruptFiredNPOtherStates[] = 535 { 536 { PwrPolWakeSuccess, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredNP TRAP_ON_EVENT }, 537 { PwrPolNull, WdfDevStatePwrPolNull }, 538 }; 539 540 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeInterruptArrivedOtherStates[] = 541 { 542 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeCapableWakeSucceeded TRAP_ON_EVENT }, 543 { PwrPolPowerDownFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrived TRAP_ON_EVENT }, 544 { PwrPolPowerDown, WdfDevStatePwrPolWaitingArmedWakeInterruptFiredDuringPowerDown }, 545 { PwrPolNull, WdfDevStatePwrPolNull }, 546 }; 547 548 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrivedOtherStates[] = 549 { 550 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled TRAP_ON_EVENT }, 551 { PwrPolNull, WdfDevStatePwrPolNull }, 552 }; 553 554 const POWER_POLICY_EVENT_TARGET_STATE FxPkgPnp::m_PowerPolWaitingArmedWakeInterruptFiredDuringPowerDownOtherStates[] = 555 { 556 { PwrPolWakeSuccess, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS TRAP_ON_EVENT }, 557 { PwrPolNull, WdfDevStatePwrPolNull }, 558 }; 559 560 const POWER_POLICY_STATE_TABLE FxPkgPnp::m_WdfPowerPolicyStates[] = 561 { 562 // transition function, 563 // { first target state }, 564 // other target states 565 // queue open, 566 567 // WdfDevStatePwrPolObjectCreated 568 { NULL, 569 { PwrPolStart, WdfDevStatePwrPolStarting DEBUGGED_EVENT }, 570 FxPkgPnp::m_PowerPolObjectCreatedOtherStates, 571 { TRUE, 572 PwrPolS0 | // Sx -> S0 transition on a PDO which was enumerated and 573 // in the disabled state 574 575 PwrPolSx | // Sx transition right after enumeration 576 PwrPolS0IdlePolicyChanged }, 577 }, 578 579 // WdfDevStatePwrPolStarting 580 { FxPkgPnp::PowerPolStarting, 581 { PwrPolPowerUp, WdfDevStatePwrPolStartingPoweredUp DEBUGGED_EVENT }, 582 FxPkgPnp::m_PowerPolStartingOtherStates, 583 { FALSE, 584 PwrPolPowerUpFailed // If the power state machine fails D0 entry upon 585 // initial start, we will get this event here. The 586 // pnp s.m. will not rely on the pwr pol s.m. to 587 // power down the stack in this case. 588 }, 589 }, 590 591 // WdfDevStatePwrPolStartingSucceeded 592 { FxPkgPnp::PowerPolStartingSucceeded, 593 { PwrPolNull, WdfDevStatePwrPolNull }, 594 NULL, 595 { FALSE, 596 0 }, 597 }, 598 599 // WdfDevStatePwrPolStartingFailed 600 { FxPkgPnp::PowerPolStartingFailed, 601 { PwrPolRemove, WdfDevStatePwrPolRemoved DEBUGGED_EVENT }, 602 NULL, 603 { TRUE, 604 0 }, 605 }, 606 607 // WdfDevStatePwrPolStartingDecideS0Wake 608 { FxPkgPnp::PowerPolStartingDecideS0Wake, 609 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out based on wake from S0 enabled 610 NULL, 611 { FALSE, 612 0 }, 613 }, 614 615 // WdfDevStatePwrPolStartedIdleCapable 616 { FxPkgPnp::PowerPolStartedIdleCapable, 617 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolIdleCapableDeviceIdle DEBUGGED_EVENT }, 618 FxPkgPnp::m_PowerPolStartedIdleCapableOtherStates, 619 { TRUE, 620 PwrPolS0 | // If the machine send a query Sx and it fails, it will send 621 // an S0 while in the running state (w/out ever sending a true set Sx irp) 622 PwrPolWakeArrived | // If the wake request is failed by the bus in between WakeArrived 623 // being posted in TimerExpiredWakeCapapble and being 624 // processed, this event will show up in this state if the idle 625 // setting changed at this exact moment as well 626 PwrPolPowerUp | // posted by power when we are powering up the first time 627 PwrPolIoPresent | // posted by the idle state machine. If we return 628 // to idle this can happen 629 PwrPolDevicePowerNotRequired | // The device-power-not-required event arrived just after an 630 // I/O request or or an S0-idle policy change caused us to 631 // become active again. The event is ignored in this case. 632 PwrPolDevicePowerRequired // The device-power-required event arrived, but we had already 633 // powered-up the device proactively because we detected that 634 // power was needed. The event is ignored in this case. 635 }, 636 }, 637 638 // WdfDevStatePwrPolTimerExpiredNoWake 639 { FxPkgPnp::PowerPolTimerExpiredNoWake, 640 { PwrPolPowerDownIoStopped, WdfDevStatePwrPolTimerExpiredNoWakeCompletePowerDown DEBUGGED_EVENT }, 641 FxPkgPnp::m_PowerPolTimerExpiredNoWakeOtherStates, 642 { FALSE, 643 0 }, 644 }, 645 646 // WdfDevStatePwrPolTimerExpiredNoWakeCompletePowerDown 647 { FxPkgPnp::PowerPolTimerExpiredNoWakeCompletePowerDown, 648 // NOTE: see the comments PowerPolWaitingArmedUsbSS() about why we query the 649 // idle state instead of going directly to WdfDevStatePwrPolWaitingUnarmed 650 { PwrPolPowerDown, WdfDevStatePwrPolTimerExpiredNoWakePoweredDownDisableIdleTimer DEBUGGED_EVENT }, 651 FxPkgPnp::m_PowerPolTimerExpiredNoWakeCompletePowerDownOtherStates, 652 { FALSE, 653 0 }, 654 }, 655 656 // WdfDevStatePwrPolWaitingUnarmed 657 { NULL, 658 { PwrPolIoPresent, WdfDevStatePwrPolWaitingUnarmedQueryIdle DEBUGGED_EVENT }, 659 FxPkgPnp::m_PowerPolWaitingUnarmedOtherStates, 660 { TRUE, 661 PwrPolS0 | // If the machine send a query Sx and it fails, it will send 662 // an S0 while in the running state (w/out ever sending a true set Sx irp) 663 PwrPolDevicePowerNotRequired // When moving from Sx -> S0, we do not power up the 664 // device if: 665 // (UsingSystemManagedIdleTimeout == TRUE) and 666 // (IdleEnabled == TRUE) and 667 // (WakeFromS0Capable == FALSE) and 668 // (PowerUpIdleDeviceOnSystemWake == FALSE). 669 // In this situation, we declare to the active/idle 670 // state machine that we are idle, but ignore the 671 // device-power-not-required event, because we are 672 // already in Dx. 673 }, 674 }, 675 676 // WdfDevStatePwrPolWaitingUnarmedQueryIdle 677 { FxPkgPnp::PowerPolWaitingUnarmedQueryIdle, 678 { PwrPolNull, WdfDevStatePwrPolNull }, 679 NULL, 680 { FALSE, 681 0 }, 682 }, 683 684 // WdfDevStatePwrPolS0NoWakePowerUp 685 { FxPkgPnp::PowerPolS0NoWakePowerUp, 686 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolS0NoWakeCompletePowerUp DEBUGGED_EVENT }, 687 FxPkgPnp::m_PowerPolS0NoWakePowerUpOtherStates, 688 { FALSE, 689 0 }, 690 }, 691 692 // WdfDevStatePwrPolS0NoWakeCompletePowerUp 693 { FxPkgPnp::PowerPolS0NoWakeCompletePowerUp, 694 { PwrPolPowerUp, WdfDevStatePwrPolStartingDecideS0Wake DEBUGGED_EVENT }, 695 FxPkgPnp::m_PowerPolS0NoWakeCompletePowerUpOtherStates, 696 { FALSE, 697 0 }, 698 }, 699 700 // WdfDevStatePwrPolSystemSleepFromDeviceWaitingUnarmed 701 { FxPkgPnp::PowerPolSystemSleepFromDeviceWaitingUnarmed, 702 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out based on wake from Sx enabled 703 NULL, 704 { FALSE, 705 0 }, 706 }, 707 708 // WdfDevStatePwrPolSystemSleepNeedWake 709 { FxPkgPnp::PowerPolSystemSleepNeedWake, 710 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemSleepNeedWakeCompletePowerUp DEBUGGED_EVENT }, 711 FxPkgPnp::m_PowerPolSystemSleepNeedWakeOtherStates, 712 { FALSE, 713 0 }, 714 }, 715 716 // WdfDevStatePwrPolSystemSleepNeedWakeCompletePowerUp 717 { FxPkgPnp::PowerPolSystemSleepNeedWakeCompletePowerUp, 718 { PwrPolPowerUp, WdfDevStatePwrPolSleeping DEBUGGED_EVENT }, 719 FxPkgPnp::m_PowerPolSystemSleepNeedWakeCompletePowerUpOtherStates, 720 { FALSE, 721 0 }, 722 }, 723 724 // WdfDevStatePwrPolSystemSleepPowerRequestFailed 725 { FxPkgPnp::PowerPolSystemSleepPowerRequestFailed, 726 { PwrPolNull, WdfDevStatePwrPolNull }, 727 NULL, 728 { FALSE, 729 0, }, 730 }, 731 732 // WdfDevStatePwrPolCheckPowerPageable 733 { FxPkgPnp::PowerPolCheckPowerPageable, 734 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out based on which DO_POWER_Xxx flags set on DO 735 NULL, 736 { FALSE, 737 0 }, 738 }, 739 740 // WdfDevStatePwrPolSleepingWakeWakeArrived 741 { FxPkgPnp::PowerPolSleepingWakeWakeArrived, 742 { PwrPolPowerDown, WdfDevStatePwrPolSystemAsleepWakeArmed DEBUGGED_EVENT }, 743 FxPkgPnp::m_PowerPolSleepingWakeWakeArrivedOtherStates, 744 { FALSE, 745 PwrPolWakeFailed | // wake completed before we could cancel 746 // the request, so the event may end up here 747 PwrPolWakeSuccess| // -do- 748 PwrPolWakeInterruptFired // Wake interrupt fired when during power 749 // down as part of system sleep transition 750 751 }, 752 }, 753 754 // WdfDevStatePwrPolSleepingWakeRevertArmWake 755 { FxPkgPnp::PowerPolSleepingWakeRevertArmWake, 756 { PwrPolWakeFailed, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 757 FxPkgPnp::m_PowerPolSleepingWakeRevertArmWakeOtherStates, 758 { FALSE, 759 0 }, 760 }, 761 762 // WdfDevStatePwrPolSystemAsleepWakeArmed 763 { FxPkgPnp::PowerPolSystemAsleepWakeArmed, 764 { PwrPolS0, WdfDevStatePwrPolSystemWakeDeviceWakeEnabled DEBUGGED_EVENT }, 765 FxPkgPnp::m_PowerPolSystemAsleepWakeArmedOtherStates, 766 { TRUE, 767 PwrPolWakeFailed | // Wake failed while in Sx 768 PwrPolIoPresent | // IO arrived when the machine was going to Sx 769 PwrPolPowerTimeoutExpired | // we don't cancel the power timer when we goto 770 // sleep from an idleable state 771 PwrPolDevicePowerNotRequired // Upon receiving Sx, we simulated a device-power- 772 // not-required, so the device-power-requirement 773 // state machine sent us this event in response. 774 // We can drop it because we already powered down. 775 }, 776 }, 777 778 // WdfDevStatePwrPolSystemWakeDeviceWakeEnabled 779 { FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabled, 780 { PwrPolWakeFailed, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceled DEBUGGED_EVENT }, 781 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledOtherStates, 782 { FALSE, 783 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 784 // device on receiving S0 due to other reasons. 785 // This event can fire until the wake interrupt 786 // machine is notified of the power up. 787 }, 788 }, 789 790 // WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceled 791 { FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledWakeCanceled, 792 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemWakeDeviceWakeDisarm DEBUGGED_EVENT }, 793 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledOtherStates, 794 { FALSE, 795 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 796 // device on receiving S0 due to other reasons. 797 // This event can fire until the wake interrupt 798 // machine is notified of the power up. 799 }, 800 }, 801 802 // WdfDevStatePwrPolSystemWakeDeviceWakeDisarm 803 { FxPkgPnp::PowerPolSystemWakeDeviceWakeDisarm, 804 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 805 NULL, 806 { FALSE, 807 0 }, 808 }, 809 810 // WdfDevStatePwrPolSystemWakeDeviceWakeTriggered 811 { NULL, 812 { PwrPolS0, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0 DEBUGGED_EVENT }, 813 NULL, 814 { TRUE, 815 0 }, 816 }, 817 818 // WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0 819 { FxPkgPnp::PowerPolSystemWakeDeviceWakeTriggeredS0, 820 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemWakeDeviceWokeDisarm DEBUGGED_EVENT }, 821 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeTriggeredS0OtherStates, 822 { FALSE, 823 0 }, 824 }, 825 826 // WdfDevStatePwrPolSystemWakeDeviceWokeDisarm 827 { FxPkgPnp::PowerPolSystemWakeDeviceWokeDisarm, 828 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 829 NULL, 830 { FALSE, 831 0 }, 832 }, 833 834 // WdfDevStatePwrPolSleepingWakeWakeArrivedNP, 835 { FxPkgPnp::PowerPolSleepingWakeWakeArrivedNP, 836 { PwrPolPowerDown, WdfDevStatePwrPolSystemAsleepWakeArmedNP DEBUGGED_EVENT }, 837 FxPkgPnp::m_PowerPolSleepingWakeWakeArrivedNPOtherStates, 838 { FALSE, 839 PwrPolWakeFailed | // wake completed before we could cancel 840 // the request, so the event may end up here 841 PwrPolWakeSuccess| // -do- 842 PwrPolWakeInterruptFired // Wake interrupt fired when during power 843 // down as part of system sleep transition 844 845 }, 846 }, 847 848 // WdfDevStatePwrPolSleepingWakeRevertArmWakeNP, 849 { FxPkgPnp::PowerPolSleepingWakeRevertArmWakeNP, 850 { PwrPolWakeFailed, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 851 FxPkgPnp::m_PowerPolSleepingWakeRevertArmWakeNPOtherStates, 852 { FALSE, 853 0 }, 854 }, 855 856 // WdfDevStatePwrPolSleepingWakePowerDownFailed 857 { FxPkgPnp::PowerPolSleepingWakePowerDownFailed, 858 { PwrPolWakeSuccess, WdfDevStatePwrPolSleepingWakePowerDownFailedWakeCanceled TRAP_ON_EVENT }, 859 FxPkgPnp::m_PowerPolSleepingWakePowerDownFailedOtherStates, 860 { FALSE, 861 0 }, 862 }, 863 864 // WdfDevStatePwrPolSleepingWakePowerDownFailedWakeCanceled 865 { FxPkgPnp::PowerPolSleepingWakePowerDownFailedWakeCanceled, 866 { PwrPolNull, WdfDevStatePwrPolNull }, 867 NULL, 868 { FALSE, 869 0 }, 870 }, 871 872 // WdfDevStatePwrPolSystemAsleepWakeArmedNP 873 { FxPkgPnp::PowerPolSystemAsleepWakeArmedNP, 874 { PwrPolS0, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledNP DEBUGGED_EVENT }, 875 FxPkgPnp::m_PowerPolSystemAsleepWakeArmedNPOtherStates, 876 { TRUE, 877 PwrPolWakeFailed | // Wake failed while in Sx 878 PwrPolIoPresent | // IO arrived when the machine was going to Sx 879 PwrPolPowerTimeoutExpired // we don't cancel the power timer when we goto 880 // sleep from an idleable state 881 }, 882 }, 883 884 // WdfDevStatePwrPolSystemWakeDeviceWakeEnabledNP 885 { FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledNP, 886 { PwrPolWakeFailed, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceledNP DEBUGGED_EVENT }, 887 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledNPOtherStates, 888 { FALSE, 889 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 890 // device on receiving S0 due to other reasons. 891 // This event can fire until the wake interrupt 892 // machine is notified of the power up. 893 }, 894 }, 895 896 // WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceledNP 897 { FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNP, 898 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemWakeDeviceWakeDisarmNP DEBUGGED_EVENT }, 899 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNPOtherStates, 900 { FALSE, 901 PwrPolWakeSuccess | // wake succeeded and completed before we could cancel 902 // the request, so the event ends up here 903 904 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 905 // device on receiving S0 due to other reasons. 906 // This event can fire until the wake interrupt 907 // machine is notified of the power up. 908 }, 909 }, 910 911 // WdfDevStatePwrPolSystemWakeDeviceWakeDisarmNP 912 { FxPkgPnp::PowerPolSystemWakeDeviceWakeDisarmNP, 913 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 914 NULL, 915 { FALSE, 916 0 }, 917 }, 918 919 // WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredNP 920 { NULL, 921 { PwrPolS0, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0NP DEBUGGED_EVENT }, 922 NULL, 923 { TRUE, 924 PwrPolIoPresent // I/O arrived before S0 arrival 925 }, 926 }, 927 928 // WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0NP 929 { FxPkgPnp::PowerPolSystemWakeDeviceWakeTriggeredS0NP, 930 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemWakeDeviceWokeDisarmNP DEBUGGED_EVENT }, 931 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeTriggeredS0NPOtherStates, 932 { FALSE, 933 0 }, 934 }, 935 936 // WdfDevStatePwrPolSystemWakeDeviceWokeDisarmNP 937 { FxPkgPnp::PowerPolSystemWakeDeviceWokeDisarmNP, 938 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 939 NULL, 940 { FALSE, 941 0 }, 942 }, 943 944 // WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp 945 { FxPkgPnp::PowerPolSystemWakeDeviceWakeCompletePowerUp, 946 { PwrPolPowerUp, WdfDevStatePwrPolStartingDecideS0Wake DEBUGGED_EVENT }, 947 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeCompletePowerUpOtherStates, 948 { FALSE, 949 0 }, 950 }, 951 952 // WdfDevStatePwrPolSleeping 953 { FxPkgPnp::PowerPolSleeping, 954 { PwrPolNull, WdfDevStatePwrPolNull }, 955 NULL, 956 { FALSE, 957 0 }, 958 }, 959 960 // WdfDevStatePwrPolSleepingNoWakePowerDown 961 { FxPkgPnp::PowerPolSleepingNoWakePowerDown, 962 { PwrPolPowerDownIoStopped, WdfDevStatePwrPolSleepingNoWakeCompletePowerDown DEBUGGED_EVENT }, 963 FxPkgPnp::m_PowerPolSleepingNoWakePowerDownOtherStates, 964 { FALSE, 965 0 }, 966 }, 967 968 // WdfDevStatePwrPolSleepingNoWakeCompletePowerDown 969 { FxPkgPnp::PowerPolSleepingNoWakeCompletePowerDown, 970 { PwrPolPowerDown, WdfDevStatePwrPolSystemAsleepNoWake DEBUGGED_EVENT }, 971 FxPkgPnp::m_PowerPolSleepingNoWakeCompletePowerDownOtherStates, 972 { FALSE, 973 PwrPolWakeArrived // wake arrived event posted after the ww irp 974 // completed from SleepingSendWake state. Ignore this 975 // event since wake is already trigged. 976 }, 977 }, 978 979 // WdfDevStatePwrPolSleepingNoWakeDxRequestFailed 980 { FxPkgPnp::PowerPolSleepingNoWakeDxRequestFailed, 981 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 982 NULL, 983 { FALSE, 984 0 }, 985 }, 986 987 // WdfDevStatePwrPolSleepingWakePowerDown 988 { FxPkgPnp::PowerPolSleepingWakePowerDown, 989 { PwrPolPowerDownIoStopped, WdfDevStatePwrPolSleepingSendWake DEBUGGED_EVENT }, 990 FxPkgPnp::m_PowerPolSleepingWakePowerDownOtherStates, 991 { FALSE, 992 0 }, 993 }, 994 995 // WdfDevStatePwrPolSleepingSendWake 996 { FxPkgPnp::PowerPolSleepingSendWake, 997 { PwrPolWakeArrived, WdfDevStatePwrPolCheckPowerPageable DEBUGGED_EVENT }, 998 FxPkgPnp::m_PowerPolSleepingSendWakeOtherStates, 999 { FALSE, 1000 0 }, 1001 }, 1002 1003 // WdfDevStatePwrPolSystemAsleepNoWake 1004 { FxPkgPnp::PowerPolSystemAsleepNoWake, 1005 { PwrPolS0, WdfDevStatePwrPolSystemWakeDeviceWakeDisabled DEBUGGED_EVENT }, 1006 NULL, 1007 { TRUE, 1008 PwrPolS0IdlePolicyChanged | // Policy changed while the device is in Dx 1009 // because of Sx, we will reevaluate the idle 1010 // settings when we return to S0 anyways 1011 PwrPolWakeArrived | // If arming for wake from sx failed, the WakeArrived 1012 // event that was a part of that arming is dequeued here 1013 PwrPolIoPresent | // I/O showed up when going into Sx 1014 PwrPolPowerTimeoutExpired | 1015 PwrPolDevicePowerNotRequired // Upon receiving Sx, we simulated a device-power- 1016 // not-required, so the device-power-requirement 1017 // state machine sent us this event in response. 1018 // We can drop it because we already powered down. 1019 }, 1020 }, 1021 1022 // WdfDevStatePwrPolSystemWakeDeviceWakeDisabled 1023 { FxPkgPnp::PowerPolSystemWakeDeviceWakeDisabled, 1024 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out based on wake from S0 enabled 1025 NULL, 1026 { FALSE, 1027 0 }, 1028 }, 1029 1030 // WdfDevStatePwrPolSystemWakeDeviceToD0 1031 { FxPkgPnp::PowerPolSystemWakeDeviceToD0, 1032 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolSystemWakeDeviceToD0CompletePowerUp DEBUGGED_EVENT }, 1033 FxPkgPnp::m_PowerPolSystemWakeDeviceToD0OtherStates, 1034 { FALSE, 1035 0 }, 1036 }, 1037 1038 // WdfDevStatePwrPolSystemWakeDeviceToD0CompletePowerUp 1039 { FxPkgPnp::PowerPolSystemWakeDeviceToD0CompletePowerUp, 1040 { PwrPolPowerUp, WdfDevStatePwrPolStartingDecideS0Wake DEBUGGED_EVENT }, 1041 FxPkgPnp::m_PowerPolSystemWakeDeviceToD0CompletePowerUpOtherStates, 1042 { FALSE, 1043 0 }, 1044 }, 1045 1046 // WdfDevStatePwrPolSystemWakeQueryIdle 1047 { FxPkgPnp::PowerPolSystemWakeQueryIdle, 1048 { PwrPolNull, WdfDevStatePwrPolNull}, // transition out based on timer expiration state 1049 NULL, 1050 { FALSE, 1051 0 }, 1052 }, 1053 1054 // WdfDevStatePwrPolStartedWakeCapable 1055 { FxPkgPnp::PowerPolStartedWakeCapable, 1056 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolWakeCapableDeviceIdle DEBUGGED_EVENT }, 1057 FxPkgPnp::m_PowerPolStartedWakeCapableOtherStates, 1058 { TRUE, 1059 PwrPolS0 | // If the machine send a query Sx and it fails, it will send 1060 // an S0 while in the running state (w/out ever sending a true set Sx irp) 1061 PwrPolPowerUp | 1062 PwrPolWakeArrived | // If the wake request is failed by the bus in between WakeArrived 1063 // being posted in TimerExpiredWakeCapapble and being 1064 // processed, this event will show up in this state 1065 1066 PwrPolWakeSuccess | // wake succeeded while we were trying to cancel it 1067 // while coming out of WaitingArmed b/c of io present 1068 1069 PwrPolWakeFailed | // wake request failed while we were trying to cancel it 1070 // while coming out of WaitingArmed b/c of io present 1071 1072 PwrPolUsbSelectiveSuspendCallback | 1073 PwrPolUsbSelectiveSuspendCompleted | // When returning from a success resume 1074 // from USB SS, the completion of the irp will 1075 // occur in the started state 1076 1077 PwrPolIoPresent | // posted by the idle state machine. If we return 1078 // to idle this can happen 1079 PwrPolDevicePowerNotRequired | // The device-power-not-required event arrived just after an 1080 // I/O request or or an S0-idle policy change caused us to 1081 // become active again. The event is ignored in this case. 1082 PwrPolDevicePowerRequired // The device-power-required event arrived, but we had already 1083 // powered-up the device proactively because we detected that 1084 // power was needed. The event is ignored in this case. 1085 }, 1086 }, 1087 1088 // WdfDevStatePwrPolTimerExpiredDecideUsbSS 1089 { FxPkgPnp::PowerPolTimerExpiredDecideUsbSS, 1090 { PwrPolNull, WdfDevStatePwrPolNull }, 1091 NULL, 1092 { FALSE, 1093 0 }, 1094 }, 1095 1096 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDown 1097 { FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDown, 1098 { PwrPolPowerDownIoStopped, WdfDevStatePwrPolTimerExpiredWakeCapableSendWake DEBUGGED_EVENT }, 1099 FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownOtherStates, 1100 { FALSE, 1101 0 }, 1102 }, 1103 1104 // WdfDevStatePwrPolTimerExpiredWakeCapableSendWake 1105 { FxPkgPnp::PowerPolTimerExpiredWakeCapableSendWake, 1106 { PwrPolWakeArrived, WdfDevStatePwrPolTimerExpiredWakeCapableWakeArrived DEBUGGED_EVENT }, 1107 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableSendWakeOtherStates, 1108 { FALSE, 1109 0 }, 1110 }, 1111 1112 // WdfDevStatePwrPolTimerExpiredWakeCapableUsbSS 1113 { FxPkgPnp::PowerPolTimerExpiredWakeCapableUsbSS, 1114 { PwrPolUsbSelectiveSuspendCallback, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDown DEBUGGED_EVENT }, 1115 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableUsbSSOtherStates, 1116 { TRUE, 1117 0 }, 1118 }, 1119 1120 // WdfDevStatePwrPolTimerExpiredWakeCapableWakeArrived 1121 { FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeArrived, 1122 { PwrPolPowerDown, WdfDevStatePwrPolWaitingArmedUsbSS DEBUGGED_EVENT }, 1123 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeArrivedOtherStates, 1124 { FALSE, 1125 0 }, 1126 }, 1127 1128 // WdfDevStatePwrPolTimerExpiredWakeCapableCancelWake 1129 { FxPkgPnp::PowerPolTimerExpiredWakeCapableCancelWake, 1130 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeCapableWakeCanceled TRAP_ON_EVENT }, 1131 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableCancelWakeOtherStates, 1132 { FALSE, 1133 0 }, 1134 }, 1135 1136 // WdfDevStatePwrPolTimerExpiredWakeCapableWakeCanceled 1137 { FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeCanceled, 1138 { PwrPolNull, WdfDevStatePwrPolNull }, 1139 NULL, 1140 { FALSE, 1141 0 }, 1142 }, 1143 1144 // WdfDevStatePwrPolTimerExpiredWakeCapableCleanup 1145 { FxPkgPnp::PowerPolTimerExpiredWakeCapableCleanup, 1146 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolTimerExpiredWakeCompletedPowerDown TRAP_ON_EVENT }, 1147 NULL, 1148 { FALSE, 1149 0 }, 1150 }, 1151 1152 // WdfDevStatePwrPolTimerExpiredWakeCapableDxAllocFailed 1153 { FxPkgPnp::PowerPolTimerExpiredWakeCapableDxAllocFailed, 1154 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolTimerExpiredWakeCapableUndoPowerDown TRAP_ON_EVENT }, 1155 NULL, 1156 { FALSE, 1157 0 }, 1158 }, 1159 1160 // WdfDevStatePwrPolTimerExpiredWakeCompletedPowerDown 1161 { FxPkgPnp::PowerPolTimerExpiredWakeCompletedPowerDown, 1162 { PwrPolPowerDown, WdfDevStatePwrPolTimerExpiredWakeCompletedPowerUp DEBUGGED_EVENT }, 1163 FxPkgPnp::m_PowerPolTimerExpiredWakeCompletedPowerDownOtherStates, 1164 { FALSE, 1165 PwrPolWakeSuccess | // arming callback failed while going into Dx armed for wake from S0 1166 // but bus completed wake request with success 1167 1168 PwrPolWakeArrived // if the wake request completes before PwrPolWakeArrived 1169 // can be processed in the PwrPolTimerExpiredWakeCapableSendWake 1170 // state, it will show up here 1171 }, 1172 }, 1173 1174 // WdfDevStatePwrPolTimerExpiredWakeCompletedPowerUp 1175 { FxPkgPnp::PowerPolTimerExpiredWakeCompletedPowerUp, 1176 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolTimerExpiredWakeCompletedHardwareStarted DEBUGGED_EVENT }, 1177 FxPkgPnp::m_PowerPolTimerExpiredWakeCompletedPowerUpOtherStates, 1178 { FALSE, 1179 PwrPolWakeSuccess | // arming callback failed while going into Dx armed for wake from S0 1180 // but bus completed wake request with success 1181 1182 PwrPolWakeArrived // if the wake request completes before PwrPolWakeArrived 1183 // can be processed in the WdfDevStatePwrPolTimerExpiredWakeCapableSendWake 1184 // state, it will show up here 1185 }, 1186 }, 1187 1188 // WdfDevStatePwrPolWaitingArmedUsbSS 1189 { FxPkgPnp::PowerPolWaitingArmedUsbSS, 1190 { PwrPolNull, WdfDevStatePwrPolNull }, 1191 NULL, 1192 { FALSE, 1193 0 }, 1194 }, 1195 1196 // WdfDevStatePwrPolWaitingArmed 1197 { NULL, 1198 { PwrPolIoPresent, WdfDevStatePwrPolWaitingArmedQueryIdle DEBUGGED_EVENT }, 1199 FxPkgPnp::m_PowerPolWaitingArmedOtherStates, 1200 { TRUE, 1201 PwrPolS0 // If the machine send a query Sx and it fails, it will send 1202 // an S0 while in the running state (w/out ever sending a true set Sx irp) 1203 }, 1204 }, 1205 1206 // WdfDevStatePwrPolWaitingArmedQueryIdle 1207 { FxPkgPnp::PowerPolWaitingArmedQueryIdle, 1208 { PwrPolNull, WdfDevStatePwrPolNull }, 1209 NULL, 1210 { FALSE, 1211 0 }, 1212 }, 1213 1214 // WdfDevStatePwrPolIoPresentArmed 1215 { FxPkgPnp::PowerPolIoPresentArmed, 1216 { PwrPolWakeFailed, WdfDevStatePwrPolIoPresentArmedWakeCanceled DEBUGGED_EVENT }, 1217 FxPkgPnp::m_PowerPolIoPresentArmedOtherStates, 1218 { FALSE, 1219 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 1220 // device on receiving IO.This event can fire 1221 // until the wake interrupt machine is notified 1222 // of the power up. 1223 }, 1224 }, 1225 1226 // WdfDevStatePwrPolIoPresentArmedWakeCanceled 1227 { FxPkgPnp::PowerPolIoPresentArmedWakeCanceled, 1228 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolS0WakeDisarm DEBUGGED_EVENT }, 1229 FxPkgPnp::m_PowerPolIoPresentArmedWakeCanceledOtherStates, 1230 { FALSE, 1231 PwrPolWakeSuccess | // The wake status was already processed before entering 1232 // this state - indicates that the client driver is 1233 // probably propagating a duplicate wake status using 1234 // the WdfDeviceIndicateWakeStatus ddi. 1235 1236 PwrPolWakeFailed | // The wake status was already processed before entering 1237 // this state - indicates that the client driver is 1238 // probably propagating a duplicate wake status using 1239 // the WdfDeviceIndicateWakeStatus ddi. 1240 1241 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 1242 // device on receiving IO.This event can fire 1243 // until the wake interrupt machine is notified 1244 // of the power up. 1245 1246 }, 1247 }, 1248 1249 // WdfDevStatePwrPolS0WakeDisarm, 1250 { FxPkgPnp::PowerPolS0WakeDisarm, 1251 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 1252 NULL, 1253 { FALSE, 1254 0 }, 1255 }, 1256 1257 // WdfDevStatePwrPolS0WakeCompletePowerUp 1258 { FxPkgPnp::PowerPolS0WakeCompletePowerUp, 1259 { PwrPolPowerUp, WdfDevStatePwrPolStartingDecideS0Wake DEBUGGED_EVENT }, 1260 FxPkgPnp::m_PowerPolS0WakeCompletePowerUpOtherStates, 1261 { FALSE, 1262 0 }, 1263 }, 1264 1265 // WdfDevStatePwrPolTimerExpiredWakeSucceeded 1266 { FxPkgPnp::PowerPolTimerExpiredWakeSucceeded, 1267 { PwrPolNull, WdfDevStatePwrPolNull }, // transition out is hardcoded in func 1268 NULL, 1269 { FALSE, 1270 0 }, 1271 }, 1272 1273 // WdfDevStatePwrPolTimerExpiredWakeCompletedDisarm 1274 { FxPkgPnp::PowerPolTimerExpiredWakeCompletedDisarm, 1275 { PwrPolNull, WdfDevStatePwrPolNull }, 1276 NULL, 1277 { FALSE, 1278 0 }, 1279 }, 1280 1281 // WdfDevStatePwrPolTimerExpiredWakeCapableWakeSucceeded 1282 { NULL, 1283 { PwrPolPowerDown, WdfDevStatePwrPolWokeFromS0UsbSS DEBUGGED_EVENT }, 1284 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeSucceededOtherStates, 1285 { FALSE, 1286 0 }, 1287 }, 1288 1289 // WdfDevStatePwrPolTimerExpiredWakeCapableWakeFailed 1290 { NULL, 1291 { PwrPolPowerDown, WdfDevStatePwrPolWakeFailedUsbSS DEBUGGED_EVENT }, 1292 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeFailedOtherStates, 1293 { FALSE, 1294 0 }, 1295 }, 1296 1297 // WdfDevStatePwrPolWakeFailedUsbSS 1298 { FxPkgPnp::PowerPolWakeFailedUsbSS, 1299 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolIoPresentArmedWakeCanceled TRAP_ON_EVENT }, 1300 NULL, 1301 { FALSE, 1302 0 }, 1303 }, 1304 1305 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedCancelWake 1306 { FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWake, 1307 { PwrPolWakeSuccess, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled DEBUGGED_EVENT }, 1308 FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWakeOtherStates, 1309 { FALSE, 1310 0 }, 1311 }, 1312 1313 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled 1314 { FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled, 1315 { PwrPolNull, WdfDevStatePwrPolNull }, 1316 NULL, 1317 { FALSE, 1318 0 }, 1319 }, 1320 1321 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedUsbSS 1322 { FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedUsbSS, 1323 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolDevicePowerRequestFailed TRAP_ON_EVENT }, 1324 NULL, 1325 { FALSE, 1326 0 }, 1327 }, 1328 1329 // WdfDevStatePwrPolCancelingWakeForSystemSleep 1330 { FxPkgPnp::PowerPolCancelingWakeForSystemSleep, 1331 { PwrPolWakeFailed, WdfDevStatePwrPolCancelingWakeForSystemSleepWakeCanceled DEBUGGED_EVENT }, 1332 FxPkgPnp::m_PowerPolCancelingWakeForSystemSleepOtherStates, 1333 { FALSE, 1334 0 }, 1335 }, 1336 1337 // WdfDevStatePwrPolCancelingWakeForSystemSleepWakeCanceled 1338 { FxPkgPnp::PowerPolCancelingWakeForSystemSleepWakeCanceled, 1339 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolDisarmingWakeForSystemSleepCompletePowerUp DEBUGGED_EVENT }, 1340 FxPkgPnp::m_PowerPolCancelingWakeForSystemSleepWakeCanceledOtherStates, 1341 { FALSE, 1342 PwrPolWakeSuccess // Wake completed successfully right as the transition 1343 // from WaitingArmed to goto Sx occurred 1344 }, 1345 }, 1346 1347 // WdfDevStatePwrPolDisarmingWakeForSystemSleepCompletePowerUp 1348 { FxPkgPnp::PowerPolDisarmingWakeForSystemSleepCompletePowerUp, 1349 { PwrPolPowerUp, WdfDevStatePwrPolStartedWakeCapableCancelTimerForSleep DEBUGGED_EVENT }, 1350 FxPkgPnp::m_PowerPolDisarmingWakeForSystemSleepCompletePowerUpOtherStates, 1351 { FALSE, 1352 0, }, 1353 }, 1354 1355 // WdfDevStatePwrPolPowerUpForSystemSleepFailed 1356 { FxPkgPnp::PowerPolPowerUpForSystemSleepFailed, 1357 { PwrPolNull, WdfDevStatePwrPolNull }, 1358 NULL, 1359 { FALSE, 1360 0 }, 1361 }, 1362 1363 // WdfDevStatePwrPolWokeFromS0UsbSS 1364 { FxPkgPnp::PowerPolWokeFromS0UsbSS, 1365 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolWokeFromS0 DEBUGGED_EVENT }, 1366 NULL, 1367 { FALSE, 1368 0 }, 1369 }, 1370 1371 // WdfDevStatePwrPolWokeFromS0 1372 { FxPkgPnp::PowerPolWokeFromS0, 1373 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolWokeFromS0NotifyDriver DEBUGGED_EVENT }, 1374 FxPkgPnp::m_PowerPolWokeFromS0OtherStates, 1375 { FALSE, 1376 0 }, 1377 }, 1378 1379 // WdfDevStatePwrPolWokeFromS0NotifyDriver 1380 { FxPkgPnp::PowerPolWokeFromS0NotifyDriver, 1381 { PwrPolNull, WdfDevStatePwrPolNull }, 1382 NULL, 1383 { FALSE, 1384 0 }, 1385 }, 1386 1387 // WdfDevStatePwrPolStoppingResetDevice 1388 { FxPkgPnp::PowerPolStoppingResetDevice, 1389 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolStoppingResetDeviceCompletePowerUp DEBUGGED_EVENT }, 1390 FxPkgPnp::m_PowerPolStoppingResetDeviceOtherStates, 1391 { FALSE, 1392 0 }, 1393 }, 1394 1395 // WdfDevStatePwrPolStoppingResetDeviceCompletePowerUp 1396 { FxPkgPnp::PowerPolStoppingResetDeviceCompletePowerUp, 1397 { PwrPolPowerUp, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 1398 FxPkgPnp::m_PowerPolStoppingResetDeviceCompletePowerUpOtherStates, 1399 { FALSE, 1400 0 }, 1401 }, 1402 1403 // WdfDevStatePwrPolStoppingResetDeviceFailed 1404 { FxPkgPnp::PowerPolStoppingResetDeviceFailed, 1405 { PwrPolNull, WdfDevStatePwrPolNull }, 1406 NULL, 1407 { FALSE, 1408 0 }, 1409 }, 1410 1411 // WdfDevStatePwrPolStoppingD0 1412 { FxPkgPnp::PowerPolStoppingD0, 1413 { PwrPolPowerUpHwStarted, WdfDevStatePwrPolStoppingDisarmWake DEBUGGED_EVENT }, 1414 FxPkgPnp::m_PowerPolStoppingD0OtherStates, 1415 { FALSE, 1416 PwrPolWakeSuccess | // In the waiting armed state, the wake completed 1417 // right after PwrPolStop arrived 1418 PwrPolWakeFailed // wake completed before we could cancel 1419 // the request, so the event may end up here 1420 }, 1421 }, 1422 1423 // WdfDevStatePwrPolStoppingD0Failed 1424 { FxPkgPnp::PowerPolStoppingD0Failed, 1425 { PwrPolNull, WdfDevStatePwrPolNull }, 1426 NULL, 1427 { FALSE, 1428 0 }, 1429 }, 1430 1431 // WdfDevStatePwrPolStoppingDisarmWake 1432 { FxPkgPnp::PowerPolStoppingDisarmWake, 1433 { PwrPolPowerUp, WdfDevStatePwrPolStoppingDisarmWakeCancelWake DEBUGGED_EVENT }, 1434 FxPkgPnp::m_PowerPolStoppingDisarmWakeOtherStates, 1435 { FALSE, 1436 PwrPolWakeFailed | // wake completed before we could cancel 1437 // the request, so the event may end up here 1438 PwrPolWakeSuccess // -do- 1439 }, 1440 }, 1441 1442 // WdfDevStatePwrPolStoppingDisarmWakeCancelWake 1443 { FxPkgPnp::PowerPolStoppingDisarmWakeCancelWake, 1444 { PwrPolWakeFailed, WdfDevStatePwrPolStoppingDisarmWakeWakeCanceled DEBUGGED_EVENT }, 1445 FxPkgPnp::m_PowerPolStoppingDisarmWakeCancelWakeOtherStates, 1446 { FALSE, 1447 PwrPolUsbSelectiveSuspendCompleted // pwr pol stopped from a usb SS device 1448 // in Dx and the irp completed when the D0 1449 // irp was sent 1450 }, 1451 }, 1452 1453 // WdfDevStatePwrPolStoppingDisarmWakeWakeCanceled 1454 { FxPkgPnp::PowerPolStoppingDisarmWakeWakeCanceled, 1455 { PwrPolNull, WdfDevStatePwrPolNull}, // transition to Stopping occurs in function 1456 NULL, 1457 { FALSE, 1458 PwrPolUsbSelectiveSuspendCompleted // pwr pol stopped from a usb SS device 1459 // in Dx and the irp completed when the D0 1460 // irp was sent 1461 }, 1462 }, 1463 1464 // WdfDevStatePwrPolStopping 1465 { FxPkgPnp::PowerPolStopping, 1466 { PwrPolPowerDown, WdfDevStatePwrPolStoppingSendStatus DEBUGGED_EVENT }, 1467 FxPkgPnp::m_PowerPolStoppingOtherStates, 1468 { FALSE, 1469 PwrPolUsbSelectiveSuspendCompleted // pwr pol stopped from a usb SS device 1470 // in Dx and the irp completed when the D0 1471 // irp was sent 1472 }, 1473 }, 1474 1475 // WdfDevStatePwrPolStoppingFailed 1476 { FxPkgPnp::PowerPolStoppingFailed, 1477 { PwrPolNull, WdfDevStatePwrPolNull }, 1478 NULL, 1479 { FALSE, 1480 0 }, 1481 }, 1482 1483 // WdfDevStatePwrPolStoppingSendStatus 1484 { FxPkgPnp::PowerPolStoppingSendStatus, 1485 { PwrPolNull, WdfDevStatePwrPolNull }, 1486 NULL, 1487 { FALSE, 1488 0 }, 1489 }, 1490 1491 // WdfDevStatePwrPolStoppingCancelTimer 1492 { FxPkgPnp::PowerPolStoppingCancelTimer, 1493 { PwrPolNull, WdfDevStatePwrPolNull }, 1494 NULL, 1495 { FALSE, 1496 0 }, 1497 }, 1498 1499 // WdfDevStatePwrPolStoppingWaitForIdleTimeout 1500 { NULL, 1501 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 1502 NULL, 1503 { TRUE, 1504 0 }, 1505 }, 1506 1507 // WdfDevStatePwrPolStoppingCancelUsbSS 1508 { FxPkgPnp::PowerPolStoppingCancelUsbSS, 1509 { PwrPolNull, WdfDevStatePwrPolNull }, 1510 NULL, 1511 { FALSE, 1512 0 }, 1513 }, 1514 1515 // WdfDevStatePwrPolStoppingWaitForUsbSSCompletion 1516 { NULL, 1517 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 1518 NULL, 1519 { TRUE, 1520 0 }, 1521 }, 1522 1523 // WdfDevStatePwrPolStoppingCancelWake 1524 { FxPkgPnp::PowerPolStoppingCancelWake, 1525 { PwrPolWakeFailed, WdfDevStatePwrPolStopping DEBUGGED_EVENT }, 1526 FxPkgPnp::m_PowerPolStoppingCancelWakeOtherStates, 1527 { TRUE, 1528 0 }, 1529 }, 1530 1531 // WdfDevStatePwrPolStopped 1532 { NULL, 1533 { PwrPolStart, WdfDevStatePwrPolRestarting DEBUGGED_EVENT }, 1534 FxPkgPnp::m_PowerPolStoppedOtherStates, 1535 { TRUE, 1536 PwrPolPowerTimeoutExpired | // idle timer fired right before stopping 1537 // pwr policy and before pwr pol could process 1538 // the timeout 1539 PwrPolIoPresent | // I/O arrived while transitioning to the 1540 // stopped state 1541 PwrPolDevicePowerRequired // Due to a power-related failure, we declared our device state 1542 // as failed and stopped the power policy state machine. But 1543 // before stopping the power policy machine, we would have 1544 // declared ourselves as powered-on (maybe fake) in order to 1545 // move the power framework to a consistent state. Since we've 1546 // already declared ourselves as powered-on, we can drop this. 1547 }, 1548 }, 1549 1550 // WdfDevStatePwrPolCancelUsbSS 1551 { FxPkgPnp::PowerPolCancelUsbSS, 1552 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolStartedCancelTimer DEBUGGED_EVENT }, 1553 FxPkgPnp::m_PowerPolCancelUsbSSOtherStates, 1554 { TRUE, 1555 PwrPolIoPresent // I/O arrived while we were waiting for the USB idle notification IOCTL 1556 // to be completed after we had canceled it. It is okay to drop this 1557 // event because we are already in the process to returning to the powered- 1558 // up state. 1559 }, 1560 }, 1561 1562 // WdfDevStatePwrPolStarted 1563 { FxPkgPnp::PowerPolStarted, 1564 { PwrPolSx, WdfDevStatePwrPolSleeping DEBUGGED_EVENT }, 1565 FxPkgPnp::m_PowerPolStartedOtherStates, 1566 { TRUE, 1567 PwrPolS0 | // If the machine send a query Sx and it fails, it will send 1568 // an S0 while in the running state (w/out ever sending a true set Sx irp) 1569 PwrPolWakeArrived | // If the wake request is failed by the bus in between WakeArrived 1570 // being posted in TimerExpiredWakeCapapble and being 1571 // processed, this event will show up in this state if the idle 1572 // setting changed at this exact moment as well 1573 PwrPolWakeSuccess | // returning from Dx armed for wake from Sx, wake 1574 // is completed w/success after S0 irp arrives 1575 PwrPolPowerUp | 1576 PwrPolUsbSelectiveSuspendCompleted | // sent when we move out of the armed 1577 // & idle enabled state into the 1578 // idle disabled state 1579 PwrPolIoPresent |// This just indicates that I/O arrived, which is fine here 1580 PwrPolPowerTimeoutExpired | // this can happen when idle timer is disabled 1581 // due to policy change while powering up. 1582 PwrPolDevicePowerRequired // idle policy changed when device was powered down 1583 // due to S0-idle. The policy change caused us to power 1584 // up. As part of powering up, the device-power-required 1585 // event arrived. Can drop because we already powered-up. 1586 }, 1587 }, 1588 1589 // WdfDevStatePwrPolStartedCancelTimer 1590 { FxPkgPnp::PowerPolStartedCancelTimer, 1591 { PwrPolNull, WdfDevStatePwrPolNull }, 1592 NULL, 1593 { FALSE, 1594 0 }, 1595 }, 1596 1597 // WdfDevStatePwrPolStartedWaitForIdleTimeout 1598 { NULL, 1599 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolStartingDecideS0Wake TRAP_ON_EVENT }, 1600 FxPkgPnp::m_PowerPolStartedWaitForIdleTimeoutOtherStates, 1601 { TRUE, 1602 0 }, 1603 }, 1604 1605 // WdfDevStatePwrPolStartedWakeCapableCancelTimerForSleep 1606 { FxPkgPnp::PowerPolStartedWakeCapableCancelTimerForSleep, 1607 { PwrPolNull, WdfDevStatePwrPolNull }, 1608 NULL, 1609 { FALSE, 1610 0 }, 1611 }, 1612 1613 // WdfDevStatePwrPolStartedWakeCapableWaitForIdleTimeout 1614 { NULL, 1615 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolSleeping TRAP_ON_EVENT }, 1616 NULL, 1617 { TRUE, 1618 0 }, 1619 }, 1620 1621 // WdfDevStatePwrPolStartedWakeCapableSleepingUsbSS 1622 { FxPkgPnp::PowerPolStartedWakeCapableSleepingUsbSS, 1623 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolSleeping DEBUGGED_EVENT }, 1624 NULL, 1625 { TRUE, 1626 0 }, 1627 }, 1628 1629 // WdfDevStatePwrPolStartedIdleCapableCancelTimerForSleep 1630 { FxPkgPnp::PowerPolStartedIdleCapableCancelTimerForSleep, 1631 { PwrPolNull, WdfDevStatePwrPolNull }, 1632 NULL, 1633 { FALSE, 1634 0 }, 1635 }, 1636 1637 // WdfDevStatePwrPolStartedIdleCapableWaitForIdleTimeout 1638 { NULL, 1639 { PwrPolPowerTimeoutExpired, WdfDevStatePwrPolSleeping TRAP_ON_EVENT }, 1640 NULL, 1641 { TRUE, 1642 0 }, 1643 }, 1644 1645 // WdfDevStatePwrPolDeviceD0PowerRequestFailed 1646 { FxPkgPnp::PowerPolDeviceD0PowerRequestFailed, 1647 { PwrPolNull, WdfDevStatePwrPolNull}, 1648 NULL, 1649 { FALSE, 1650 0 }, 1651 }, 1652 1653 // WdfDevStatePwrPolDevicePowerRequestFailed 1654 { FxPkgPnp::PowerPolDevicePowerRequestFailed, 1655 { PwrPolStop, WdfDevStatePwrPolStoppingCancelTimer DEBUGGED_EVENT }, 1656 FxPkgPnp::m_PowerPolDevicePowerRequestFailedOtherStates, 1657 { TRUE, 1658 PwrPolUsbSelectiveSuspendCompleted | // Device was suspened and surprise 1659 // removed while in Dx 1660 PwrPolS0 | // If the device failed D0Exit while the machine was going into 1661 // Sx, then we will get this event when the machine comes back up 1662 1663 PwrPolWakeArrived | // wake was completed before PwrPolWakeArrived was 1664 // sent. On immediate power down or up, the power 1665 // operation failed 1666 1667 PwrPolWakeFailed | // If the device failed exit d0 after being armed, the 1668 // this event will be processed in the failed state 1669 PwrPolDevicePowerRequired | // We can drop because we already declared ourselves 1670 // as being powered on (fake power-on in order to 1671 // move the power framework to consistent state). 1672 PwrPolIoPresent // We're being notified that we need to be powered-on because 1673 // there is I/O to process, but the device is already in failed 1674 // state and is about to be removed. 1675 }, 1676 }, 1677 1678 // State exists only for the non power policy owner state machine 1679 // WdfDevStatePwrPolGotoDx 1680 { NULL, 1681 { PwrPolNull, WdfDevStatePwrPolNull }, 1682 NULL, 1683 { TRUE, 1684 0 }, 1685 }, 1686 1687 // WdfDevStatePwrPolGotoDxInDx 1688 { NULL, 1689 { PwrPolNull, WdfDevStatePwrPolNull }, 1690 NULL, 1691 { TRUE, 1692 0 }, 1693 }, 1694 1695 // State exists only for the non power policy owner state machine 1696 // WdfDevStatePwrPolDx 1697 { NULL, 1698 { PwrPolNull, WdfDevStatePwrPolNull }, 1699 NULL, 1700 { TRUE, 1701 0 }, 1702 }, 1703 1704 // State exists only for the non power policy owner state machine 1705 // WdfDevStatePwrPolGotoD0 1706 { NULL, 1707 { PwrPolNull, WdfDevStatePwrPolNull }, 1708 NULL, 1709 { TRUE, 1710 0 }, 1711 }, 1712 1713 // WdfDevStatePwrPolGotoD0InD0 1714 { NULL, 1715 { PwrPolNull, WdfDevStatePwrPolNull }, 1716 NULL, 1717 { TRUE, 1718 0 }, 1719 }, 1720 1721 // WdfDevStatePwrPolFinal 1722 { NULL, 1723 { PwrPolNull, WdfDevStatePwrPolNull }, 1724 NULL, 1725 { TRUE, 1726 0 }, 1727 }, 1728 1729 // WdfDevStatePwrPolSleepingPowerDownNotProcessed 1730 { FxPkgPnp::PowerPolSleepingPowerDownNotProcessed, 1731 { PwrPolNull, WdfDevStatePwrPolNull }, 1732 NULL, 1733 { FALSE, 1734 0 }, 1735 }, 1736 1737 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownNotProcessed 1738 { FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownNotProcessed, 1739 { PwrPolNull, WdfDevStatePwrPolNull }, 1740 NULL, 1741 { FALSE, 1742 0 }, 1743 }, 1744 1745 // WdfDevStatePwrPolTimerExpiredNoWakePowerDownNotProcessed 1746 { FxPkgPnp::PowerPolTimerExpiredNoWakePowerDownNotProcessed, 1747 { PwrPolNull, WdfDevStatePwrPolNull }, 1748 NULL, 1749 { FALSE, 1750 0 }, 1751 }, 1752 1753 // WdfDevStatePwrPolTimerExpiredNoWakePoweredDownDisableIdleTimer 1754 { FxPkgPnp::PowerPolTimerExpiredNoWakePoweredDownDisableIdleTimer, 1755 { PwrPolNull, WdfDevStatePwrPolNull }, 1756 NULL, 1757 { FALSE, 1758 0 }, 1759 }, 1760 1761 // WdfDevStatePwrPolStoppingWaitingForImplicitPowerDown 1762 { NULL, 1763 { PwrPolNull, WdfDevStatePwrPolNull }, 1764 NULL, 1765 { FALSE, 1766 0 }, 1767 }, 1768 1769 // WdfDevStatePwrPolStoppingPoweringUp 1770 { NULL, 1771 { PwrPolNull, WdfDevStatePwrPolNull }, 1772 NULL, 1773 { FALSE, 1774 0 }, 1775 }, 1776 1777 // WdfDevStatePwrPolStoppingPoweringDown 1778 { NULL, 1779 { PwrPolNull, WdfDevStatePwrPolNull }, 1780 NULL, 1781 { FALSE, 1782 0 }, 1783 }, 1784 1785 // WdfDevStatePwrPolPowerUpForSystemSleepNotSeen 1786 { FxPkgPnp::PowerPolPowerUpForSystemSleepNotSeen, 1787 { PwrPolNull, WdfDevStatePwrPolNull }, 1788 NULL, 1789 { FALSE, 1790 0 }, 1791 }, 1792 1793 // WdfDevStatePwrPolWaitingArmedStoppingCancelUsbSS 1794 { FxPkgPnp::PowerPolWaitingArmedStoppingCancelUsbSS, 1795 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolStoppingCancelWake DEBUGGED_EVENT }, 1796 NULL, 1797 { FALSE, 1798 PwrPolWakeFailed | // wake completed before we could cancel 1799 // the request, so the event may end up here 1800 PwrPolWakeSuccess // -do- 1801 }, 1802 }, 1803 1804 // WdfDevStatePwrPolWaitingArmedWakeFailedCancelUsbSS 1805 { FxPkgPnp::PowerPolWaitingArmedWakeFailedCancelUsbSS, 1806 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolIoPresentArmedWakeCanceled TRAP_ON_EVENT }, 1807 NULL, 1808 { FALSE, 1809 0 }, 1810 }, 1811 1812 // WdfDevStatePwrPolWaitingArmedIoPresentCancelUsbSS 1813 { FxPkgPnp::PowerPolWaitingArmedIoPresentCancelUsbSS, 1814 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolIoPresentArmed DEBUGGED_EVENT }, 1815 NULL, 1816 { FALSE, 1817 PwrPolWakeFailed | // wake completed before we could cancel 1818 // the request, so the event may end up here 1819 PwrPolWakeSuccess | // -do- 1820 PwrPolWakeInterruptFired // wake interrupt fired as we were waking the 1821 // device on receiving IO.This event can fire 1822 // until the wake interrupt machine is notified 1823 // of the power up. 1824 }, 1825 }, 1826 1827 // WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS 1828 { FxPkgPnp::PowerPolWaitingArmedWakeSucceededCancelUsbSS, 1829 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolWokeFromS0 DEBUGGED_EVENT }, 1830 NULL, 1831 { FALSE, 1832 0 }, 1833 }, 1834 1835 // WdfDevStatePwrPolCancelingUsbSSForSystemSleep 1836 { FxPkgPnp::PowerPolCancelingUsbSSForSystemSleep, 1837 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolCancelingWakeForSystemSleep DEBUGGED_EVENT }, 1838 NULL, 1839 { FALSE, 1840 PwrPolWakeFailed | // wake completed before we could cancel 1841 // the request, so the event may end up here 1842 PwrPolWakeSuccess // -do- 1843 }, 1844 }, 1845 1846 // WdfDevStatePwrPolStoppingD0CancelUsbSS 1847 { FxPkgPnp::PowerPolStoppingD0CancelUsbSS, 1848 { PwrPolUsbSelectiveSuspendCompleted, WdfDevStatePwrPolStoppingD0 TRAP_ON_EVENT }, 1849 NULL, 1850 { FALSE, 1851 PwrPolWakeFailed | // wake completed before we could cancel 1852 // the request, so the event may end up here 1853 PwrPolWakeSuccess // -do- 1854 }, 1855 }, 1856 1857 // WdfDevStatePwrPolStartingPoweredUp 1858 { FxPkgPnp::PowerPolStartingPoweredUp, 1859 { PwrPolNull, WdfDevStatePwrPolNull }, 1860 NULL, 1861 { FALSE, 1862 0 }, 1863 }, 1864 1865 // WdfDevStatePwrPolIdleCapableDeviceIdle 1866 { FxPkgPnp::PowerPolIdleCapableDeviceIdle, 1867 { PwrPolDevicePowerNotRequired, WdfDevStatePwrPolTimerExpiredNoWake DEBUGGED_EVENT }, 1868 FxPkgPnp::m_PowerPolIdleCapableDeviceIdleOtherStates, 1869 { TRUE, 1870 0 }, 1871 }, 1872 1873 // WdfDevStatePwrPolDeviceIdleReturnToActive 1874 { FxPkgPnp::PowerPolDeviceIdleReturnToActive, 1875 { PwrPolNull, WdfDevStatePwrPolNull }, 1876 NULL, 1877 { FALSE, 1878 0 }, 1879 }, 1880 1881 // WdfDevStatePwrPolDeviceIdleSleeping 1882 { FxPkgPnp::PowerPolDeviceIdleSleeping, 1883 { PwrPolNull, WdfDevStatePwrPolNull }, 1884 NULL, 1885 { FALSE, 1886 0 }, 1887 }, 1888 1889 // WdfDevStatePwrPolDeviceIdleStopping 1890 { FxPkgPnp::PowerPolDeviceIdleStopping, 1891 { PwrPolNull, WdfDevStatePwrPolNull }, 1892 NULL, 1893 { FALSE, 1894 0 }, 1895 }, 1896 1897 // WdfDevStatePwrPolTimerExpiredNoWakeUndoPowerDown 1898 { FxPkgPnp::PowerPolTimerExpiredNoWakeUndoPowerDown, 1899 { PwrPolNull, WdfDevStatePwrPolNull }, 1900 NULL, 1901 { FALSE, 1902 0 }, 1903 }, 1904 1905 // WdfDevStatePwrPolWakeCapableDeviceIdle 1906 { FxPkgPnp::PowerPolWakeCapableDeviceIdle, 1907 { PwrPolDevicePowerNotRequired, WdfDevStatePwrPolTimerExpiredDecideUsbSS DEBUGGED_EVENT }, 1908 FxPkgPnp::m_PowerPolWakeCapableDeviceIdleOtherStates, 1909 { TRUE, 1910 PwrPolDevicePowerRequired // The device-power-required event arrived, but we had already 1911 // powered-up the device proactively because we detected that 1912 // power was needed. And after we powered up, we become idle 1913 // again and arrived in our current state before the device- 1914 // power-required event was received. The event is ignored in 1915 // this case. 1916 }, 1917 }, 1918 1919 // WdfDevStatePwrPolWakeCapableUsbSSCompleted 1920 { FxPkgPnp::PowerPolWakeCapableUsbSSCompleted, 1921 { PwrPolNull, WdfDevStatePwrPolNull }, 1922 NULL, 1923 { FALSE, 1924 0 }, 1925 }, 1926 1927 // WdfDevStatePwrPolTimerExpiredWakeCapableUndoPowerDown 1928 { FxPkgPnp::PowerPolTimerExpiredWakeCapableUndoPowerDown, 1929 { PwrPolNull, WdfDevStatePwrPolNull }, 1930 NULL, 1931 { FALSE, 1932 0 }, 1933 }, 1934 1935 // WdfDevStatePwrPolTimerExpiredWakeCompletedHardwareStarted 1936 { FxPkgPnp::PowerPolTimerExpiredWakeCompletedHardwareStarted, 1937 { PwrPolNull, WdfDevStatePwrPolNull }, 1938 NULL, 1939 { FALSE, 1940 0 }, 1941 }, 1942 1943 // WdfDevStatePwrPolStoppedRemoving 1944 { FxPkgPnp::PowerPolStoppedRemoving, 1945 { PwrPolNull, WdfDevStatePwrPolNull }, 1946 NULL, 1947 { FALSE, 1948 0 }, 1949 }, 1950 1951 // WdfDevStatePwrPolRemoved 1952 { FxPkgPnp::PowerPolRemoved, 1953 { PwrPolStart, WdfDevStatePwrPolStarting DEBUGGED_EVENT }, 1954 FxPkgPnp::m_PowerPolRemovedOtherStates, 1955 { TRUE, 1956 PwrPolSx | // device is disabled (must be a PDO) and then the machine 1957 // moves into an Sx state 1958 PwrPolS0 | // driver failed power up when moving out of S0 Dx idle 1959 // state and system resumed after failure 1960 PwrPolS0IdlePolicyChanged // driver changes S0 idle settings while being 1961 // removed 1962 }, 1963 }, 1964 1965 // WdfDevStatePwrPolRestarting 1966 { FxPkgPnp::PowerPolRestarting, 1967 { PwrPolPowerUp, WdfDevStatePwrPolStartingSucceeded DEBUGGED_EVENT }, 1968 FxPkgPnp::m_PowerPolRestartingOtherStates, 1969 { FALSE, 1970 0 }, 1971 }, 1972 1973 // WdfDevStatePwrPolRestartingFailed 1974 { FxPkgPnp::PowerPolRestartingFailed, 1975 { PwrPolNull, WdfDevStatePwrPolNull }, 1976 NULL, 1977 { FALSE, 1978 0 }, 1979 }, 1980 1981 // WdfDevStatePwrPolStartingPoweredUpFailed 1982 { FxPkgPnp::PowerPolStartingPoweredUpFailed, 1983 { PwrPolPowerDown, WdfDevStatePwrPolStartingFailed DEBUGGED_EVENT }, 1984 NULL, 1985 { FALSE, 1986 0 }, 1987 }, 1988 1989 // WdfDevStatePwrPolTimerExpiredNoWakeReturnToActive 1990 { FxPkgPnp::PowerPolTimerExpiredNoWakeReturnToActive, 1991 { PwrPolNull, WdfDevStatePwrPolNull }, 1992 NULL, 1993 { FALSE, 1994 0 }, 1995 }, 1996 1997 // WdfDevStatePwrPolWaitingArmedWakeInterruptFired 1998 { FxPkgPnp::PowerPolWaitingArmedWakeInterruptFired, 1999 { PwrPolWakeFailed, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS DEBUGGED_EVENT }, 2000 FxPkgPnp::m_PowerPolWaitingArmedWakeInterruptFiredOtherStates, 2001 { FALSE, 2002 0 }, 2003 }, 2004 2005 // WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFired 2006 { FxPkgPnp::PowerPolSystemWakeDeviceWakeInterruptFired, 2007 { PwrPolWakeFailed, WdfDevStatePwrPolSystemWakeDeviceWakeTriggered TRAP_ON_EVENT }, 2008 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeInterruptFiredOtherStates, 2009 { FALSE, 2010 0 }, 2011 }, 2012 2013 // WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFiredNP 2014 { FxPkgPnp::PowerPolSystemWakeDeviceWakeInterruptFiredNP, 2015 { PwrPolWakeFailed, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredNP TRAP_ON_EVENT }, 2016 FxPkgPnp::m_PowerPolSystemWakeDeviceWakeInterruptFiredNPOtherStates, 2017 { FALSE, 2018 0 }, 2019 }, 2020 2021 // WdfDevStatePwrPolTimerExpiredWakeCapableWakeInterruptArrived 2022 { FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeInterruptArrived, 2023 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCapableWakeSucceeded DEBUGGED_EVENT }, 2024 FxPkgPnp::m_PowerPolTimerExpiredWakeCapableWakeInterruptArrivedOtherStates, 2025 { FALSE, 2026 0 }, 2027 }, 2028 2029 // WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrived 2030 { NULL, 2031 { PwrPolWakeFailed, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled DEBUGGED_EVENT }, 2032 FxPkgPnp::m_PowerPolTimerExpiredWakeCapablePowerDownFailedWakeInterruptArrivedOtherStates, 2033 { FALSE, 2034 0 }, 2035 }, 2036 2037 // WdfDevStatePwrPolWaitingArmedWakeInterruptFiredDuringPowerDown 2038 { NULL, 2039 { PwrPolWakeFailed, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS DEBUGGED_EVENT }, 2040 FxPkgPnp::m_PowerPolWaitingArmedWakeInterruptFiredDuringPowerDownOtherStates, 2041 { FALSE, 2042 0 }, 2043 }, 2044 2045 // WdfDevStatePwrPolNull 2046 // *** no entry for this state *** 2047 }; 2048 2049 // @@SMVERIFY_SPLIT_END 2050 2051 VOID 2052 FxPkgPnp::PowerPolicyCheckAssumptions( 2053 VOID 2054 ) 2055 /*++ 2056 2057 Routine Description: 2058 This routine is never actually called by running code, it just has 2059 WDFCASSERTs who upon failure, would not allow this file to be compiled. 2060 2061 DO NOT REMOVE THIS FUNCTION just because it is not callec by any running 2062 code. 2063 2064 Arguments: 2065 None 2066 2067 Return Value: 2068 None 2069 2070 --*/ 2071 { 2072 WDFCASSERT(sizeof(FxPwrPolStateInfo) == sizeof(ULONG)); 2073 2074 WDFCASSERT((sizeof(m_WdfPowerPolicyStates)/sizeof(m_WdfPowerPolicyStates[0])) 2075 == 2076 (WdfDevStatePwrPolNull - WdfDevStatePwrPolObjectCreated)); 2077 2078 // we assume these are the same length when we update the history index 2079 WDFCASSERT((sizeof(m_PowerPolicyMachine.m_Queue)/ 2080 sizeof(m_PowerPolicyMachine.m_Queue[0])) 2081 == 2082 (sizeof(m_PowerPolicyMachine.m_States.History)/ 2083 sizeof(m_PowerPolicyMachine.m_States.History[0]))); 2084 } 2085 2086 CfxDevice * 2087 IdleTimeoutManagement::GetDevice( 2088 VOID 2089 ) 2090 { 2091 IdlePolicySettings * idlePolicySettings = NULL; 2092 FxPowerPolicyOwnerSettings * ppoSettings = NULL; 2093 FxPkgPnp * pPkgPnp = NULL; 2094 2095 idlePolicySettings = (IdlePolicySettings *) CONTAINING_RECORD( 2096 this, 2097 IdlePolicySettings, 2098 m_TimeoutMgmt 2099 ); 2100 ppoSettings = (FxPowerPolicyOwnerSettings *) CONTAINING_RECORD( 2101 idlePolicySettings, 2102 FxPowerPolicyOwnerSettings, 2103 m_IdleSettings 2104 ); 2105 pPkgPnp = ppoSettings->m_PkgPnp; 2106 2107 return pPkgPnp->GetDevice(); 2108 } 2109 2110 IdleTimeoutManagement::IdleTimeoutStatusUpdateResult 2111 IdleTimeoutManagement::UpdateIdleTimeoutStatus( 2112 __in IdleTimeoutManagement::IdleTimeoutStatusFlag Flag 2113 ) 2114 { 2115 LONG idleTimeoutStatusSnapshot; 2116 LONG updatedIdleTimeoutStatus; 2117 LONG preInterlockedIdleTimeoutStatus; 2118 2119 // 2120 // Take a snapshot of the idle timeout management status 2121 // 2122 idleTimeoutStatusSnapshot = m_IdleTimeoutStatus; 2123 2124 // 2125 // Verify that the flag we're trying to set is not already set 2126 // 2127 if (0 != (idleTimeoutStatusSnapshot & Flag)) { 2128 return IdleTimeoutStatusFlagAlreadySet; 2129 } 2130 2131 // 2132 // Verify that the idle timeout management status is not already 2133 // "frozen" 2134 // 2135 if (0 != (idleTimeoutStatusSnapshot & IdleTimeoutStatusFrozen)) { 2136 // 2137 // It was too late to set the flag. The flag value was already 2138 // "frozen". 2139 // 2140 return IdleTimeoutStatusFlagsAlreadyFrozen; 2141 } 2142 2143 // 2144 // Try to set the flag 2145 // 2146 updatedIdleTimeoutStatus = idleTimeoutStatusSnapshot | Flag; 2147 2148 preInterlockedIdleTimeoutStatus = InterlockedCompareExchange( 2149 &m_IdleTimeoutStatus, 2150 updatedIdleTimeoutStatus, 2151 idleTimeoutStatusSnapshot 2152 ); 2153 if (preInterlockedIdleTimeoutStatus != idleTimeoutStatusSnapshot) { 2154 2155 if (0 != (preInterlockedIdleTimeoutStatus & 2156 IdleTimeoutStatusFrozen)) { 2157 // 2158 // It was too late to set the flag. The flag value was already 2159 // "frozen". 2160 // 2161 return IdleTimeoutStatusFlagsAlreadyFrozen; 2162 } 2163 else { 2164 // 2165 // Idle timeout management status is being changed by multiple 2166 // threads in parallel. This is not supported. 2167 // 2168 return IdleTimeoutStatusFlagsUnexpected; 2169 } 2170 } 2171 2172 // 2173 // We have successfully set the flag 2174 // 2175 return IdleTimeoutStatusFlagsUpdated; 2176 } 2177 2178 NTSTATUS 2179 IdleTimeoutManagement::UseSystemManagedIdleTimeout( 2180 __in PFX_DRIVER_GLOBALS DriverGlobals 2181 ) 2182 { 2183 NTSTATUS status; 2184 IdleTimeoutStatusUpdateResult statusUpdateResult; 2185 CfxDevice * device; 2186 2187 // 2188 // First check if we are running on Windows 8 or above 2189 // 2190 if (_SystemManagedIdleTimeoutAvailable()) { 2191 2192 // 2193 // Get the device object so we can use it for logging 2194 // 2195 device = GetDevice(); 2196 2197 // 2198 // Try to update the flag that specifies that the power framework should 2199 // determine the idle timeout. 2200 // 2201 statusUpdateResult = UpdateIdleTimeoutStatus(IdleTimeoutSystemManaged); 2202 2203 switch (statusUpdateResult) { 2204 case IdleTimeoutStatusFlagsAlreadyFrozen: 2205 { 2206 // 2207 // Status is already frozen. Too late to update it. 2208 // 2209 status = STATUS_INVALID_DEVICE_REQUEST; 2210 DoTraceLevelMessage( 2211 DriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 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. " 2217 "%!STATUS!.", 2218 device->GetHandle(), 2219 device->GetDeviceObject(), 2220 status 2221 ); 2222 FxVerifierDbgBreakPoint(DriverGlobals); 2223 } 2224 break; 2225 2226 case IdleTimeoutStatusFlagsUnexpected: 2227 { 2228 // 2229 // Status being updated from multiple threads in parallel. Not 2230 // supported. 2231 // 2232 status = STATUS_INVALID_DEVICE_REQUEST; 2233 DoTraceLevelMessage( 2234 DriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 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!.", 2239 device->GetHandle(), 2240 device->GetDeviceObject(), 2241 status 2242 ); 2243 FxVerifierDbgBreakPoint(DriverGlobals); 2244 } 2245 break; 2246 2247 case IdleTimeoutStatusFlagAlreadySet: 2248 { 2249 // 2250 // Status flag was already set. This should never happen for the 2251 // IdleTimeoutSystemManaged flag. The caller ensures this. 2252 // 2253 ASSERTMSG( 2254 "IdleTimeoutManagement::UseSystemManagedIdleTimeout was " 2255 "called more than once\n", FALSE); 2256 } 2257 2258 // 2259 // Fall through 2260 // 2261 // || || || 2262 // \/ \/ \/ 2263 // 2264 case IdleTimeoutStatusFlagsUpdated: 2265 { 2266 status = STATUS_SUCCESS; 2267 } 2268 break; 2269 2270 default: 2271 { 2272 ASSERTMSG("Unexpected IdleTimeoutStatusUpdateResult value\n", 2273 FALSE); 2274 status = STATUS_INTERNAL_ERROR; 2275 } 2276 } 2277 2278 } else { 2279 // 2280 // If we're not running on Windows 8 or above, then there is nothing to 2281 // do. 2282 // 2283 status = STATUS_SUCCESS; 2284 } 2285 2286 return status; 2287 } 2288 2289 VOID 2290 IdleTimeoutManagement::FreezeIdleTimeoutManagementStatus( 2291 __in PFX_DRIVER_GLOBALS DriverGlobals 2292 ) 2293 { 2294 LONG idleTimeoutSnapshot; 2295 LONG idleTimeoutStatus; 2296 LONG idleTimeoutPreviousStatus; 2297 CfxDevice * device; 2298 2299 // 2300 // Get the device object so we can use it for logging 2301 // 2302 device = GetDevice(); 2303 2304 // 2305 // Take a snapshot of the idle timeout management status 2306 // 2307 idleTimeoutSnapshot = m_IdleTimeoutStatus; 2308 2309 // 2310 // Set the bit that freezes the status 2311 // 2312 idleTimeoutStatus = idleTimeoutSnapshot | IdleTimeoutStatusFrozen; 2313 2314 // 2315 // Update the status 2316 // 2317 idleTimeoutPreviousStatus = InterlockedExchange(&m_IdleTimeoutStatus, 2318 idleTimeoutStatus); 2319 2320 if (idleTimeoutPreviousStatus != idleTimeoutSnapshot) { 2321 // 2322 // An update of idle timeout status is racing with the freezing of idle 2323 // timeout status 2324 // 2325 DoTraceLevelMessage( 2326 DriverGlobals, TRACE_LEVEL_WARNING, TRACINGPNP, 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.", 2331 device->GetHandle(), 2332 device->GetDeviceObject() 2333 ); 2334 FxVerifierDbgBreakPoint(DriverGlobals); 2335 } 2336 2337 // 2338 // If the driver has specified power framework settings and system managed 2339 // idle timeout is available on this OS, then the driver must have opted for 2340 // system managed idle timeout. 2341 // 2342 if ((0 != (idleTimeoutStatus & IdleTimeoutPoxSettingsSpecified)) && 2343 (_SystemManagedIdleTimeoutAvailable()) && 2344 (0 == (idleTimeoutStatus & IdleTimeoutSystemManaged))) { 2345 DoTraceLevelMessage( 2346 DriverGlobals, TRACE_LEVEL_WARNING, TRACINGPNP, 2347 "WDFDEVICE %p !devobj %p The driver specified power framework " 2348 "settings, but did not opt for system-managed idle timeout.", 2349 device->GetHandle(), 2350 device->GetDeviceObject() 2351 ); 2352 FxVerifierDbgBreakPoint(DriverGlobals); 2353 } 2354 } 2355 2356 BOOLEAN 2357 IdleTimeoutManagement::UsingSystemManagedIdleTimeout( 2358 VOID 2359 ) 2360 { 2361 // 2362 // If the value of this constant is changed, the debugger extension needs 2363 // to be fixed as well. 2364 // 2365 C_ASSERT(0x2 == IdleTimeoutSystemManaged); 2366 2367 return (0 != (m_IdleTimeoutStatus & IdleTimeoutSystemManaged)); 2368 } 2369 2370 BOOLEAN 2371 IdleTimeoutManagement::DriverSpecifiedPowerFrameworkSettings( 2372 VOID 2373 ) 2374 { 2375 return (0 != (m_IdleTimeoutStatus & IdleTimeoutPoxSettingsSpecified)); 2376 } 2377 2378 NTSTATUS 2379 IdleTimeoutManagement::CommitPowerFrameworkSettings( 2380 __in PFX_DRIVER_GLOBALS DriverGlobals, 2381 __in PPOX_SETTINGS PoxSettings 2382 ) 2383 { 2384 NTSTATUS status; 2385 IdleTimeoutStatusUpdateResult statusUpdateResult; 2386 PVOID oldPoxSettings = NULL; 2387 BOOLEAN settingsSuccessfullySaved = FALSE; 2388 CfxDevice * device; 2389 2390 // 2391 // We should never get here if system-managed idle timeout is not available 2392 // 2393 ASSERT(_SystemManagedIdleTimeoutAvailable()); 2394 2395 // 2396 // Get the device object so we can use it for logging 2397 // 2398 device = GetDevice(); 2399 2400 // 2401 // Try to save the driver's power framework settings 2402 // 2403 oldPoxSettings = InterlockedCompareExchangePointer((PVOID*) &m_PoxSettings, 2404 PoxSettings, 2405 NULL // Comparand 2406 ); 2407 if (NULL != oldPoxSettings) { 2408 // 2409 // The driver's power framework settings have already been specified 2410 // earlier. The driver should not be attempting to specify them more 2411 // than once. 2412 // 2413 status = STATUS_INVALID_DEVICE_REQUEST; 2414 DoTraceLevelMessage( 2415 DriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2416 "WDFDEVICE %p !devobj %p The driver attempted to specify power " 2417 "framework settings more than once. %!STATUS!.", 2418 device->GetHandle(), 2419 device->GetDeviceObject(), 2420 status 2421 ); 2422 FxVerifierDbgBreakPoint(DriverGlobals); 2423 goto exit; 2424 } 2425 settingsSuccessfullySaved = TRUE; 2426 2427 // 2428 // Try to update the flag that indicates that the client driver has 2429 // specified settings that are to be used when we register with the power 2430 // framework. 2431 // 2432 statusUpdateResult = UpdateIdleTimeoutStatus( 2433 IdleTimeoutPoxSettingsSpecified 2434 ); 2435 switch (statusUpdateResult) { 2436 case IdleTimeoutStatusFlagsAlreadyFrozen: 2437 { 2438 // 2439 // Status is already frozen. Too late to update it. 2440 // 2441 status = STATUS_INVALID_DEVICE_REQUEST; 2442 DoTraceLevelMessage( 2443 DriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 2444 "WDFDEVICE %p !devobj %p Power framework settings must be " 2445 "specified before the first start IRP is completed. %!STATUS!.", 2446 device->GetHandle(), 2447 device->GetDeviceObject(), 2448 status 2449 ); 2450 FxVerifierDbgBreakPoint(DriverGlobals); 2451 goto exit; 2452 } 2453 break; 2454 2455 case IdleTimeoutStatusFlagsUnexpected: 2456 { 2457 // 2458 // Status being updated from multiple threads in parallel. Not 2459 // supported. 2460 // 2461 status = STATUS_INVALID_DEVICE_REQUEST; 2462 DoTraceLevelMessage( 2463 DriverGlobals, TRACE_LEVEL_ERROR, TRACINGPNP, 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!.", 2468 device->GetHandle(), 2469 device->GetDeviceObject(), 2470 status 2471 ); 2472 FxVerifierDbgBreakPoint(DriverGlobals); 2473 goto exit; 2474 } 2475 break; 2476 2477 case IdleTimeoutStatusFlagAlreadySet: 2478 { 2479 // 2480 // Status flag was already set. This should never happen for the 2481 // IdleTimeoutPoxSettingsSpecified flag because we have logic in the 2482 // beginning of this function to ensure that only the first caller 2483 // attempts to set this flag. 2484 // 2485 ASSERTMSG( 2486 "Attempt to set the IdleTimeoutPoxSettingsSpecified flag more " 2487 "than once\n", FALSE); 2488 status = STATUS_INTERNAL_ERROR; 2489 goto exit; 2490 } 2491 2492 case IdleTimeoutStatusFlagsUpdated: 2493 { 2494 status = STATUS_SUCCESS; 2495 } 2496 break; 2497 2498 default: 2499 { 2500 ASSERTMSG("Unexpected IdleTimeoutStatusUpdateResult value\n", 2501 FALSE); 2502 status = STATUS_INTERNAL_ERROR; 2503 goto exit; 2504 } 2505 } 2506 2507 // 2508 // If we get here, we must have a successful status 2509 // 2510 ASSERT(STATUS_SUCCESS == status); 2511 2512 exit: 2513 if (FALSE == NT_SUCCESS(status)) { 2514 if (settingsSuccessfullySaved) { 2515 // 2516 // Since a failure has occurred, we must reset the pointer to the 2517 // power framework settings. 2518 // 2519 m_PoxSettings = NULL; 2520 } 2521 } 2522 return status; 2523 } 2524 2525 PolicySettings::~PolicySettings() 2526 { 2527 2528 2529 2530 2531 2532 2533 2534 } 2535 2536 FxPowerPolicyMachine::FxPowerPolicyMachine( 2537 VOID 2538 ) : FxThreadedEventQueue(FxPowerPolicyEventQueueDepth) 2539 { 2540 m_Owner = NULL; 2541 2542 RtlZeroMemory(&m_Queue[0], sizeof(m_Queue)); 2543 RtlZeroMemory(&m_States, sizeof(m_States)); 2544 2545 m_States.History[IncrementHistoryIndex()] = WdfDevStatePwrPolObjectCreated; 2546 2547 m_SingularEventsPresent = 0x0; 2548 } 2549 2550 FxPowerPolicyMachine::~FxPowerPolicyMachine( 2551 VOID 2552 ) 2553 { 2554 if (m_Owner != NULL) { 2555 delete m_Owner; 2556 m_Owner = NULL; 2557 } 2558 } 2559 2560 _Must_inspect_result_ 2561 NTSTATUS 2562 FxPowerPolicyMachine::InitUsbSS( 2563 VOID 2564 ) 2565 { 2566 FxUsbIdleInfo* pInfo; 2567 NTSTATUS status; 2568 2569 // 2570 // The field is already set, we are good to go 2571 // 2572 if (m_Owner->m_UsbIdle != NULL) { 2573 return STATUS_SUCCESS; 2574 } 2575 2576 pInfo = new (m_PkgPnp->GetDriverGlobals()) FxUsbIdleInfo(m_PkgPnp); 2577 2578 if (pInfo == NULL) { 2579 return STATUS_INSUFFICIENT_RESOURCES; 2580 } 2581 2582 status = pInfo->Initialize(); 2583 if (!NT_SUCCESS(status)) { 2584 delete pInfo; 2585 return status; 2586 } 2587 2588 if (InterlockedCompareExchangePointer((PVOID*) &m_Owner->m_UsbIdle, 2589 pInfo, 2590 NULL) == NULL) { 2591 // 2592 // This thread was the one that set the field value. 2593 // 2594 DO_NOTHING(); 2595 } 2596 else { 2597 // 2598 // Another thread raced in and beat this thread in setting the field, 2599 // just delete our allocation and use the other allocated FxUsbIdleInfo. 2600 // 2601 delete pInfo; 2602 } 2603 2604 return STATUS_SUCCESS; 2605 } 2606 2607 FxPowerPolicyOwnerSettings::FxPowerPolicyOwnerSettings( 2608 __in FxPkgPnp* PkgPnp 2609 ) : m_PoxInterface(PkgPnp) 2610 { 2611 ULONG i; 2612 2613 m_UsbIdle = NULL; 2614 2615 m_PkgPnp = PkgPnp; 2616 2617 // 2618 // Default every state to D3 except for system working which is D0 by 2619 // default. 2620 // 2621 m_SystemToDeviceStateMap = 0x0; 2622 2623 for (i = 0; i < PowerSystemMaximum; i++) { 2624 FxPkgPnp::_SetPowerCapState(i, 2625 i == PowerSystemWorking ? PowerDeviceD0 2626 : PowerDeviceD3, 2627 &m_SystemToDeviceStateMap); 2628 } 2629 2630 m_IdealDxStateForSx = PowerDeviceD3; 2631 2632 m_RequestedPowerUpIrp = FALSE; 2633 m_RequestedPowerDownIrp = FALSE; 2634 m_RequestedWaitWakeIrp = FALSE; 2635 m_WakeCompletionEventDropped = FALSE; 2636 m_PowerFailed = FALSE; 2637 m_CanSaveState = TRUE; 2638 2639 m_ChildrenCanPowerUp = FALSE; 2640 m_ChildrenPoweredOnCount = 0; 2641 m_ChildrenArmedCount = 0; 2642 2643 m_WaitWakeStatus = STATUS_NOT_SUPPORTED; 2644 m_SystemWakeSource = FALSE; 2645 m_WaitWakeCancelCompletionOwnership = CancelOwnershipUnclaimed; 2646 2647 m_PowerCallbackObject = NULL; 2648 m_PowerCallbackRegistration = NULL; 2649 } 2650 2651 FxPowerPolicyOwnerSettings::~FxPowerPolicyOwnerSettings( 2652 VOID 2653 ) 2654 { 2655 // 2656 // There are paths which cleanup this object which do not go through the 2657 // pnp state machine, so make sure the power object callback fields are 2658 // freed. In these paths, we are guaranteed PASSIVE_LEVEL b/c there will 2659 // be no dangling references which can cause deletion at a greater IRQL. 2660 // 2661 CleanupPowerCallback(); 2662 2663 if (m_UsbIdle != NULL) { 2664 delete m_UsbIdle; 2665 m_UsbIdle = NULL; 2666 } 2667 } 2668 2669 VOID 2670 FxPowerPolicyOwnerSettings::CleanupPowerCallback( 2671 VOID 2672 ) 2673 /*++ 2674 2675 Routine Description: 2676 Cleans up the power state callback registration for this object. 2677 2678 Arguments: 2679 None 2680 2681 Return Value: 2682 None 2683 2684 --*/ 2685 { 2686 if (m_PowerCallbackRegistration != NULL) { 2687 Mx::UnregisterCallback(m_PowerCallbackRegistration); 2688 m_PowerCallbackRegistration = NULL; 2689 2690 } 2691 2692 if (m_PowerCallbackObject != NULL) { 2693 Mx::MxDereferenceObject(m_PowerCallbackObject); 2694 m_PowerCallbackObject = NULL; 2695 } 2696 } 2697 2698 _Must_inspect_result_ 2699 NTSTATUS 2700 FxPowerPolicyOwnerSettings::Init( 2701 VOID 2702 ) 2703 /*++ 2704 2705 Routine Description: 2706 Initialize the object. We will try to register a power state callback so 2707 that we can be informed of when the machine is changing S states. We are 2708 interested in system state changes because we need to know when NOT to write 2709 to the registry (to save wake settings) so that we don't cause a deadlock 2710 in a non power pageable device while moving into Sx. 2711 2712 Arguments: 2713 None 2714 2715 Return Value: 2716 NTSTATUS 2717 2718 --*/ 2719 { 2720 OBJECT_ATTRIBUTES oa; 2721 UNICODE_STRING string; 2722 NTSTATUS status; 2723 2724 RtlInitUnicodeString(&string, L"\\Callback\\PowerState"); 2725 InitializeObjectAttributes( 2726 &oa, 2727 &string, 2728 OBJ_CASE_INSENSITIVE, 2729 NULL, 2730 NULL 2731 ); 2732 2733 // 2734 // Create a callback object, but we do not want to be the first ones 2735 // to create it (it should be created way before we load in NTOS 2736 // anyways) 2737 // 2738 status = Mx::CreateCallback(&m_PowerCallbackObject, &oa, FALSE, TRUE); 2739 2740 if (NT_SUCCESS(status)) { 2741 m_PowerCallbackRegistration = Mx::RegisterCallback( 2742 m_PowerCallbackObject, 2743 _PowerStateCallback, 2744 this 2745 ); 2746 2747 if (m_PowerCallbackRegistration == NULL) { 2748 // 2749 // Non-critical failure, so we'll free the callback object and keep 2750 // going 2751 // 2752 Mx::MxDereferenceObject(m_PowerCallbackObject); 2753 m_PowerCallbackObject = NULL; 2754 } 2755 } 2756 2757 // 2758 // Initialize FxPowerIdleMachine 2759 // 2760 status = m_PowerIdleMachine.Init(); 2761 if (!NT_SUCCESS(status)) { 2762 return status; 2763 } 2764 2765 return status; 2766 } 2767 2768 VOID 2769 FxPowerPolicyOwnerSettings::_PowerStateCallback( 2770 __in PVOID Context, 2771 __in_opt PVOID Argument1, 2772 __in_opt PVOID Argument2 2773 ) 2774 /*++ 2775 2776 Routine Description: 2777 Callback invoked by the power subsystem when the system is changing S states 2778 2779 Arguments: 2780 Context - FxPowerPolicyOwnerSettings pointer (the "this" pointer) 2781 2782 Argument1 - Reason why the callback was invoked, we only care about 2783 PO_CB_SYSTEM_STATE_LOCK 2784 2785 Argument2 - State transition that is occurring 2786 2787 Return Value: 2788 None 2789 2790 --*/ 2791 { 2792 FxPowerPolicyOwnerSettings* pThis; 2793 2794 pThis = (FxPowerPolicyOwnerSettings*) Context; 2795 2796 if (Argument1 != (PVOID) PO_CB_SYSTEM_STATE_LOCK) { 2797 return; 2798 } 2799 2800 pThis->m_PkgPnp->m_PowerPolicyMachine.m_StateMachineLock.AcquireLock( 2801 pThis->m_PkgPnp->GetDriverGlobals(), 2802 NULL 2803 ); 2804 2805 if (Argument2 == (PVOID) 0) { 2806 // 2807 // Write out the state if necessary before we turn off the paging path. 2808 // 2809 pThis->m_PkgPnp->SaveState(TRUE); 2810 2811 // 2812 // Exiting S0 2813 // 2814 pThis->m_CanSaveState = FALSE; 2815 } 2816 else if (Argument2 == (PVOID) 1) { 2817 // 2818 // We have reentered S0 2819 // 2820 pThis->m_CanSaveState = TRUE; 2821 2822 // 2823 // Write out the state if necessary now that the paging path is back 2824 // 2825 pThis->m_PkgPnp->SaveState(TRUE); 2826 } 2827 2828 pThis->m_PkgPnp->m_PowerPolicyMachine.m_StateMachineLock.ReleaseLock( 2829 pThis->m_PkgPnp->GetDriverGlobals() 2830 ); 2831 } 2832 2833 /*++ 2834 2835 The locking model for the Power policy state machine requires that events be enqueued 2836 possibly at DISPATCH_LEVEL. It also requires that the state machine be 2837 runnable at PASSIVE_LEVEL. Consequently, we have two locks, one DISPATCH_LEVEL 2838 lock that guards the event queue and one PASSIVE_LEVEL lock that guards the 2839 state machine itself. 2840 2841 The Power policy state machine has a few constraints that the PnP state machine 2842 doesn't. Sometimes it has to call some driver functions at PASSIVE_LEVEL, but 2843 with the disks turned off. This means that these functions absolutely must not 2844 page fault. You might think that this means that we should call the driver at 2845 DISPATCH_LEVEL, and you'd be right if your only concern were for perfectly 2846 safe code. The problem with that approach, though is that it will force much 2847 of the rest of the driver to DISPATCH_LEVEL, which will only push the driver 2848 writer into using lots of asynchronous work items, which will complicate their 2849 code and make it unsafe in a new variety of ways. So we're going to go with 2850 PASSIVE_LEVEL here and setting a timeout of 20 seconds. If the driver faults, 2851 the timer will fire and log the failure. This also means that the driver must 2852 complete these callbacks within 20 seconds. Even beyond that, it means that 2853 the work items must be queued onto a special thread, one that once the machine 2854 has started to go to sleep, never handles any work items that may fault. 2855 2856 Algorithm: 2857 2858 1) Acquire the Power policy queue lock. 2859 2) Enqueue the event. events are put at the end of the queue. 2860 3) Drop the Power policy queue lock. 2861 4) If the thread is running at PASSIVE_LEVEL, skip to step 6. 2862 5) Queue a work item onto the special power thread. 2863 6) Attempt to acquire the state machine lock, with a zero-length timeout (*). 2864 7) If successful, skip to step 9. 2865 8) Queue a work item onto the special power thread. 2866 9) Acquire the state machine lock. 2867 10) Acquire the Power policy queue lock. 2868 11) Attempt to dequeue an event. 2869 12) Drop the Power policyqueue lock. 2870 13) If there was no event to dequeue, drop the state machine lock and exit. 2871 14) Execute the state handler. This may involve taking one of the other state 2872 machine queue locks, briefly, to deliver an event. 2873 15) Go to Step 10. 2874 2875 (*) zero length is different then NULL (infinite) being passed for the timeout 2876 2877 Implementing this algorithm requires three functions. 2878 2879 PowerPolicyProcessEvent -- Implements steps 1-8. 2880 _PowerPolicyProcessEventInner -- Implements step 9. 2881 PowerPolicyProcessEventInner -- Implements steps 10-15. 2882 2883 --*/ 2884 2885 VOID 2886 FxPkgPnp::PowerPolicyProcessEvent( 2887 __in FxPowerPolicyEvent Event, 2888 __in BOOLEAN ProcessOnDifferentThread 2889 ) 2890 /*++ 2891 2892 Routine Description: 2893 This function implements steps 1-8 of the algorithm described above. 2894 2895 Arguments: 2896 Event - Current Power event 2897 2898 Return Value: 2899 2900 NTSTATUS 2901 2902 --*/ 2903 { 2904 NTSTATUS status; 2905 ULONG mask; 2906 KIRQL irql; 2907 2908 // 2909 // Take the lock, raising to DISPATCH_LEVEL. 2910 // 2911 m_PowerPolicyMachine.Lock(&irql); 2912 2913 // 2914 // If the input Event is any of the events described by PowerSingularEventMask, 2915 // then check whether it is already queued up. If so, then dont enqueue this 2916 // Event. 2917 // 2918 if (Event & PowerPolSingularEventMask) { 2919 if ((m_PowerPolicyMachine.m_SingularEventsPresent & Event) == 0x00) { 2920 m_PowerPolicyMachine.m_SingularEventsPresent |= Event; 2921 } 2922 else { 2923 DoTraceLevelMessage( 2924 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP, 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.", 2928 m_Device->GetHandle(), 2929 m_Device->GetDeviceObject(), 2930 m_Device->GetDevicePowerPolicyState(), Event); 2931 2932 m_PowerPolicyMachine.Unlock(irql); 2933 return; 2934 } 2935 } 2936 2937 if (m_PowerPolicyMachine.IsFull()) { 2938 // 2939 // The queue is full. Bail. 2940 // 2941 m_PowerPolicyMachine.Unlock(irql); 2942 2943 ASSERT(!"The Power queue is full. This shouldn't be able to happen."); 2944 return; 2945 } 2946 2947 if (m_PowerPolicyMachine.IsClosedLocked()) { 2948 DoTraceLevelMessage( 2949 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP, 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", 2953 m_Device->GetHandle(), 2954 m_Device->GetDeviceObject(), 2955 m_Device->GetDevicePowerPolicyState(), Event); 2956 2957 // 2958 // The queue is closed. Bail 2959 // 2960 m_PowerPolicyMachine.Unlock(irql); 2961 2962 return; 2963 } 2964 2965 // 2966 // Enqueue the event. Whether the event goes on the front 2967 // or the end of the queue depends on which event it is and if we are the 2968 // PPO or not. 2969 // 2970 // Yes, mask could be a member variable of m_PowerPolicyMachine, but why 2971 // waste 4 bytes when it is very easy to figure out? 2972 // 2973 mask = IsPowerPolicyOwner() ? PwrPolPriorityEventsMask 2974 : PwrPolNotOwnerPriorityEventsMask; 2975 2976 if (Event & mask) { 2977 // 2978 // Stick it on the front of the queue, making it the next event that 2979 // will be processed if, otherwise let these events go by. 2980 // 2981 m_PowerPolicyMachine.m_Queue[m_PowerPolicyMachine.InsertAtHead()] = Event; 2982 } 2983 else { 2984 // 2985 // Stick it on the end of the queue. 2986 // 2987 m_PowerPolicyMachine.m_Queue[m_PowerPolicyMachine.InsertAtTail()] = Event; 2988 } 2989 2990 // 2991 // Drop the lock. 2992 // 2993 m_PowerPolicyMachine.Unlock(irql); 2994 2995 // 2996 // Now, if we are running at PASSIVE_LEVEL, attempt to run the state 2997 // machine on this thread. If we can't do that, then queue a work item. 2998 // 2999 if (FALSE == ShouldProcessPowerPolicyEventOnDifferentThread( 3000 irql, 3001 ProcessOnDifferentThread 3002 )) { 3003 3004 LONGLONG timeout = 0; 3005 3006 status = m_PowerPolicyMachine.m_StateMachineLock.AcquireLock( 3007 GetDriverGlobals(), &timeout); 3008 3009 if (FxWaitLockInternal::IsLockAcquired(status)) { 3010 FxPostProcessInfo info; 3011 3012 // 3013 // We now hold the state machine lock. So call the function that 3014 // dispatches the next state. 3015 // 3016 PowerPolicyProcessEventInner(&info); 3017 3018 // 3019 // The pnp state machine should be the only one deleting the object 3020 // 3021 ASSERT(info.m_DeleteObject == FALSE); 3022 3023 m_PowerPolicyMachine.m_StateMachineLock.ReleaseLock( 3024 GetDriverGlobals()); 3025 3026 info.Evaluate(this); 3027 3028 return; 3029 } 3030 } 3031 3032 // 3033 // The tag added above will be released when the work item runs 3034 // 3035 3036 // 3037 // For one reason or another, we couldn't run the state machine on this 3038 // thread. So queue a work item to do it. If m_PnPWorkItemEnqueuing 3039 // is non-zero, that means that the work item is already being enqueued 3040 // on another thread. This is significant, since it means that we can't do 3041 // anything with the work item on this thread, but it's okay, since the 3042 // work item will pick up our work and do it. 3043 // 3044 m_PowerPolicyMachine.QueueToThread(); 3045 } 3046 3047 VOID 3048 FxPkgPnp::_PowerPolicyProcessEventInner( 3049 __inout FxPkgPnp* This, 3050 __inout FxPostProcessInfo* Info, 3051 __in PVOID Context 3052 ) 3053 { 3054 3055 UNREFERENCED_PARAMETER(Context); 3056 3057 // 3058 // Take the state machine lock. 3059 // 3060 This->m_PowerPolicyMachine.m_StateMachineLock.AcquireLock( 3061 This->GetDriverGlobals() 3062 ); 3063 3064 // 3065 // Call the function that will actually run the state machine. 3066 // 3067 This->PowerPolicyProcessEventInner(Info); 3068 3069 // 3070 // We are being called from the work item and m_WorkItemRunning is > 0, so 3071 // we cannot be deleted yet. 3072 // 3073 ASSERT(Info->SomethingToDo() == FALSE); 3074 3075 // 3076 // Now release the lock 3077 // 3078 This->m_PowerPolicyMachine.m_StateMachineLock.ReleaseLock( 3079 This->GetDriverGlobals() 3080 ); 3081 } 3082 3083 VOID 3084 FxPkgPnp::PowerPolicyProcessEventInner( 3085 __inout FxPostProcessInfo* Info 3086 ) 3087 { 3088 WDF_DEVICE_POWER_POLICY_STATE newState; 3089 FxPowerPolicyEvent event; 3090 ULONG i; 3091 KIRQL irql; 3092 3093 if (IsPowerPolicyOwner()) { 3094 CPPOWER_POLICY_STATE_TABLE entry; 3095 3096 // 3097 // Process as many events as we can. 3098 // 3099 for ( ; ; ) { 3100 entry = GetPowerPolicyTableEntry(m_Device->GetDevicePowerPolicyState()); 3101 3102 // 3103 // Get an event from the queue. 3104 // 3105 m_PowerPolicyMachine.Lock(&irql); 3106 3107 if (m_PowerPolicyMachine.IsEmpty()) { 3108 m_PowerPolicyMachine.GetFinishedState(Info); 3109 3110 // 3111 // The queue is empty. 3112 // 3113 m_PowerPolicyMachine.Unlock(irql); 3114 return; 3115 } 3116 3117 event = m_PowerPolicyMachine.m_Queue[m_PowerPolicyMachine.GetHead()]; 3118 3119 // 3120 // At this point, we need to determine whether we can process this 3121 // event. 3122 // 3123 if (event & PwrPolPriorityEventsMask) { 3124 // 3125 // These are always possible to handle. 3126 // 3127 DO_NOTHING(); 3128 } 3129 else { 3130 // 3131 // Check to see if this state can handle new events, ie if this 3132 // is a green dot (queue open) or red dot (queue *not* open) state. 3133 // 3134 if (entry->StateInfo.Bits.QueueOpen == FALSE) { 3135 // 3136 // This state can't handle new events. 3137 // 3138 m_PowerPolicyMachine.Unlock(irql); 3139 return; 3140 } 3141 } 3142 3143 // 3144 // If the event obtained from the queue was a singular event, then 3145 // clear the flag to allow other similar events to be put into this 3146 // queue for processing. 3147 // 3148 if (m_PowerPolicyMachine.m_SingularEventsPresent & event) { 3149 m_PowerPolicyMachine.m_SingularEventsPresent &= ~event; 3150 } 3151 3152 m_PowerPolicyMachine.IncrementHead(); 3153 m_PowerPolicyMachine.Unlock(irql); 3154 3155 // 3156 // Find the entry in the power policy state table that corresponds 3157 // to this event. 3158 // 3159 newState = WdfDevStatePwrPolNull; 3160 3161 if (entry->FirstTargetState.PowerPolicyEvent == event) { 3162 newState = entry->FirstTargetState.TargetState; 3163 3164 DO_EVENT_TRAP(&entry->FirstTargetState); 3165 } 3166 else if (entry->OtherTargetStates != NULL) { 3167 for (i = 0; 3168 entry->OtherTargetStates[i].PowerPolicyEvent != PwrPolNull; 3169 i++) { 3170 if (entry->OtherTargetStates[i].PowerPolicyEvent == event) { 3171 newState = entry->OtherTargetStates[i].TargetState; 3172 DO_EVENT_TRAP(&entry->OtherTargetStates[i]); 3173 break; 3174 } 3175 } 3176 } 3177 3178 if (newState == WdfDevStatePwrPolNull) { 3179 // 3180 // This state doesn't respond to the event. Just throw the event 3181 // away. 3182 // 3183 DoTraceLevelMessage( 3184 GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 3185 "WDFDEVICE 0x%p !devobj 0x%p current pwr pol state " 3186 "%!WDF_DEVICE_POWER_POLICY_STATE! dropping event " 3187 "%!FxPowerPolicyEvent!", m_Device->GetHandle(), 3188 m_Device->GetDeviceObject(), 3189 m_Device->GetDevicePowerPolicyState(), event); 3190 3191 if ((entry->StateInfo.Bits.KnownDroppedEvents & event) == 0) { 3192 COVERAGE_TRAP(); 3193 3194 DoTraceLevelMessage( 3195 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 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!", 3200 m_Device->GetHandle(), m_Device->GetDeviceObject(), 3201 m_Device->GetDevicePowerPolicyState(), 3202 event, entry->StateInfo.Bits.KnownDroppedEvents); 3203 3204 3205 } 3206 3207 // 3208 // Failsafes for events which have required processing in them. 3209 // 3210 switch (event) { 3211 case PwrPolSx: 3212 // 3213 // The Sx handling code expects that the state machine 3214 // complete the Sx irp. (S0 irps are never pended). Since 3215 // we don't have a state to transition to that will complete 3216 // the request, do so now. 3217 // 3218 // (This can legitimately happen if a PDO is disabled and 3219 // the machines moves into an Sx state.) 3220 // 3221 PowerPolicyCompleteSystemPowerIrp(); 3222 break; 3223 3224 case PwrPolUsbSelectiveSuspendCompleted: 3225 // 3226 // This state did not handle the event and event got 3227 // dropped. However some state is definitely going to wait 3228 // for this event. That's why we need m_EventDropped flag. 3229 // If we didn't have this flag there will be no way to know 3230 // if the event got dropped and some state will end up 3231 // waiting for it indefinitely. 3232 // 3233 m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_EventDropped = TRUE; 3234 break; 3235 3236 case PwrPolUsbSelectiveSuspendCallback: 3237 m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 3238 break; 3239 3240 case PwrPolWakeSuccess: 3241 case PwrPolWakeFailed: 3242 // 3243 // This state did not handle the event and event got 3244 // dropped. However some state is definitely going to wait 3245 // for this event. That's why we need 3246 // m_WakeCompletionEventDropped flag. If we didn't have this 3247 // flag there will be no way to know if the event got 3248 // dropped and some state will end up waiting for it 3249 // indefinitely. 3250 // 3251 m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped = TRUE; 3252 break; 3253 3254 default: 3255 DO_NOTHING(); 3256 break; 3257 } 3258 } 3259 else { 3260 // 3261 // Now enter the new state. 3262 // 3263 PowerPolicyEnterNewState(newState); 3264 } 3265 } 3266 } 3267 else { 3268 // 3269 // Process as many events as we can. 3270 // 3271 for ( ; ; ) { 3272 CPNOT_POWER_POLICY_OWNER_STATE_TABLE entry; 3273 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") 3275 entry = GetNotPowerPolicyOwnerTableEntry( 3276 m_Device->GetDevicePowerPolicyState() 3277 ); 3278 3279 // 3280 // Get an event from the queue. 3281 // 3282 m_PowerPolicyMachine.Lock(&irql); 3283 3284 if (m_PowerPolicyMachine.IsEmpty()) { 3285 // 3286 // The queue is empty. 3287 // 3288 m_PowerPolicyMachine.Unlock(irql); 3289 return; 3290 } 3291 3292 event = m_PowerPolicyMachine.m_Queue[m_PowerPolicyMachine.GetHead()]; 3293 3294 // 3295 // At this point, we need to determine whether we can process this 3296 // event. 3297 // 3298 if (event & PwrPolNotOwnerPriorityEventsMask) { 3299 // 3300 // These are always possible to handle. 3301 // 3302 DO_NOTHING(); 3303 } 3304 else { 3305 // 3306 // Check to see if this state can handle new events, ie if this 3307 // is a green dot (queue open) or red dot (queue *not* open) state. 3308 // 3309 if (entry->QueueOpen == FALSE) { 3310 // 3311 // This state can't handle new events. 3312 // 3313 m_PowerPolicyMachine.Unlock(irql); 3314 return; 3315 } 3316 } 3317 3318 // 3319 // If the event obtained from the queue was a singular event, then 3320 // clear the flag to allow other similar events to be put into this 3321 // queue for processing. 3322 // 3323 if (m_PowerPolicyMachine.m_SingularEventsPresent & event) { 3324 m_PowerPolicyMachine.m_SingularEventsPresent &= ~event; 3325 } 3326 3327 m_PowerPolicyMachine.IncrementHead(); 3328 m_PowerPolicyMachine.Unlock(irql); 3329 3330 if (entry != NULL && entry->TargetStatesCount > 0) { 3331 for (i = 0; i < entry->TargetStatesCount; i++) { 3332 if (event == entry->TargetStates[i].PowerPolicyEvent) { 3333 DO_EVENT_TRAP(&entry->TargetStates[i]); 3334 3335 // 3336 // Now enter the new state. 3337 // 3338 NotPowerPolicyOwnerEnterNewState( 3339 entry->TargetStates[i].TargetState); 3340 break; 3341 } 3342 } 3343 } 3344 } 3345 } 3346 } 3347 3348 VOID 3349 FxPkgPnp::PowerPolicyEnterNewState( 3350 __in WDF_DEVICE_POWER_POLICY_STATE NewState 3351 ) 3352 /*++ 3353 3354 Routine Description: 3355 This function looks up the handler for a state and then calls it. 3356 3357 Arguments: 3358 Event - Current power plicy event 3359 3360 Return Value: 3361 3362 NTSTATUS 3363 3364 --*/ 3365 { 3366 CPPOWER_POLICY_STATE_TABLE entry; 3367 WDF_DEVICE_POWER_POLICY_STATE currentState, newState; 3368 WDF_DEVICE_POWER_POLICY_NOTIFICATION_DATA data; 3369 FxWatchdog watchdog(this); 3370 3371 currentState = m_Device->GetDevicePowerPolicyState(); 3372 newState = NewState; 3373 3374 while (newState != WdfDevStatePwrPolNull) { 3375 DoTraceLevelMessage( 3376 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNPPOWERSTATES, 3377 "WDFDEVICE 0x%p !devobj 0x%p entering power policy state " 3378 "%!WDF_DEVICE_POWER_POLICY_STATE! from " 3379 "%!WDF_DEVICE_POWER_POLICY_STATE!", m_Device->GetHandle(), 3380 m_Device->GetDeviceObject(), newState, currentState); 3381 3382 if (m_PowerPolicyStateCallbacks != NULL) { 3383 // 3384 // Callback for leaving the old state 3385 // 3386 RtlZeroMemory(&data, sizeof(data)); 3387 3388 data.Type = StateNotificationLeaveState; 3389 data.Data.LeaveState.CurrentState = currentState; 3390 data.Data.LeaveState.NewState = newState; 3391 3392 m_PowerPolicyStateCallbacks->Invoke(currentState, 3393 StateNotificationLeaveState, 3394 m_Device->GetHandle(), 3395 &data); 3396 } 3397 3398 m_PowerPolicyMachine.m_States.History[ 3399 m_PowerPolicyMachine.IncrementHistoryIndex()] = (USHORT) newState; 3400 3401 if (m_PowerPolicyStateCallbacks != NULL) { 3402 // 3403 // Callback for entering the new state 3404 // 3405 RtlZeroMemory(&data, sizeof(data)); 3406 3407 data.Type = StateNotificationEnterState; 3408 data.Data.EnterState.CurrentState = currentState; 3409 data.Data.EnterState.NewState = newState; 3410 3411 m_PowerPolicyStateCallbacks->Invoke(newState, 3412 StateNotificationEnterState, 3413 m_Device->GetHandle(), 3414 &data); 3415 } 3416 3417 m_Device->SetDevicePowerPolicyState(newState); 3418 currentState = newState; 3419 3420 entry = GetPowerPolicyTableEntry(currentState); 3421 3422 // 3423 // And call the state handler, if there is one. 3424 // 3425 if (entry->StateFunc != NULL) { 3426 watchdog.StartTimer(currentState); 3427 newState = entry->StateFunc(this); 3428 watchdog.CancelTimer(currentState); 3429 3430 // 3431 // Validate the return value if FX_STATE_MACHINE_VERIFY is enabled 3432 // 3433 VALIDATE_PWR_POL_STATE(currentState, newState); 3434 3435 } 3436 else { 3437 newState = WdfDevStatePwrPolNull; 3438 } 3439 3440 if (m_PowerPolicyStateCallbacks != NULL) { 3441 // 3442 // Callback for post processing the new state 3443 // 3444 RtlZeroMemory(&data, sizeof(data)); 3445 3446 data.Type = StateNotificationPostProcessState; 3447 data.Data.PostProcessState.CurrentState = currentState; 3448 3449 m_PowerPolicyStateCallbacks->Invoke(currentState, 3450 StateNotificationPostProcessState, 3451 m_Device->GetHandle(), 3452 &data); 3453 } 3454 } 3455 } 3456 3457 3458 /*++ 3459 3460 One of the goals of the Driver Framework is to make it really easy to write 3461 a driver for a device which keeps the device in the lowest useful power state 3462 at all times. This could (and often does) mean that the device remains in the 3463 D0 state whenever the machine is running. Or it could mean that the device is 3464 only in D0 when there are outstanding IRPs in its queues. Or it could mean 3465 that the device is in D0 whenever the driver explicitly says that it has to be. 3466 3467 Consequently, the Power Policy state machine has a bunch of states that relate 3468 only to managing the state of the device while the system is running, possibly 3469 allowing the device to "idle-out" to low power states while it isn't being 3470 heavily used. Once that idle-out process has begun, there needs to be some 3471 way for the Framework I/O Package and the driver itself to tell the Power Policy 3472 engine that the device must, for some time at least, be in the D0 (high-power, 3473 working) state. The problem is made much harder by the fact that the driver 3474 (or the Framework itself) probably has to stall some operation while the device 3475 is brought back into the D0 state. 3476 3477 So we've created two operations, PowerReference and PowerDereference, which 3478 tell the Power Policy state machine when a device needs to be in the D0 state. 3479 The I/O Package uses these internally, and the driver may as well. We want 3480 these operations to be as light-weight as possible, so that a driver never 3481 experiences meaningful degradation in performance simply because it chose to 3482 be a good electricity consumer and enabled idle-time power management. 3483 Fortunately, the Framework I/O package can significantly reduce the number of 3484 times that it needs to call these functions by only calling them when the 3485 queue state transitions from empty to non-empty or back again. A caller within 3486 the driver itself will need to be aware that their usage can be somewhat 3487 expensive. 3488 3489 Furthermore, these functions need to be callable at both PASSIVE_LEVEL and 3490 DISPATCH_LEVEL. This really necessitates two versions, as a PASSIVE_LEVEL 3491 user within the driver probably would like us to block while the device is 3492 moved into D0, while a DISPATCH_LEVEL user (or the Framework I/O package) would 3493 prefer a much more asynchronous mode of use. 3494 3495 Dealing with these multiple modes involves a fairly complex locking scheme. Here 3496 is a statement of algorithm. 3497 3498 Locks: 3499 3500 A) Idle Transition Spinlock - DISPATCH_LEVEL 3501 B) Device in D0 Notification Event - PASSIVE_LEVEL 3502 3503 Device-wide variables: 3504 3505 I) Power Reference Count - number of outstanding reasons to be in D0. 3506 II) Idle Timout -- value set by the driver which governs the idle timer 3507 III) Transitioning -- boolean indicating whether we're in the process of 3508 moving the device from Dx to D0. 3509 3510 PowerDecrement: 3511 3512 1) Take Idle Transition lock. 3513 3) Decrement of the device-wide power reference count. 3514 3) If that's not zero, drop the lock and exit. 3515 4) Set the driver's Idle Timer. 3516 5) Drop the Idle Transition lock. 3517 3518 PowerIncrement: 3519 3520 1) Take Idle Transition lock. 3521 2) Increment of the device-wide power reference count. 3522 3) If that's 1, then we're transitioning out of idle. Goto Step 6. 3523 4) If Transitioning == TRUE, we need to wait, Goto Step 13. 3524 5) Drop the Idle Transition lock. Exit. 3525 6) Cancel the Idle Timer. If that was unsuccessful, then the timer was not 3526 set, which means that the device has either moved out of D0 or it is moving 3527 out of D0. Goto Step 8. 3528 7) Drop the Idle Transition lock. Exit. 3529 8) The timer was not succefully cancelled. This means that we have timed out 3530 in the past and we need to put the device back in D0. 3531 Set Transitioning = TRUE. 3532 9) Drop Idle Transition lock. 3533 10) Reset the D0 Notification Event. 3534 11) Send IoPresent event to the Power Policy state machine. 3535 12) If IRQL == DISPATCH_LEVEL goto Step 15. 3536 13) Wait for the D0 Notification Event. 3537 14) Exit. 3538 15) Note that I/O needs to be restarted later. 3539 16) Exit STATUS_PENDING. 3540 3541 --*/ 3542 WDF_DEVICE_POWER_POLICY_STATE 3543 FxPkgPnp::PowerPolStarting( 3544 __inout FxPkgPnp* This 3545 ) 3546 { 3547 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStarting); 3548 3549 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Start(); 3550 3551 This->PowerProcessEvent(PowerImplicitD0); 3552 3553 // 3554 // Wait for the successful power up before starting any idle timers. If 3555 // the power up fails, we will not send a power policy stop from the pnp 3556 // engine. 3557 // 3558 return WdfDevStatePwrPolNull; 3559 } 3560 3561 WDF_DEVICE_POWER_POLICY_STATE 3562 FxPkgPnp::PowerPolStartingPoweredUp( 3563 __inout FxPkgPnp* This 3564 ) 3565 /*++ 3566 3567 Routine Description: 3568 The power state policy state machine has powered up. Tell the active/idle 3569 state machine to initialize. 3570 3571 The device needs to be in D0 before the active/idle state machine registers 3572 with the power framework. Therefore, we wait until the power state machine 3573 has brought the device into D0 before we tell the active/idle state machine 3574 to start. Moving the device into D0 allows us to touch hardware if needed 3575 (for example, to determine the number of components in the device) before 3576 registering with the power framework. 3577 3578 Arguments: 3579 This - instance of the state machine 3580 3581 Return Value: 3582 WdfDevStatePwrPolNull 3583 3584 --*/ 3585 { 3586 NTSTATUS status; 3587 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartingPoweredUp); 3588 3589 // 3590 // The decision regarding whether or not the power framework determines the 3591 // idle timeout is now "frozen" and cannot be changed unless the device is 3592 // stopped and restarted. 3593 // 3594 This->m_PowerPolicyMachine.m_Owner-> 3595 m_IdleSettings.m_TimeoutMgmt.FreezeIdleTimeoutManagementStatus( 3596 This->GetDriverGlobals() 3597 ); 3598 3599 status = This->m_PowerPolicyMachine.m_Owner-> 3600 m_PoxInterface.InitializeComponents(); 3601 if (FALSE == NT_SUCCESS(status)) { 3602 return WdfDevStatePwrPolStartingPoweredUpFailed; 3603 } 3604 3605 return WdfDevStatePwrPolStartingSucceeded; 3606 } 3607 3608 WDF_DEVICE_POWER_POLICY_STATE 3609 FxPkgPnp::PowerPolStartingPoweredUpFailed( 3610 __inout FxPkgPnp* This 3611 ) 3612 /*++ 3613 3614 Routine Description: 3615 We failed to initialize the device's components. We have already started the 3616 power state machine, so ask it to run down before we tell the PNP state 3617 machine to fail device start. 3618 3619 Arguments: 3620 This - instance of the state machine 3621 3622 Return Value: 3623 WdfDevStatePwrPolNull 3624 3625 --*/ 3626 { 3627 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartingPoweredUpFailed); 3628 3629 This->PowerProcessEvent(PowerImplicitD3); 3630 3631 return WdfDevStatePwrPolNull; 3632 } 3633 3634 WDF_DEVICE_POWER_POLICY_STATE 3635 FxPkgPnp::PowerPolStartingSucceeded( 3636 __inout FxPkgPnp* This 3637 ) 3638 /*++ 3639 3640 Routine Description: 3641 The power policy state machine has successfully started. Notify the pnp 3642 state machine that this has occurred and then tell the active/idle state 3643 machine to move to an active state. 3644 3645 Arguments: 3646 This - instance of the state machine 3647 3648 Return Value: 3649 WdfDevStatePwrPolStartingDecideS0Wake 3650 3651 --*/ 3652 { 3653 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartingSucceeded); 3654 3655 This->PnpProcessEvent(PnpEventPwrPolStarted); 3656 3657 return WdfDevStatePwrPolStartingDecideS0Wake; 3658 } 3659 3660 WDF_DEVICE_POWER_POLICY_STATE 3661 FxPkgPnp::PowerPolStartingFailed( 3662 __inout FxPkgPnp* This 3663 ) 3664 /*++ 3665 3666 Routine Description: 3667 Attempting to bring the device into the D0 state failed. Report the status 3668 to pnp. 3669 3670 Arguments: 3671 This - instance of the state machine 3672 3673 Return Value 3674 WdfDevStatePwrPolNull 3675 3676 --*/ 3677 { 3678 KIRQL irql; 3679 3680 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartingFailed); 3681 3682 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Stop(); 3683 3684 // 3685 // We raise IRQL to dispatch level so that pnp is forced onto its own thread 3686 // to process the PwrPolStartFailed event. If pnp is on the power thread when 3687 // it processes the event and it tries to delete the dedicated thread, it 3688 // will deadlock waiting for the thread its on to exit. 3689 // 3690 Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql); 3691 This->PnpProcessEvent(PnpEventPwrPolStartFailed); 3692 Mx::MxLowerIrql(irql); 3693 3694 return WdfDevStatePwrPolNull; 3695 } 3696 3697 WDF_DEVICE_POWER_POLICY_STATE 3698 FxPkgPnp::PowerPolStartingDecideS0Wake( 3699 __inout FxPkgPnp* This 3700 ) 3701 { 3702 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartingDecideS0Wake); 3703 3704 This->PowerPolicyChildrenCanPowerUp(); 3705 3706 // 3707 // Save idle state if it is dirty. We check when deciding the S0 state 3708 // because any change in the S0 idle settings will go through this state. 3709 // 3710 This->SaveState(TRUE); 3711 3712 // 3713 // If necessary update the idle timeout hint to the power framework 3714 // 3715 This->m_PowerPolicyMachine.m_Owner->m_PoxInterface.UpdateIdleTimeoutHint(); 3716 3717 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.Enabled) { 3718 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.WakeFromS0Capable) { 3719 // 3720 // We can idle out and wake from S0 3721 // 3722 return WdfDevStatePwrPolStartedWakeCapable; 3723 } 3724 else { 3725 // 3726 // We can idle out, but not wake from the idle state 3727 // 3728 return WdfDevStatePwrPolStartedIdleCapable; 3729 } 3730 } 3731 3732 return WdfDevStatePwrPolStarted; 3733 } 3734 3735 WDF_DEVICE_POWER_POLICY_STATE 3736 FxPkgPnp::PowerPolStartedIdleCapable( 3737 __inout FxPkgPnp* This 3738 ) 3739 { 3740 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartedIdleCapable); 3741 3742 // 3743 // Enable the idle state machine. This will release any threads who are 3744 // waiting for the device to return to D0. 3745 // 3746 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.EnableTimer(); 3747 3748 return WdfDevStatePwrPolNull; 3749 } 3750 3751 WDF_DEVICE_POWER_POLICY_STATE 3752 FxPkgPnp::PowerPolIdleCapableDeviceIdle( 3753 __inout FxPkgPnp* This 3754 ) 3755 /*++ 3756 3757 Routine Description: 3758 We are now idle. Tell the active/idle state machine to move us to an idle 3759 state. 3760 3761 Arguments: 3762 This - instance of the state machine 3763 3764 Return Value: 3765 WdfDevStatePwrPolNull 3766 3767 --*/ 3768 { 3769 BOOLEAN canPowerDown; 3770 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolIdleCapableDeviceIdle); 3771 3772 canPowerDown = This->m_PowerPolicyMachine.m_Owner-> 3773 m_PoxInterface.DeclareComponentIdle(); 3774 3775 // 3776 // If we are using driver-managed idle timeout we can power down immediately 3777 // and so we jump to the next state (that initiates power down) immediately. 3778 // If we are using system-managed idle timeout, we wait in the current state 3779 // for device-power-not-required notification. 3780 // 3781 return (canPowerDown ? 3782 WdfDevStatePwrPolTimerExpiredNoWake : 3783 WdfDevStatePwrPolNull); 3784 } 3785 3786 WDF_DEVICE_POWER_POLICY_STATE 3787 FxPkgPnp::PowerPolDeviceIdleReturnToActive( 3788 __inout FxPkgPnp* This 3789 ) 3790 /*++ 3791 3792 Routine Description: 3793 We are idle, but still in D0. We need to return to an active state. 3794 3795 Arguments: 3796 This - instance of the state machine 3797 3798 Return Value: 3799 WdfDevStatePwrPolNull 3800 3801 --*/ 3802 { 3803 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolDeviceIdleReturnToActive); 3804 3805 This->m_PowerPolicyMachine.m_Owner-> 3806 m_PoxInterface.RequestComponentActive(); 3807 3808 return WdfDevStatePwrPolStartedCancelTimer; 3809 } 3810 3811 WDF_DEVICE_POWER_POLICY_STATE 3812 FxPkgPnp::PowerPolDeviceIdleSleeping( 3813 __inout FxPkgPnp* This 3814 ) 3815 /*++ 3816 3817 Routine Description: 3818 We are idle, but still in D0. System is going to a low power state. 3819 3820 Arguments: 3821 This - instance of the state machine 3822 3823 Return Value: 3824 WdfDevStatePwrPolNull 3825 3826 --*/ 3827 { 3828 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolDeviceIdleSleeping); 3829 3830 // 3831 // Normally we'd make the component active when we get the device-power- 3832 // required notification. But we've not yet processed the device-power-not- 3833 // required notification, so we will not be processing the device-power- 3834 // required notification either. So let's activate the component before we 3835 // process the Sx IRP. 3836 // 3837 This->m_PowerPolicyMachine.m_Owner-> 3838 m_PoxInterface.RequestComponentActive(); 3839 3840 return WdfDevStatePwrPolStartedIdleCapableCancelTimerForSleep; 3841 } 3842 3843 WDF_DEVICE_POWER_POLICY_STATE 3844 FxPkgPnp::PowerPolDeviceIdleStopping( 3845 __inout FxPkgPnp* This 3846 ) 3847 /*++ 3848 3849 Routine Description: 3850 We are idle, but still in D0. Power policy state machine is being stopped. 3851 3852 Arguments: 3853 This - instance of the state machine 3854 3855 Return Value: 3856 WdfDevStatePwrPolNull 3857 3858 --*/ 3859 { 3860 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolDeviceIdleStopping); 3861 3862 // 3863 // Normally we'd make the component active when we get the device-power- 3864 // required notification. But we've not yet processed the device-power-not- 3865 // required notification, so we will not be processing the device-power- 3866 // required notification either. So let's activate the component before we 3867 // process the stop/remove request. 3868 // 3869 This->m_PowerPolicyMachine.m_Owner-> 3870 m_PoxInterface.RequestComponentActive(); 3871 3872 return WdfDevStatePwrPolStoppingCancelTimer; 3873 } 3874 3875 WDF_DEVICE_POWER_POLICY_STATE 3876 FxPkgPnp::PowerPolTimerExpiredNoWake( 3877 __inout FxPkgPnp* This 3878 ) 3879 { 3880 BOOLEAN poweredDown; 3881 NTSTATUS notifyPowerDownStatus; 3882 3883 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredNoWake); 3884 3885 // 3886 // Notify the device power requirement state machine that we are about to 3887 // power down. 3888 // 3889 notifyPowerDownStatus = This->m_PowerPolicyMachine.m_Owner-> 3890 m_PoxInterface.NotifyDevicePowerDown(); 3891 if (FALSE == NT_SUCCESS(notifyPowerDownStatus)) { 3892 // 3893 // We couldn't notify the device power requirement state machine that 3894 // we are about to power down, because the "device-power-required" 3895 // notification has already arrived. So we should not power down at this 3896 // time. Revert back to the started state. 3897 // 3898 return WdfDevStatePwrPolTimerExpiredNoWakeReturnToActive; 3899 } 3900 3901 poweredDown = This->PowerPolicyCanIdlePowerDown( 3902 This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.DxState 3903 ); 3904 3905 if (poweredDown == FALSE) { 3906 // 3907 // Upon failure, revert back to the started state. 3908 // 3909 return WdfDevStatePwrPolTimerExpiredNoWakeUndoPowerDown; 3910 } 3911 3912 return WdfDevStatePwrPolNull; 3913 } 3914 3915 WDF_DEVICE_POWER_POLICY_STATE 3916 FxPkgPnp::PowerPolTimerExpiredNoWakeCompletePowerDown( 3917 __inout FxPkgPnp* This 3918 ) 3919 /*++ 3920 3921 Routine Description: 3922 The device idled out and we sent the Dx request. The power state machine has 3923 gone as far as stopping I/O is waiting to be notified to complete the Dx 3924 process. Send the PowerCompleteDx event to move the device fully into Dx. 3925 3926 Arguments: 3927 This - instance of the state machine 3928 3929 Return Value: 3930 WdfDevStatePwrPolNull 3931 3932 --*/ 3933 { 3934 ASSERT_PWR_POL_STATE(This, 3935 WdfDevStatePwrPolTimerExpiredNoWakeCompletePowerDown); 3936 3937 This->PowerProcessEvent(PowerCompleteDx); 3938 3939 return WdfDevStatePwrPolNull; 3940 } 3941 3942 WDF_DEVICE_POWER_POLICY_STATE 3943 FxPkgPnp::PowerPolWaitingUnarmedQueryIdle( 3944 __inout FxPkgPnp* This 3945 ) 3946 /*++ 3947 3948 Routine Description: 3949 The device was in the WaitingUnarmed state and received a PwrPolIoPresent 3950 event. Before committing the device to move back to D0, check to see if 3951 the device has returned to an idle state. This can easily happen if the 3952 driver causes a power reference in D0Exit accidentally and the power 3953 reference is removed before exiting the function. 3954 3955 Arguments: 3956 This - instance of the state machine 3957 3958 Return Value: 3959 new state 3960 3961 --*/ 3962 { 3963 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingUnarmedQueryIdle); 3964 3965 // 3966 // If QueryReturnToIdle returns TRUE, return to the waiting state 3967 // 3968 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.QueryReturnToIdle()) { 3969 return WdfDevStatePwrPolWaitingUnarmed; 3970 } 3971 else { 3972 return WdfDevStatePwrPolS0NoWakePowerUp; 3973 } 3974 } 3975 3976 WDF_DEVICE_POWER_POLICY_STATE 3977 FxPkgPnp::PowerPolS0NoWakePowerUp( 3978 __inout FxPkgPnp* This 3979 ) 3980 { 3981 NTSTATUS status; 3982 3983 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolS0NoWakePowerUp); 3984 3985 // 3986 // Attempt to get back to the D0 state 3987 // 3988 This->m_PowerPolicyMachine.m_Owner-> 3989 m_PoxInterface.RequestComponentActive(); 3990 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 3991 3992 if (!NT_SUCCESS(status)) { 3993 COVERAGE_TRAP(); 3994 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 3995 } 3996 3997 return WdfDevStatePwrPolNull; 3998 } 3999 4000 WDF_DEVICE_POWER_POLICY_STATE 4001 FxPkgPnp::PowerPolS0NoWakeCompletePowerUp( 4002 __inout FxPkgPnp* This 4003 ) 4004 /*++ 4005 4006 Routine Description: 4007 The device was in a Dx unarmed for wake while in S0 and is now being brought 4008 into the D0 state. The device is currently in a partial D0 state (HW 4009 started), move it into the full D0 state by sending PowerCompleteD0 to the 4010 power state machine. 4011 4012 Arguments: 4013 This - instance of the state machine 4014 4015 Return Value: 4016 WdfDevStatePwrPolNull 4017 4018 --*/ 4019 { 4020 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolS0NoWakeCompletePowerUp); 4021 4022 This->m_PowerPolicyMachine.m_Owner-> 4023 m_PoxInterface.DeviceIsPoweredOn(); 4024 4025 This->PowerProcessEvent(PowerCompleteD0); 4026 4027 return WdfDevStatePwrPolNull; 4028 } 4029 4030 WDF_DEVICE_POWER_POLICY_STATE 4031 FxPkgPnp::PowerPolSystemSleepFromDeviceWaitingUnarmed( 4032 __inout FxPkgPnp* This 4033 ) 4034 { 4035 SYSTEM_POWER_STATE systemState; 4036 4037 ASSERT_PWR_POL_STATE( 4038 This, WdfDevStatePwrPolSystemSleepFromDeviceWaitingUnarmed); 4039 4040 systemState = This->PowerPolicyGetPendingSystemState(); 4041 4042 if (This->PowerPolicyIsWakeEnabled() && 4043 This->PowerPolicyCanWakeFromSystemState(systemState)) { 4044 return WdfDevStatePwrPolSystemSleepNeedWake; 4045 } 4046 else { 4047 return WdfDevStatePwrPolSystemAsleepNoWake; 4048 } 4049 } 4050 4051 WDF_DEVICE_POWER_POLICY_STATE 4052 FxPkgPnp::PowerPolSystemSleepNeedWake( 4053 __inout FxPkgPnp* This 4054 ) 4055 { 4056 NTSTATUS status; 4057 BOOLEAN result; 4058 4059 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemSleepNeedWake); 4060 4061 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 4062 ASSERT(result); 4063 UNREFERENCED_PARAMETER(result); 4064 4065 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 4066 4067 // 4068 // We are currently in Dx and not armed for wake. While the current Dx 4069 // state may not be the same Dx state we would be for Sx, we can't get to 4070 // D0 to arm ourselves for Sx wake so just leave ourselves as is. 4071 // 4072 if (!NT_SUCCESS(status)) { 4073 DoTraceLevelMessage( 4074 This->GetDriverGlobals(), TRACE_LEVEL_WARNING, TRACINGPNP, 4075 "Failed to allocate D0 request to disarm from wake from S0 to allow " 4076 "arm for wake from Sx, %!STATUS!", status); 4077 4078 COVERAGE_TRAP(); 4079 4080 // 4081 // If D0 IRP allocation fails, we don't treat that as an error. Instead, 4082 // we just let the device remain in Dx without arming it for 4083 // wake-from-Sx, even though the driver had enabled wake-from-Sx. 4084 // 4085 return WdfDevStatePwrPolSystemAsleepNoWake; 4086 } 4087 4088 return WdfDevStatePwrPolNull; 4089 } 4090 4091 WDF_DEVICE_POWER_POLICY_STATE 4092 FxPkgPnp::PowerPolSystemSleepNeedWakeCompletePowerUp( 4093 __inout FxPkgPnp* This 4094 ) 4095 /*++ 4096 4097 Routine Description: 4098 The machine is going into Sx while the device was in Dx. We have started 4099 the D0 process. The power state machine has moved the device into the HW 4100 working state and is waiting to be notified to complete the D0 process. 4101 Send the PowerCompleteD0 event to complete it. 4102 4103 Arguments: 4104 This - instance of the state machine 4105 4106 Return Value: 4107 WdfDevStatePwrPolNull 4108 4109 --*/ 4110 { 4111 ASSERT_PWR_POL_STATE(This, 4112 WdfDevStatePwrPolSystemSleepNeedWakeCompletePowerUp); 4113 4114 This->PowerProcessEvent(PowerCompleteD0); 4115 4116 return WdfDevStatePwrPolNull; 4117 } 4118 4119 WDF_DEVICE_POWER_POLICY_STATE 4120 FxPkgPnp::PowerPolSystemSleepPowerRequestFailed( 4121 __inout FxPkgPnp* This 4122 ) 4123 /*++ 4124 4125 Routine Description: 4126 Power up failed in the power state machine. Complete the pending system 4127 power irp with success (system ignores the results) even if the Dx irp 4128 failed. 4129 4130 Arguments: 4131 This - instance of the state machine 4132 4133 Return Value: 4134 new state WdfDevStatePwrPolDevicePowerRequestFailed 4135 4136 --*/ 4137 { 4138 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemSleepPowerRequestFailed); 4139 4140 This->PowerPolicyCompleteSystemPowerIrp(); 4141 4142 return WdfDevStatePwrPolDevicePowerRequestFailed; 4143 } 4144 4145 WDF_DEVICE_POWER_POLICY_STATE 4146 FxPkgPnp::PowerPolCheckPowerPageable( 4147 __inout FxPkgPnp* This 4148 ) 4149 /*++ 4150 4151 Routine Description: 4152 Checks to see if the device should move down the power pagable wake path 4153 or the NP path. 4154 4155 Arguments: 4156 This - instance of the state machine 4157 4158 Return Value: 4159 new state 4160 4161 --*/ 4162 { 4163 ULONG flags; 4164 MxDeviceObject deviceObject; 4165 4166 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolCheckPowerPageable); 4167 4168 deviceObject.SetObject(This->m_Device->GetDeviceObject()); 4169 flags = deviceObject.GetFlags(); 4170 4171 if (flags & DO_POWER_PAGABLE) { 4172 ASSERT((flags & DO_POWER_INRUSH) == 0); 4173 4174 return WdfDevStatePwrPolSleepingWakeWakeArrived; 4175 } 4176 else { 4177 // 4178 // DO_POWER_INRUSH also gets us to this state, but since it is mutually 4179 // exclusive with DO_POWER_PAGABLE, we don't need to check for it 4180 // 4181 return WdfDevStatePwrPolSleepingWakeWakeArrivedNP; 4182 } 4183 } 4184 4185 WDF_DEVICE_POWER_POLICY_STATE 4186 FxPkgPnp::PowerPolSleepingWakeWakeArrived( 4187 __inout FxPkgPnp* This 4188 ) 4189 /*++ 4190 4191 Routine Description: 4192 The device is in partial Dx (I/O has stopped) and will now be armed for wake. 4193 Complete the going Dx transition by sending a PowerCompleteDx irp to the 4194 4195 Arguments: 4196 This - instance of the state machine 4197 4198 Return Value: 4199 new state 4200 4201 --*/ 4202 { 4203 NTSTATUS status; 4204 ULONG wakeReason; 4205 4206 ASSERT_PWR_POL_STATE( 4207 This, WdfDevStatePwrPolSleepingWakeWakeArrived); 4208 4209 ASSERT(This->PowerPolicyCanWakeFromSystemState( 4210 This->PowerPolicyGetPendingSystemState() 4211 )); 4212 4213 wakeReason = This->PowerPolicyGetCurrentWakeReason(); 4214 4215 status = This->m_PowerPolicyMachine.m_Owner->m_DeviceArmWakeFromSx.Invoke( 4216 This->m_Device->GetHandle(), 4217 FLAG_TO_BOOL(wakeReason, FxPowerPolicySxWakeDeviceEnabledFlag), 4218 FLAG_TO_BOOL(wakeReason, FxPowerPolicySxWakeChildrenArmedFlag) 4219 ); 4220 4221 if (!NT_SUCCESS(status)) { 4222 DoTraceLevelMessage( 4223 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 4224 "WDFDEVICE %p Failed to arm for wake from Sx, %!STATUS!", 4225 This->m_Device->GetHandle(), status); 4226 4227 return WdfDevStatePwrPolSleepingWakeRevertArmWake; 4228 } 4229 4230 // 4231 // If the PDO is the Power Policy owner, then enable wake at bus, otherwise 4232 // the power state machine will enable wake at bus. 4233 // 4234 if (This->m_Device->IsPdo()) { 4235 status = This->PowerEnableWakeAtBusOverload(); 4236 if (!NT_SUCCESS(status)) { 4237 DoTraceLevelMessage( 4238 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 4239 "WDFDEVICE %p Failed to Enable Wake at Bus, %!STATUS!", 4240 This->m_Device->GetHandle(), status); 4241 return WdfDevStatePwrPolSleepingWakeRevertArmWake; 4242 } 4243 } 4244 4245 This->PowerProcessEvent(PowerCompleteDx); 4246 4247 return WdfDevStatePwrPolNull; 4248 } 4249 4250 WDF_DEVICE_POWER_POLICY_STATE 4251 FxPkgPnp::PowerPolSleepingWakeRevertArmWake( 4252 __inout FxPkgPnp* This 4253 ) 4254 { 4255 ASSERT_PWR_POL_STATE( 4256 This, WdfDevStatePwrPolSleepingWakeRevertArmWake); 4257 4258 DoTraceLevelMessage( 4259 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 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"); 4263 4264 // 4265 // Enable calls should be matched with Disable calls even in the failure 4266 // cases. However, for the Enable wake at bus failure, we do not call the 4267 // disable wake at bus method as we try to keep the failure behavior 4268 // consistent with the Power State machine. Only the Device Disarm wake 4269 // callback will be invoked here. 4270 // 4271 This->PowerPolicyDisarmWakeFromSx(); 4272 4273 // 4274 // attempt to cancel ww 4275 // 4276 if (This->PowerPolicyCancelWaitWake() == FALSE && 4277 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4278 return WdfDevStatePwrPolSleepingNoWakeCompletePowerDown; 4279 } 4280 4281 return WdfDevStatePwrPolNull; 4282 } 4283 4284 WDF_DEVICE_POWER_POLICY_STATE 4285 FxPkgPnp::PowerPolSystemAsleepWakeArmed( 4286 __inout FxPkgPnp* This 4287 ) 4288 { 4289 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemAsleepWakeArmed); 4290 This->PowerPolicyCompleteSystemPowerIrp(); 4291 4292 return WdfDevStatePwrPolNull; 4293 } 4294 4295 WDF_DEVICE_POWER_POLICY_STATE 4296 FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabled( 4297 __inout FxPkgPnp* This 4298 ) 4299 { 4300 ASSERT_PWR_POL_STATE( 4301 This, WdfDevStatePwrPolSystemWakeDeviceWakeEnabled); 4302 4303 if (This->PowerPolicyCancelWaitWake() == FALSE && 4304 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4305 return WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceled; 4306 } 4307 4308 return WdfDevStatePwrPolNull; 4309 } 4310 4311 WDF_DEVICE_POWER_POLICY_STATE 4312 FxPkgPnp::PowerPolSystemWakeDeviceWakeInterruptFired( 4313 __inout FxPkgPnp* This 4314 ) 4315 { 4316 ASSERT_PWR_POL_STATE( 4317 This, WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFired); 4318 4319 // 4320 // Make a note of the fact that system was woken by 4321 // a wake interrupt of this device 4322 // 4323 This->m_SystemWokenByWakeInterrupt = TRUE; 4324 4325 if (This->PowerPolicyCancelWaitWake() == FALSE && 4326 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4327 4328 return WdfDevStatePwrPolSystemWakeDeviceWakeTriggered; 4329 } 4330 4331 return WdfDevStatePwrPolNull; 4332 } 4333 4334 WDF_DEVICE_POWER_POLICY_STATE 4335 FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledWakeCanceled( 4336 __inout FxPkgPnp* This 4337 ) 4338 { 4339 NTSTATUS status; 4340 4341 ASSERT_PWR_POL_STATE( 4342 This, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceled); 4343 4344 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 4345 4346 if (!NT_SUCCESS(status)) { 4347 COVERAGE_TRAP(); 4348 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 4349 } 4350 4351 return WdfDevStatePwrPolNull; 4352 } 4353 4354 WDF_DEVICE_POWER_POLICY_STATE 4355 FxPkgPnp::PowerPolSystemWakeDeviceWakeDisarm( 4356 __inout FxPkgPnp* This 4357 ) 4358 { 4359 ASSERT_PWR_POL_STATE( 4360 This, WdfDevStatePwrPolSystemWakeDeviceWakeDisarm); 4361 4362 // 4363 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 4364 // the power state machine will disable wake at bus. 4365 // 4366 if (This->m_Device->IsPdo()) { 4367 This->PowerDisableWakeAtBusOverload(); 4368 } 4369 4370 This->PowerPolicyDisarmWakeFromSx(); 4371 4372 return WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp; 4373 } 4374 4375 WDF_DEVICE_POWER_POLICY_STATE 4376 FxPkgPnp::PowerPolSystemWakeDeviceWakeTriggeredS0( 4377 __inout FxPkgPnp* This 4378 ) 4379 { 4380 NTSTATUS status; 4381 4382 ASSERT_PWR_POL_STATE( 4383 This, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0); 4384 4385 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 4386 4387 if (!NT_SUCCESS(status)) { 4388 COVERAGE_TRAP(); 4389 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 4390 } 4391 4392 return WdfDevStatePwrPolNull; 4393 } 4394 4395 WDF_DEVICE_POWER_POLICY_STATE 4396 FxPkgPnp::PowerPolSystemWakeDeviceWokeDisarm( 4397 __inout FxPkgPnp* This 4398 ) 4399 { 4400 ASSERT_PWR_POL_STATE( 4401 This, WdfDevStatePwrPolSystemWakeDeviceWokeDisarm); 4402 4403 // 4404 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 4405 // the power state machine will enable wake at bus. 4406 // 4407 if (This->m_Device->IsPdo()) { 4408 This->PowerDisableWakeAtBusOverload(); 4409 } 4410 4411 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromSxTriggered.Invoke( 4412 This->m_Device->GetHandle() 4413 ); 4414 4415 This->PowerPolicyDisarmWakeFromSx(); 4416 4417 return WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp; 4418 } 4419 4420 WDF_DEVICE_POWER_POLICY_STATE 4421 FxPkgPnp::PowerPolSleepingWakeWakeArrivedNP( 4422 __inout FxPkgPnp* This 4423 ) 4424 /*++ 4425 4426 Routine Description: 4427 The device is in partial Dx (I/O has stopped) and will now be armed for wake. 4428 Complete the going Dx transition by sending a PowerCompleteDx irp to the 4429 power state machine. 4430 4431 Arguments: 4432 This - instance of the state machine 4433 4434 Return Value: 4435 new state 4436 4437 --*/ 4438 { 4439 NTSTATUS status; 4440 ULONG wakeReason; 4441 4442 ASSERT_PWR_POL_STATE( 4443 This, WdfDevStatePwrPolSleepingWakeWakeArrivedNP); 4444 4445 ASSERT(This->PowerPolicyCanWakeFromSystemState( 4446 This->PowerPolicyGetPendingSystemState() 4447 )); 4448 4449 wakeReason = This->PowerPolicyGetCurrentWakeReason(); 4450 4451 status = This->m_PowerPolicyMachine.m_Owner->m_DeviceArmWakeFromSx.Invoke( 4452 This->m_Device->GetHandle(), 4453 FLAG_TO_BOOL(wakeReason, FxPowerPolicySxWakeDeviceEnabledFlag), 4454 FLAG_TO_BOOL(wakeReason, FxPowerPolicySxWakeChildrenArmedFlag) 4455 ); 4456 4457 if (!NT_SUCCESS(status)) { 4458 DoTraceLevelMessage( 4459 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 4460 "WDFDEVICE %p Failed to arm for wake from Sx, %!STATUS!", 4461 This->m_Device->GetHandle(), status); 4462 4463 return WdfDevStatePwrPolSleepingWakeRevertArmWakeNP; 4464 } 4465 4466 // 4467 // If the PDO is the Power Policy owner, then enable wake at bus, otherwise 4468 // the power state machine will enable wake at bus. 4469 // 4470 if (This->m_Device->IsPdo()) { 4471 status = This->PowerEnableWakeAtBusOverload(); 4472 if (!NT_SUCCESS(status)) { 4473 DoTraceLevelMessage( 4474 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 4475 "WDFDEVICE %p Failed to Enable Wake at Bus, %!STATUS!", 4476 This->m_Device->GetHandle(), status); 4477 return WdfDevStatePwrPolSleepingWakeRevertArmWakeNP; 4478 } 4479 } 4480 4481 This->PowerProcessEvent(PowerCompleteDx); 4482 4483 return WdfDevStatePwrPolNull; 4484 } 4485 4486 WDF_DEVICE_POWER_POLICY_STATE 4487 FxPkgPnp::PowerPolSleepingWakeRevertArmWakeNP( 4488 __inout FxPkgPnp* This 4489 ) 4490 { 4491 ASSERT_PWR_POL_STATE( 4492 This, WdfDevStatePwrPolSleepingWakeRevertArmWakeNP); 4493 4494 DoTraceLevelMessage( 4495 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 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"); 4499 4500 // 4501 // Enable calls should be matched with Disable calls even in the failure 4502 // cases. However, for the Enable wake at bus failure, we do not call the 4503 // disable wake at bus method as we try to keep the failure behavior 4504 // consistent with the Power State machine. Only the Device Disarm wake 4505 // callback will be invoked here. 4506 // 4507 This->PowerPolicyDisarmWakeFromSx(); 4508 4509 // 4510 // attempt to cancel ww 4511 // 4512 if (This->PowerPolicyCancelWaitWake() == FALSE && 4513 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4514 return WdfDevStatePwrPolSleepingNoWakeCompletePowerDown; 4515 } 4516 4517 return WdfDevStatePwrPolNull; 4518 } 4519 4520 WDF_DEVICE_POWER_POLICY_STATE 4521 FxPkgPnp::PowerPolSleepingWakePowerDownFailed( 4522 __inout FxPkgPnp* This 4523 ) 4524 /*++ 4525 4526 Routine Description: 4527 Power down failed in the power state machine. Cancel the wait wake irp 4528 that was just sent down and revert the arming before moving to the failed 4529 state. 4530 4531 Arguments: 4532 This - instance of the state machine. 4533 4534 Return Value: 4535 new state 4536 4537 --*/ 4538 { 4539 ASSERT_PWR_POL_STATE( 4540 This, WdfDevStatePwrPolSleepingWakePowerDownFailed); 4541 4542 if (This->PowerPolicyCancelWaitWake() == FALSE && 4543 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4544 return WdfDevStatePwrPolSleepingWakePowerDownFailedWakeCanceled; 4545 } 4546 4547 return WdfDevStatePwrPolNull; 4548 } 4549 4550 WDF_DEVICE_POWER_POLICY_STATE 4551 FxPkgPnp::PowerPolSleepingWakePowerDownFailedWakeCanceled( 4552 __inout FxPkgPnp* This 4553 ) 4554 /*++ 4555 4556 Routine Description: 4557 Wait wake irp has been cancelled. Complete the Sx irp and goto the failed 4558 state. 4559 4560 Arguments: 4561 This - instance of the state machine 4562 4563 Return Value: 4564 new state 4565 4566 --*/ 4567 { 4568 ASSERT_PWR_POL_STATE( 4569 This, WdfDevStatePwrPolSleepingWakePowerDownFailedWakeCanceled); 4570 4571 This->PowerPolicyCompleteSystemPowerIrp(); 4572 4573 return WdfDevStatePwrPolDevicePowerRequestFailed; 4574 } 4575 4576 WDF_DEVICE_POWER_POLICY_STATE 4577 FxPkgPnp::PowerPolSystemAsleepWakeArmedNP( 4578 __inout FxPkgPnp* This 4579 ) 4580 { 4581 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemAsleepWakeArmedNP); 4582 4583 This->PowerPolicyCompleteSystemPowerIrp(); 4584 4585 return WdfDevStatePwrPolNull; 4586 } 4587 4588 WDF_DEVICE_POWER_POLICY_STATE 4589 FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledNP( 4590 __inout FxPkgPnp* This 4591 ) 4592 { 4593 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledNP); 4594 4595 if (This->PowerPolicyCancelWaitWake() == FALSE && 4596 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4597 return WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceledNP; 4598 } 4599 4600 return WdfDevStatePwrPolNull; 4601 } 4602 4603 WDF_DEVICE_POWER_POLICY_STATE 4604 FxPkgPnp::PowerPolSystemWakeDeviceWakeInterruptFiredNP( 4605 __inout FxPkgPnp* This 4606 ) 4607 { 4608 ASSERT_PWR_POL_STATE( 4609 This, WdfDevStatePwrPolSystemWakeDeviceWakeInterruptFiredNP); 4610 4611 // 4612 // Make a notee of the fact that system was woken by 4613 // a wake interrupt of this device 4614 // 4615 This->m_SystemWokenByWakeInterrupt = TRUE; 4616 4617 if (This->PowerPolicyCancelWaitWake() == FALSE && 4618 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 4619 return WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredNP; 4620 } 4621 4622 return WdfDevStatePwrPolNull; 4623 } 4624 4625 WDF_DEVICE_POWER_POLICY_STATE 4626 FxPkgPnp::PowerPolSystemWakeDeviceWakeEnabledWakeCanceledNP( 4627 __inout FxPkgPnp* This 4628 ) 4629 { 4630 NTSTATUS status; 4631 4632 ASSERT_PWR_POL_STATE( 4633 This, WdfDevStatePwrPolSystemWakeDeviceWakeEnabledWakeCanceledNP); 4634 4635 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 4636 4637 if (!NT_SUCCESS(status)) { 4638 COVERAGE_TRAP(); 4639 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 4640 } 4641 4642 return WdfDevStatePwrPolNull; 4643 } 4644 4645 WDF_DEVICE_POWER_POLICY_STATE 4646 FxPkgPnp::PowerPolSystemWakeDeviceWakeDisarmNP( 4647 __inout FxPkgPnp* This 4648 ) 4649 { 4650 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceWakeDisarmNP); 4651 4652 // 4653 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 4654 // the power state machine will disable wake at bus. 4655 // 4656 if (This->m_Device->IsPdo()) { 4657 This->PowerDisableWakeAtBusOverload(); 4658 } 4659 4660 This->PowerPolicyDisarmWakeFromSx(); 4661 4662 return WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp; 4663 } 4664 4665 WDF_DEVICE_POWER_POLICY_STATE 4666 FxPkgPnp::PowerPolSystemWakeDeviceWakeTriggeredS0NP( 4667 __inout FxPkgPnp* This 4668 ) 4669 { 4670 NTSTATUS status; 4671 4672 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceWakeTriggeredS0NP); 4673 4674 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 4675 4676 if (!NT_SUCCESS(status)) { 4677 COVERAGE_TRAP(); 4678 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 4679 } 4680 4681 return WdfDevStatePwrPolNull; 4682 } 4683 4684 WDF_DEVICE_POWER_POLICY_STATE 4685 FxPkgPnp::PowerPolSystemWakeDeviceWokeDisarmNP( 4686 __inout FxPkgPnp* This 4687 ) 4688 { 4689 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceWokeDisarmNP); 4690 4691 // 4692 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 4693 // the power state machine will disable wake at bus. 4694 // 4695 if (This->m_Device->IsPdo()) { 4696 This->PowerDisableWakeAtBusOverload(); 4697 } 4698 4699 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromSxTriggered.Invoke( 4700 This->m_Device->GetHandle() 4701 ); 4702 4703 This->PowerPolicyDisarmWakeFromSx(); 4704 4705 return WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp; 4706 } 4707 4708 WDF_DEVICE_POWER_POLICY_STATE 4709 FxPkgPnp::PowerPolSystemWakeDeviceWakeCompletePowerUp( 4710 __inout FxPkgPnp* This 4711 ) 4712 /*++ 4713 4714 Routine Description: 4715 The system went into Sx and the device was armed for wake. The system has 4716 now returned to S0, the device has started the D0 transition, and the device 4717 has been disarmed for wake. We must now complete the D0 transition by sending 4718 PowerCompleteD0 to the power state machine. 4719 4720 Arguments: 4721 This - instance of the state machine 4722 4723 Return Value: 4724 WdfDevStatePwrPolNull 4725 4726 --*/ 4727 { 4728 ASSERT_PWR_POL_STATE(This, 4729 WdfDevStatePwrPolSystemWakeDeviceWakeCompletePowerUp); 4730 4731 // 4732 // Simulate a device-power-required notification from the power framework. 4733 // An S0-IRP is essentially equivalent to a device-power-required 4734 // notification. 4735 // 4736 This->m_PowerPolicyMachine.m_Owner-> 4737 m_PoxInterface.SimulateDevicePowerRequired(); 4738 4739 // 4740 // Notify the device-power-requirement state machine that we are powered on 4741 // 4742 This->m_PowerPolicyMachine.m_Owner-> 4743 m_PoxInterface.DeviceIsPoweredOn(); 4744 4745 This->PowerProcessEvent(PowerCompleteD0); 4746 4747 return WdfDevStatePwrPolNull; 4748 } 4749 4750 WDF_DEVICE_POWER_POLICY_STATE 4751 FxPkgPnp::PowerPolSleeping( 4752 __inout FxPkgPnp* This 4753 ) 4754 /*++ 4755 4756 Routine Description: 4757 The machine is going into Sx. Send a Dx irp to the stack. The "x" depends 4758 on if the target system state is one which we can wake the system and 4759 the device is enabled to wake from Sx. 4760 4761 Arguments: 4762 This - instance of the state machine 4763 4764 Return Value: 4765 new state 4766 4767 --*/ 4768 { 4769 NTSTATUS notifyPowerDownStatus; 4770 SYSTEM_POWER_STATE systemState; 4771 4772 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleeping); 4773 4774 // 4775 // If the bus/PDO is not in the hibernate path, then verify that all the 4776 // children have powered down by now. 4777 // 4778 if (This->GetUsageCount(WdfSpecialFileHibernation) == 0 && 4779 This->m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount > 0) { 4780 DoTraceLevelMessage( 4781 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 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()); 4786 4787 FxVerifierBreakOnDeviceStateError( 4788 This->m_Device->GetDriverGlobals()); 4789 } 4790 4791 // 4792 // Simulate a device-power-not-required notification from the power 4793 // framework. An Sx-IRP is essentially equivalent to a device-power-not- 4794 // required notification. 4795 // 4796 This->m_PowerPolicyMachine.m_Owner-> 4797 m_PoxInterface.SimulateDevicePowerNotRequired(); 4798 4799 // 4800 // Notify the device-power-requirement state machine that we are about to 4801 // power down 4802 // 4803 notifyPowerDownStatus = This->m_PowerPolicyMachine.m_Owner-> 4804 m_PoxInterface.NotifyDevicePowerDown(); 4805 4806 // 4807 // We simulated a device-power-not-required notification before we notified 4808 // the device-power-requirement state machine that we are powering down. 4809 // Therefore, our notification should have succeeded. 4810 // 4811 ASSERT(NT_SUCCESS(notifyPowerDownStatus)); 4812 UNREFERENCED_PARAMETER(notifyPowerDownStatus); 4813 4814 systemState = This->PowerPolicyGetPendingSystemState(); 4815 4816 if (This->PowerPolicyIsWakeEnabled() && 4817 This->PowerPolicyCanWakeFromSystemState(systemState)) { 4818 return WdfDevStatePwrPolSleepingWakePowerDown; 4819 } 4820 else { 4821 return WdfDevStatePwrPolSleepingNoWakePowerDown; 4822 } 4823 } 4824 4825 WDF_DEVICE_POWER_POLICY_STATE 4826 FxPkgPnp::PowerPolSleepingNoWakePowerDown( 4827 __inout FxPkgPnp* This 4828 ) 4829 /*++ 4830 4831 Routine Description: 4832 Machine is going into Sx and the device is not enabled to wake from Sx. 4833 Request a D3 irp to put the device into a low power state. 4834 4835 Arguments: 4836 This - instance of the state machine 4837 4838 Return Value: 4839 new state 4840 4841 --*/ 4842 { 4843 NTSTATUS status; 4844 DEVICE_POWER_STATE dxState; 4845 4846 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleepingNoWakePowerDown); 4847 4848 dxState = (DEVICE_POWER_STATE) 4849 This->m_PowerPolicyMachine.m_Owner->m_IdealDxStateForSx; 4850 4851 if (dxState != PowerDeviceD3) { 4852 DEVICE_POWER_STATE dxMappedState; 4853 4854 // 4855 // Get the lightest Dx state for this Sx state as reported by the 4856 // device capabilities of the stack. 4857 // 4858 dxMappedState = _GetPowerCapState( 4859 This->PowerPolicyGetPendingSystemState(), 4860 This->m_PowerPolicyMachine.m_Owner->m_SystemToDeviceStateMap 4861 ); 4862 4863 // 4864 // If the ideal desired state is lighter than what the S->D mapping says 4865 // is the lightest supported D state, use the mapping value instead. 4866 // 4867 if (dxState < dxMappedState) { 4868 dxState = dxMappedState; 4869 } 4870 } 4871 4872 ASSERT(dxState >= PowerDeviceD1 && dxState <= PowerDeviceD3); 4873 4874 status = This->PowerPolicyPowerDownForSx(dxState, Retry); 4875 4876 if (!NT_SUCCESS(status)) { 4877 COVERAGE_TRAP(); 4878 return WdfDevStatePwrPolSleepingNoWakeDxRequestFailed; 4879 } 4880 4881 return WdfDevStatePwrPolNull; 4882 } 4883 4884 WDF_DEVICE_POWER_POLICY_STATE 4885 FxPkgPnp::PowerPolSleepingNoWakeCompletePowerDown( 4886 __inout FxPkgPnp* This 4887 ) 4888 /*++ 4889 4890 Routine Description: 4891 The system has moved into Sx and the device is not armed for wake. The 4892 device in partial Dx (I/O has stopped), transition the device into full 4893 Dx by sending the PowerCompleteDx event to the power state machine. 4894 4895 Arguments: 4896 This - instance of the state machine 4897 4898 Return Value: 4899 WdfDevStatePwrPolNull 4900 4901 --*/ 4902 { 4903 ASSERT_PWR_POL_STATE(This, 4904 WdfDevStatePwrPolSleepingNoWakeCompletePowerDown); 4905 4906 This->PowerProcessEvent(PowerCompleteDx); 4907 4908 return WdfDevStatePwrPolNull; 4909 } 4910 4911 WDF_DEVICE_POWER_POLICY_STATE 4912 FxPkgPnp::PowerPolSleepingNoWakeDxRequestFailed( 4913 __inout FxPkgPnp* This 4914 ) 4915 { 4916 COVERAGE_TRAP(); 4917 4918 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleepingNoWakeDxRequestFailed); 4919 4920 This->SetInternalFailure(); 4921 This->PowerPolicyCompleteSystemPowerIrp(); 4922 4923 if (FALSE == This->m_ReleaseHardwareAfterDescendantsOnFailure) { 4924 This->PnpProcessEvent(PnpEventPowerDownFailed); 4925 } 4926 4927 return WdfDevStatePwrPolDevicePowerRequestFailed; 4928 } 4929 4930 WDF_DEVICE_POWER_POLICY_STATE 4931 FxPkgPnp::PowerPolSleepingWakePowerDown( 4932 __inout FxPkgPnp* This 4933 ) 4934 /*++ 4935 4936 Routine Description: 4937 The system is going into Sx and the device is set to arm itself for wake from 4938 Sx. Start the power down process by requesting the Dx irp to stop I/O in 4939 the power state machine. 4940 4941 Arguments: 4942 This - instance of the state machine 4943 4944 Return Value: 4945 new state 4946 4947 --*/ 4948 { 4949 NTSTATUS status; 4950 4951 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleepingWakePowerDown); 4952 4953 status = This->PowerPolicyPowerDownForSx( 4954 This->m_PowerPolicyMachine.m_Owner->m_WakeSettings.DxState, NoRetry 4955 ); 4956 4957 if (!NT_SUCCESS(status)) { 4958 COVERAGE_TRAP(); 4959 return WdfDevStatePwrPolSleepingNoWakePowerDown; 4960 } 4961 4962 return WdfDevStatePwrPolNull; 4963 } 4964 4965 WDF_DEVICE_POWER_POLICY_STATE 4966 FxPkgPnp::PowerPolSleepingSendWake( 4967 __inout FxPkgPnp* This 4968 ) 4969 /*++ 4970 4971 Routine Description: 4972 Machine is moving into an Sx state and the device is in a partial Dx (I/O 4973 stopped) state. Send a wait wake request so that the device can be armed 4974 for wake from Sx. 4975 4976 Arguments: 4977 This - instance of the state machine 4978 4979 Return Value: 4980 new state 4981 4982 --*/ 4983 { 4984 SYSTEM_POWER_STATE systemState; 4985 NTSTATUS status; 4986 4987 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleepingSendWake); 4988 4989 // 4990 // We are in a wake-enabled path, keep wake interrupts connected. 4991 // 4992 This->m_WakeInterruptsKeepConnected = TRUE; 4993 4994 // 4995 // We use the deepest possible Sx state instead of the current Sx state so 4996 // that we can handle the FastS4 case where PowerPolicyGetPendingSystemState 4997 // would return, but we could possible goto S4. By using the deepest 4998 // possible state, we can arm for any possible Sx state that we are capable 4999 // of waking from. 5000 // 5001 systemState = This->PowerPolicyGetDeviceDeepestSystemWakeState(); 5002 5003 status = This->PowerPolicySendWaitWakeRequest(systemState); 5004 5005 if (!NT_SUCCESS(status)) { 5006 DoTraceLevelMessage( 5007 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 5008 "Attempting to send wait wake request for EvtDeviceArmWakeFromSx() " 5009 "failed, %!STATUS!", status); 5010 5011 COVERAGE_TRAP(); 5012 5013 return WdfDevStatePwrPolSleepingNoWakeCompletePowerDown; 5014 } 5015 5016 return WdfDevStatePwrPolNull; 5017 } 5018 5019 WDF_DEVICE_POWER_POLICY_STATE 5020 FxPkgPnp::PowerPolSystemAsleepNoWake( 5021 __inout FxPkgPnp* This 5022 ) 5023 { 5024 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemAsleepNoWake); 5025 5026 This->PowerPolicyCompleteSystemPowerIrp(); 5027 5028 return WdfDevStatePwrPolNull; 5029 } 5030 5031 WDF_DEVICE_POWER_POLICY_STATE 5032 FxPkgPnp::PowerPolSystemWakeDeviceWakeDisabled( 5033 __inout FxPkgPnp* This 5034 ) 5035 /*++ 5036 5037 Routine Description: 5038 The machine is moving from Sx->S0 and the device was in Dx and not armed for 5039 wake from Sx. Determine if the device should remain in Dx after the machine 5040 has moved into S0. 5041 5042 Arguments: 5043 This - instance of the state machine 5044 5045 Return Value: 5046 new state 5047 5048 --*/ 5049 { 5050 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceWakeDisabled); 5051 5052 // 5053 // We do not attempt to let the device remain in Dx if we are using system- 5054 // managed idle timeout. This is because an S0 IRP is equivalent to a 5055 // device-power-required notification from the power framework. In response 5056 // to it, we need to power up the device and notify the power framework that 5057 // the device is powered on. 5058 // 5059 if ((This->m_PowerPolicyMachine.m_Owner-> 5060 m_IdleSettings.m_TimeoutMgmt.UsingSystemManagedIdleTimeout() == FALSE) 5061 && 5062 (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.Enabled) 5063 && 5064 (This->m_PowerPolicyMachine.m_Owner-> 5065 m_IdleSettings.WakeFromS0Capable == FALSE) 5066 && 5067 (This->m_PowerPolicyMachine.m_Owner-> 5068 m_IdleSettings.PowerUpIdleDeviceOnSystemWake == FALSE)) { 5069 5070 return WdfDevStatePwrPolSystemWakeQueryIdle; 5071 } 5072 else { 5073 return WdfDevStatePwrPolSystemWakeDeviceToD0; 5074 } 5075 } 5076 5077 WDF_DEVICE_POWER_POLICY_STATE 5078 FxPkgPnp::PowerPolSystemWakeDeviceToD0( 5079 __inout FxPkgPnp* This 5080 ) 5081 { 5082 NTSTATUS status; 5083 5084 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeDeviceToD0); 5085 5086 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 5087 if (!NT_SUCCESS(status)) { 5088 COVERAGE_TRAP(); 5089 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 5090 } 5091 5092 return WdfDevStatePwrPolNull; 5093 } 5094 5095 WDF_DEVICE_POWER_POLICY_STATE 5096 FxPkgPnp::PowerPolSystemWakeDeviceToD0CompletePowerUp( 5097 __inout FxPkgPnp* This 5098 ) 5099 /*++ 5100 5101 Routine Description: 5102 The machine was in Sx and the device was not armed for wake from Sx. The 5103 machine is moving back into S0 and the device is in partial D0 (HW has 5104 started). Move the device into full D0 by sending the PowerCompleteD0 5105 event to the power state machine. 5106 5107 Arguments: 5108 This - instance of the state machine 5109 5110 Return Value: 5111 WdfDevStatePwrPolNull 5112 5113 --*/ 5114 { 5115 ASSERT_PWR_POL_STATE( 5116 This, WdfDevStatePwrPolSystemWakeDeviceToD0CompletePowerUp); 5117 5118 // 5119 // Simulate a device-power-not-required notification from the power 5120 // framework. An S0-IRP is essentially equivalent to a device-power-required 5121 // notification. 5122 // 5123 This->m_PowerPolicyMachine.m_Owner-> 5124 m_PoxInterface.SimulateDevicePowerRequired(); 5125 5126 // 5127 // Notify the device-power-requirement state machine that we are powered on 5128 // 5129 This->m_PowerPolicyMachine.m_Owner-> 5130 m_PoxInterface.DeviceIsPoweredOn(); 5131 5132 This->PowerProcessEvent(PowerCompleteD0); 5133 5134 return WdfDevStatePwrPolNull; 5135 } 5136 5137 WDF_DEVICE_POWER_POLICY_STATE 5138 FxPkgPnp::PowerPolSystemWakeQueryIdle( 5139 __inout FxPkgPnp* This 5140 ) 5141 { 5142 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSystemWakeQueryIdle); 5143 5144 // 5145 // This state can be reached only if we are using driver-managed idle 5146 // timeout. 5147 // 5148 ASSERT( 5149 This->m_PowerPolicyMachine.m_Owner-> 5150 m_IdleSettings.m_TimeoutMgmt.UsingSystemManagedIdleTimeout() == FALSE 5151 ); 5152 5153 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.QueryReturnToIdle()) { 5154 return WdfDevStatePwrPolWaitingUnarmed; 5155 } 5156 else { 5157 return WdfDevStatePwrPolSystemWakeDeviceToD0; 5158 } 5159 } 5160 5161 5162 WDF_DEVICE_POWER_POLICY_STATE 5163 FxPkgPnp::PowerPolStartedWakeCapable( 5164 __inout FxPkgPnp* This 5165 ) 5166 { 5167 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartedWakeCapable); 5168 5169 // 5170 // Enable the idle state machine. This will release any threads who are 5171 // waiting for the device to return to D0. 5172 // 5173 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.EnableTimer(); 5174 5175 return WdfDevStatePwrPolNull; 5176 } 5177 5178 WDF_DEVICE_POWER_POLICY_STATE 5179 FxPkgPnp::PowerPolWakeCapableDeviceIdle( 5180 __inout FxPkgPnp* This 5181 ) 5182 /*++ 5183 5184 Routine Description: 5185 We are now idle. Tell the active/idle state machine to move us to an idle 5186 state. 5187 5188 Arguments: 5189 This - instance of the state machine 5190 5191 Return Value: 5192 WdfDevStatePwrPolNull 5193 5194 --*/ 5195 { 5196 BOOLEAN canPowerDown; 5197 5198 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWakeCapableDeviceIdle); 5199 5200 canPowerDown = This->m_PowerPolicyMachine.m_Owner-> 5201 m_PoxInterface.DeclareComponentIdle(); 5202 5203 // 5204 // If we are using driver-managed idle timeout we can power down immediately 5205 // and so we jump to the next state (that initiates power down) immediately. 5206 // If we are using system-managed idle timeout, we wait in the current state 5207 // for device-power-not-required notification. 5208 // 5209 return (canPowerDown ? 5210 WdfDevStatePwrPolTimerExpiredDecideUsbSS : 5211 WdfDevStatePwrPolNull); 5212 } 5213 5214 WDF_DEVICE_POWER_POLICY_STATE 5215 FxPkgPnp::PowerPolTimerExpiredDecideUsbSS( 5216 __inout FxPkgPnp* This 5217 ) 5218 /*++ 5219 5220 Routine Description: 5221 Decides how to handle the idle timer firing. If the device is capable of 5222 USB selective suspend, it will move the machine into that path. Otherwise, 5223 the machine will be moved into the normal arm for wake while in D0 path. 5224 5225 Arguments: 5226 This - instance of the state machine 5227 5228 Return Value: 5229 WdfDevStatePwrPolTimerExpiredWakeCapableUsbSS 5230 or 5231 WdfDevStatePwrPolTimerExpiredWakeCapable 5232 5233 --*/ 5234 { 5235 NTSTATUS notifyPowerDownStatus; 5236 5237 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredDecideUsbSS); 5238 5239 // 5240 // Notify the device power requirement state machine that we are about to 5241 // power down. 5242 // 5243 notifyPowerDownStatus = This->m_PowerPolicyMachine.m_Owner-> 5244 m_PoxInterface.NotifyDevicePowerDown(); 5245 if (FALSE == NT_SUCCESS(notifyPowerDownStatus)) { 5246 // 5247 // We couldn't notify the device power requirement state machine that 5248 // we are about to power down, because the "device-power-required" 5249 // notification has already arrived. So we should not power down at this 5250 // time. Revert back to the started state. 5251 // 5252 return WdfDevStatePwrPolDeviceIdleReturnToActive; 5253 } 5254 5255 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 5256 return WdfDevStatePwrPolTimerExpiredWakeCapableUsbSS; 5257 } 5258 else { 5259 return WdfDevStatePwrPolTimerExpiredWakeCapablePowerDown; 5260 } 5261 } 5262 5263 WDF_DEVICE_POWER_POLICY_STATE 5264 FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDown( 5265 __inout FxPkgPnp* This 5266 ) 5267 /*++ 5268 5269 Routine Description: 5270 The device is enabled to be armed for wake from S0. The device just idled 5271 out and is now about to transition into this state. The first step is to 5272 move into a partial Dx state (I/O stopped), send the wake request, arm the 5273 device, and then move into full Dx. This function starts the transition 5274 by requesting a Dx irp. 5275 5276 Arguments: 5277 This - instance of the state machine 5278 5279 Return Value: 5280 new state 5281 5282 --*/ 5283 5284 { 5285 BOOLEAN poweredDown; 5286 5287 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDown); 5288 5289 poweredDown = This->PowerPolicyCanIdlePowerDown( 5290 This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.DxState 5291 ); 5292 5293 if (poweredDown == FALSE) { 5294 // 5295 // Upon failure, revert back to the started state. 5296 // 5297 return WdfDevStatePwrPolTimerExpiredWakeCapableDxAllocFailed; 5298 } 5299 5300 return WdfDevStatePwrPolNull; 5301 } 5302 5303 WDF_DEVICE_POWER_POLICY_STATE 5304 FxPkgPnp::PowerPolTimerExpiredWakeCapableSendWake( 5305 __inout FxPkgPnp* This 5306 ) 5307 { 5308 NTSTATUS status; 5309 5310 ASSERT_PWR_POL_STATE( 5311 This, WdfDevStatePwrPolTimerExpiredWakeCapableSendWake); 5312 5313 // 5314 // We are in a wake-enabled path, keep wake interrupts connected. 5315 // 5316 This->m_WakeInterruptsKeepConnected = TRUE; 5317 5318 status = This->PowerPolicySendWaitWakeRequest(PowerSystemWorking); 5319 5320 if (!NT_SUCCESS(status)) { 5321 DoTraceLevelMessage( 5322 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 5323 "Could not allocate wake request for wake from S0, revert arming," 5324 " %!STATUS!", status); 5325 5326 COVERAGE_TRAP(); 5327 5328 return WdfDevStatePwrPolTimerExpiredWakeCapableCleanup; 5329 } 5330 5331 return WdfDevStatePwrPolNull; 5332 } 5333 5334 WDF_DEVICE_POWER_POLICY_STATE 5335 FxPkgPnp::PowerPolTimerExpiredWakeCapableUsbSS( 5336 __inout FxPkgPnp* This 5337 ) 5338 /*++ 5339 5340 Routine Description: 5341 Sends the selective suspend ready irp down to the USB parent 5342 5343 Arguments: 5344 This - instance of the state machine 5345 5346 Return Value: 5347 WdfDevStatePwrPolNull 5348 5349 --*/ 5350 { 5351 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapableUsbSS); 5352 5353 This->PowerPolicySubmitUsbIdleNotification(); 5354 5355 return WdfDevStatePwrPolNull; 5356 } 5357 5358 WDF_DEVICE_POWER_POLICY_STATE 5359 FxPkgPnp::PowerPolWakeCapableUsbSSCompleted( 5360 __inout FxPkgPnp* This 5361 ) 5362 /*++ 5363 5364 Routine Description: 5365 We've sent the USB idle notification, but the bus driver completed it even 5366 before sending the USB idle callback. 5367 5368 Arguments: 5369 This - instance of the state machine 5370 5371 Return Value: 5372 WdfDevStatePwrPolNull 5373 5374 --*/ 5375 { 5376 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWakeCapableUsbSSCompleted); 5377 5378 // 5379 // We notified the device power requirement state machine that we are about 5380 // to power down, but eventually we didn't power down. So notify the device 5381 // power requirement state machine that the device should be considered 5382 // powered on. 5383 // 5384 This->m_PowerPolicyMachine.m_Owner-> 5385 m_PoxInterface.DeviceIsPoweredOn(); 5386 5387 This->m_PowerPolicyMachine.m_Owner-> 5388 m_PoxInterface.RequestComponentActive(); 5389 5390 return WdfDevStatePwrPolStartedWakeCapable; 5391 } 5392 5393 WDF_DEVICE_POWER_POLICY_STATE 5394 FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeArrived( 5395 __inout FxPkgPnp* This 5396 ) 5397 /*++ 5398 5399 Routine Description: 5400 The device is has been armed for wake from S0. It is in a partial Dx state 5401 (I/O stopped) and needs to transition to the total Dx state by sending 5402 a PowerCompleteDx event to the power state machine. 5403 5404 Arguments: 5405 This - instance of the state machine 5406 5407 Return Value: 5408 WdfDevStatePwrPolNull 5409 5410 --*/ 5411 { 5412 NTSTATUS status; 5413 5414 ASSERT_PWR_POL_STATE( 5415 This, WdfDevStatePwrPolTimerExpiredWakeCapableWakeArrived); 5416 5417 status = This->m_PowerPolicyMachine.m_Owner->m_DeviceArmWakeFromS0.Invoke( 5418 This->m_Device->GetHandle() 5419 ); 5420 5421 if (!NT_SUCCESS(status)) { 5422 return WdfDevStatePwrPolTimerExpiredWakeCapableCancelWake; 5423 } 5424 5425 // 5426 // If the PDO is the Power Policy owner, then enable wake at bus, otherwise 5427 // the power state machine will enable wake at bus. 5428 // 5429 if (This->m_Device->IsPdo()) { 5430 status = This->PowerEnableWakeAtBusOverload(); 5431 if (!NT_SUCCESS(status)) { 5432 DoTraceLevelMessage( 5433 This->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 5434 "WDFDEVICE %p Failed to Enable Wake at Bus, %!STATUS!", 5435 This->m_Device->GetHandle(), status); 5436 5437 return WdfDevStatePwrPolTimerExpiredWakeCapableCancelWake; 5438 } 5439 } 5440 5441 This->PowerProcessEvent(PowerCompleteDx); 5442 5443 return WdfDevStatePwrPolNull; 5444 } 5445 5446 WDF_DEVICE_POWER_POLICY_STATE 5447 FxPkgPnp::PowerPolTimerExpiredWakeCapableCancelWake( 5448 __inout FxPkgPnp* This 5449 ) 5450 /*++ 5451 5452 Routine Description: 5453 Device was attempting to enter Dx armed for wake from S0, but 5454 EvtDeviceArmForWakeFromS0 returned failure. Cancel the wait wake irp and 5455 move into Dx. 5456 5457 Arguments: 5458 This - instance of the state machine 5459 5460 Return Value: 5461 new state 5462 5463 --*/ 5464 { 5465 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapableCancelWake); 5466 5467 if (This->PowerPolicyCancelWaitWake() == FALSE) { 5468 return WdfDevStatePwrPolTimerExpiredWakeCapableWakeCanceled; 5469 } 5470 5471 return WdfDevStatePwrPolNull; 5472 } 5473 5474 WDF_DEVICE_POWER_POLICY_STATE 5475 FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeCanceled( 5476 __inout FxPkgPnp* This 5477 ) 5478 /*++ 5479 5480 Routine Description: 5481 The device was put into a wake from S0 state and the arm failed. The wait 5482 wake irp has been canceled, now complete the power down. 5483 5484 Arguments: 5485 This - instance of the state machine 5486 5487 Return Value: 5488 WdfDevStatePwrPolTimerExpiredWakeCapableCleanup 5489 5490 --*/ 5491 { 5492 UNREFERENCED_PARAMETER(This); 5493 5494 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapableWakeCanceled); 5495 5496 return WdfDevStatePwrPolTimerExpiredWakeCapableCleanup; 5497 } 5498 5499 WDF_DEVICE_POWER_POLICY_STATE 5500 FxPkgPnp::PowerPolTimerExpiredWakeCapableCleanup( 5501 __inout FxPkgPnp* This 5502 ) 5503 /*++ 5504 5505 Routine Description: 5506 An attempt to arm the device for wake from S0 has failed. Decide if we need 5507 to complete the USB SS callback or not before completely powering down so 5508 that we can power back up again. 5509 5510 Arguments: 5511 This - instance of the state machine 5512 5513 Return Value: 5514 new state 5515 5516 --*/ 5517 { 5518 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapableCleanup); 5519 5520 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 5521 COVERAGE_TRAP(); 5522 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 5523 } 5524 5525 // 5526 // Cancel UsbSS if present 5527 // 5528 if (This->PowerPolicyCancelUsbSSIfCapable()) { 5529 // 5530 // wait for Usbss completion event to move us from this state. 5531 // 5532 return WdfDevStatePwrPolNull; 5533 } 5534 5535 return WdfDevStatePwrPolTimerExpiredWakeCompletedPowerDown; 5536 } 5537 5538 WDF_DEVICE_POWER_POLICY_STATE 5539 FxPkgPnp::PowerPolTimerExpiredWakeCapableDxAllocFailed( 5540 __inout FxPkgPnp* This 5541 ) 5542 /*++ 5543 5544 Routine Description: 5545 The device idled out and we attempted to allocate a Dx irp so that we could 5546 be armed for wake from S0. The Dx irp allocation failed. Complete the 5547 USB SS callback and move back into the working state. 5548 5549 Arguments: 5550 This - instance of the state machine 5551 5552 Return Value: 5553 WdfDevStatePwrPolTimerExpiredWakeCapableUndoPowerDown 5554 5555 --*/ 5556 { 5557 ASSERT_PWR_POL_STATE( 5558 This, WdfDevStatePwrPolTimerExpiredWakeCapableDxAllocFailed); 5559 5560 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 5561 COVERAGE_TRAP(); 5562 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 5563 } 5564 5565 // 5566 // cancel USB SS irp if capable 5567 // 5568 if (This->PowerPolicyCancelUsbSSIfCapable()) { 5569 // 5570 // wait for Usbss completion event to move us from this state. 5571 // 5572 return WdfDevStatePwrPolNull; 5573 } 5574 5575 return WdfDevStatePwrPolTimerExpiredWakeCapableUndoPowerDown; 5576 } 5577 5578 WDF_DEVICE_POWER_POLICY_STATE 5579 FxPkgPnp::PowerPolTimerExpiredWakeCapableUndoPowerDown( 5580 __inout FxPkgPnp* This 5581 ) 5582 /*++ 5583 5584 Routine Description: 5585 The device idled out, but a failure occurred when we attempted to power 5586 down. So we need to return to the active state now. 5587 5588 Arguments: 5589 This - instance of the state machine 5590 5591 Return Value: 5592 WdfDevStatePwrPolDeviceIdleReturnToActive 5593 5594 --*/ 5595 { 5596 ASSERT_PWR_POL_STATE( 5597 This, WdfDevStatePwrPolTimerExpiredWakeCapableUndoPowerDown); 5598 5599 // 5600 // We notified the device power requirement state machine that we are about 5601 // to power down, but eventually we didn't power down. So notify the device 5602 // power requirement state machine that the device should be considered 5603 // powered on. 5604 // 5605 This->m_PowerPolicyMachine.m_Owner-> 5606 m_PoxInterface.DeviceIsPoweredOn(); 5607 return WdfDevStatePwrPolDeviceIdleReturnToActive; 5608 } 5609 5610 WDF_DEVICE_POWER_POLICY_STATE 5611 FxPkgPnp::PowerPolTimerExpiredWakeCompletedPowerDown( 5612 __inout FxPkgPnp* This 5613 ) 5614 /*++ 5615 5616 Routine Description: 5617 Complete the Dx transition from Dx armed for S0 wake. Upon going into Dx, 5618 we will move back into D0 since the wake completed already (or there was 5619 an error in arming). 5620 5621 Arguments: 5622 This - instance of the state machine 5623 5624 Return Value: 5625 WdfDevStatePwrPolNull 5626 5627 --*/ 5628 { 5629 ASSERT_PWR_POL_STATE( 5630 This, WdfDevStatePwrPolTimerExpiredWakeCompletedPowerDown); 5631 5632 This->PowerProcessEvent(PowerCompleteDx); 5633 5634 return WdfDevStatePwrPolNull; 5635 } 5636 5637 WDF_DEVICE_POWER_POLICY_STATE 5638 FxPkgPnp::PowerPolTimerExpiredWakeCompletedPowerUp( 5639 __inout FxPkgPnp* This 5640 ) 5641 /*++ 5642 5643 Routine Description: 5644 The device was armed for wake from S0 and the wake completed immediately 5645 (or there was a problem). We put the device into Dx and we are now trying 5646 to bring it back into D0. 5647 5648 Arguments: 5649 This - instance of the state machine 5650 5651 Return Value: 5652 new state 5653 5654 --*/ 5655 { 5656 NTSTATUS status; 5657 BOOLEAN result; 5658 5659 ASSERT_PWR_POL_STATE( 5660 This, WdfDevStatePwrPolTimerExpiredWakeCompletedPowerUp); 5661 5662 This->m_PowerPolicyMachine.m_Owner-> 5663 m_PoxInterface.RequestComponentActive(); 5664 5665 // 5666 // Disable the timer so that when we move back into D0, the timer is not 5667 // automatically started. Since the timer has already fired, we should never 5668 // get FALSE back (which indicates we should wait for the timer to fire). 5669 // 5670 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 5671 ASSERT(result); 5672 UNREFERENCED_PARAMETER(result); 5673 5674 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 5675 5676 if (!NT_SUCCESS(status)) { 5677 // 5678 // Couldn't allocate power irp, goto the failed state 5679 // 5680 COVERAGE_TRAP(); 5681 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 5682 } 5683 5684 return WdfDevStatePwrPolNull; 5685 } 5686 5687 WDF_DEVICE_POWER_POLICY_STATE 5688 FxPkgPnp::PowerPolTimerExpiredWakeCompletedHardwareStarted( 5689 __inout FxPkgPnp* This 5690 ) 5691 /*++ 5692 5693 Routine Description: 5694 We went idle and were in the process of powering down, but the wait-wake IRP 5695 completed even before we could arm the device for wake. We finished powering 5696 down the device and we're now powering it back up due to the wait-wake 5697 completion. 5698 5699 Arguments: 5700 This - instance of the state machine 5701 5702 Return Value: 5703 WdfDevStatePwrPolNull 5704 5705 --*/ 5706 { 5707 ASSERT_PWR_POL_STATE(This, 5708 WdfDevStatePwrPolTimerExpiredWakeCompletedHardwareStarted); 5709 5710 This->m_PowerPolicyMachine.m_Owner-> 5711 m_PoxInterface.DeviceIsPoweredOn(); 5712 5713 return WdfDevStatePwrPolS0WakeCompletePowerUp; 5714 } 5715 5716 WDF_DEVICE_POWER_POLICY_STATE 5717 FxPkgPnp::PowerPolWaitingArmedUsbSS( 5718 __inout FxPkgPnp* This 5719 ) 5720 /*++ 5721 5722 Routine Description: 5723 Complete the USB SS callback now tha the device is armed and in Dx 5724 5725 Arguments: 5726 This - instance of the state machine 5727 5728 Return Value: 5729 WdfDevStatePwrPolWaitingArmed 5730 5731 --*/ 5732 { 5733 BOOLEAN result; 5734 5735 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedUsbSS); 5736 5737 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 5738 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 5739 } 5740 5741 // 5742 // Disable the timer so that when we move back into D0, the timer is not 5743 // automatically started. Since the timer has already fired, we should never 5744 // get FALSE back (which indicates we should wait for the timer to fire). 5745 // 5746 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 5747 ASSERT(result); 5748 UNREFERENCED_PARAMETER(result); 5749 5750 // 5751 // PwrPolIoPresent can be sent before PwrPolPowerTimeoutExpired in the idle 5752 // state machine if the idle s.m. attempts to cancel the timer after it has 5753 // started running. That means the PwrPolIoPresent meant to wake up the 5754 // device and resume from idle is lost. By first querying the idle s.m. 5755 // after moving into Dx we can recover from the lost event. 5756 // 5757 return WdfDevStatePwrPolWaitingArmedQueryIdle; 5758 } 5759 5760 WDF_DEVICE_POWER_POLICY_STATE 5761 FxPkgPnp::PowerPolWaitingArmedQueryIdle( 5762 __inout FxPkgPnp* This 5763 ) 5764 /*++ 5765 5766 Routine Description: 5767 The device was in the WaitingArmed state and received a PwrPolIoPresent 5768 event. Before committing the device to move back to D0, check to see if 5769 the device has returned to an idle state. This can easily happen if the 5770 driver causes a power reference in D0Exit accidentally and the power 5771 reference is removed before exitting the function. 5772 5773 Arguments: 5774 This - instance of the state machine 5775 5776 Return Value: 5777 new state 5778 5779 --*/ 5780 5781 { 5782 // 5783 // If QueryReturnToIdle returns TRUE, return to the waiting state 5784 // 5785 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.QueryReturnToIdle()) { 5786 return WdfDevStatePwrPolWaitingArmed; 5787 } 5788 else { 5789 return WdfDevStatePwrPolWaitingArmedIoPresentCancelUsbSS; 5790 } 5791 } 5792 5793 WDF_DEVICE_POWER_POLICY_STATE 5794 FxPkgPnp::PowerPolIoPresentArmed( 5795 __inout FxPkgPnp* This 5796 ) 5797 { 5798 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolIoPresentArmed); 5799 5800 if (This->PowerPolicyCancelWaitWake() == FALSE && 5801 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 5802 COVERAGE_TRAP(); 5803 return WdfDevStatePwrPolIoPresentArmedWakeCanceled; 5804 } 5805 5806 return WdfDevStatePwrPolNull; 5807 } 5808 5809 WDF_DEVICE_POWER_POLICY_STATE 5810 FxPkgPnp::PowerPolWaitingArmedWakeInterruptFired( 5811 __inout FxPkgPnp* This 5812 ) 5813 { 5814 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedWakeInterruptFired); 5815 5816 if (This->PowerPolicyCancelWaitWake() == FALSE && 5817 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 5818 return WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS; 5819 } 5820 5821 return WdfDevStatePwrPolNull; 5822 } 5823 5824 WDF_DEVICE_POWER_POLICY_STATE 5825 FxPkgPnp::PowerPolIoPresentArmedWakeCanceled( 5826 __inout FxPkgPnp* This 5827 ) 5828 { 5829 NTSTATUS status; 5830 5831 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolIoPresentArmedWakeCanceled); 5832 5833 This->m_PowerPolicyMachine.m_Owner-> 5834 m_PoxInterface.RequestComponentActive(); 5835 5836 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 5837 5838 if (!NT_SUCCESS(status)) { 5839 COVERAGE_TRAP(); 5840 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 5841 } 5842 5843 return WdfDevStatePwrPolNull; 5844 } 5845 5846 WDF_DEVICE_POWER_POLICY_STATE 5847 FxPkgPnp::PowerPolS0WakeDisarm( 5848 __inout FxPkgPnp* This 5849 ) 5850 { 5851 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolS0WakeDisarm); 5852 5853 This->m_PowerPolicyMachine.m_Owner-> 5854 m_PoxInterface.DeviceIsPoweredOn(); 5855 5856 // 5857 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 5858 // the power state machine will disable wake at bus. 5859 // 5860 if (This->m_Device->IsPdo()) { 5861 This->PowerDisableWakeAtBusOverload(); 5862 } 5863 5864 This->m_PowerPolicyMachine.m_Owner->m_DeviceDisarmWakeFromS0.Invoke( 5865 This->m_Device->GetHandle() 5866 ); 5867 5868 return WdfDevStatePwrPolS0WakeCompletePowerUp; 5869 } 5870 5871 WDF_DEVICE_POWER_POLICY_STATE 5872 FxPkgPnp::PowerPolS0WakeCompletePowerUp( 5873 __inout FxPkgPnp* This 5874 ) 5875 /*++ 5876 5877 Routine Description: 5878 We are moving back into D0 from being armed for wake from S0. The device 5879 is in partial D0 (hw started) already, so complete the transition to D0 5880 by posting the PowerCompleteD0 event to the power state machine. 5881 5882 Arguments: 5883 This - instance of the state machine 5884 5885 Return Value: 5886 WdfDevStatePwrPolNull 5887 5888 --*/ 5889 { 5890 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolS0WakeCompletePowerUp); 5891 5892 This->PowerProcessEvent(PowerCompleteD0); 5893 5894 return WdfDevStatePwrPolNull; 5895 } 5896 5897 WDF_DEVICE_POWER_POLICY_STATE 5898 FxPkgPnp::PowerPolTimerExpiredWakeSucceeded( 5899 __inout FxPkgPnp* This 5900 ) 5901 /*++ 5902 5903 Routine Description: 5904 The wake irp succeeded synchronously when we sent it down the stack. Notify 5905 the driver and move immediately back into the working state. 5906 5907 Arguments: 5908 This - instance of the state machine 5909 5910 Return Value: 5911 WdfDevStatePwrPolStartingDecideS0Wake 5912 5913 --*/ 5914 { 5915 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeSucceeded); 5916 5917 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromS0Triggered.Invoke( 5918 This->m_Device->GetHandle() 5919 ); 5920 5921 return WdfDevStatePwrPolTimerExpiredWakeCompletedDisarm; 5922 } 5923 5924 WDF_DEVICE_POWER_POLICY_STATE 5925 FxPkgPnp::PowerPolTimerExpiredWakeCompletedDisarm( 5926 __inout FxPkgPnp* This 5927 ) 5928 /*++ 5929 5930 Routine Description: 5931 The device was armed for wake from Dx in S0. The wake irp completed 5932 before the PwrPolPowerDown was processed. Disarm the device, move to Dx, 5933 and then immediately back to D0. 5934 5935 Arguments: 5936 This - instance of the state machine 5937 5938 Return Value: 5939 WdfDevStatePwrPolTimerExpiredWakeCapableCleanup 5940 5941 --*/ 5942 { 5943 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCompletedDisarm); 5944 5945 // 5946 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 5947 // the power state machine will disable wake at bus. 5948 // 5949 if (This->m_Device->IsPdo()) { 5950 This->PowerDisableWakeAtBusOverload(); 5951 } 5952 5953 This->m_PowerPolicyMachine.m_Owner->m_DeviceDisarmWakeFromS0.Invoke( 5954 This->m_Device->GetHandle() 5955 ); 5956 5957 return WdfDevStatePwrPolTimerExpiredWakeCapableCleanup; 5958 5959 } 5960 5961 WDF_DEVICE_POWER_POLICY_STATE 5962 FxPkgPnp::PowerPolWakeFailedUsbSS( 5963 __inout FxPkgPnp* This 5964 ) 5965 /*++ 5966 5967 Routine Description: 5968 Wake failed before we got the Dx irp. Complete the SS calback and then 5969 move to the WakeFailed state. 5970 5971 Arguments: 5972 This - instance of the state machine 5973 5974 Return Value: 5975 WdfDevStatePwrPolIoPresentArmedWakeCanceled 5976 5977 --*/ 5978 { 5979 BOOLEAN result; 5980 5981 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWakeFailedUsbSS); 5982 5983 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 5984 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 5985 } 5986 5987 // 5988 // Disable the timer so that when we move back into D0, the timer is not 5989 // automatically started. Since the timer has already fired, we should never 5990 // get FALSE back (which indicates we should wait for the timer to fire). 5991 // 5992 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 5993 ASSERT(result); 5994 UNREFERENCED_PARAMETER(result); 5995 5996 // 5997 // cancel USB SS irp if capable 5998 // 5999 if (This->PowerPolicyCancelUsbSSIfCapable()) { 6000 // 6001 // wait for Usbss completion event to move us from this state. 6002 // 6003 return WdfDevStatePwrPolNull; 6004 } 6005 6006 return WdfDevStatePwrPolIoPresentArmedWakeCanceled; 6007 } 6008 6009 WDF_DEVICE_POWER_POLICY_STATE 6010 FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedCancelWake( 6011 __inout FxPkgPnp* This 6012 ) 6013 /*++ 6014 6015 Routine Description: 6016 We sent the wake request, but the power state machine failed. Cancel the 6017 wake request and then move to the failed state. 6018 6019 Arguments: 6020 This - instance of the state machine 6021 6022 Return Value: 6023 new state 6024 6025 --*/ 6026 { 6027 ASSERT_PWR_POL_STATE( 6028 This, 6029 WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedCancelWake); 6030 6031 if (This->PowerPolicyCancelWaitWake() == FALSE) { 6032 return WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled; 6033 } 6034 6035 return WdfDevStatePwrPolNull; 6036 } 6037 6038 WDF_DEVICE_POWER_POLICY_STATE 6039 FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled( 6040 __inout FxPkgPnp* This 6041 ) 6042 /*++ 6043 6044 Routine Description: 6045 The wake request has been canceled. Move to the state where we will decide 6046 if we need to complete the USB SS callback. 6047 6048 There is no need to disarm for wake from S0 because the failure here is for 6049 the device to power down. We must assume the device is now in Dx and we 6050 cannot touch hw in this state. 6051 6052 Arguments: 6053 This - instance of the state machine 6054 6055 Return Value: 6056 new state, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedDecideUsbSS 6057 6058 --*/ 6059 { 6060 UNREFERENCED_PARAMETER(This); 6061 6062 ASSERT_PWR_POL_STATE( 6063 This, 6064 WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedWakeCanceled); 6065 6066 return WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedUsbSS; 6067 } 6068 6069 WDF_DEVICE_POWER_POLICY_STATE 6070 FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownFailedUsbSS( 6071 __inout FxPkgPnp* This 6072 ) 6073 /*++ 6074 6075 Routine Description: 6076 Complete the USB SS callback if enabled and the move to the failed state 6077 6078 Arguments: 6079 This - instance of the state machine 6080 6081 Return Value: 6082 new state, WdfDevStatePwrPolDevicePowerRequestFailed 6083 6084 --*/ 6085 { 6086 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownFailedUsbSS); 6087 6088 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 6089 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 6090 } 6091 6092 if (This->PowerPolicyCancelUsbSSIfCapable()) { 6093 // 6094 // wait for Usbss completion event to move us from this state. 6095 // 6096 return WdfDevStatePwrPolNull; 6097 } 6098 6099 return WdfDevStatePwrPolDevicePowerRequestFailed; 6100 } 6101 6102 WDF_DEVICE_POWER_POLICY_STATE 6103 FxPkgPnp::PowerPolCancelingWakeForSystemSleep( 6104 __inout FxPkgPnp* This 6105 ) 6106 { 6107 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolCancelingWakeForSystemSleep); 6108 6109 if (This->PowerPolicyCancelWaitWake() == FALSE && 6110 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 6111 return WdfDevStatePwrPolCancelingWakeForSystemSleepWakeCanceled; 6112 } 6113 6114 return WdfDevStatePwrPolNull; 6115 } 6116 6117 WDF_DEVICE_POWER_POLICY_STATE 6118 FxPkgPnp::PowerPolCancelingWakeForSystemSleepWakeCanceled( 6119 __inout FxPkgPnp* This 6120 ) 6121 { 6122 NTSTATUS status; 6123 6124 ASSERT_PWR_POL_STATE( 6125 This, WdfDevStatePwrPolCancelingWakeForSystemSleepWakeCanceled); 6126 6127 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, NoRetry); 6128 6129 if (!NT_SUCCESS(status)) { 6130 COVERAGE_TRAP(); 6131 return WdfDevStatePwrPolPowerUpForSystemSleepNotSeen; 6132 } 6133 6134 return WdfDevStatePwrPolNull; 6135 } 6136 6137 WDF_DEVICE_POWER_POLICY_STATE 6138 FxPkgPnp::PowerPolDisarmingWakeForSystemSleepCompletePowerUp( 6139 __inout FxPkgPnp* This 6140 ) 6141 /*++ 6142 6143 Routine Description: 6144 The device was armed for wake from S0 and in Dx. The machine is now moving 6145 into Sx. The device is currently in partial D0 (HW started). Disarm wake 6146 from S0 and then move the device fully into D0 (I/0 started). 6147 6148 Arguments: 6149 This - instance of the state machine 6150 6151 Return Value: 6152 WdfDevStatePwrPolNull 6153 6154 --*/ 6155 { 6156 ASSERT_PWR_POL_STATE( 6157 This, WdfDevStatePwrPolDisarmingWakeForSystemSleepCompletePowerUp); 6158 6159 // 6160 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 6161 // the power state machine will disable wake at bus. 6162 // 6163 if (This->m_Device->IsPdo()) { 6164 This->PowerDisableWakeAtBusOverload(); 6165 } 6166 6167 This->m_PowerPolicyMachine.m_Owner->m_DeviceDisarmWakeFromS0.Invoke( 6168 This->m_Device->GetHandle() 6169 ); 6170 6171 This->PowerProcessEvent(PowerCompleteD0); 6172 6173 return WdfDevStatePwrPolNull; 6174 } 6175 6176 WDF_DEVICE_POWER_POLICY_STATE 6177 FxPkgPnp::PowerPolPowerUpForSystemSleepFailed( 6178 __inout FxPkgPnp* This 6179 ) 6180 /*++ 6181 6182 Routine Description: 6183 The system is moving into an Sx state and the device was in a Dx armed for 6184 wake from S0 state. Power up has failed (could not allocate the request, 6185 actual power up path failed, etc). Complete the Sx irp and move into a 6186 state where we can be removed when we return to S0. 6187 6188 Arguments: 6189 This - instance of the state machine 6190 6191 Return Value: 6192 WdfDevStatePwrPolDevicePowerRequestFailed 6193 6194 --*/ 6195 { 6196 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolPowerUpForSystemSleepFailed); 6197 6198 This->PowerPolicyCompleteSystemPowerIrp(); 6199 6200 return WdfDevStatePwrPolDevicePowerRequestFailed; 6201 } 6202 6203 WDF_DEVICE_POWER_POLICY_STATE 6204 FxPkgPnp::PowerPolWokeFromS0UsbSS( 6205 __inout FxPkgPnp* This 6206 ) 6207 /*++ 6208 6209 Routine Description: 6210 The device successfully woke up before we got to the WaitingArmed state. 6211 Complete the USB SS callback while we are in Dx. 6212 6213 Arguments: 6214 This - instance of the state machine 6215 6216 Return Value: 6217 WdfDevStatePwrPolWokeFromS0 6218 6219 --*/ 6220 { 6221 BOOLEAN result; 6222 6223 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWokeFromS0UsbSS); 6224 6225 if (This->m_PowerPolicyMachine.m_Owner->m_IdleSettings.UsbSSCapable) { 6226 This->m_PowerPolicyMachine.UsbSSCallbackProcessingComplete(); 6227 } 6228 6229 // 6230 // Disable the timer so that when we move back into D0, the timer is not 6231 // automatically started. Since the timer has already fired, we should never 6232 // get FALSE back (which indicates we should wait for the timer to fire). 6233 // 6234 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 6235 ASSERT(result); 6236 UNREFERENCED_PARAMETER(result); 6237 6238 // 6239 // Cancel USBSS irp if capable 6240 // 6241 if (This->PowerPolicyCancelUsbSSIfCapable()) { 6242 // 6243 // Usbss completion event will move us from this state. 6244 // 6245 return WdfDevStatePwrPolNull; 6246 } 6247 6248 return WdfDevStatePwrPolWokeFromS0; 6249 } 6250 6251 WDF_DEVICE_POWER_POLICY_STATE 6252 FxPkgPnp::PowerPolWokeFromS0( 6253 __inout FxPkgPnp* This 6254 ) 6255 { 6256 NTSTATUS status; 6257 6258 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWokeFromS0); 6259 6260 This->m_PowerPolicyMachine.m_Owner-> 6261 m_PoxInterface.RequestComponentActive(); 6262 6263 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 6264 if (!NT_SUCCESS(status)) { 6265 COVERAGE_TRAP(); 6266 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 6267 } 6268 6269 return WdfDevStatePwrPolNull; 6270 } 6271 6272 WDF_DEVICE_POWER_POLICY_STATE 6273 FxPkgPnp::PowerPolWokeFromS0NotifyDriver( 6274 __inout FxPkgPnp* This 6275 ) 6276 /*++ 6277 6278 Routine Description: 6279 The device was armed for wake from S0 and it successfully woke up and triggered 6280 wake. Notify the driver of this on the way back up to D0. 6281 6282 Arguments: 6283 This - instance of the state machine 6284 6285 Return Value: 6286 WdfDevStatePwrPolS0WakeDisarm 6287 6288 --*/ 6289 { 6290 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWokeFromS0NotifyDriver); 6291 6292 This->m_PowerPolicyMachine.m_Owner->m_DeviceWakeFromS0Triggered.Invoke( 6293 This->m_Device->GetHandle() 6294 ); 6295 6296 return WdfDevStatePwrPolS0WakeDisarm; 6297 } 6298 6299 WDF_DEVICE_POWER_POLICY_STATE 6300 FxPkgPnp::PowerPolStoppingResetDevice( 6301 __inout FxPkgPnp* This 6302 ) 6303 /*++ 6304 6305 Routine Description: 6306 The device was in a Dx state, unarmed for wake. The device is not being 6307 removed, so we must disable the idle timer and power up the device so that 6308 we can implicitly power it down. 6309 6310 Arguments: 6311 This - instance of the state machine 6312 6313 Return Value: 6314 new state 6315 6316 --*/ 6317 { 6318 NTSTATUS status; 6319 BOOLEAN result; 6320 6321 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingResetDevice); 6322 6323 This->m_PowerPolicyMachine.m_Owner-> 6324 m_PoxInterface.RequestComponentActive(); 6325 6326 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 6327 ASSERT(result); 6328 UNREFERENCED_PARAMETER(result); 6329 6330 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 6331 6332 if (!NT_SUCCESS(status)) { 6333 COVERAGE_TRAP(); 6334 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 6335 } 6336 6337 return WdfDevStatePwrPolNull; 6338 } 6339 6340 WDF_DEVICE_POWER_POLICY_STATE 6341 FxPkgPnp::PowerPolStoppingResetDeviceCompletePowerUp( 6342 __inout FxPkgPnp* This 6343 ) 6344 /*++ 6345 6346 Routine Description: 6347 The device was idled out and in Dx (not armed for wake from S0). The power 6348 policy state machine is being stopped and the device has been brought into 6349 partial D0 (HW started). Complete the D0 transition by sending PowerCompleteD0 6350 to the power state machine. 6351 6352 Arguments: 6353 This - Instance of the state machine 6354 6355 Return Value: 6356 WdfDevStatePwrPolNull 6357 6358 --*/ 6359 { 6360 ASSERT_PWR_POL_STATE( 6361 This, WdfDevStatePwrPolStoppingResetDeviceCompletePowerUp); 6362 6363 This->m_PowerPolicyMachine.m_Owner-> 6364 m_PoxInterface.DeviceIsPoweredOn(); 6365 6366 This->PowerProcessEvent(PowerCompleteD0); 6367 6368 return WdfDevStatePwrPolNull; 6369 } 6370 6371 WDF_DEVICE_POWER_POLICY_STATE 6372 FxPkgPnp::PowerPolStoppingResetDeviceFailed( 6373 __inout FxPkgPnp* This 6374 ) 6375 /*++ 6376 6377 Routine Description: 6378 The attempt to power on a device in the idled out state so that we can stop 6379 the power policy state machine failed. Record the error and continue down 6380 the stop path. 6381 6382 Arguments: 6383 This - instance of the state machine 6384 6385 Return Value: 6386 WdfDevStatePwrPolStopping 6387 6388 --*/ 6389 6390 { 6391 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingResetDeviceFailed); 6392 6393 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed = TRUE; 6394 6395 // 6396 // Notify the device power requirement state machine that the device should 6397 // be considered powered on, although it is not. Doing this will ensure that 6398 // component activation before device removal will succeed. 6399 // 6400 This->m_PowerPolicyMachine.m_Owner-> 6401 m_PoxInterface.DeviceIsPoweredOn(); 6402 6403 return WdfDevStatePwrPolStopping; 6404 } 6405 6406 WDF_DEVICE_POWER_POLICY_STATE 6407 FxPkgPnp::PowerPolStoppingD0( 6408 __inout FxPkgPnp* This 6409 ) 6410 { 6411 NTSTATUS status; 6412 6413 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingD0); 6414 6415 This->m_PowerPolicyMachine.m_Owner-> 6416 m_PoxInterface.RequestComponentActive(); 6417 6418 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 6419 6420 status = This->PowerPolicySendDevicePowerRequest(PowerDeviceD0, Retry); 6421 if (!NT_SUCCESS(status)) { 6422 COVERAGE_TRAP(); 6423 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 6424 } 6425 6426 return WdfDevStatePwrPolNull; 6427 } 6428 6429 WDF_DEVICE_POWER_POLICY_STATE 6430 FxPkgPnp::PowerPolStoppingD0Failed( 6431 __inout FxPkgPnp* This 6432 ) 6433 /*++ 6434 6435 Routine Description: 6436 While attempting to stop the device and bring it into D0, power up failed. 6437 Record the error and continue. 6438 6439 Arguments: 6440 This - instance of the state machine 6441 6442 Return Value: 6443 WdfDevStatePwrPolStoppingDisarmWakeCancelWake 6444 6445 --*/ 6446 6447 { 6448 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingD0Failed); 6449 6450 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed = TRUE; 6451 6452 // 6453 // Notify the device power requirement state machine that the device should 6454 // be considered powered on, although it is not. Doing this will ensure that 6455 // component activation before device removal will succeed. 6456 // 6457 This->m_PowerPolicyMachine.m_Owner-> 6458 m_PoxInterface.DeviceIsPoweredOn(); 6459 6460 return WdfDevStatePwrPolStoppingDisarmWakeCancelWake; 6461 } 6462 6463 WDF_DEVICE_POWER_POLICY_STATE 6464 FxPkgPnp::PowerPolStoppingDisarmWake( 6465 __inout FxPkgPnp* This 6466 ) 6467 { 6468 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingDisarmWake); 6469 6470 This->m_PowerPolicyMachine.m_Owner-> 6471 m_PoxInterface.DeviceIsPoweredOn(); 6472 6473 // 6474 // If the PDO is the Power Policy owner, then disable wake at bus, otherwise 6475 // the power state machine will disable wake at bus. 6476 // 6477 if (This->m_Device->IsPdo()) { 6478 This->PowerDisableWakeAtBusOverload(); 6479 } 6480 6481 This->m_PowerPolicyMachine.m_Owner->m_DeviceDisarmWakeFromS0.Invoke( 6482 This->m_Device->GetHandle() 6483 ); 6484 6485 This->PowerProcessEvent(PowerCompleteD0); 6486 6487 return WdfDevStatePwrPolNull; 6488 6489 } 6490 6491 WDF_DEVICE_POWER_POLICY_STATE 6492 FxPkgPnp::PowerPolStoppingDisarmWakeCancelWake( 6493 __inout FxPkgPnp* This 6494 ) 6495 { 6496 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingDisarmWakeCancelWake); 6497 6498 if (This->PowerPolicyCancelWaitWake() == FALSE && 6499 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 6500 return WdfDevStatePwrPolStoppingDisarmWakeWakeCanceled; 6501 } 6502 6503 return WdfDevStatePwrPolNull; 6504 } 6505 6506 WDF_DEVICE_POWER_POLICY_STATE 6507 FxPkgPnp::PowerPolStoppingDisarmWakeWakeCanceled( 6508 __inout FxPkgPnp* This 6509 ) 6510 { 6511 UNREFERENCED_PARAMETER(This); 6512 6513 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingDisarmWakeWakeCanceled); 6514 6515 return WdfDevStatePwrPolStopping; 6516 } 6517 6518 WDF_DEVICE_POWER_POLICY_STATE 6519 FxPkgPnp::PowerPolStopping( 6520 __inout FxPkgPnp* This 6521 ) 6522 { 6523 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStopping); 6524 6525 // 6526 // Prevent any children from powering up. Technically this is not necessary 6527 // because if we are getting to this point, all of our children have already 6528 // been implicitly stopped as well, but this keeps the child power up state 6529 // consistent with the power policy state. 6530 // 6531 This->PowerPolicyBlockChildrenPowerUp(); 6532 6533 // 6534 // This power change event does not need to be synchronous 6535 // 6536 This->PowerProcessEvent(PowerImplicitD3); 6537 6538 return WdfDevStatePwrPolNull; 6539 } 6540 6541 WDF_DEVICE_POWER_POLICY_STATE 6542 FxPkgPnp::PowerPolStoppingFailed( 6543 __inout FxPkgPnp* This 6544 ) 6545 /*++ 6546 6547 Routine Description: 6548 The attempt to move the power state machine into a Dx state failed. Report 6549 the failure to pnp and move to the stopped state. 6550 6551 Arguments: 6552 This - instance of the state machine 6553 6554 Return Value: 6555 WdfDevStatePwrPolStopped 6556 6557 --*/ 6558 { 6559 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingFailed); 6560 6561 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed = TRUE; 6562 6563 return WdfDevStatePwrPolStoppingSendStatus; 6564 } 6565 6566 WDF_DEVICE_POWER_POLICY_STATE 6567 FxPkgPnp::PowerPolStoppingSendStatus( 6568 __inout FxPkgPnp* This 6569 ) 6570 /*++ 6571 6572 Routine Description: 6573 The power policy machine is about to finish stopping. The final act of 6574 stopping is notify the Pnp state machine of the final outcome. Do so, reset 6575 state, and move to the stopped state. 6576 6577 Arguments: 6578 This - instance of the state machine 6579 6580 Return Value: 6581 WdfDevStatePwrPolStopped 6582 6583 --*/ 6584 { 6585 KIRQL irql; 6586 6587 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingSendStatus); 6588 6589 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Stop(); 6590 6591 // 6592 // We raise IRQL to dispatch level so that pnp is forced onto its own thread 6593 // to process the PwrPolStopped event. If pnp is on the power thread when 6594 // it processes the event and it tries to delete the dedicated thread, it 6595 // will deadlock waiting for the thread its on to exit. 6596 // 6597 Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql); 6598 This->PnpProcessEvent( 6599 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed 6600 ? PnpEventPwrPolStopFailed 6601 : PnpEventPwrPolStopped 6602 ); 6603 Mx::MxLowerIrql(irql); 6604 6605 // 6606 // Reset back to a non failed state 6607 // 6608 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed = FALSE; 6609 6610 return WdfDevStatePwrPolStopped; 6611 } 6612 6613 WDF_DEVICE_POWER_POLICY_STATE 6614 FxPkgPnp::PowerPolStoppedRemoving( 6615 __inout FxPkgPnp* This 6616 ) 6617 /*++ 6618 6619 Routine Description: 6620 The device is being removed. Tell the active/idle state machine to 6621 unregister with the power framework. 6622 6623 Arguments: 6624 This - instance of the state machine 6625 6626 Return Value: 6627 WdfDevStatePwrPolNull 6628 6629 --*/ 6630 { 6631 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppedRemoving); 6632 6633 This->m_PowerPolicyMachine.m_Owner-> 6634 m_PoxInterface.UninitializeComponents(); 6635 6636 return WdfDevStatePwrPolRemoved; 6637 } 6638 6639 WDF_DEVICE_POWER_POLICY_STATE 6640 FxPkgPnp::PowerPolRemoved( 6641 __inout FxPkgPnp* This 6642 ) 6643 /*++ 6644 6645 Routine Description: 6646 The active/idle state machine has unregistered with the power framework. 6647 Tell the PNP state machine that device removal can proceed. 6648 6649 Arguments: 6650 This - instance of the state machine 6651 6652 Return Value: 6653 WdfDevStatePwrPolNull 6654 6655 --*/ 6656 { 6657 KIRQL irql; 6658 6659 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolRemoved); 6660 6661 // 6662 // We raise IRQL to dispatch level so that pnp is forced onto its own thread 6663 // to process the PwrPolRemoved event. If pnp is on the power thread when 6664 // it processes the event and it tries to delete the dedicated thread, it 6665 // will deadlock waiting for the thread it is on to exit. 6666 // 6667 Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql); 6668 This->PnpProcessEvent(PnpEventPwrPolRemoved); 6669 Mx::MxLowerIrql(irql); 6670 6671 return WdfDevStatePwrPolNull; 6672 } 6673 6674 WDF_DEVICE_POWER_POLICY_STATE 6675 FxPkgPnp::PowerPolRestarting( 6676 __inout FxPkgPnp* This 6677 ) 6678 /*++ 6679 6680 Routine Description: 6681 The device is restarting after being stopped 6682 6683 Arguments: 6684 This - instance of the state machine 6685 6686 Return Value: 6687 WdfDevStatePwrPolNull 6688 6689 --*/ 6690 { 6691 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolRestarting); 6692 6693 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Start(); 6694 6695 This->PowerProcessEvent(PowerImplicitD0); 6696 6697 // 6698 // Wait for the successful power up before starting any idle timers. If 6699 // the power up fails, we will not send a power policy stop from the pnp 6700 // engine. 6701 // 6702 return WdfDevStatePwrPolNull; 6703 } 6704 6705 WDF_DEVICE_POWER_POLICY_STATE 6706 FxPkgPnp::PowerPolRestartingFailed( 6707 __inout FxPkgPnp* This 6708 ) 6709 /*++ 6710 6711 Routine Description: 6712 Power up failed when restarting the device 6713 6714 Arguments: 6715 This - instance of the state machine 6716 6717 Return Value: 6718 WdfDevStatePwrPolStopped 6719 6720 --*/ 6721 { 6722 KIRQL irql; 6723 6724 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolRestartingFailed); 6725 6726 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.Stop(); 6727 6728 // 6729 // We raise IRQL to dispatch level so that pnp is forced onto its own thread 6730 // to process the PwrPolStartFailed event. If pnp is on the power thread 6731 // when it processes the event and it tries to delete the dedicated thread, 6732 // it will deadlock waiting for the thread it is on to exit. 6733 // 6734 Mx::MxRaiseIrql(DISPATCH_LEVEL, &irql); 6735 This->PnpProcessEvent(PnpEventPwrPolStartFailed); 6736 Mx::MxLowerIrql(irql); 6737 6738 return WdfDevStatePwrPolStopped; 6739 } 6740 6741 WDF_DEVICE_POWER_POLICY_STATE 6742 FxPkgPnp::PowerPolStoppingCancelTimer( 6743 __inout FxPkgPnp* This 6744 ) 6745 /*++ 6746 6747 Routine Description: 6748 Moving to the stopping state. Need to cancel the idle timeout timer. 6749 6750 Arguments: 6751 This - instance of the state machine 6752 6753 Return Value: 6754 new power policy state 6755 6756 --*/ 6757 { 6758 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingCancelTimer); 6759 6760 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer()) { 6761 return WdfDevStatePwrPolStopping; 6762 } 6763 else { 6764 // 6765 // Timer was not canceled, move to the state where we wait for the 6766 // timeout event to be posted. 6767 // 6768 return WdfDevStatePwrPolStoppingWaitForIdleTimeout; 6769 } 6770 } 6771 6772 WDF_DEVICE_POWER_POLICY_STATE 6773 FxPkgPnp::PowerPolStoppingCancelUsbSS( 6774 __inout FxPkgPnp* This 6775 ) 6776 /*++ 6777 6778 Routine Description: 6779 Cancel the USB SS request because we are being stopped or surprise removed 6780 6781 Arguments: 6782 This - instance of the state machine 6783 6784 Return Value: 6785 WdfDevStatePwrPolStoppingWaitForUsbSSCompletion 6786 6787 --*/ 6788 { 6789 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingCancelUsbSS); 6790 6791 // 6792 // We notified the device power requirement state machine that we are about 6793 // to power down, but eventually we didn't power down. So notify the device 6794 // power requirement state machine that the device should be considered 6795 // powered on. 6796 // 6797 This->m_PowerPolicyMachine.m_Owner-> 6798 m_PoxInterface.DeviceIsPoweredOn(); 6799 6800 This->m_PowerPolicyMachine.m_Owner-> 6801 m_PoxInterface.RequestComponentActive(); 6802 6803 if (This->PowerPolicyCancelUsbSSIfCapable() == FALSE) { 6804 // 6805 // UsbSS already canceled/completed 6806 // 6807 return WdfDevStatePwrPolStoppingCancelTimer; 6808 } 6809 6810 return WdfDevStatePwrPolStoppingWaitForUsbSSCompletion; 6811 } 6812 6813 WDF_DEVICE_POWER_POLICY_STATE 6814 FxPkgPnp::PowerPolStoppingCancelWake( 6815 __inout FxPkgPnp* This 6816 ) 6817 /*++ 6818 6819 Routine Description: 6820 Cancels the pended wait wake in the case where we are surprise removed and 6821 in a Dx state and armed for wake. 6822 6823 Arguments: 6824 This - instance of the state machine 6825 6826 Return Value: 6827 If there was no request to cancel, WdfDevStatePwrPolStopping. If there was, 6828 wait for the wait completion event to be posted before transitioning. 6829 6830 --*/ 6831 { 6832 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingCancelWake); 6833 6834 if (This->PowerPolicyCancelWaitWake() == FALSE && 6835 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 6836 COVERAGE_TRAP(); 6837 return WdfDevStatePwrPolStopping; 6838 } 6839 else { 6840 return WdfDevStatePwrPolNull; 6841 } 6842 } 6843 6844 WDF_DEVICE_POWER_POLICY_STATE 6845 FxPkgPnp::PowerPolCancelUsbSS( 6846 __inout FxPkgPnp* This 6847 ) 6848 /*++ 6849 6850 Routine Description: 6851 The S0 idle policy has changed. Cancel the idle notification so we can move 6852 to another S0 started state 6853 6854 Arguments: 6855 This - instance of the state machine 6856 6857 Return Value: 6858 WdfDevStatePwrPolNull 6859 6860 --*/ 6861 { 6862 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolCancelUsbSS); 6863 6864 // 6865 // We notified the device power requirement state machine that we are about 6866 // to power down, but eventually we didn't power down. So notify the device 6867 // power requirement state machine that the device should be considered 6868 // powered on. 6869 // 6870 This->m_PowerPolicyMachine.m_Owner-> 6871 m_PoxInterface.DeviceIsPoweredOn(); 6872 6873 This->m_PowerPolicyMachine.m_Owner-> 6874 m_PoxInterface.RequestComponentActive(); 6875 6876 if (This->PowerPolicyCancelUsbSSIfCapable() == FALSE) { 6877 // 6878 // UsbSS has already been canceled/completed 6879 // 6880 return WdfDevStatePwrPolStartedCancelTimer; 6881 } 6882 6883 return WdfDevStatePwrPolNull; 6884 } 6885 6886 WDF_DEVICE_POWER_POLICY_STATE 6887 FxPkgPnp::PowerPolStarted( 6888 __inout FxPkgPnp* This 6889 ) 6890 /*++ 6891 6892 Routine Description: 6893 The device is now in the started state (w/regard to power policy). 6894 6895 Arguments: 6896 This - instance of the state machine 6897 6898 Return Value: 6899 WdfDevStatePwrPolNull 6900 6901 --*/ 6902 { 6903 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStarted); 6904 6905 // 6906 // We signal we are in D0 even though there is idling out in this state 6907 // because we could have just come from a state which *was* idled out. 6908 // For instance 6909 // 1) We are in WaitingArmed and an io present event moved us out of this state 6910 // 2) Immediately afterward, the s0 idle policy was changed 6911 // 3) When we enter StartingDecideS0Wake, we will move into this state without 6912 // first entering StartedWakeCapable. 6913 // 4) The source of the io present event, if waiting synchronously needs to 6914 // be unblocked. 6915 // 6916 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 6917 6918 return WdfDevStatePwrPolNull; 6919 } 6920 6921 WDF_DEVICE_POWER_POLICY_STATE 6922 FxPkgPnp::PowerPolStartedCancelTimer( 6923 __inout FxPkgPnp* This 6924 ) 6925 /*++ 6926 6927 Routine Description: 6928 Device is started and we need to cancel the idle timer 6929 6930 Arguments: 6931 This - instance of the state machine 6932 6933 Return Value: 6934 new power policy state 6935 6936 --*/ 6937 { 6938 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartedCancelTimer); 6939 6940 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer()) { 6941 return WdfDevStatePwrPolStartingDecideS0Wake; 6942 } 6943 else { 6944 COVERAGE_TRAP(); 6945 return WdfDevStatePwrPolStartedWaitForIdleTimeout; 6946 } 6947 } 6948 6949 WDF_DEVICE_POWER_POLICY_STATE 6950 FxPkgPnp::PowerPolStartedWakeCapableCancelTimerForSleep( 6951 __inout FxPkgPnp* This 6952 ) 6953 /*++ 6954 6955 Routine Description: 6956 Device is wake capable and enabled for idling out. Try to disable the 6957 power idle state machine. 6958 6959 Arguments: 6960 This - instance of the state machine 6961 6962 Return Value: 6963 new power policy state 6964 6965 --*/ 6966 { 6967 ASSERT_PWR_POL_STATE( 6968 This, WdfDevStatePwrPolStartedWakeCapableCancelTimerForSleep); 6969 6970 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer()) { 6971 return WdfDevStatePwrPolSleeping; 6972 } 6973 else { 6974 COVERAGE_TRAP(); 6975 return WdfDevStatePwrPolStartedWakeCapableWaitForIdleTimeout; 6976 } 6977 } 6978 6979 WDF_DEVICE_POWER_POLICY_STATE 6980 FxPkgPnp::PowerPolStartedWakeCapableSleepingUsbSS( 6981 __inout FxPkgPnp* This 6982 ) 6983 /*++ 6984 6985 Routine Description: 6986 The machine is going to sleep after we have submitted the USB SS request 6987 but before USB has called us back on the go to idle callback. Cancel the 6988 request and wait for its completion 6989 6990 Arguments: 6991 This - instance of the state machine 6992 6993 Return Value: 6994 WdfDevStatePwrPol 6995 6996 --*/ 6997 { 6998 BOOLEAN result; 6999 7000 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStartedWakeCapableSleepingUsbSS); 7001 7002 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 7003 7004 // 7005 // Since the power timeout expired, the disable should not return FALSE 7006 // 7007 ASSERT(result); 7008 UNREFERENCED_PARAMETER(result); 7009 7010 // 7011 // Cancel USBSS irp 7012 // 7013 This->PowerPolicyCancelUsbSS(); 7014 7015 return WdfDevStatePwrPolNull; 7016 } 7017 7018 WDF_DEVICE_POWER_POLICY_STATE 7019 FxPkgPnp::PowerPolStartedIdleCapableCancelTimerForSleep( 7020 __inout FxPkgPnp* This 7021 ) 7022 /*++ 7023 7024 Routine Description: 7025 Device is idle capable and enabled for idling out. Try to disable the 7026 power idle state machine. 7027 7028 Arguments: 7029 This - instance of the state machine 7030 7031 Return Value: 7032 new power policy state 7033 7034 --*/ 7035 { 7036 ASSERT_PWR_POL_STATE( 7037 This, WdfDevStatePwrPolStartedIdleCapableCancelTimerForSleep); 7038 7039 if (This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer()) { 7040 return WdfDevStatePwrPolSleeping; 7041 } 7042 else { 7043 COVERAGE_TRAP(); 7044 return WdfDevStatePwrPolStartedIdleCapableWaitForIdleTimeout; 7045 } 7046 } 7047 7048 WDF_DEVICE_POWER_POLICY_STATE 7049 FxPkgPnp::PowerPolDeviceD0PowerRequestFailed( 7050 __inout FxPkgPnp* This 7051 ) 7052 /*++ 7053 7054 Routine Description: 7055 A D0 request failed, notify pnp. 7056 7057 Arguments: 7058 This - instance of the state machine 7059 7060 Return Value: 7061 WdfDevStatePwrPolDevicePowerRequestFailed 7062 7063 --*/ 7064 { 7065 COVERAGE_TRAP(); 7066 7067 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolDeviceD0PowerRequestFailed); 7068 7069 This->SetInternalFailure(); 7070 7071 if (FALSE == This->m_ReleaseHardwareAfterDescendantsOnFailure) { 7072 This->PnpProcessEvent(PnpEventPowerUpFailed); 7073 } 7074 7075 return WdfDevStatePwrPolDevicePowerRequestFailed; 7076 } 7077 7078 WDF_DEVICE_POWER_POLICY_STATE 7079 FxPkgPnp::PowerPolDevicePowerRequestFailed( 7080 __inout FxPkgPnp* This 7081 ) 7082 /*++ 7083 7084 Routine Description: 7085 Either we could not allocate a device power irp or the power state machine 7086 reported failure. Mark the failure and then wait for pnp to send a stop 7087 event. 7088 7089 Arguments: 7090 This - instance of the state machine 7091 7092 Return Value: 7093 WdfDevStatePwrPolNull 7094 7095 --*/ 7096 { 7097 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolDevicePowerRequestFailed); 7098 7099 // 7100 // In the failure path we still need to notify the children that they can 7101 // power up so that they will unblock. 7102 // 7103 This->PowerPolicyChildrenCanPowerUp(); 7104 7105 This->m_PowerPolicyMachine.m_Owner->m_PowerFailed = TRUE; 7106 7107 // 7108 // Notify the device power requirement state machine that the device should 7109 // be considered powered on, although it may not be in reality. Doing this 7110 // will ensure that component activation before device removal will succeed. 7111 // 7112 This->m_PowerPolicyMachine.m_Owner-> 7113 m_PoxInterface.DeviceIsPoweredOn(); 7114 7115 return WdfDevStatePwrPolNull; 7116 } 7117 7118 WDF_DEVICE_POWER_POLICY_STATE 7119 FxPkgPnp::PowerPolSleepingPowerDownNotProcessed( 7120 __inout FxPkgPnp* This 7121 ) 7122 /*++ 7123 7124 Routine Description: 7125 We requested a Dx irp but a driver layered above our device failed the 7126 request without sending it down the stack. Queue a Tear down the stack and 7127 then move into a state where we will complete the Sx irp. 7128 7129 Arguments: 7130 This - instance of the state machine 7131 7132 Return Value: 7133 WdfDevStatePwrPolSystemSleepPowerRequestFailed 7134 7135 --*/ 7136 { 7137 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolSleepingPowerDownNotProcessed); 7138 7139 This->SetInternalFailure(); 7140 7141 return WdfDevStatePwrPolSystemSleepPowerRequestFailed; 7142 } 7143 7144 WDF_DEVICE_POWER_POLICY_STATE 7145 FxPkgPnp::PowerPolTimerExpiredWakeCapablePowerDownNotProcessed( 7146 __inout FxPkgPnp* This 7147 ) 7148 /*++ 7149 7150 Routine Description: 7151 We requested a Dx irp after idling out, but a driver layered above our device 7152 failed the request without sending it down the stack. Queue a tear down the 7153 stack and then move into a state where we can handle tear down. 7154 7155 Arguments: 7156 This - instance of the state machine 7157 7158 Return Value: 7159 WdfDevStatePwrPolTimerExpiredWakeCapableDxAllocFailed 7160 7161 --*/ 7162 { 7163 ASSERT_PWR_POL_STATE( 7164 This, WdfDevStatePwrPolTimerExpiredWakeCapablePowerDownNotProcessed); 7165 7166 This->SetInternalFailure(); 7167 7168 return WdfDevStatePwrPolTimerExpiredWakeCapableDxAllocFailed; 7169 } 7170 7171 WDF_DEVICE_POWER_POLICY_STATE 7172 FxPkgPnp::PowerPolTimerExpiredNoWakePowerDownNotProcessed( 7173 __inout FxPkgPnp* This 7174 ) 7175 /*++ 7176 7177 Routine Description: 7178 We requested a Dx irp after idling out, but a driver layered above our device 7179 failed the request without sending it down the stack. Queue a tear down the 7180 stack and then move into a state where we can handle tear down. 7181 7182 Arguments: 7183 This - instance of the state machine 7184 7185 Return Value: 7186 WdfDevStatePwrPolStartedIdleCapable 7187 7188 --*/ 7189 { 7190 ASSERT_PWR_POL_STATE( 7191 This, WdfDevStatePwrPolTimerExpiredNoWakePowerDownNotProcessed); 7192 7193 This->SetInternalFailure(); 7194 7195 return WdfDevStatePwrPolTimerExpiredNoWakeUndoPowerDown; 7196 } 7197 7198 WDF_DEVICE_POWER_POLICY_STATE 7199 FxPkgPnp::PowerPolTimerExpiredNoWakeUndoPowerDown( 7200 __inout FxPkgPnp* This 7201 ) 7202 /*++ 7203 7204 Routine Description: 7205 The device was idle and attempting to go to Dx (without wake-from-S0), but 7206 a power down failure occurred. 7207 7208 Arguments: 7209 This - instance of the state machine 7210 7211 Return Value: 7212 WdfDevStatePwrPolNull 7213 7214 --*/ 7215 { 7216 ASSERT_PWR_POL_STATE( 7217 This, WdfDevStatePwrPolTimerExpiredNoWakeUndoPowerDown); 7218 7219 // 7220 // We notified the device power requirement state machine that we are about 7221 // to power down, but eventually we didn't power down. So notify the device 7222 // power requirement state machine that the device should be considered 7223 // powered on. 7224 // 7225 This->m_PowerPolicyMachine.m_Owner-> 7226 m_PoxInterface.DeviceIsPoweredOn(); 7227 7228 return WdfDevStatePwrPolTimerExpiredNoWakeReturnToActive; 7229 } 7230 7231 WDF_DEVICE_POWER_POLICY_STATE 7232 FxPkgPnp::PowerPolTimerExpiredNoWakeReturnToActive( 7233 __inout FxPkgPnp* This 7234 ) 7235 /*++ 7236 7237 Routine Description: 7238 The device was idle and attempting to go to Dx (without wake-from-S0), but 7239 eventually it did not go to Dx. This might have been because a power down 7240 failure occurred or because we received the device power required 7241 notification from the power framework before we could go to Dx. 7242 7243 Arguments: 7244 This - instance of the state machine 7245 7246 Return Value: 7247 WdfDevStatePwrPolNull 7248 7249 --*/ 7250 { 7251 ASSERT_PWR_POL_STATE( 7252 This, WdfDevStatePwrPolTimerExpiredNoWakeReturnToActive); 7253 7254 This->m_PowerPolicyMachine.m_Owner-> 7255 m_PoxInterface.RequestComponentActive(); 7256 7257 return WdfDevStatePwrPolStartedIdleCapable; 7258 } 7259 7260 WDF_DEVICE_POWER_POLICY_STATE 7261 FxPkgPnp::PowerPolTimerExpiredNoWakePoweredDownDisableIdleTimer( 7262 __inout FxPkgPnp* This 7263 ) 7264 /*++ 7265 7266 Routine Description: 7267 The device has fully powered down. Disable the idle timer so that when we 7268 we power up the idle timer will not start running immediately. Rather, 7269 we should power up and only start the idle timer after being explicitly 7270 enabled again. 7271 7272 Arguments: 7273 This - instance of the state machine 7274 7275 Return Value: 7276 WdfDevStatePwrPolWaitingUnarmedQueryIdle 7277 7278 --*/ 7279 { 7280 BOOLEAN result; 7281 7282 ASSERT_PWR_POL_STATE( 7283 This, WdfDevStatePwrPolTimerExpiredNoWakePoweredDownDisableIdleTimer); 7284 7285 // 7286 // Disable the timer so that when we move back into D0, the timer is not 7287 // automatically started. Since the timer has already fired, we should never 7288 // get FALSE back (which indicates we should wait for the timer to fire). 7289 // 7290 result = This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 7291 ASSERT(result); 7292 UNREFERENCED_PARAMETER(result); 7293 7294 // 7295 // Check to see if we should immediately power up 7296 // 7297 return WdfDevStatePwrPolWaitingUnarmedQueryIdle; 7298 } 7299 7300 WDF_DEVICE_POWER_POLICY_STATE 7301 FxPkgPnp::PowerPolPowerUpForSystemSleepNotSeen( 7302 __inout FxPkgPnp* This 7303 ) 7304 /*++ 7305 7306 Routine Description: 7307 PowerDeviceD0 request was not forwarded to this driver by upper driver even 7308 though this driver requested it. Power completion routine detects this 7309 condition, and causes transition to this state. Ensure that any pending 7310 S-IRP is completed. 7311 7312 Arguments: 7313 This - instance of the state machine 7314 7315 Return Value: 7316 WdfDevStatePwrPolDeviceD0PowerRequestFailed 7317 7318 --*/ 7319 { 7320 if (This->m_PendingSystemPowerIrp != NULL) { 7321 This->PowerPolicyCompleteSystemPowerIrp(); 7322 } 7323 7324 return WdfDevStatePwrPolDeviceD0PowerRequestFailed; 7325 } 7326 7327 __drv_sameIRQL 7328 VOID 7329 FxPkgPnp::_PowerPolDeviceWaitWakeComplete( 7330 __in MdDeviceObject DeviceObject, 7331 __in UCHAR MinorFunction, 7332 __in POWER_STATE PowerState, 7333 __in_opt PVOID Context, 7334 __in PIO_STATUS_BLOCK IoStatus 7335 ) 7336 /*++ 7337 7338 Routine Description: 7339 Completion routine for a requested wait wake irp. Called once the wait wake 7340 irp has traveled through the entire stack or when some driver in the stack 7341 completes the wait wake irp. We feed the result of the wait wake operation 7342 back into the power policy state machine through an event. 7343 7344 Arguments: 7345 Context - instance of the state machine 7346 IoStatus - pointer to the IO_STATUS_BLOCK structure for the completed IRP 7347 All others ignored 7348 7349 Return Value: 7350 None 7351 7352 --*/ 7353 { 7354 FxPkgPnp* pThis; 7355 7356 UNREFERENCED_PARAMETER(DeviceObject); 7357 UNREFERENCED_PARAMETER(MinorFunction); 7358 UNREFERENCED_PARAMETER(PowerState); 7359 7360 pThis = (FxPkgPnp*) Context; 7361 pThis->m_PowerPolicyMachine.m_Owner->m_WaitWakeStatus = IoStatus->Status; 7362 7363 if (NT_SUCCESS(IoStatus->Status)) { 7364 pThis->PowerPolicyProcessEvent(PwrPolWakeSuccess); 7365 } 7366 else { 7367 pThis->PowerPolicyProcessEvent(PwrPolWakeFailed); 7368 } 7369 } 7370 7371 __drv_sameIRQL 7372 VOID 7373 FxPkgPnp::_PowerPolDevicePowerDownComplete( 7374 __in MdDeviceObject DeviceObject, 7375 __in UCHAR MinorFunction, 7376 __in POWER_STATE PowerState, 7377 __in_opt PVOID Context, 7378 __in PIO_STATUS_BLOCK IoStatus 7379 ) 7380 /*++ 7381 7382 Routine Description: 7383 Completion routine for a requested power irp. Called once the power irp 7384 has traveled through the entire stack. We feed the result of the power 7385 operation back into the power policy state machine through an event. 7386 7387 Arguments: 7388 Context - instance of the state machine 7389 All others ignored 7390 7391 Return Value: 7392 None 7393 7394 --*/ 7395 7396 { 7397 FxPkgPnp* pThis; 7398 7399 UNREFERENCED_PARAMETER(DeviceObject); 7400 UNREFERENCED_PARAMETER(MinorFunction); 7401 UNREFERENCED_PARAMETER(PowerState); 7402 UNREFERENCED_PARAMETER(IoStatus); 7403 7404 pThis = (FxPkgPnp*) Context; 7405 7406 // 7407 // Note that we are ignoring IoStatus.Status intentionally. If we failed 7408 // power down in this device, we have tracked that state via 7409 // m_PowerDownFailure. If some other device failed power down, we are still 7410 // in the state where we succeeded power down and we don't want to alter 7411 // that yet. 7412 // 7413 // Note that the state machine also handles an upper filter completing the 7414 // Dx irp before our device gets to process it (which would be a bug in the 7415 // filter driver) by handling the PwrPolPowerDown from the appropriate 7416 // state, as an example... 7417 // 7418 // a successful power down state transition looks like this 7419 // 1) power policy state where we request a power irp 7420 // 2) power sends a partial power down message (PwrPolPowerDownIoStopped) 7421 // to power policy, moves to the partial power down state 7422 // 3) power policy tells power to complete the power down 7423 // 4) power completes the irp and we send the power down complete message 7424 // (PwrPolPowerDown) moving from the partial power down state to the 7425 // final power down state 7426 // 7427 // In the case where the top filter driver completes the PIRP without our 7428 // driver seeing it, we will be in the state where we requested a power irp 7429 // and process a power down complete event instead of the partial power down 7430 // event and in this transition, we detect the error. 7431 // 7432 if (pThis->m_PowerMachine.m_PowerDownFailure) { 7433 // 7434 // Clear the faliure condition if we ever attempt to power off this 7435 // device again (highly possible if it is a PDO). 7436 // 7437 pThis->m_PowerMachine.m_PowerDownFailure = FALSE; 7438 7439 // 7440 // Power down failed, send ourself an even indicating that. 7441 // 7442 pThis->PowerPolicyProcessEvent(PwrPolPowerDownFailed); 7443 7444 // 7445 // Inform pnp last so that all the other state machines are in the failed 7446 // state by the time we transition the pnp state of the device. 7447 // 7448 if (FALSE == pThis->m_ReleaseHardwareAfterDescendantsOnFailure) { 7449 pThis->PnpProcessEvent(PnpEventPowerDownFailed); 7450 } 7451 } 7452 else { 7453 // 7454 // Power down succeeded, send ourself an even indicating that. 7455 // 7456 pThis->PowerPolicyProcessEvent(PwrPolPowerDown); 7457 } 7458 } 7459 7460 __drv_sameIRQL 7461 VOID 7462 FxPkgPnp::_PowerPolDevicePowerUpComplete( 7463 __in MdDeviceObject DeviceObject, 7464 __in UCHAR MinorFunction, 7465 __in POWER_STATE PowerState, 7466 __in_opt PVOID Context, 7467 __in PIO_STATUS_BLOCK IoStatus 7468 ) 7469 /*++ 7470 7471 Routine Description: 7472 Completion routine for a requested power irp. Called once the power irp 7473 has traveled through the entire stack. We feed the result of the power 7474 operation back into the power policy state machine through an event. 7475 7476 Arguments: 7477 Context - instance of the state machine 7478 All others ignored 7479 7480 Return Value: 7481 None 7482 7483 --*/ 7484 7485 { 7486 FxPkgPnp* pThis; 7487 7488 UNREFERENCED_PARAMETER(DeviceObject); 7489 UNREFERENCED_PARAMETER(MinorFunction); 7490 UNREFERENCED_PARAMETER(PowerState); 7491 UNREFERENCED_PARAMETER(IoStatus); 7492 7493 pThis = (FxPkgPnp*) Context; 7494 7495 // 7496 // The state machine handles an upper filter completing the 7497 // D0 irp before our device gets to process it (which would be a bug in the 7498 // filter driver). 7499 // 7500 if (pThis->m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp) { 7501 // 7502 // We requested a Power Irp but that never arrived in dispatch routine. 7503 // We know this because m_RequestedPowerUpIrp is still TRUE at the end of 7504 // the power irp completion (it is set to false when it arrives in 7505 // dispatch routine). 7506 // 7507 DoTraceLevelMessage( 7508 pThis->GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 7509 "PowerDeviceD0 requested by WDFDEVICE 0x%p !devobj 0x%p, " 7510 "is being completed by upper driver without sending it to " 7511 "driver that requested it", 7512 pThis->m_Device->GetHandle(), 7513 pThis->m_Device->GetDeviceObject()); 7514 7515 // 7516 // Power-up request not seen, send ourself an event indicating that. 7517 // 7518 pThis->PowerPolicyProcessEvent(PwrPolPowerUpNotSeen); 7519 } 7520 } 7521 7522 _Must_inspect_result_ 7523 NTSTATUS 7524 FxPkgPnp::PowerPolicySendDevicePowerRequest( 7525 __in DEVICE_POWER_STATE DeviceState, 7526 __in SendDeviceRequestAction Action 7527 ) 7528 /*++ 7529 7530 Routine Description: 7531 Attempts to send a D irp to the stack. The caller can specify if the 7532 request allocation is retried in case of failure. 7533 7534 Design Notes: 7535 The timeout and number of retries are somewhat magical numbers. They were 7536 picked so that the total amount of time spent attempting to retry would be 7537 under a minute. Any memory pressure the machine would be under after the 7538 first failure should be over by the end of the minute; if not, there are 7539 bigger problems. 7540 7541 If you look at each of the callers who specify Retry for the Action, nearly 7542 each one transitions to the WdfDevStatePwrPolDevicePowerRequestFailed state 7543 if the request cannot be allocated. This transition could be placed in this 7544 function, but it is not for 2 reasons: 7545 7546 1) Keep this function simple 7547 7548 2) It makes the flow of the state transition function easier to understand; 7549 all transitions out of the current state happen within top level 7550 transition function 7551 7552 Arguments: 7553 DeviceState - The new D state being request 7554 7555 Action - Whether to retry upon failure to allocate the request 7556 7557 Return Value: 7558 NT_SUCCESS if the request was allocated, !NT_SUCCESS otherwise 7559 7560 --*/ 7561 { 7562 MdRequestPowerComplete pCompletionRoutine; 7563 LARGE_INTEGER interval; 7564 NTSTATUS status; 7565 POWER_STATE state; 7566 ULONG i; 7567 7568 status = STATUS_UNSUCCESSFUL; 7569 interval.QuadPart = WDF_REL_TIMEOUT_IN_MS(500); 7570 state.DeviceState = DeviceState; 7571 7572 if (DeviceState == PowerDeviceD0) { 7573 // 7574 // We are powering up, we do not synchronize the completion of the D0 irp 7575 // with a potential S0 irp. However we need to ensure that if an upper filter 7576 // driver fails the power irp, we handle it gracefully rather than keep waiting 7577 // for the power irp to arrive. 7578 // 7579 pCompletionRoutine = _PowerPolDevicePowerUpComplete; 7580 } 7581 else { 7582 // 7583 // We are powering down, we synchronize the completion of the Dx irp 7584 // with a potential Sx irp. If there is no pending Sx irp, the state 7585 // machine takes care of it. 7586 // 7587 pCompletionRoutine = _PowerPolDevicePowerDownComplete; 7588 } 7589 7590 // 7591 // We track when we request power irps to catch someone other then ourselves 7592 // sending power irps to our own stack. 7593 // 7594 if (DeviceState == PowerDeviceD0) { 7595 m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp = TRUE; 7596 } 7597 else { 7598 m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp = TRUE; 7599 } 7600 7601 for (i = 0; i < 100; i++) { 7602 status = FxIrp::RequestPowerIrp(m_Device->GetDeviceObject(), 7603 IRP_MN_SET_POWER, 7604 state, 7605 pCompletionRoutine, 7606 this); 7607 7608 // 7609 // If we are not retrying, we always break out 7610 // 7611 if (NT_SUCCESS(status) || Action == NoRetry) { 7612 break; 7613 } 7614 7615 Mx::MxDelayExecutionThread(KernelMode, FALSE, &interval); 7616 } 7617 7618 if (!NT_SUCCESS(status)) { 7619 // 7620 // We are no longer requesting a power irp 7621 // 7622 if (DeviceState == PowerDeviceD0) { 7623 m_PowerPolicyMachine.m_Owner->m_RequestedPowerUpIrp = FALSE; 7624 } 7625 else { 7626 m_PowerPolicyMachine.m_Owner->m_RequestedPowerDownIrp = FALSE; 7627 } 7628 7629 if (Action == Retry) { 7630 COVERAGE_TRAP(); 7631 7632 DoTraceLevelMessage( 7633 GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 7634 "Could not request D%d irp for device %p (WDFDEVICE %p), " 7635 "%!STATUS!", DeviceState-1, 7636 m_Device->GetDeviceObject(), 7637 m_Device->GetHandle(), status); 7638 } 7639 } 7640 7641 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7642 "Requesting D%d irp, %!STATUS!", 7643 DeviceState-1, status); 7644 7645 return status; 7646 } 7647 7648 _Must_inspect_result_ 7649 NTSTATUS 7650 FxPkgPnp::PowerPolicySendWaitWakeRequest( 7651 __in SYSTEM_POWER_STATE SystemState 7652 ) 7653 { 7654 NTSTATUS status; 7655 POWER_STATE state; 7656 7657 state.SystemState = SystemState; 7658 7659 // 7660 // We track when we request power irps to catch someone other then ourselves 7661 // sending power irps to our own stack. 7662 // 7663 m_PowerPolicyMachine.m_Owner->m_RequestedWaitWakeIrp = TRUE; 7664 7665 // 7666 // Since we are sending a fresh wake, clear any state that was meant 7667 // for the last wake IRP 7668 // 7669 m_SystemWokenByWakeInterrupt = FALSE; 7670 7671 // 7672 // we are requesting new ww irp so re-initialize dropped event tracker. 7673 // 7674 m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped = FALSE; 7675 7676 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7677 "Requesting wait wake irp for S%d", SystemState-1); 7678 7679 status = FxIrp::RequestPowerIrp(m_Device->GetDeviceObject(), 7680 IRP_MN_WAIT_WAKE, 7681 state, 7682 _PowerPolDeviceWaitWakeComplete, 7683 this); 7684 7685 if (!NT_SUCCESS(status)) { 7686 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, 7687 "Requesting wait wake irp for S%d failed, %!STATUS!", 7688 SystemState-1, status); 7689 7690 // 7691 // We are no longer requesting a power irp 7692 // 7693 m_PowerPolicyMachine.m_Owner->m_RequestedWaitWakeIrp = FALSE; 7694 } 7695 7696 return status; 7697 } 7698 7699 VOID 7700 FxPkgPnp::PowerPolicyCompleteSystemPowerIrp( 7701 VOID 7702 ) 7703 { 7704 FxIrp irp(m_PendingSystemPowerIrp); 7705 NTSTATUS status; 7706 7707 ASSERT(m_PendingSystemPowerIrp != NULL); 7708 7709 status = STATUS_SUCCESS; 7710 7711 DoTraceLevelMessage( 7712 GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7713 "Completing system power irp %p (S%d), %!STATUS!", 7714 m_PendingSystemPowerIrp, 7715 irp.GetParameterPowerStateSystemState()-1, 7716 status); 7717 7718 m_PendingSystemPowerIrp = NULL; 7719 7720 CompletePowerRequest(&irp, STATUS_SUCCESS); 7721 } 7722 7723 BOOLEAN 7724 FxPkgPnp::PowerPolicyCancelWaitWake( 7725 VOID 7726 ) 7727 /*++ 7728 7729 Routine Description: 7730 Completes or cancels a pending wait wake irp depending on if the irp is 7731 present and if the device is the owner of the wait wake irp. 7732 7733 Arguments: 7734 7735 Return Value: 7736 7737 7738 --*/ 7739 { 7740 MdIrp wwIrp; 7741 BOOLEAN cancelled, result; 7742 7743 if (m_SharedPower.m_WaitWakeOwner) { 7744 // 7745 // This will complete the irp and then post the appropriate events to 7746 // both the power and power policy state machines. 7747 // 7748 cancelled = PowerIndicateWaitWakeStatus(STATUS_CANCELLED); 7749 } 7750 else { 7751 wwIrp = (MdIrp) InterlockedExchangePointer( 7752 (PVOID*) &m_SharedPower.m_WaitWakeIrp, NULL); 7753 7754 if (wwIrp != NULL) { 7755 FxIrp irp(wwIrp); 7756 7757 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7758 "Successfully got WaitWake irp %p for cancelling", wwIrp); 7759 7760 result = irp.Cancel(); 7761 7762 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7763 "Cancel of irp %p returned %d", wwIrp, result); 7764 7765 7766 if (m_PowerPolicyMachine.CanCompleteWaitWakeIrp()) { 7767 CompletePowerRequest(&irp, irp.GetStatus()); 7768 } 7769 else { 7770 // 7771 // Irp has been completed by the lower bus driver, that's OK 7772 // because the completion of the request will trigger the 7773 // same transition 7774 // 7775 DO_NOTHING(); 7776 } 7777 7778 cancelled = TRUE; 7779 } 7780 else { 7781 DoTraceLevelMessage(GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7782 "No WaitWake irp to cancel"); 7783 7784 cancelled = FALSE; 7785 } 7786 } 7787 7788 return cancelled; 7789 } 7790 7791 __drv_sameIRQL 7792 NTSTATUS 7793 FxPkgPnp::_PowerPolicyWaitWakeCompletionRoutine( 7794 __in MdDeviceObject DeviceObject, 7795 __in MdIrp OriginalIrp, 7796 __in_xcount_opt("varies") PVOID Context 7797 ) 7798 { 7799 FxIrp originalIrp(OriginalIrp); 7800 MdIrp pOldIrp; 7801 FxPkgPnp *pThis; 7802 NTSTATUS status; 7803 7804 pThis = (FxPkgPnp*) Context; 7805 7806 if (originalIrp.PendingReturned()) { 7807 originalIrp.MarkIrpPending(); 7808 } 7809 7810 DoTraceLevelMessage(pThis->GetDriverGlobals(), 7811 TRACE_LEVEL_INFORMATION, TRACINGPNP, 7812 "WDFDEVICE %p !devobj %p Completion of WaitWake irp %p," 7813 " %!STATUS!", pThis->m_Device->GetHandle(), 7814 DeviceObject, originalIrp.GetIrp(), 7815 originalIrp.GetStatus()); 7816 7817 if (NT_SUCCESS(originalIrp.GetStatus())) { 7818 7819 // 7820 // Check to see if this device caused the machine to wake up 7821 // 7822 pThis->PowerPolicyUpdateSystemWakeSource(&originalIrp); 7823 } 7824 7825 if (pThis->m_SystemWokenByWakeInterrupt) { 7826 // 7827 // If the system was woken by a wake interrupt, we need to mark this 7828 // device as the wake source. Since we typically cancel the wait 7829 // wake IRP in this path, it is expected that the completion 7830 // status will not be success. We need to change this status code to 7831 // success because power manager ignores the wake source information 7832 // reported by a wait wake IRP that is not completed successfully. 7833 // 7834 pThis->_PowerSetSystemWakeSource(&originalIrp); 7835 originalIrp.SetStatus(STATUS_SUCCESS); 7836 } 7837 7838 // 7839 // Attempt to gain exclusive ownership of the irp from the cancel call site. 7840 // If we do (indicated by the exchange returning a non-NULL pointer), we can 7841 // complete the request w/out worrying about the cancel call site. 7842 // 7843 // If we can't, we must check to see if we can complete the wait wake irp 7844 // (the cancel call site at least has the irp pointer value and has called 7845 // IoCancelIrp on it). 7846 // 7847 pOldIrp = (MdIrp) InterlockedExchangePointer( 7848 (PVOID*)&pThis->m_SharedPower.m_WaitWakeIrp, NULL); 7849 7850 ASSERT(pOldIrp == NULL || pOldIrp == originalIrp.GetIrp()); 7851 7852 if (pOldIrp != NULL || 7853 pThis->m_PowerPolicyMachine.CanCompleteWaitWakeIrp()) { 7854 DoTraceLevelMessage(pThis->GetDriverGlobals(), 7855 TRACE_LEVEL_VERBOSE, TRACINGPNP, 7856 "Completion of WaitWake irp %p", 7857 originalIrp.GetIrp()); 7858 7859 originalIrp.StartNextPowerIrp(); 7860 7861 status = STATUS_CONTINUE_COMPLETION; 7862 7863 Mx::MxReleaseRemoveLock( 7864 &FxDevice::_GetFxWdmExtension( 7865 DeviceObject)->IoRemoveLock, 7866 originalIrp.GetIrp() 7867 ); 7868 } 7869 else { 7870 // 7871 // ************ WARNING ************* 7872 // By this time the IRP may have got completed by cancel call site, so 7873 // don't touch irp *members* in this path (it is ok to use the IRP 7874 // address though as in the log below). 7875 // 7876 DoTraceLevelMessage( 7877 pThis->GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, 7878 "Not completing WaitWake irp %p in completion routine", 7879 originalIrp.GetIrp()); 7880 7881 status = STATUS_MORE_PROCESSING_REQUIRED; 7882 } 7883 7884 return status; 7885 } 7886 7887 __drv_sameIRQL 7888 NTSTATUS 7889 FxPkgPnp::_PowerPolicyUsbSelectiveSuspendCompletionRoutine( 7890 __in MdDeviceObject DeviceObject, 7891 __in MdIrp Irp, 7892 __in_xcount_opt("varies") PVOID Context 7893 ) 7894 { 7895 FxPkgPnp* This; 7896 FxIrp irp(Irp); 7897 7898 UNREFERENCED_PARAMETER(DeviceObject); 7899 7900 This = (FxPkgPnp*) Context; 7901 7902 // 7903 // Parameters DeviceObejct and Irp are always set to NULL in UMDF, so 7904 // don't touch these in UMDF trace 7905 // 7906 #if FX_IS_KERNEL_MODE 7907 DoTraceLevelMessage(This->GetDriverGlobals(), 7908 TRACE_LEVEL_INFORMATION, TRACINGPNP, 7909 "WDFDEVICE %p, !devobj %p Completion of UsbSS irp %p, %!STATUS!", 7910 This->m_Device, This->m_Device->GetDeviceObject(), 7911 irp.GetIrp(), irp.GetStatus()); 7912 7913 #elif FX_IS_USER_MODE 7914 UNREFERENCED_PARAMETER(irp); 7915 7916 DoTraceLevelMessage(This->GetDriverGlobals(), 7917 TRACE_LEVEL_INFORMATION, TRACINGPNP, 7918 "WDFDEVICE %p, !devobj %p Completion of UsbSS irp", 7919 This->m_Device, This->m_Device->GetDeviceObject()); 7920 #endif 7921 7922 // 7923 // Post an event indicating that the irp has been completed 7924 // 7925 This->PowerPolicyProcessEvent( 7926 PwrPolUsbSelectiveSuspendCompleted 7927 ); 7928 7929 return STATUS_MORE_PROCESSING_REQUIRED; 7930 } 7931 7932 BOOLEAN 7933 FxPkgPnp::PowerPolicyCanIdlePowerDown( 7934 __in DEVICE_POWER_STATE DxState 7935 ) 7936 /*++ 7937 7938 Routine Description: 7939 Attempts to send a Dx irp down the stack after this device has idled out. 7940 Before the Dx can be set, we must check that no child devices have attempted 7941 to power up in between the idle timer firing and the state machine 7942 processing the event. After we have determined that no children are in 7943 D0, we setup a guard so that any child which attempts to power up after this 7944 point will pend the power up until this device has either powered all the 7945 way down and back up or could not allocate a device power irp 7946 7947 Arguments: 7948 DxState - the destination device state 7949 7950 Return Value: 7951 TRUE if the device power irp was sent, FALSE otherwise 7952 7953 --*/ 7954 { 7955 BOOLEAN powerDown; 7956 7957 // 7958 // If we potentially have children, make sure that they are all in Dx before 7959 // the parent powers down. 7960 // 7961 if (m_EnumInfo != NULL) { 7962 m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals()); 7963 if (m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount == 0) { 7964 // 7965 // Setup a guard so that no children power up until we either fail 7966 // this power down or power all the way down and back up. 7967 // 7968 m_PowerPolicyMachine.m_Owner->m_ChildrenCanPowerUp = FALSE; 7969 powerDown = TRUE; 7970 } 7971 else { 7972 DoTraceLevelMessage( 7973 GetDriverGlobals(), TRACE_LEVEL_INFORMATION, TRACINGPNP, 7974 "WDFDEVICE %p !devobj 0x%p not idling out because there are %d " 7975 "children who are powered up", m_Device->GetHandle(), 7976 m_Device->GetDeviceObject(), 7977 m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount); 7978 powerDown = FALSE; 7979 } 7980 m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals()); 7981 } 7982 else { 7983 powerDown = TRUE; 7984 } 7985 7986 if (powerDown) { 7987 NTSTATUS status; 7988 7989 status = PowerPolicySendDevicePowerRequest(DxState, NoRetry); 7990 7991 if (!NT_SUCCESS(status)) { 7992 // 7993 // This will set m_ChildrenCanPowerUp to TRUE and send a 7994 // ParentMovesToD0 in case any children powered down in between 7995 // determining if the parent can go idle and failing to do so. 7996 // 7997 PowerPolicyChildrenCanPowerUp(); 7998 7999 powerDown = FALSE; 8000 } 8001 } 8002 8003 return powerDown; 8004 } 8005 8006 VOID 8007 FxPkgPnp::PowerPolicyPostParentToD0ToChildren( 8008 VOID 8009 ) 8010 /*++ 8011 8012 Routine Description: 8013 Indicates to all of the children that the parent is in D0 8014 8015 Arguments: 8016 None 8017 8018 Return Value: 8019 None. 8020 8021 --*/ 8022 { 8023 FxTransactionedEntry* ple; 8024 8025 ASSERT(IsPowerPolicyOwner()); 8026 8027 if (m_EnumInfo != NULL) { 8028 m_EnumInfo->m_ChildListList.LockForEnum(GetDriverGlobals()); 8029 8030 ple = NULL; 8031 while ((ple = m_EnumInfo->m_ChildListList.GetNextEntry(ple)) != NULL) { 8032 ((FxChildList*) ple->GetTransactionedObject())->PostParentToD0(); 8033 } 8034 8035 m_EnumInfo->m_ChildListList.UnlockFromEnum(GetDriverGlobals()); 8036 } 8037 } 8038 8039 VOID 8040 FxPkgPnp::PowerPolicyChildrenCanPowerUp( 8041 VOID 8042 ) 8043 /*++ 8044 8045 Routine Description: 8046 After this function returns, any child devices rooted off of this parent 8047 device can now move into D0. 8048 8049 Arguments: 8050 None 8051 8052 Return Value: 8053 None 8054 8055 --*/ 8056 { 8057 // 8058 // This can be called for any PPO so we must check first if we have any 8059 // possibility of children. 8060 // 8061 if (m_EnumInfo == NULL) { 8062 return; 8063 } 8064 8065 if (IsPowerPolicyOwner()) { 8066 m_EnumInfo->AcquireParentPowerStateLock(GetDriverGlobals()); 8067 8068 // 8069 // When the child attempts to power up, m_ChildrenPoweredOnCount can 8070 // be incremented while the parent is in Dx. The important value 8071 // here is the guard value, m_ChildrenCanPowerUp which must be 8072 // FALSE. 8073 // 8074 // ASSERT (m_PowerPolicyMachine.m_Owner->m_ChildrenPoweredOnCount == 0); 8075 8076 // 8077 // In the USB SS case, we can return to StartingDecideS0Wake without 8078 // ever attempting to go into a Dx state state, so m_ChildrenCanPowerUp 8079 // can be TRUE. 8080 // 8081 // ASSERT(m_PowerPolicyMachine.m_Owner->m_ChildrenCanPowerUp == FALSE); 8082 8083 m_PowerPolicyMachine.m_Owner->m_ChildrenCanPowerUp = TRUE; 8084 m_EnumInfo->ReleaseParentPowerStateLock(GetDriverGlobals()); 8085 8086 // 8087 // Now that we have set the state of the parent, any child which checks 8088 // the power state after we have released the lock will be able to 8089 // power up immediately. We now need to unblock all children which 8090 // checked the parent state before this function was called by posting 8091 // a PowerParentToD0 event to each child (regardless of the PDO device 8092 // power state). 8093 // 8094 PowerPolicyPostParentToD0ToChildren(); 8095 } 8096 else { 8097 // 8098 // Since we are not the power policy owner for the parent device, 8099 // we cannot make any guarantees about the child being in D0 while 8100 // the parent is in D0 so we do not call PowerPostParentToD0ToChildren(). 8101 // Additionally in PowerPolicyCanChildPowerUp(), if the parent (this) 8102 // device is not the PPO, we don't even check the parent D state before 8103 // powering up the child. 8104 // 8105 DO_NOTHING(); 8106 } 8107 } 8108 8109 VOID 8110 __inline 8111 FxPkgPnp::PowerPolicyDisarmWakeFromSx( 8112 VOID 8113 ) 8114 /*++ 8115 8116 Routine Description: 8117 Calls into the client driver to disarm itself from wake and the clears the 8118 flag which indicates that the device is a source of system wake. The disarm 8119 callback is the last callback available to the driver to indicate the wake 8120 status of its children and have the wake status propagate upwards to the 8121 PDO's stack. 8122 8123 --*/ 8124 { 8125 NTSTATUS wwStatus; 8126 FxTransactionedEntry* ple; 8127 8128 m_PowerPolicyMachine.m_Owner->m_DeviceDisarmWakeFromSx.Invoke( 8129 m_Device->GetHandle() 8130 ); 8131 8132 wwStatus = m_PowerPolicyMachine.m_Owner->m_WaitWakeStatus; 8133 8134 if (wwStatus != STATUS_CANCELLED && 8135 m_EnumInfo != NULL && 8136 PowerPolicyShouldPropagateWakeStatusToChildren()) { 8137 m_EnumInfo->m_ChildListList.LockForEnum(GetDriverGlobals()); 8138 8139 ple = NULL; 8140 while ((ple = m_EnumInfo->m_ChildListList.GetNextEntry(ple)) != NULL) { 8141 ((FxChildList*) ple->GetTransactionedObject())-> 8142 IndicateWakeStatus(wwStatus); 8143 } 8144 8145 m_EnumInfo->m_ChildListList.UnlockFromEnum(GetDriverGlobals()); 8146 } 8147 8148 m_PowerPolicyMachine.m_Owner->m_WaitWakeStatus = STATUS_NOT_SUPPORTED; 8149 8150 // 8151 // Always set the wake source back to FALSE regardless of it previous value. 8152 // 8153 m_PowerPolicyMachine.m_Owner->m_SystemWakeSource = FALSE; 8154 } 8155 8156 WDF_DEVICE_POWER_POLICY_STATE 8157 FxPkgPnp::PowerPolWaitingArmedStoppingCancelUsbSS( 8158 __inout FxPkgPnp* This 8159 ) 8160 /*++ 8161 8162 Routine Description: 8163 The device is in Dx and surprise removed. Cancel the idle notification so 8164 we can move to another state 8165 8166 Arguments: 8167 This - instance of the state machine 8168 8169 Return Value: 8170 WdfDevStatePwrPolStoppingCancelWake 8171 8172 --*/ 8173 { 8174 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedStoppingCancelUsbSS); 8175 8176 This->m_PowerPolicyMachine.m_Owner->m_PowerIdleMachine.DisableTimer(); 8177 8178 // 8179 // Since we are in Dx and surprise removed, cancel the usb SS irp if it is 8180 // there. Otherwise, the USB PDO will call us back after we have processed 8181 // remove. 8182 // 8183 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8184 // 8185 // Usbss completion event will move us from this state. 8186 // 8187 return WdfDevStatePwrPolNull; 8188 } 8189 8190 // 8191 // If usbss irp was there it has already been canceled, so march on. 8192 // 8193 return WdfDevStatePwrPolStoppingCancelWake; 8194 } 8195 8196 WDF_DEVICE_POWER_POLICY_STATE 8197 FxPkgPnp::PowerPolWaitingArmedWakeFailedCancelUsbSS( 8198 __inout FxPkgPnp* This 8199 ) 8200 /*++ 8201 8202 Routine Description: 8203 The device is in Dx armed for wake and wait wake irp got failed. 8204 Cancel the idle notification so we can move to another state 8205 8206 Arguments: 8207 This - instance of the state machine 8208 8209 Return Value: 8210 WdfDevStatePwrPolIoPresentArmedWakeCanceled 8211 8212 --*/ 8213 { 8214 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedWakeFailedCancelUsbSS); 8215 8216 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8217 // 8218 // Usbss completion event will move us from this state. 8219 // 8220 return WdfDevStatePwrPolNull; 8221 } 8222 8223 // 8224 // If usbss irp was there it has already been canceled, so march on. 8225 // 8226 return WdfDevStatePwrPolIoPresentArmedWakeCanceled; 8227 } 8228 8229 WDF_DEVICE_POWER_POLICY_STATE 8230 FxPkgPnp::PowerPolWaitingArmedIoPresentCancelUsbSS( 8231 __inout FxPkgPnp* This 8232 ) 8233 /*++ 8234 8235 Routine Description: 8236 The device is in Dx armed for wake. 8237 Cancel the idle notification so we can move to another state 8238 8239 Arguments: 8240 This - instance of the state machine 8241 8242 Return Value: 8243 WdfDevStatePwrPolIoPresentArmed 8244 8245 --*/ 8246 { 8247 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedIoPresentCancelUsbSS); 8248 8249 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8250 // 8251 // Usbss completion event will move us from this state. 8252 // 8253 return WdfDevStatePwrPolNull; 8254 } 8255 8256 // 8257 // If usbss irp was there it has already been canceled, so march on. 8258 // 8259 return WdfDevStatePwrPolIoPresentArmed; 8260 } 8261 8262 WDF_DEVICE_POWER_POLICY_STATE 8263 FxPkgPnp::PowerPolWaitingArmedWakeSucceededCancelUsbSS( 8264 __inout FxPkgPnp* This 8265 ) 8266 /*++ 8267 8268 Routine Description: 8269 The device woke from S0. 8270 Cancel the idle notification so we can move to another state 8271 8272 Arguments: 8273 This - instance of the state machine 8274 8275 Return Value: 8276 WdfDevStatePwrPolWokeFromS0 8277 8278 --*/ 8279 { 8280 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolWaitingArmedWakeSucceededCancelUsbSS); 8281 8282 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8283 // 8284 // Usbss completion event will move us from this state. 8285 // 8286 return WdfDevStatePwrPolNull; 8287 } 8288 8289 // 8290 // If usbss irp was there it has already been canceled, so march on. 8291 // 8292 return WdfDevStatePwrPolWokeFromS0; 8293 } 8294 8295 WDF_DEVICE_POWER_POLICY_STATE 8296 FxPkgPnp::PowerPolCancelingUsbSSForSystemSleep( 8297 __inout FxPkgPnp* This 8298 ) 8299 /*++ 8300 8301 Routine Description: 8302 The system is going to sleep.. 8303 Cancel the idle notification so we can move to another state 8304 8305 Arguments: 8306 This - instance of the state machine 8307 8308 Return Value: 8309 WdfDevStatePwrPolCancelingWakeForSystemSleep 8310 8311 --*/ 8312 { 8313 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolCancelingUsbSSForSystemSleep); 8314 8315 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8316 // 8317 // Usbss completion event will move us from this state. 8318 // 8319 return WdfDevStatePwrPolNull; 8320 } 8321 8322 // 8323 // If usbss irp was there it has already been canceled, so march on. 8324 // 8325 return WdfDevStatePwrPolCancelingWakeForSystemSleep; 8326 } 8327 8328 WDF_DEVICE_POWER_POLICY_STATE 8329 FxPkgPnp::PowerPolStoppingD0CancelUsbSS( 8330 __inout FxPkgPnp* This 8331 ) 8332 /*++ 8333 8334 Routine Description: 8335 Cancel the idle notification so we can move to another state 8336 8337 Arguments: 8338 This - instance of the state machine 8339 8340 Return Value: 8341 WdfDevStatePwrPolStoppingD0 8342 8343 --*/ 8344 { 8345 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolStoppingD0CancelUsbSS); 8346 8347 if (This->PowerPolicyCancelUsbSSIfCapable()) { 8348 // 8349 // Usbss completion event will move us from this state. 8350 // 8351 return WdfDevStatePwrPolNull; 8352 } 8353 8354 // 8355 // If usbss irp was there it has already been canceled, so march on. 8356 // 8357 return WdfDevStatePwrPolStoppingD0; 8358 } 8359 8360 BOOLEAN 8361 FxPkgPnp::PowerPolicyCancelUsbSSIfCapable( 8362 VOID 8363 ) 8364 /*++ 8365 8366 Routine Description: 8367 Cancel the idle notification irp if capable 8368 8369 Arguments: 8370 none 8371 8372 Return Value: 8373 TRUE if irp was canceled 8374 FALSE if not capable of USBSS or if Irp was already completed. 8375 8376 --*/ 8377 { 8378 if (m_PowerPolicyMachine.m_Owner->m_UsbIdle == NULL || 8379 m_PowerPolicyMachine.m_Owner->m_UsbIdle->m_EventDropped) { 8380 return FALSE; 8381 } 8382 else { 8383 PowerPolicyCancelUsbSS(); 8384 return TRUE; 8385 } 8386 } 8387 8388 WDF_DEVICE_POWER_POLICY_STATE 8389 FxPkgPnp::PowerPolTimerExpiredWakeCapableWakeInterruptArrived( 8390 __inout FxPkgPnp* This 8391 ) 8392 { 8393 ASSERT_PWR_POL_STATE(This, WdfDevStatePwrPolTimerExpiredWakeCapableWakeInterruptArrived); 8394 8395 if (This->PowerPolicyCancelWaitWake() == FALSE && 8396 This->m_PowerPolicyMachine.m_Owner->m_WakeCompletionEventDropped) { 8397 return WdfDevStatePwrPolTimerExpiredWakeCapableWakeSucceeded; 8398 } 8399 8400 return WdfDevStatePwrPolNull; 8401 } 8402 8403 8404