svn commit: r353178 - in stable/11/sys/dev/usb: . controller
Hans Petter Selasky
hselasky at FreeBSD.org
Mon Oct 7 08:24:47 UTC 2019
Author: hselasky
Date: Mon Oct 7 08:24:46 2019
New Revision: 353178
URL: https://svnweb.freebsd.org/changeset/base/353178
Log:
MFC r352556:
Add quirk for XHCI(4) controllers to support USB control transfers
above 1Kbyte. It might look like some XHCI(4) controllers do not
support when the USB control transfer is split using a link TRB. The
next NORMAL TRB after the link TRB is simply failing with XHCI error
code 4. The quirk ensures we allocate a 64Kbyte buffer so that the
data stage TRB is not broken with a link TRB.
Found at: EuroBSDcon 2019
Sponsored by: Mellanox Technologies
Modified:
stable/11/sys/dev/usb/controller/xhci.c
stable/11/sys/dev/usb/usb_bus.h
stable/11/sys/dev/usb/usb_transfer.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/usb/controller/xhci.c
==============================================================================
--- stable/11/sys/dev/usb/controller/xhci.c Mon Oct 7 08:24:07 2019 (r353177)
+++ stable/11/sys/dev/usb/controller/xhci.c Mon Oct 7 08:24:46 2019 (r353178)
@@ -599,6 +599,9 @@ xhci_init(struct xhci_softc *sc, device_t self, uint8_
device_printf(self, "%d bytes context size, %d-bit DMA\n",
sc->sc_ctx_is_64_byte ? 64 : 32, (int)sc->sc_bus.dma_bits);
+ /* enable 64Kbyte control endpoint quirk */
+ sc->sc_bus.control_ep_quirk = 1;
+
temp = XREAD4(sc, capa, XHCI_HCSPARAMS1);
/* get number of device slots */
Modified: stable/11/sys/dev/usb/usb_bus.h
==============================================================================
--- stable/11/sys/dev/usb/usb_bus.h Mon Oct 7 08:24:07 2019 (r353177)
+++ stable/11/sys/dev/usb/usb_bus.h Mon Oct 7 08:24:46 2019 (r353178)
@@ -129,6 +129,7 @@ struct usb_bus {
uint8_t do_probe; /* set if USB should be re-probed */
uint8_t no_explore; /* don't explore USB ports */
uint8_t dma_bits; /* number of DMA address lines */
+ uint8_t control_ep_quirk; /* need 64kByte buffer for data stage */
};
#endif /* _USB_BUS_H_ */
Modified: stable/11/sys/dev/usb/usb_transfer.c
==============================================================================
--- stable/11/sys/dev/usb/usb_transfer.c Mon Oct 7 08:24:07 2019 (r353177)
+++ stable/11/sys/dev/usb/usb_transfer.c Mon Oct 7 08:24:46 2019 (r353178)
@@ -105,6 +105,33 @@ static const struct usb_config usb_control_ep_cfg[USB_
},
};
+static const struct usb_config usb_control_ep_quirk_cfg[USB_CTRL_XFER_MAX] = {
+
+ /* This transfer is used for generic control endpoint transfers */
+
+ [0] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control endpoint */
+ .direction = UE_DIR_ANY,
+ .bufsize = 65535, /* bytes */
+ .callback = &usb_request_callback,
+ .usb_mode = USB_MODE_DUAL, /* both modes */
+ },
+
+ /* This transfer is used for generic clear stall only */
+
+ [1] = {
+ .type = UE_CONTROL,
+ .endpoint = 0x00, /* Control pipe */
+ .direction = UE_DIR_ANY,
+ .bufsize = sizeof(struct usb_device_request),
+ .callback = &usb_do_clear_stall_callback,
+ .timeout = 1000, /* 1 second */
+ .interval = 50, /* 50ms */
+ .usb_mode = USB_MODE_HOST,
+ },
+};
+
/* function prototypes */
static void usbd_update_max_frame_size(struct usb_xfer *);
@@ -1020,7 +1047,8 @@ usbd_transfer_setup(struct usb_device *udev,
* context, else there is a chance of
* deadlock!
*/
- if (setup_start == usb_control_ep_cfg)
+ if (setup_start == usb_control_ep_cfg ||
+ setup_start == usb_control_ep_quirk_cfg)
info->done_p =
USB_BUS_CONTROL_XFER_PROC(udev->bus);
else if (xfer_mtx == &Giant)
@@ -3148,7 +3176,8 @@ repeat:
*/
iface_index = 0;
if (usbd_transfer_setup(udev, &iface_index,
- udev->ctrl_xfer, usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
+ udev->ctrl_xfer, udev->bus->control_ep_quirk ?
+ usb_control_ep_quirk_cfg : usb_control_ep_cfg, USB_CTRL_XFER_MAX, NULL,
&udev->device_mtx)) {
DPRINTFN(0, "could not setup default "
"USB transfer\n");
More information about the svn-src-all
mailing list