Add a wmb() barrier between the write to the cycle bit
in the first TRB and the write to the doorbell register.
Without this the hardware might read the ring entry before the write
completes and not action the transfer until the next time a request is added.

Since it isn't needed in the other places the doobell is rung
(because the ring contents haven't been changed) add it to
giveback_first_trb() rather than somewhere later.

Signed-off-by: David Laight <david.lai...@aculab.com>
---

Changes for v2:
- Comment why the wmb() is needed.

 drivers/usb/host/xhci-ring.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ebc2961..6d8b119 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -3182,6 +3182,12 @@ static void giveback_first_trb(struct xhci_hcd *xhci, 
int slot_id,
         */
        wmb();
        start_trb->field[3] ^= cpu_to_le32(TRB_CYCLE);
+       /*
+        * Ensure that the write above happens before the xhci hardware reads
+        * the ring following the write to the doorbell register below.
+        * This is the only critical write to the doorbell.
+        */
+       wmb();
        xhci_ring_ep_doorbell(xhci, slot_id, ep_index, stream_id);
 }
 
-- 
1.8.1.2



--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to