Author: hselasky
Date: Tue Jan 12 08:49:40 2016
New Revision: 293735
URL: https://svnweb.freebsd.org/changeset/base/293735

Log:
  MFC r293192:
  Fix for directly connected FULL or LOW speed USB devices.

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  Tue Jan 12 08:32:53 2016        
(r293734)
+++ stable/10/sys/dev/usb/controller/dwc_otg.c  Tue Jan 12 08:49:40 2016        
(r293735)
@@ -457,6 +457,18 @@ dwc_otg_init_fifo(struct dwc_otg_softc *
        return (0);
 }
 
+static uint8_t
+dwc_otg_uses_split(struct usb_device *udev)
+{
+       /*
+        * When a LOW or FULL speed device is connected directly to
+        * the USB port we don't use split transactions:
+        */ 
+       return (udev->speed != USB_SPEED_HIGH &&
+           udev->parent_hs_hub != NULL &&
+           udev->parent_hs_hub->parent_hub != NULL);
+}
+
 static void
 dwc_otg_update_host_frame_interval(struct dwc_otg_softc *sc)
 {
@@ -3325,16 +3337,16 @@ dwc_otg_setup_standard_chain(struct usb_
                else
                        hcchar |= (td->ep_type << HCCHAR_EPTYPE_SHIFT);
 
-               if (usbd_get_speed(xfer->xroot->udev) == USB_SPEED_LOW)
-                       hcchar |= HCCHAR_LSPDDEV;
                if (UE_GET_DIR(xfer->endpointno) == UE_DIR_IN)
                        hcchar |= HCCHAR_EPDIR_IN;
 
                switch (xfer->xroot->udev->speed) {
-               case USB_SPEED_FULL:
                case USB_SPEED_LOW:
+                       hcchar |= HCCHAR_LSPDDEV;
+                       /* FALLTHROUGH */
+               case USB_SPEED_FULL:
                        /* check if root HUB port is running High Speed */
-                       if (xfer->xroot->udev->parent_hs_hub != NULL) {
+                       if (dwc_otg_uses_split(xfer->xroot->udev)) {
                                hcsplt = HCSPLT_SPLTENA |
                                    (xfer->xroot->udev->hs_port_no <<
                                    HCSPLT_PRTADDR_SHIFT) |
@@ -4156,7 +4168,10 @@ dwc_otg_device_isoc_start(struct usb_xfe
                framenum = DSTS_SOFFN_GET(temp);
        }
 
-       if (xfer->xroot->udev->parent_hs_hub != NULL)
+       /*
+        * Check if port is doing 8000 or 1000 frames per second:
+        */
+       if (sc->sc_flags.status_high_speed)
                framenum /= 8;
 
        framenum &= DWC_OTG_FRAME_MASK;
@@ -4833,7 +4848,7 @@ dwc_otg_xfer_setup(struct usb_setup_para
                        td = USB_ADD_BYTES(parm->buf, parm->size[0]);
 
                        /* compute shared bandwidth resource index for TT */
-                       if (parm->udev->parent_hs_hub != NULL && 
parm->udev->speed != USB_SPEED_HIGH) {
+                       if (dwc_otg_uses_split(parm->udev)) {
                                if 
(parm->udev->parent_hs_hub->ddesc.bDeviceProtocol == UDPROTO_HSHUBMTT)
                                        td->tt_index = parm->udev->device_index;
                                else
_______________________________________________
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