Browse Source

USB: xhci: Avoid compiler reordering in Link TRB giveback.

Force the compiler to write the cycle bit of the Link TRB last.  This
ensures that the hardware doesn't think it owns the Link TRB before we set
the chain bit.  Reported by Oliver in this thread:
	http://marc.info/?l=linux-usb&m=124091532410219&w=2

Reported-by: Oliver Neukum <oliver@neukum.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Sarah Sharp 16 years ago
parent
commit
b7116ebca4
1 changed files with 3 additions and 2 deletions
  1. 3 2
      drivers/usb/host/xhci-ring.c

+ 3 - 2
drivers/usb/host/xhci-ring.c

@@ -183,13 +183,14 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer
 	while (last_trb(xhci, ring, ring->enq_seg, next)) {
 		if (!consumer) {
 			if (ring != xhci->event_ring) {
+				next->link.control &= ~TRB_CHAIN;
+				next->link.control |= chain;
 				/* Give this link TRB to the hardware */
+				wmb();
 				if (next->link.control & TRB_CYCLE)
 					next->link.control &= (u32) ~TRB_CYCLE;
 				else
 					next->link.control |= (u32) TRB_CYCLE;
-				next->link.control &= ~TRB_CHAIN;
-				next->link.control |= chain;
 			}
 			/* Toggle the cycle bit after the last ring segment. */
 			if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) {