diff options
author | hselasky <hselasky@FreeBSD.org> | 2015-06-03 15:41:03 +0000 |
---|---|---|
committer | hselasky <hselasky@FreeBSD.org> | 2015-06-03 15:41:03 +0000 |
commit | cec9850b2970e22824f696185360a38ade7f140b (patch) | |
tree | 69090afccf0bdb52f52ca6d543513367a50e882e | |
parent | 79cd6230a5ab8914948a63f3edd0eb3baae36865 (diff) | |
download | FreeBSD-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.c | 33 |
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; |