aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--payloads/libpayload/drivers/usb/xhci.c8
-rw-r--r--payloads/libpayload/drivers/usb/xhci_private.h3
2 files changed, 11 insertions, 0 deletions
diff --git a/payloads/libpayload/drivers/usb/xhci.c b/payloads/libpayload/drivers/usb/xhci.c
index 33009bc637..7adb304a23 100644
--- a/payloads/libpayload/drivers/usb/xhci.c
+++ b/payloads/libpayload/drivers/usb/xhci.c
@@ -551,6 +551,14 @@ xhci_enqueue_td(transfer_ring_t *const tr, const int ep, const size_t mps,
} else {
TRB_SET(TT, trb, TRB_NORMAL);
}
+ /*
+ * This is a workaround for Synopsys DWC3. If the ENT flag is
+ * not set for the Normal and Data Stage TRBs. We get Event TRB
+ * with length 0x20d from the controller when we enqueue a TRB
+ * for the IN endpoint with length 0x200.
+ */
+ if (!length)
+ TRB_SET(ENT, trb, 1);
xhci_enqueue_trb(tr);
diff --git a/payloads/libpayload/drivers/usb/xhci_private.h b/payloads/libpayload/drivers/usb/xhci_private.h
index 43800d8d49..3861858b44 100644
--- a/payloads/libpayload/drivers/usb/xhci_private.h
+++ b/payloads/libpayload/drivers/usb/xhci_private.h
@@ -93,6 +93,9 @@ enum { TRB_DIR_OUT = 0, TRB_DIR_IN = 1 };
#define TRB_TC_FIELD control /* TC - Toggle Cycle */
#define TRB_TC_START 1
#define TRB_TC_LEN 1
+#define TRB_ENT_FIELD control /* ENT - Evaluate Next TRB */
+#define TRB_ENT_START 1
+#define TRB_ENT_LEN 1
#define TRB_ISP_FIELD control /* ISP - Interrupt-on Short Packet */
#define TRB_ISP_START 2
#define TRB_ISP_LEN 1