summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/controller
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2014-01-24 07:48:52 +0000
committerhselasky <hselasky@FreeBSD.org>2014-01-24 07:48:52 +0000
commitf692196495136a8dd592a7f06a940e6fae03fd6d (patch)
tree839fc6ad65b9e949db26d1b71d21c9f0c50ef134 /sys/dev/usb/controller
parent34792a80a8f08a81c382a8100ee6ff81820ed688 (diff)
downloadFreeBSD-src-f692196495136a8dd592a7f06a940e6fae03fd6d.zip
FreeBSD-src-f692196495136a8dd592a7f06a940e6fae03fd6d.tar.gz
MFC r260588 and r260589:
- Separate I/O errors from reception of STALL PID. - Implement better error recovery for Transaction Translators, TTs, found in High Speed USB HUBs which translate from High Speed USB into FULL or LOW speed USB. In some rare cases SPLIT transactions might get lost, which might leave the TT in an unknown state. Whenever we detect such an error try to issue either a clear TT buffer request, or if that is not possible reset the whole TT.
Diffstat (limited to 'sys/dev/usb/controller')
-rw-r--r--sys/dev/usb/controller/ehci.c13
-rw-r--r--sys/dev/usb/controller/uhci.c9
2 files changed, 17 insertions, 5 deletions
diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c
index b303261..e930eac 100644
--- a/sys/dev/usb/controller/ehci.c
+++ b/sys/dev/usb/controller/ehci.c
@@ -1198,9 +1198,16 @@ ehci_non_isoc_done_sub(struct usb_xfer *xfer)
(status & EHCI_QTD_PINGSTATE) ? "[PING]" : "");
}
#endif
-
- return ((status & EHCI_QTD_HALTED) ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
+ if (status & EHCI_QTD_HALTED) {
+ if ((xfer->xroot->udev->parent_hs_hub != NULL) ||
+ (xfer->xroot->udev->address != 0)) {
+ /* try to separate I/O errors from STALL */
+ if (EHCI_QTD_GET_CERR(status) == 0)
+ return (USB_ERR_IOERROR);
+ }
+ return (USB_ERR_STALLED);
+ }
+ return (USB_ERR_NORMAL_COMPLETION);
}
static void
diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c
index fe3cf93..9c216b5 100644
--- a/sys/dev/usb/controller/uhci.c
+++ b/sys/dev/usb/controller/uhci.c
@@ -1179,8 +1179,13 @@ uhci_non_isoc_done_sub(struct usb_xfer *xfer)
(status & UHCI_TD_SPD) ? "[SPD]" : "");
}
#endif
- return (status & UHCI_TD_STALLED) ?
- USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION;
+ if (status & UHCI_TD_STALLED) {
+ /* try to separate I/O errors from STALL */
+ if (UHCI_TD_GET_ERRCNT(status) == 0)
+ return (USB_ERR_IOERROR);
+ return (USB_ERR_STALLED);
+ }
+ return (USB_ERR_NORMAL_COMPLETION);
}
static void
OpenPOWER on IntegriCloud