Skip to content

Commit c133ec0

Browse files
Michal Peciogregkh
authored andcommitted
usb: xhci: Enable the TRB overfetch quirk on VIA VL805
Raspberry Pi is a major user of those chips and they discovered a bug - when the end of a transfer ring segment is reached, up to four TRBs can be prefetched from the next page even if the segment ends with link TRB and on page boundary (the chip claims to support standard 4KB pages). It also appears that if the prefetched TRBs belong to a different ring whose doorbell is later rung, they may be used without refreshing from system RAM and the endpoint will stay idle if their cycle bit is stale. Other users complain about IOMMU faults on x86 systems, unsurprisingly. Deal with it by using existing quirk which allocates a dummy page after each transfer ring segment. This was seen to resolve both problems. RPi came up with a more efficient solution, shortening each segment by four TRBs, but it complicated the driver and they ditched it for this quirk. Also rename the quirk and add VL805 device ID macro. Signed-off-by: Michal Pecio <michal.pecio@gmail.com> Link: raspberrypi/linux#4685 Closes: https://bugzilla.kernel.org/show_bug.cgi?id=215906 CC: stable@vger.kernel.org Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20250225095927.2512358-2-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent c783e12 commit c133ec0

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

drivers/usb/host/xhci-mem.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2437,7 +2437,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
24372437
* and our use of dma addresses in the trb_address_map radix tree needs
24382438
* TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need.
24392439
*/
2440-
if (xhci->quirks & XHCI_ZHAOXIN_TRB_FETCH)
2440+
if (xhci->quirks & XHCI_TRB_OVERFETCH)
2441+
/* Buggy HC prefetches beyond segment bounds - allocate dummy space at the end */
24412442
xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
24422443
TRB_SEGMENT_SIZE * 2, TRB_SEGMENT_SIZE * 2, xhci->page_size * 2);
24432444
else

drivers/usb/host/xhci-pci.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
#define PCI_DEVICE_ID_ETRON_EJ168 0x7023
3939
#define PCI_DEVICE_ID_ETRON_EJ188 0x7052
4040

41+
#define PCI_DEVICE_ID_VIA_VL805 0x3483
42+
4143
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI 0x8c31
4244
#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI 0x9c31
4345
#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI 0x9cb1
@@ -418,8 +420,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
418420
pdev->device == 0x3432)
419421
xhci->quirks |= XHCI_BROKEN_STREAMS;
420422

421-
if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == 0x3483)
423+
if (pdev->vendor == PCI_VENDOR_ID_VIA && pdev->device == PCI_DEVICE_ID_VIA_VL805) {
422424
xhci->quirks |= XHCI_LPM_SUPPORT;
425+
xhci->quirks |= XHCI_TRB_OVERFETCH;
426+
}
423427

424428
if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA &&
425429
pdev->device == PCI_DEVICE_ID_ASMEDIA_1042_XHCI) {
@@ -467,11 +471,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
467471

468472
if (pdev->device == 0x9202) {
469473
xhci->quirks |= XHCI_RESET_ON_RESUME;
470-
xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
474+
xhci->quirks |= XHCI_TRB_OVERFETCH;
471475
}
472476

473477
if (pdev->device == 0x9203)
474-
xhci->quirks |= XHCI_ZHAOXIN_TRB_FETCH;
478+
xhci->quirks |= XHCI_TRB_OVERFETCH;
475479
}
476480

477481
if (pdev->vendor == PCI_VENDOR_ID_CDNS &&

drivers/usb/host/xhci.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ struct xhci_hcd {
16321632
#define XHCI_EP_CTX_BROKEN_DCS BIT_ULL(42)
16331633
#define XHCI_SUSPEND_RESUME_CLKS BIT_ULL(43)
16341634
#define XHCI_RESET_TO_DEFAULT BIT_ULL(44)
1635-
#define XHCI_ZHAOXIN_TRB_FETCH BIT_ULL(45)
1635+
#define XHCI_TRB_OVERFETCH BIT_ULL(45)
16361636
#define XHCI_ZHAOXIN_HOST BIT_ULL(46)
16371637
#define XHCI_WRITE_64_HI_LO BIT_ULL(47)
16381638
#define XHCI_CDNS_SCTX_QUIRK BIT_ULL(48)

0 commit comments

Comments
 (0)