summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2004-09-29 18:12:33 +0000
committerwpaul <wpaul@FreeBSD.org>2004-09-29 18:12:33 +0000
commit098b50576337659d238992b2ccffffb412382b92 (patch)
treed1673162425b6f5740d8aab6f8826930eb88201b /sys
parent53a9ecac892997d1d279f61c274e81af3b410626 (diff)
downloadFreeBSD-src-098b50576337659d238992b2ccffffb412382b92.zip
FreeBSD-src-098b50576337659d238992b2ccffffb412382b92.tar.gz
When opening a pipe, usbd_setup_pipe() will do a usbd_clear_endpoint_stall()
to make sure the pipe is ready. Some devices apparently don't support the clear stall command however. So what happens when you issue such devices a clear stall command? Typically, the command just times out. This, at least, is the behavior I've observed with two devices that I own: a Rio600 mp3 player and a T-Mobile Sidekick II. It used to be that after the timeout expired, the pipe open operation would conclude and you could still access the device, with the only negative effect being a long delay on open. But in the recent past, someone added code to make the timeout a fatal error, thereby breaking the ability to communicate with these devices in any way. I don't know exactly what the right solution is for this problem: presumeably there is some way to determine whether or not a device supports the 'clear stall' command beyond just issuing one and waiting to see if it times out, but I don't know what that is. So for now, I've added a special case to the error checking code so that the timeout is once again non-fatal, thereby letting me use my two devices again.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/usb/usb_subr.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index adeb436..c0e1442 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -818,9 +818,14 @@ usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface,
/* Clear any stall and make sure DATA0 toggle will be used next. */
if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT) {
err = usbd_clear_endpoint_stall(p);
- /* Some devices reject this command, so ignore a STALL. */
- if (err && err != USBD_STALLED) {
- printf("usbd_setup_pipe: failed to start endpoint, %s\n", usbd_errstr(err));
+ /*
+ * Some devices reject this command, so ignore a STALL. */
+ * Some device just time out on this command, so ignore
+ * that too.
+ */
+ if (err && err != USBD_STALLED && err != USBD_TIMEOUT) {
+ printf("usbd_setup_pipe: failed to start "
+ "endpoint, %s\n", usbd_errstr(err));
return (err);
}
}
OpenPOWER on IntegriCloud