USB Idle Notification Callback Routine
The bus driver (either an instance of the hub driver or the generic parent driver) determines when it is safe to suspend its device's children. If it is, it calls the idle notification callback routine supplied by each child's client driver.
The function prototype for USB_IDLE_CALLBACK is as follows:
typedef VOID (*USB_IDLE_CALLBACK)(__in PVOID Context);
A device driver must take the following actions in its idle notification callback routine:
- Request an IRP_MN_WAIT_WAKE IRP for the device if the device needs to be armed for remote wakeup.
- Cancel all I/O and prepare the device to go to a lower power state.
- Put the device in a WDM sleep state by calling PoRequestPowerIrp with the PowerState parameter set to the enumerator value PowerDeviceD2 (defined in wdm.h; ntddk.h). In Windows XP, a driver must not put its device in PowerDeviceD3, even if the device is not armed for remote wake.
In Windows XP, a driver must rely on an idle notification callback routine to selectively suspend a device. If a driver running in Windows XP puts a device in a lower power state directly without using an idle notification callback routine, this might prevent other devices in the USB device tree from suspending. For more details, see USB Global Suspend .
Both the hub driver and the USB Generic Parent Driver (Usbccgp.sys) call the idle notification callback routine at IRQL = PASSIVE_LEVEL. This allows the callback routine to block while it waits for the power state change request to complete.
The callback routine is invoked only while the system is in S0 and the device is in D0.
The following restrictions apply to idle request notification callback routines:
- Device drivers can initiate a device power state transition from D0 to D2 in the idle notification callback routine, but no other power state transition is allowed. In particular, a driver must not attempt to change its device to D0 while executing its callback routine.
- Device drivers must not request more than one power IRP from within the idle notification callback routine.
The idle notification callback routine should determine whether its device has an IRP_MN_WAIT_WAKE request pending. If no IRP_MN_WAIT_WAKE request is pending, the callback routine should submit an IRP_MN_WAIT_WAKE request before suspending the device. For more information about the wait wake mechanism, see Supporting Devices That Have WakeUp Capabilities.