diff options
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index aa88a067148b..011458f4d9ce 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -172,8 +172,9 @@ static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
172 | * have their chain bit cleared (so that each Link TRB is a separate TD). | 172 | * have their chain bit cleared (so that each Link TRB is a separate TD). |
173 | * | 173 | * |
174 | * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit | 174 | * Section 6.4.4.1 of the 0.95 spec says link TRBs cannot have the chain bit |
175 | * set, but other sections talk about dealing with the chain bit set. | 175 | * set, but other sections talk about dealing with the chain bit set. This was |
176 | * Assume section 6.4.4.1 is wrong, and the chain bit can be set in a Link TRB. | 176 | * fixed in the 0.96 specification errata, but we have to assume that all 0.95 |
177 | * xHCI hardware can't handle the chain bit being cleared on a link TRB. | ||
177 | */ | 178 | */ |
178 | static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) | 179 | static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer) |
179 | { | 180 | { |
@@ -191,8 +192,14 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, bool consumer | |||
191 | while (last_trb(xhci, ring, ring->enq_seg, next)) { | 192 | while (last_trb(xhci, ring, ring->enq_seg, next)) { |
192 | if (!consumer) { | 193 | if (!consumer) { |
193 | if (ring != xhci->event_ring) { | 194 | if (ring != xhci->event_ring) { |
194 | next->link.control &= ~TRB_CHAIN; | 195 | /* If we're not dealing with 0.95 hardware, |
195 | next->link.control |= chain; | 196 | * carry over the chain bit of the previous TRB |
197 | * (which may mean the chain bit is cleared). | ||
198 | */ | ||
199 | if (!xhci_link_trb_quirk(xhci)) { | ||
200 | next->link.control &= ~TRB_CHAIN; | ||
201 | next->link.control |= chain; | ||
202 | } | ||
196 | /* Give this link TRB to the hardware */ | 203 | /* Give this link TRB to the hardware */ |
197 | wmb(); | 204 | wmb(); |
198 | if (next->link.control & TRB_CYCLE) | 205 | if (next->link.control & TRB_CYCLE) |