diff options
Diffstat (limited to 'drivers/usb/host/ehci-q.c')
-rw-r--r-- | drivers/usb/host/ehci-q.c | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 4b66374bdc8e..940a63f67a21 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1018,6 +1018,12 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) head->qh_next.qh = qh; head->hw->hw_next = dma; + /* + * flush qh descriptor into memory immediately, + * see comments in qh_append_tds. + */ + ehci_sync_mem(); + qh->xacterrs = 0; qh->qh_state = QH_STATE_LINKED; /* qtd completions reported later by interrupt */ @@ -1106,6 +1112,18 @@ static struct ehci_qh *qh_append_tds ( wmb (); dummy->hw_token = token; + /* + * Writing to dma coherent buffer on ARM may + * be delayed to reach memory, so HC may not see + * hw_token of dummy qtd in time, which can cause + * the qtd transaction to be executed very late, + * and degrade performance a lot. ehci_sync_mem + * is added to flush 'token' immediatelly into + * memory, so that ehci can execute the transaction + * ASAP. + */ + ehci_sync_mem(); + urb->hcpriv = qh; } } |