[Applies to KMDF only]
A KMDF driver for a multiple-component device can support idle power-down and functional power states. Because in this case the driver registers directly with the power management framework (PoFx), the driver must coordinate the resulting Dx state changes with PoFx.
Providing Device Power Policy Idle Settings
When it calls WdfDeviceAssignS0IdleSettings, the driver must set IdleTimeoutType to DriverManagedIdleTimeout in the WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS structure. In addition, the driver must set PowerUpIdleDeviceOnSystemWake to WdfTrue, and IdleCaps to IdleCannotWakeFromS0, as shown in the following example.
WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS s0IdleSettings; WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&s0IdleSettings, IdleCannotWakeFromS0); s0IdleSettings.IdleTimeoutType = DriverManagedIdleTimeout; s0IdleSettings.PowerUpIdleDeviceOnSystemWake = WdfTrue; s0IdleSettings.IdleTimeout = 1; status = WdfDeviceAssignS0IdleSettings(device, &s0IdleSettings);
Transitioning from Working (D0) to Low-Power (Dx) State
The driver typically specifies a very short idle timeout so that WDF puts the device into a low-power state soon after all power references are released.
Transitioning from Low-Power (Dx) to Working (D0) State
In DevicePowerRequiredCallback, the driver must bring the device to its working (D0) state. To do so, it must defer to a worker thread a call to WdfDeviceStopIdle with the WaitForD0 parameter set to TRUE. This blocking call to WdfDeviceStopIdle must not be made from within DevicePowerRequiredCallback.
Instead, the driver must defer the blocking call to a worker thread that is running at passive level and is guaranteed not to make the WdfDeviceStopIdle call in the context of a power-managed queue’s I/O dispatch routine.
If the driver has previously called WdfDeviceInitSetPowerPageable (meaning it can access pageable data during power transitions), the driver can call WdfWorkItemCreate to create a framework work item. If the driver has not set power-pageable, the driver must create its own system thread. For more information, see PsCreateSystemThread.