@@ -1463,6 +1463,29 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
}
}
+ /*
+ * Check for undercalculated bandwidth quirk for interrupt endpoints
+ * associated with fullspeed BI.
+ */
+ if ((xhci->quirks & XHCI_LIMIT_FS_BI_INTR_EP) &&
+ usb_endpoint_xfer_int(&ep->desc) &&
+ udev->speed == USB_SPEED_FULL &&
+ interval == 5) {
+ struct usb_device *top_dev;
+
+ for (top_dev = udev;
+ top_dev->parent && top_dev->parent->parent;
+ top_dev = top_dev->parent)
+ /* Found device below root hub */;
+
+ /*
+ * If the top device is operating at fullspeed, then the
+ * controller is using fullspeed BI for this device.
+ */
+ if (top_dev->speed == USB_SPEED_FULL)
+ interval = 4;
+ }
+
mult = xhci_get_endpoint_mult(udev, ep);
max_packet = usb_endpoint_maxp(&ep->desc);
max_burst = xhci_get_endpoint_max_burst(udev, ep);
@@ -59,6 +59,7 @@
#define XHCI_SG_TRB_CACHE_SIZE_QUIRK BIT_ULL(39)
#define XHCI_NO_SOFT_RETRY BIT_ULL(40)
#define XHCI_ISOC_BLOCKED_DISCONNECT BIT_ULL(41)
+#define XHCI_LIMIT_FS_BI_INTR_EP BIT_ULL(42)
struct usb_hcd;
DWC_usb31 host version 1.90a and prior undercalculates the bandwidth available for interrupt endpoints. The controller will return bandwidth error on config endpoint commands if there are already 6 or more fullspeed interrupt endpoints with bInterval of 4 (or 4ms) associated with a single fullspeed bus instance (BI). To workaround this, configure and use the endpoint at a shorter interrupt interval. Lower the ep_ctx interval from 5 to 4 (or 2ms) for interrupt endpoints of the fullspeed BI. Note: we have not observed functional impact to the fullspeed devices by lowering the interrupt service interval (at least for a few devices that we tested). To simplify the workaround, let's just check and apply the workaround if the endpoint is a fullspeed interrupt endpoint with interval of 4ms and if the top parent device is also operating in fullspeed (i.e. associated with fullspeed BI). Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> --- Note: Checkpatch will give a warning below for getting top_dev: WARNING: suspect code indent for conditional statements Since this logic is done everywhere else in the driver, I'm keeping it consistent here. drivers/usb/host/xhci-mem.c | 23 +++++++++++++++++++++++ include/linux/usb/xhci-quirks.h | 1 + 2 files changed, 24 insertions(+)