svn commit: r339388 - head/sys/dev/usb/controller
Hans Petter Selasky
hselasky at FreeBSD.org
Tue Oct 16 18:47:14 UTC 2018
Author: hselasky
Date: Tue Oct 16 18:47:13 2018
New Revision: 339388
URL: https://svnweb.freebsd.org/changeset/base/339388
Log:
Fix for reception of large full speed isochronous frames via the transaction
translator, when using the DWC OTG USB controller driver. Make sure to re-try
getting the complete split packets until a DATA0 packet is received. Larger
isochronous frames may be split into multiple MDATA packets terminated
by a single DATA0 packet.
PR: 230434
MFC after: 3 days
Approved by: re (gjb)
Sponsored by: Mellanox Technologies
Modified:
head/sys/dev/usb/controller/dwc_otg.c
Modified: head/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- head/sys/dev/usb/controller/dwc_otg.c Tue Oct 16 18:17:07 2018 (r339387)
+++ head/sys/dev/usb/controller/dwc_otg.c Tue Oct 16 18:47:13 2018 (r339388)
@@ -1458,6 +1458,8 @@ dwc_otg_host_data_rx(struct dwc_otg_softc *sc, struct
/* check if we are complete */
if (td->tt_xactpos == HCSPLT_XACTPOS_BEGIN) {
goto complete;
+ } else if (td->hcsplt != 0) {
+ goto receive_pkt;
} else {
/* get more packets */
goto busy;
@@ -1516,8 +1518,10 @@ receive_pkt:
if (td->hcsplt != 0) {
delta = td->tt_complete_slot - sc->sc_last_frame_num - 1;
if (td->tt_scheduled == 0 || delta < DWC_OTG_TT_SLOT_MAX) {
- td->state = DWC_CHAN_ST_WAIT_C_PKT;
- goto busy;
+ if (td->ep_type != UE_ISOCHRONOUS) {
+ td->state = DWC_CHAN_ST_WAIT_C_PKT;
+ goto busy;
+ }
}
delta = sc->sc_last_frame_num - td->tt_start_slot;
if (delta > DWC_OTG_TT_SLOT_MAX) {
@@ -1563,12 +1567,23 @@ receive_pkt:
hcchar = td->hcchar;
hcchar |= HCCHAR_EPDIR_IN;
- /* receive complete split ASAP */
- if ((sc->sc_last_frame_num & 1) != 0 &&
- td->ep_type == UE_ISOCHRONOUS)
- hcchar |= HCCHAR_ODDFRM;
- else
+ if (td->ep_type == UE_ISOCHRONOUS) {
+ if (td->hcsplt != 0) {
+ /* continously buffer */
+ if (sc->sc_last_frame_num & 1)
+ hcchar &= ~HCCHAR_ODDFRM;
+ else
+ hcchar |= HCCHAR_ODDFRM;
+ } else {
+ /* multi buffer, if any */
+ if (sc->sc_last_frame_num & 1)
+ hcchar |= HCCHAR_ODDFRM;
+ else
+ hcchar &= ~HCCHAR_ODDFRM;
+ }
+ } else {
hcchar &= ~HCCHAR_ODDFRM;
+ }
/* must enable channel before data can be received */
DWC_OTG_WRITE_4(sc, DOTG_HCCHAR(channel), hcchar);
More information about the svn-src-all
mailing list