Loading drivers/usb/host/xhci-ring.c +25 −40 Original line number Diff line number Diff line Loading @@ -89,19 +89,6 @@ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, return seg->dma + (segment_offset * sizeof(*trb)); } /* Does this link TRB point to the first segment in a ring, * or was the previous TRB the last TRB on the last segment in the ERST? */ static bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *seg, union xhci_trb *trb) { if (ring == xhci->event_ring) return (trb == &seg->trbs[TRBS_PER_SEGMENT]) && (seg->next == xhci->event_ring->first_seg); else return le32_to_cpu(trb->link.control) & LINK_TOGGLE; } static bool trb_is_link(union xhci_trb *trb) { return TRB_TYPE_LINK_LE32(trb->link.control); Loading @@ -118,6 +105,11 @@ static bool last_trb_on_ring(struct xhci_ring *ring, return last_trb_on_seg(seg, trb) && (seg->next == ring->first_seg); } static bool link_trb_toggles_cycle(union xhci_trb *trb) { return le32_to_cpu(trb->link.control) & LINK_TOGGLE; } /* Updates trb to point to the next TRB in the ring, and updates seg if the next * TRB is in a new segment. This does not skip over link TRBs, and it does not * effect the ring dequeue or enqueue pointers. Loading Loading @@ -226,7 +218,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, next->link.control ^= cpu_to_le32(TRB_CYCLE); /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) if (link_trb_toggles_cycle(next)) ring->cycle_state ^= 1; ring->enq_seg = ring->enq_seg->next; Loading Loading @@ -2885,36 +2877,29 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, } } if (trb_is_link(ep_ring->enqueue)) { struct xhci_ring *ring = ep_ring; union xhci_trb *next; next = ring->enqueue; while (trb_is_link(next)) { while (trb_is_link(ep_ring->enqueue)) { /* If we're not dealing with 0.95 hardware or isoc rings * on AMD 0.96 host, clear the chain bit. */ if (!xhci_link_trb_quirk(xhci) && !(ring->type == TYPE_ISOC && !(ep_ring->type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST))) next->link.control &= cpu_to_le32(~TRB_CHAIN); ep_ring->enqueue->link.control &= cpu_to_le32(~TRB_CHAIN); else next->link.control |= cpu_to_le32(TRB_CHAIN); ep_ring->enqueue->link.control |= cpu_to_le32(TRB_CHAIN); wmb(); next->link.control ^= cpu_to_le32(TRB_CYCLE); ep_ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE); /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { ring->cycle_state ^= 1; } ring->enq_seg = ring->enq_seg->next; ring->enqueue = ring->enq_seg->trbs; next = ring->enqueue; } } if (link_trb_toggles_cycle(ep_ring->enqueue)) ep_ring->cycle_state ^= 1; ep_ring->enq_seg = ep_ring->enq_seg->next; ep_ring->enqueue = ep_ring->enq_seg->trbs; } return 0; } Loading Loading
drivers/usb/host/xhci-ring.c +25 −40 Original line number Diff line number Diff line Loading @@ -89,19 +89,6 @@ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, return seg->dma + (segment_offset * sizeof(*trb)); } /* Does this link TRB point to the first segment in a ring, * or was the previous TRB the last TRB on the last segment in the ERST? */ static bool last_trb_on_last_seg(struct xhci_hcd *xhci, struct xhci_ring *ring, struct xhci_segment *seg, union xhci_trb *trb) { if (ring == xhci->event_ring) return (trb == &seg->trbs[TRBS_PER_SEGMENT]) && (seg->next == xhci->event_ring->first_seg); else return le32_to_cpu(trb->link.control) & LINK_TOGGLE; } static bool trb_is_link(union xhci_trb *trb) { return TRB_TYPE_LINK_LE32(trb->link.control); Loading @@ -118,6 +105,11 @@ static bool last_trb_on_ring(struct xhci_ring *ring, return last_trb_on_seg(seg, trb) && (seg->next == ring->first_seg); } static bool link_trb_toggles_cycle(union xhci_trb *trb) { return le32_to_cpu(trb->link.control) & LINK_TOGGLE; } /* Updates trb to point to the next TRB in the ring, and updates seg if the next * TRB is in a new segment. This does not skip over link TRBs, and it does not * effect the ring dequeue or enqueue pointers. Loading Loading @@ -226,7 +218,7 @@ static void inc_enq(struct xhci_hcd *xhci, struct xhci_ring *ring, next->link.control ^= cpu_to_le32(TRB_CYCLE); /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) if (link_trb_toggles_cycle(next)) ring->cycle_state ^= 1; ring->enq_seg = ring->enq_seg->next; Loading Loading @@ -2885,36 +2877,29 @@ static int prepare_ring(struct xhci_hcd *xhci, struct xhci_ring *ep_ring, } } if (trb_is_link(ep_ring->enqueue)) { struct xhci_ring *ring = ep_ring; union xhci_trb *next; next = ring->enqueue; while (trb_is_link(next)) { while (trb_is_link(ep_ring->enqueue)) { /* If we're not dealing with 0.95 hardware or isoc rings * on AMD 0.96 host, clear the chain bit. */ if (!xhci_link_trb_quirk(xhci) && !(ring->type == TYPE_ISOC && !(ep_ring->type == TYPE_ISOC && (xhci->quirks & XHCI_AMD_0x96_HOST))) next->link.control &= cpu_to_le32(~TRB_CHAIN); ep_ring->enqueue->link.control &= cpu_to_le32(~TRB_CHAIN); else next->link.control |= cpu_to_le32(TRB_CHAIN); ep_ring->enqueue->link.control |= cpu_to_le32(TRB_CHAIN); wmb(); next->link.control ^= cpu_to_le32(TRB_CYCLE); ep_ring->enqueue->link.control ^= cpu_to_le32(TRB_CYCLE); /* Toggle the cycle bit after the last ring segment. */ if (last_trb_on_last_seg(xhci, ring, ring->enq_seg, next)) { ring->cycle_state ^= 1; } ring->enq_seg = ring->enq_seg->next; ring->enqueue = ring->enq_seg->trbs; next = ring->enqueue; } } if (link_trb_toggles_cycle(ep_ring->enqueue)) ep_ring->cycle_state ^= 1; ep_ring->enq_seg = ep_ring->enq_seg->next; ep_ring->enqueue = ep_ring->enq_seg->trbs; } return 0; } Loading