On 10/10/17 15:24, David Laight wrote: > From: Mathias Nyman >> Sent: 10 October 2017 15:13 > ... >> [ 428.409645] print_req_error: I/O error, dev sdb, sector 128 >> [ 428.426612] arm-smmu 2b500000.iommu: Unhandled context fault: fsr=0x8, iova=0xff0b1000, >> fsynr=0x183, cb=0 >> >> a ring segment is 256 TRBS, each *16 bytes, that ring last TRB should be at 0xff0b0ff0 >> >> If the adm-smmu iova 0xff0b1000 means something is poking that DMA address >> it's ring after that ring. > > That could 'just' be the hardware doing a 'readahead' of the ring. > Somewhat annoying if it is doing that across page boundaries. > > Although, in that case, the read values wouldn't be used because the > last TRB is a link. > So that shouldn't stop the USB transfer - just gives an annoying error message. > OTOH if the PCIe read completion ends up with an error status it might halt > the ring (or similar). Indeed, on my machine once the PCIe root complex gets an abort back from the IOMMU, the VL805 is basically dead until a hard reset. The grotty diff below does resolve that particular issue, but I'm not sure I like it :/ Robin. ----->8----- diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 2a82c927ded2..9bec2a6d271a 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -2376,9 +2376,17 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) * however, the command ring segment needs 64-byte aligned segments * and our use of dma addresses in the trb_address_map radix tree needs * TRB_SEGMENT_SIZE alignment, so we pick the greater alignment need. + * If the HC might prefetch past the end of the segment across page + * boundaries, reserve enough space to prevent that going wrong. */ + val = TRB_SEGMENT_SIZE; + val2 = xhci->page_size; + if (xhci->quirks & XHCI_READAHEAD_QUIRK) { + val *= 2; + val2 *= 2; + } xhci->segment_pool = dma_pool_create("xHCI ring segments", dev, - TRB_SEGMENT_SIZE, TRB_SEGMENT_SIZE, xhci->page_size); + val, TRB_SEGMENT_SIZE, val2); /* See Table 46 and Note on Figure 55 */ xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev, diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 8071c8fdd15e..458404a22cf1 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -212,6 +212,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) pdev->device == 0x3432) xhci->quirks |= XHCI_BROKEN_STREAMS; + /* VIA VL805 reads past the end of queue segments */ + if (pdev->vendor == PCI_VENDOR_ID_VIA && + pdev->device == 0x3483) + xhci->quirks |= XHCI_READAHEAD_QUIRK; + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && pdev->device == 0x1042) xhci->quirks |= XHCI_BROKEN_STREAMS; diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 2abaa4d6d39d..c78ed53ed5c4 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1828,6 +1828,7 @@ struct xhci_hcd { #define XHCI_LIMIT_ENDPOINT_INTERVAL_7 (1 << 26) #define XHCI_U2_DISABLE_WAKE (1 << 27) #define XHCI_ASMEDIA_MODIFY_FLOWCONTROL (1 << 28) +#define XHCI_READAHEAD_QUIRK (1 << 29) unsigned int num_active_eps; unsigned int limit_active_eps; -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html