Changelog: https://cdn.kernel.org/pub/linux/kernel/v6.x/ChangeLog-6.6.83 Removed upstreamed: bcm27xx/patches-6.6/950-0483-usb-xhci-borrow-upstream-TRB_FETCH-quirk-on-VL805-ho.patch[1] Manually rebased: bcm27xx/patches-6.6/950-0061-Revert-Revert-xhci-add-quirk-for-host-controllers-th.patch bcm27xx/patches-6.6/950-0485-usb-xhci-add-XHCI_VLI_HUB_TT_QUIRK.patch bcm27xx/patches-6.6/950-0519-usb-dwc3-Set-DMA-and-coherent-masks-early.patch All other patches automatically rebased. 1. https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/drivers/usb/host/xhci-pci.c?h=linux-6.6.y&id=c401b1b4b835d66792e884b76264d742a20d931d Build system: x86/64 Build-tested: x86/64 Run-tested: x86/64 Signed-off-by: John Audia <therealgraysky@proton.me> [fixed issues with bcm27xx patches] Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
111 lines
3.9 KiB
Diff
111 lines
3.9 KiB
Diff
From 786f498d9d4eb6af69f1ff5d374f1710c860a664 Mon Sep 17 00:00:00 2001
|
|
From: Jonathan Bell <jonathan@raspberrypi.com>
|
|
Date: Thu, 8 Sep 2022 15:50:15 +0100
|
|
Subject: [PATCH 0484/1085] usb: xhci: add VLI_SS_BULK_OUT_BUG quirk
|
|
|
|
The VL805 can cause data corruption if a SS Bulk OUT endpoint enters a
|
|
flow-control condition and there are TRBs in the transfer ring that are
|
|
not an integral size of wMaxPacket and the endpoint is behind one or more
|
|
hubs.
|
|
|
|
This is frequently the case encountered when FAT32 filesystems are
|
|
present on mass-storage devices with cluster sizes of 1 sector, and the
|
|
filesystem is being written to with an aggregate of small files.
|
|
|
|
The initial implementation of this quirk separated TRBs that didn't
|
|
adhere to this limitation into two - the first a multiple of wMaxPacket
|
|
and the second the 512-byte remainder - in an attempt to force TD
|
|
fragments to align with packet boundaries. This reduced the incidence
|
|
rate of data corruption but did not resolve it.
|
|
|
|
The fix as recommended by VIA is to disable bursts if this sequence of
|
|
TRBs can occur.
|
|
|
|
Limit turning off bursts to just USB mass-storage devices by searching
|
|
the device's configuration for an interface with a class type of
|
|
USB_CLASS_MASS_STORAGE.
|
|
|
|
Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
|
|
---
|
|
drivers/usb/host/xhci-mem.c | 31 ++++++++++++++++++++++++++++++-
|
|
drivers/usb/host/xhci-pci.c | 1 +
|
|
drivers/usb/host/xhci.h | 1 +
|
|
3 files changed, 32 insertions(+), 1 deletion(-)
|
|
|
|
--- a/drivers/usb/host/xhci-mem.c
|
|
+++ b/drivers/usb/host/xhci-mem.c
|
|
@@ -1400,6 +1400,7 @@ int xhci_endpoint_init(struct xhci_hcd *
|
|
unsigned int ep_index;
|
|
struct xhci_ep_ctx *ep_ctx;
|
|
struct xhci_ring *ep_ring;
|
|
+ struct usb_interface_cache *intfc;
|
|
unsigned int max_packet;
|
|
enum xhci_ring_type ring_type;
|
|
u32 max_esit_payload;
|
|
@@ -1409,6 +1410,8 @@ int xhci_endpoint_init(struct xhci_hcd *
|
|
unsigned int mult;
|
|
unsigned int avg_trb_len;
|
|
unsigned int err_count = 0;
|
|
+ unsigned int is_ums_dev = 0;
|
|
+ unsigned int i;
|
|
|
|
ep_index = xhci_get_endpoint_index(&ep->desc);
|
|
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
|
@@ -1440,9 +1443,35 @@ int xhci_endpoint_init(struct xhci_hcd *
|
|
|
|
mult = xhci_get_endpoint_mult(udev, ep);
|
|
max_packet = usb_endpoint_maxp(&ep->desc);
|
|
- max_burst = xhci_get_endpoint_max_burst(udev, ep);
|
|
avg_trb_len = max_esit_payload;
|
|
|
|
+ /*
|
|
+ * VL805 errata - Bulk OUT bursts to superspeed mass-storage
|
|
+ * devices behind hub ports can cause data corruption with
|
|
+ * non-wMaxPacket-multiple transfers.
|
|
+ */
|
|
+ for (i = 0; i < udev->config->desc.bNumInterfaces; i++) {
|
|
+ intfc = udev->config->intf_cache[i];
|
|
+ /*
|
|
+ * Slight hack - look at interface altsetting 0, which
|
|
+ * should be the UMS bulk-only interface. If the class
|
|
+ * matches, then we disable out bursts for all OUT
|
|
+ * endpoints because endpoint assignments may change
|
|
+ * between alternate settings.
|
|
+ */
|
|
+ if (intfc->altsetting[0].desc.bInterfaceClass ==
|
|
+ USB_CLASS_MASS_STORAGE) {
|
|
+ is_ums_dev = 1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ if (xhci->quirks & XHCI_VLI_SS_BULK_OUT_BUG &&
|
|
+ usb_endpoint_is_bulk_out(&ep->desc) && is_ums_dev &&
|
|
+ udev->route)
|
|
+ max_burst = 0;
|
|
+ else
|
|
+ max_burst = xhci_get_endpoint_max_burst(udev, ep);
|
|
+
|
|
/* FIXME dig Mult and streams info out of ep companion desc */
|
|
|
|
/* Allow 3 retries for everything but isoc, set CErr = 3 */
|
|
--- a/drivers/usb/host/xhci-pci.c
|
|
+++ b/drivers/usb/host/xhci-pci.c
|
|
@@ -487,6 +487,7 @@ static void xhci_pci_quirks(struct devic
|
|
xhci->quirks |= XHCI_TRB_OVERFETCH;
|
|
xhci->quirks |= XHCI_EP_CTX_BROKEN_DCS;
|
|
xhci->quirks |= XHCI_AVOID_DQ_ON_LINK;
|
|
+ xhci->quirks |= XHCI_VLI_SS_BULK_OUT_BUG;
|
|
}
|
|
|
|
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
|
|
--- a/drivers/usb/host/xhci.h
|
|
+++ b/drivers/usb/host/xhci.h
|
|
@@ -1666,6 +1666,7 @@ struct xhci_hcd {
|
|
|
|
/* Downstream VLI fixes */
|
|
#define XHCI_AVOID_DQ_ON_LINK BIT_ULL(56)
|
|
+#define XHCI_VLI_SS_BULK_OUT_BUG BIT_ULL(57)
|
|
|
|
unsigned int num_active_eps;
|
|
unsigned int limit_active_eps;
|