Am Dienstag 28 April 2009 04:53:56 schrieb Sarah Sharp: > +static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) > +{ > + u32 chain; > + union xhci_trb *next; > + > + chain = ring->enqueue->generic.field[3] & TRB_CHAIN; > + next = ++(ring->enqueue); > + > + ring->enq_updates++; > + /* Update the dequeue pointer further if that was a link TRB or we're at > + * the end of an event ring segment (which doesn't have link TRBS) > + */ > + while (last_trb(xhci, ring, ring->enq_seg, next)) { This looks fishy. If this really hands over the TRB to the hardware, we need to make sure that the TRBs hit RAM in order. You need a wmb(). > + if (!consumer) { > + if (ring != xhci->event_ring) { > + /* Give this link TRB to the hardware */ > + 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; Coded this way, the compiler is free to spill intermediate values into RAM, so the hardware sees them. Regards Oliver -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html