A Device Enters a Low-Power State
A device leaves its working (D0) state and enters a low-power state if one of the following occurs:
The device is idle (that is, not being accessed) and is capable of entering a low-power idle state while the system remains in its working (S0) state.
The system's power state has changed from its working (S0) state to a low-power state. (Drivers can call WdfDeviceGetSystemPowerAction to determine the reason that a system's power state is changing.)
For each function and filter driver that supports the device, the framework does the following, in sequence, one driver at a time, starting with the driver that is highest in the driver stack:
If the driver is using self-managed I/O, the framework calls the driver's EvtDeviceSelfManagedIoSuspend callback function.
The framework stops all of the driver's power-managed I/O queues and calls their EvtIoStop callback functions (if they exist).
If the driver is the device's power policy owner, the framework calls its EvtDeviceArmWakeFromS0, EvtDeviceArmWakeFromSx, or EvtDeviceArmWakeFromSxWithReason callback function.
If the hardware and driver support DMA, the framework calls the driver's EvtDmaEnablerSelfManagedIoStop, EvtDmaEnablerFlush, and EvtDmaEnablerDisable callback functions (if they exist) for each DMA channel created.
The framework calls the driver's EvtDeviceD0ExitPreInterruptsDisabled callback function (if it exists), and then it calls the driver's EvtInterruptDisable callback function (if it exists) for each interrupt, so that the driver can disable device interrupts.
The framework calls the driver's EvtDeviceD0Exit callback function (if it exists).
The bus driver is the driver in the stack that is called last. When the framework calls the bus driver's EvtDeviceD0Exit callback function, the callback function sets the power state of the device (a child device of the bus) to a low-power state. The framework specifies the D3 low-power state unless the power policy owner has specified a different low-power state.
Note
The method used by the bus driver to set the power state of the child device is bus-specific. For example, the PCI bus power management specification defines a 16-bit Power Management Control / Status register (PMCSR). The lowest two bits ("PowerState") both determine the current power state of the device and are used to set the device into a new power state. When the pci.sys
PDO receives IRP_MN_SET_POWER/D3, it reads the PMCSR, changes the PowerState bits to 11b (power level D3), and writes back the PMCSR.