Author: hselasky
Date: Fri Oct 19 08:40:25 2018
New Revision: 339443
URL: https://svnweb.freebsd.org/changeset/base/339443

Log:
  MFC r339388:
  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
  Sponsored by:         Mellanox Technologies

Modified:
  stable/10/sys/dev/usb/controller/dwc_otg.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/usb/controller/dwc_otg.c
==============================================================================
--- stable/10/sys/dev/usb/controller/dwc_otg.c  Fri Oct 19 08:38:34 2018        
(r339442)
+++ stable/10/sys/dev/usb/controller/dwc_otg.c  Fri Oct 19 08:40:25 2018        
(r339443)
@@ -1461,6 +1461,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;
@@ -1519,8 +1521,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) {
@@ -1566,12 +1570,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);
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to