Canceling a USB Idle Request
Under certain circumstances, a device driver might need to cancel an idle request IRP that has been submitted to the bus driver. This might occur if the device is removed, becomes active after being idle and sending the idle request, or if the entire system is transitioning to a lower system power state.
The client driver cancels the idle IRP by calling IoCancelIrp. The following table describes three scenarios for canceling an idle IRP and specifies the action the driver must take:
|Scenario||Idle Request Cancellation Mechanism|
|The client driver has canceled the idle IRP and the USB driver stack has not called the USB Idle Notification Callback Routine.||
The USB driver stack completes the idle IRP. Because the device never left the D0, the driver does not change the device state.
|The client driver has canceled the idle IRP, the USB driver stack has called the USB idle notification callback routine, and it has not yet returned.||
It is possible that the USB idle notification callback routine is invoked even though the client driver has invoked cancellation on the IRP. In this case, the client driver's callback routine must still power down the device by sending the device to a lower power state synchronously.
When the device is in the lower power state, the client driver can then send a D0 request.
Alternatively, the driver can wait for the USB driver stack to complete the idle IRP and then send the D0 IRP.
If the callback routine is unable to put the device into a low power state due to insufficient memory to allocate a power IRP, it should cancel the idle IRP and exit immediately. The idle IRP will not be completed until the callback routine has returned; therefore, the callback routine should not block waiting for the canceled idle IRP to complete.
|The device is already in a low power state.||
If the device is already in a low power state, the client driver can send a D0 IRP. The USB driver stack completes the idle request IRP with STATUS_SUCCESS.
Alternatively, the driver can cancel the idle IRP, wait for the USB driver stack to complete the idle IRP, and then send a D0 IRP.