- The USB device driver is based on the Microsoft Windows Kernel Mode Driver Framework (KMDF) version 1.9 or earlier.
- The USB device driver implements a USB Continuous Reader to perform Read (IN) transfers from a Bulk IN or Interrupt IN pipe on the device.
- The USB device driver's D0Exit handler calls WdfIoTargetStop with a handle to the USB Device to stop all pending transfers for the device, without first calling WdfIoTargetStop with a handle to each USB Pipe belonging to the USB Device to stop all pending transfers for each of the device's USB pipes.
- The USB device driver does not implement an EvtReadersFailed callback routine for the USB Continuous Reader, or implements an EvtReadersFailed callback routine that returns TRUE for transfers that fail due to errors associated with the device being surprised removed such as STATUS_NO_SUCH_DEVICE or other unrecoverable errors.
Under this configuration, if the USB device is surprise-removed, USB transfers being performed by the USB Continuous Reader will complete with an error such as STATUS_NO_SUCH_DEVICE. If an EvtReadersFailed callback routine is not registered for the USB Continuous Reader, the failed transfers are retried continuously.
Meanwhile, the USB device driver's D0Exit handler may be called to handle the device surprise removal, and call WdfIoTargetStop for the USB Device to stop all pending transfers. If the USB device driver's D0Exit handler does not first call WdfIoTargetStop with a handle to each USB Pipe belonging to the USB Device to stop all pending transfers for each of the device's USB pipes, a deadlock may occur which prevents Windows from completing removal of the device and unloading the device's driver.
In this scenario, there are two bugs in the Microsoft KMDF framework that can cause a WdfIoTargetStop operation for a USB Device to hang while attempting to cancel pending transfers for a USB Continuous Reader:
- In preparation for cancelling pending USB transfers, the Microsoft KMDF framework issues a USB Get Port Status request to get the device's connection status, but does not set the WDF_REQUEST_SEND_OPTION_IGNORE_TARGET_STATE option. This may cause such requests to block indefinitely if the device is disconnected.
- The Microsoft KMDF framework's implementation of the WdfIoTargetStop method for a USB Device does not wait for pending transfers to complete for a Continuous Reader pipe. This may cause deadlocks between multiple threads performing actions for this device.
- In the USB device driver's D0Exit routine, call WdfIoTargetStop for each of the USB Pipes (including the pipe associated with the USB Continuous Reader) before calling WdfIoTargetStop for the USB Device itself. This will avoid deadlocks with the thread performing the actions related to stopping the USB I/O targets.
This is the correct implementation for stopping a USB IO Target, and is demonstrated in KMDF-based USB device driver samples included in the Windows Driver Kit for Windows 7, including the USBSamp and OSRUSBFX2 samples.
Under some circumstances, it may be possible to reduce the likelihood or frequency of occurrence of this problem by implementing the following functionality in the affected KMDF-Based USB device driver:
- Register an EvtReadersFailed callback routine for the USB Continuous Reader, and return FALSE from this callback routine on errors such as STATUS_NO_SUCH_DEVICE. This will stop the USB Continuous Reader and prevent further retries of this failed transfer.
For more information on Windows driver development details related to this issue, see the following topics in the Microsoft Windows Driver Kit (WDK) documentation:
WdfIoTargetStop Method (WDK)
Working with USB Pipes (WDK)
WdfUsbTargetPipeConfigContinuousReader Method (WDK)
UsbSamp sample (WDK)
OSRUSBFX2 sample (WDK)
Raksta ID: 2516416. Pēdējo reizi pārskatīts: 2011. gada 18. marts. Pārskatījums: 1