Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

KMDF-Based USB Device Driver Hangs and Cannot Be Unloaded After Surprise Removal or System Suspend and Resume


View products that this article applies to.

Symptoms

A USB device driver is based on the Microsoft Windows Kernel Mode Driver Framework (KMDF) may hang and be unable to be unloaded and reloaded after the USB device is surprise-removed.

↑ Back to the top


Cause

This problem may occur if the USB device driver has all of the following characteristics:
  • 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 problem may be more likely to occur, or occur more frequently, if the following condition is also true:
  • 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:
  1. 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.
  2. 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.

↑ Back to the top


Resolution

A KMDF-Based USB device driver can work around these problems by implementing the following solution:
  • 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.

↑ Back to the top


More Information

A fix for this problem is being considered for inclusion in a future version of the Microsoft Windows Kernel Mode Driver Framework (KMDF).

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.
While there are benefits to be gained from implementing a EvtReadersFailed callback routine for a USB Continuous Reader, and the above implementation may reduce the likelihood or frequency of occurrence of this problem under some circumstances, this is not a sufficient solution to the above-described problem in all circumstances under which this problem might occur, and is not the Microsoft-recommended solution for this issue.

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)
EvtUsbTargetPipeReadersFailed (WDK)
UsbSamp sample (WDK)
OSRUSBFX2 sample (WDK)

↑ Back to the top


Keywords: kb

↑ Back to the top

Article Info
Article ID : 2516416
Revision : 1
Created on : 1/7/2017
Published on : 3/18/2011
Exists online : False
Views : 658