When trying to access our last TRB, XHCI was actually reading memory outside of the TRB array/ring due to an off-by-one error. This patch fixes that error and has the side effect of also fixing some rare situations where long mass storage transfers would timeout and XHCI would reset the mass storage device before continuing. Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> --- drivers/usb/host/xhci-ring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6c41dbbf9f2f..ba610a72c396 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -95,7 +95,7 @@ static bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *seg, union xhci_trb *trb) { if (ring == xhci->event_ring) - return (trb == &seg->trbs[TRBS_PER_SEGMENT]) && + return (trb == &seg->trbs[TRBS_PER_SEGMENT - 1]) && (seg->next == xhci->event_ring->first_seg); else return le32_to_cpu(trb->link.control) & LINK_TOGGLE; @@ -109,7 +109,7 @@ static int last_trb(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *seg, union xhci_trb *trb) { if (ring == xhci->event_ring) - return trb == &seg->trbs[TRBS_PER_SEGMENT]; + return trb == &seg->trbs[TRBS_PER_SEGMENT - 1]; else return TRB_TYPE_LINK_LE32(trb->link.control); } -- 2.8.1 -- 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