A USB client driver sends in and out transfers to its device. At times transfers to/from the device fail and the client driver needs to recover from the error condition. Failure may be due to a legitimate error response from the USB device (e.g. transfer failed with status USBD_STATUS_STALL_PID) or it may be unexpected (e.g. transfer failed with status USBD_STATUS_XACT_ERROR).
Various articles do talk about the recovery process, however they are not comprehensive. Thus it can be confusing for a client driver writer. Some examples are:
In this blog series, I will provide clear guidelines on the steps a client driver should take to recover from USB transfer errors. This blog will give you an overview of the recovery process, and the future ones will describe the recovery steps needed by a WDM client driver, a WDF client driver and a WinUSB driver.
When a transfer to/from the device fails, the corresponding pipe transitions into halted state. No further transfers for that pipe are processed until the error condition on the pipe is cleared. A client driver can do the following types of error recovery:
(In case the error is due to device having disconnected, client driver should not invoke the following error recovery)
Usually it is a good idea to do a reset pipe first, and if the problem persists do the reset port or cycle port.
Note that some of the operations mentioned below can only be executed at PASSIVE LEVEL, thus your driver may need to queue a work item.
This is the first step that the client driver should do to recover from a USB error. The client driver uses this mechanism if a previous transfer to its non-default pipe failed. Failure can be due to a device error (such as USBD_STATUS_STALL_PID or USBD_STATUS_BABBLE_DETECTED), or due to an error reported by the host controller (such as USBD_STATUS_XACT_ERROR).
To reset the pipe, the client driver must do the following steps:
In response to a reset pipe request, the core USB stack performs the following steps:
Client driver need not worry about the error conditions on the default control pipe of the device. These errors are cleared automatically.
If even after resetting the pipe a transfer to the pipe still fails, the client driver can request a reset port operation. Reset port is more expensive than resetting the pipe and may result in more state loss.
To reset the port, the client driver must do the following steps:
In response to a reset port request, the core USB stack performs the following steps:
Kindly note it is not possible to reset an individual function of a multi-function (composite) device. For a composite device, if the client driver of one function requests a reset operation, the whole device would be reset. This has a potential to affect operation of drivers for the other functions of that device (especially if the USB device that was reset maintained state). Unfortunately there is no current solution for this problem, thus it's important that the client driver first tries to reset the pipe before resetting the port.
Cycle port operation is similar to the device being unplugged and then plugged back in, except that the device is not electrically disconnected. Think of it as software unplug and re-plug. Cycle port may be used if the client driver itself wants to re-rebuild its PNP stack, in addition to resetting the device.
To cycle the port, the client driver must do the following steps:
In response to a cycle port request, core USB stack performs full PNP re-enumeration of the device. It performs the following steps:
As a result of cycle port operation any application that has a handle open to the device will get a device removal notification (assuming the application registered for it). In response, the application may report a device disconnected message to the user. Thus a client driver may want to be careful before it chooses to cycle the port.
For a composite device, similar to reset port, cycle port operation would be carried out for the device and thus would affect all functions for the device.
- Pankaj Gupta, USB Developer, Microsoft