summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhselasky <hselasky@FreeBSD.org>2015-06-03 15:41:03 +0000
committerhselasky <hselasky@FreeBSD.org>2015-06-03 15:41:03 +0000
commitcec9850b2970e22824f696185360a38ade7f140b (patch)
tree69090afccf0bdb52f52ca6d543513367a50e882e
parent79cd6230a5ab8914948a63f3edd0eb3baae36865 (diff)
downloadFreeBSD-src-cec9850b2970e22824f696185360a38ade7f140b.zip
FreeBSD-src-cec9850b2970e22824f696185360a38ade7f140b.tar.gz
MFC r283103:
Fix for DWC OTG device side isochronous transfers. The even or odd isochronous frame bit needs to be flipped.
-rw-r--r--sys/dev/usb/controller/dwc_otg.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c
index d195b7f..f895d06 100644
--- a/sys/dev/usb/controller/dwc_otg.c
+++ b/sys/dev/usb/controller/dwc_otg.c
@@ -1561,6 +1561,22 @@ dwc_otg_data_rx(struct dwc_otg_softc *sc, struct dwc_otg_td *td)
/* release FIFO */
dwc_otg_common_rx_ack(sc);
+ temp = sc->sc_out_ctl[td->ep_no];
+
+ /* check for isochronous mode */
+ if ((temp & DIEPCTL_EPTYPE_MASK) ==
+ (DIEPCTL_EPTYPE_ISOC << DIEPCTL_EPTYPE_SHIFT)) {
+ /* toggle odd or even frame bit */
+ if (temp & DIEPCTL_SETD1PID) {
+ temp &= ~DIEPCTL_SETD1PID;
+ temp |= DIEPCTL_SETD0PID;
+ } else {
+ temp &= ~DIEPCTL_SETD0PID;
+ temp |= DIEPCTL_SETD1PID;
+ }
+ sc->sc_out_ctl[td->ep_no] = temp;
+ }
+
/* check if we are complete */
if ((td->remainder == 0) || got_short) {
if (td->short_pkt) {
@@ -2136,10 +2152,23 @@ repeat:
temp = sc->sc_in_ctl[td->ep_no];
+ /* check for isochronous mode */
+ if ((temp & DIEPCTL_EPTYPE_MASK) ==
+ (DIEPCTL_EPTYPE_ISOC << DIEPCTL_EPTYPE_SHIFT)) {
+ /* toggle odd or even frame bit */
+ if (temp & DIEPCTL_SETD1PID) {
+ temp &= ~DIEPCTL_SETD1PID;
+ temp |= DIEPCTL_SETD0PID;
+ } else {
+ temp &= ~DIEPCTL_SETD0PID;
+ temp |= DIEPCTL_SETD1PID;
+ }
+ sc->sc_in_ctl[td->ep_no] = temp;
+ }
+
/* must enable before writing data to FIFO */
DWC_OTG_WRITE_4(sc, DOTG_DIEPCTL(td->ep_no), temp |
- DIEPCTL_EPENA |
- DIEPCTL_CNAK);
+ DIEPCTL_EPENA | DIEPCTL_CNAK);
td->tx_bytes = count;
OpenPOWER on IntegriCloud