From 8e1c2074d25794c30a62ff3de982bbc10c13f7cb Mon Sep 17 00:00:00 2001 From: hselasky Date: Mon, 7 Mar 2016 10:07:01 +0000 Subject: [PATCH] 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. git-svn-id: svn://svn.freebsd.org/base/stable/8@296448 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/dev/usb/controller/xhci.c | 31 ++++++++++++++++++++++++------- sys/dev/usb/controller/xhci.h | 1 + 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c index c67d95085..c31f9f113 100644 --- a/sys/dev/usb/controller/xhci.c +++ b/sys/dev/usb/controller/xhci.c @@ -135,8 +135,8 @@ static struct xhci_endpoint_ext *xhci_get_endpoint_ext(struct usb_device *, 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, struct mtx *mtx, uint16_t address) 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 *udev, uint32_t mask, uint8_t drop) 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_device *udev, 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 usb_xfer *xfer) 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 *xfer) 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); diff --git a/sys/dev/usb/controller/xhci.h b/sys/dev/usb/controller/xhci.h index 0a49628bd..01fcef82a 100644 --- a/sys/dev/usb/controller/xhci.h +++ b/sys/dev/usb/controller/xhci.h @@ -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 { -- 2.42.0