Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Mar 2016 10:07:01 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r296448 - stable/8/sys/dev/usb/controller
Message-ID:  <201603071007.u27A71oH066496@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Mon Mar  7 10:07:01 2016
New Revision: 296448
URL: https://svnweb.freebsd.org/changeset/base/296448

Log:
  MFC r295928:
  Configure the correct bMaxPacketSize for control endpoints before
  requesting the initial complete device descriptor and not as part of
  the subsequent babble error recovery. Babble means that the received
  USB packet was bigger than than configured maximum packet size. This
  only affects enumeration of FULL speed USB devices which use a
  bMaxPacketSize different from 8 bytes. This patch might help fix
  enumeration of USB devices which exhibit USB I/O errors in dmesg
  during boot.

Modified:
  stable/8/sys/dev/usb/controller/xhci.c
  stable/8/sys/dev/usb/controller/xhci.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/dev/   (props changed)
  stable/8/sys/dev/usb/   (props changed)

Modified: stable/8/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/8/sys/dev/usb/controller/xhci.c	Mon Mar  7 10:02:31 2016	(r296447)
+++ stable/8/sys/dev/usb/controller/xhci.c	Mon Mar  7 10:07:01 2016	(r296448)
@@ -135,8 +135,8 @@ static struct xhci_endpoint_ext *xhci_ge
 static usb_proc_callback_t xhci_configure_msg;
 static usb_error_t xhci_configure_device(struct usb_device *);
 static usb_error_t xhci_configure_endpoint(struct usb_device *,
-		    struct usb_endpoint_descriptor *, uint64_t, uint16_t,
-		    uint8_t, uint8_t, uint8_t, uint16_t, uint16_t);
+    struct usb_endpoint_descriptor *, struct xhci_endpoint_ext *,
+    uint16_t, uint8_t, uint8_t, uint8_t, uint16_t, uint16_t);
 static usb_error_t xhci_configure_mask(struct usb_device *,
 		    uint32_t, uint8_t);
 static usb_error_t xhci_cmd_evaluate_ctx(struct xhci_softc *,
@@ -1393,7 +1393,7 @@ xhci_set_address(struct usb_device *udev
 		USB_BUS_UNLOCK(udev->bus);
 
 		err = xhci_configure_endpoint(udev,
-		    &udev->ctrl_ep_desc, pepext->physaddr,
+		    &udev->ctrl_ep_desc, pepext,
 		    0, 1, 1, 0, mps, mps);
 
 		if (err != 0) {
@@ -2289,13 +2289,15 @@ xhci_configure_mask(struct usb_device *u
 
 static usb_error_t
 xhci_configure_endpoint(struct usb_device *udev,
-    struct usb_endpoint_descriptor *edesc, uint64_t ring_addr,
-    uint16_t interval, uint8_t max_packet_count, uint8_t mult,
-    uint8_t fps_shift, uint16_t max_packet_size, uint16_t max_frame_size)
+    struct usb_endpoint_descriptor *edesc, struct xhci_endpoint_ext *pepext,
+    uint16_t interval, uint8_t max_packet_count,
+    uint8_t mult, uint8_t fps_shift, uint16_t max_packet_size,
+    uint16_t max_frame_size)
 {
 	struct usb_page_search buf_inp;
 	struct xhci_softc *sc = XHCI_BUS2SC(udev->bus);
 	struct xhci_input_dev_ctx *pinp;
+	uint64_t ring_addr = pepext->physaddr;
 	uint32_t temp;
 	uint8_t index;
 	uint8_t epno;
@@ -2326,6 +2328,10 @@ xhci_configure_endpoint(struct usb_devic
 	if (mult == 0)
 		return (USB_ERR_BAD_BUFSIZE);
 
+	/* store bMaxPacketSize for control endpoints */
+	pepext->trb_ep_maxp = edesc->wMaxPacketSize[0];
+	usb_pc_cpu_flush(pepext->page_cache);
+
 	temp = XHCI_EPCTX_0_EPSTATE_SET(0) |
 	    XHCI_EPCTX_0_MAXP_STREAMS_SET(0) |
 	    XHCI_EPCTX_0_LSA_SET(0);
@@ -2445,7 +2451,7 @@ xhci_configure_endpoint_by_xfer(struct u
 	usb_pc_cpu_flush(pepext->page_cache);
 
 	return (xhci_configure_endpoint(xfer->xroot->udev,
-	    xfer->endpoint->edesc, pepext->physaddr,
+	    xfer->endpoint->edesc, pepext,
 	    xfer->interval, xfer->max_packet_count,
 	    (ecomp != NULL) ? (ecomp->bmAttributes & 3) + 1 : 1,
 	    usbd_xfer_get_fps_shift(xfer), xfer->max_packet_size,
@@ -2837,6 +2843,17 @@ xhci_transfer_insert(struct usb_xfer *xf
 		return (USB_ERR_NOMEM);
 	}
 
+	/* check if bMaxPacketSize changed */
+	if (xfer->flags_int.control_xfr != 0 &&
+	    pepext->trb_ep_maxp != xfer->endpoint->edesc->wMaxPacketSize[0]) {
+
+		DPRINTFN(8, "Reconfigure control endpoint\n");
+
+		/* force driver to reconfigure endpoint */
+		pepext->trb_halted = 1;
+		pepext->trb_running = 0;
+	}
+
 	/* check for stopped condition, after putting transfer on interrupt queue */
 	if (pepext->trb_running == 0) {
 		struct xhci_softc *sc = XHCI_BUS2SC(xfer->xroot->bus);

Modified: stable/8/sys/dev/usb/controller/xhci.h
==============================================================================
--- stable/8/sys/dev/usb/controller/xhci.h	Mon Mar  7 10:02:31 2016	(r296447)
+++ stable/8/sys/dev/usb/controller/xhci.h	Mon Mar  7 10:07:01 2016	(r296448)
@@ -373,6 +373,7 @@ struct xhci_endpoint_ext {
 	uint8_t			trb_index;
 	uint8_t			trb_halted;
 	uint8_t			trb_running;
+	uint8_t			trb_ep_maxp;
 };
 
 enum {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201603071007.u27A71oH066496>