From ae58b99370df3a86bf15d84b97db858a968b1dbd Mon Sep 17 00:00:00 2001 From: Rajmohan Mani Date: Fri, 30 May 2014 13:06:01 -0700 Subject: [PATCH] libpayload: usb: xhci: Fix TD size if it overflows 5 bits xHCI Spec says TD Size (5 bits) field shall be forced to 31, if the number of packets to be scheduled is greater than 31. BUG=chrome-os-partner:27837 BRANCH=rambi,nyan TEST=Manual: Ensure recovery boot with USB 2.0 media on Squawks works fine without any babble errors. Change-Id: Iff14000e2a0ca1b28c49d0da921dbb2a350a1bbd Signed-off-by: Rajmohan Mani Originally-Reviewed-on: https://chromium-review.googlesource.com/202297 Reviewed-on: https://chromium-review.googlesource.com/202330 Reviewed-by: Shawn Nematbakhsh Commit-Queue: Julius Werner Tested-by: Julius Werner --- payloads/libpayload/drivers/usb/xhci.c | 2 +- payloads/libpayload/drivers/usb/xhci_private.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c index 7bfb4b4040..ed5ac76f03 100644 --- a/payloads/libpayload/drivers/usb/xhci.c +++ b/payloads/libpayload/drivers/usb/xhci.c @@ -515,7 +515,7 @@ xhci_enqueue_td(transfer_ring_t *const tr, const int ep, const size_t mps, xhci_clear_trb(trb, tr->pcs); trb->ptr_low = virt_to_phys(cur_start); TRB_SET(TL, trb, cur_length); - TRB_SET(TDS, trb, packets); + TRB_SET(TDS, trb,((packets > TRB_MAX_TD_SIZE) ? TRB_MAX_TD_SIZE : packets)); TRB_SET(CH, trb, 1); /* Check for first, data stage TRB */ diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h index 34f6285634..779ac1d713 100644 --- a/payloads/libpayload/drivers/usb/xhci_private.h +++ b/payloads/libpayload/drivers/usb/xhci_private.h @@ -140,6 +140,8 @@ typedef volatile struct trb { u32 control; } trb_t; +#define TRB_MAX_TD_SIZE 0x1F /* bits 21:17 of TD Size in TRB */ + #define EVENT_RING_SIZE 64 typedef struct { trb_t *ring;