From de3a24155bd81263282e01f13c41fabada9160d3 Mon Sep 17 00:00:00 2001 From: hselasky Date: Tue, 19 May 2015 09:22:06 +0000 Subject: [PATCH] Fix for DWC OTG device side isochronous transfers. The even or odd isochronous frame bit needs to be flipped. MFC after: 3 days --- sys/dev/usb/controller/dwc_otg.c | 33 ++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c index ea59ae6f880a..50ead5c290a7 100644 --- a/sys/dev/usb/controller/dwc_otg.c +++ b/sys/dev/usb/controller/dwc_otg.c @@ -1557,6 +1557,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) { @@ -2132,10 +2148,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;