xhci: get isochronous ring directly from endpoint structure
[ Upstream commit d4dff8043ea5b93a30cb9b19d4407bd506a6877a ] isochronous endpoints do not support streams, meaning that there is only one ring per endpoint. Avoid double-fetching the transfer event DMA to get the ring. Also makes passing the event to skip_isoc_td() uncecessary. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Link: https://lore.kernel.org/r/20210129130044.206855-3-mathias.nyman@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Stable-dep-of: a1575120972e ("xhci: Prevent infinite loop in transaction errors recovery for streams") Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:

committed by
Greg Kroah-Hartman

parent
a81ace0656
commit
aaaa7cc4ab
@@ -2209,7 +2209,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||||||
union xhci_trb *ep_trb, struct xhci_transfer_event *event,
|
union xhci_trb *ep_trb, struct xhci_transfer_event *event,
|
||||||
struct xhci_virt_ep *ep, int *status)
|
struct xhci_virt_ep *ep, int *status)
|
||||||
{
|
{
|
||||||
struct xhci_ring *ep_ring;
|
|
||||||
struct urb_priv *urb_priv;
|
struct urb_priv *urb_priv;
|
||||||
int idx;
|
int idx;
|
||||||
struct usb_iso_packet_descriptor *frame;
|
struct usb_iso_packet_descriptor *frame;
|
||||||
@@ -2218,7 +2217,6 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||||||
u32 remaining, requested, ep_trb_len;
|
u32 remaining, requested, ep_trb_len;
|
||||||
int short_framestatus;
|
int short_framestatus;
|
||||||
|
|
||||||
ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
|
|
||||||
trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
|
trb_comp_code = GET_COMP_CODE(le32_to_cpu(event->transfer_len));
|
||||||
urb_priv = td->urb->hcpriv;
|
urb_priv = td->urb->hcpriv;
|
||||||
idx = urb_priv->num_tds_done;
|
idx = urb_priv->num_tds_done;
|
||||||
@@ -2279,7 +2277,7 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sum_trbs_for_length)
|
if (sum_trbs_for_length)
|
||||||
frame->actual_length = sum_trb_lengths(xhci, ep_ring, ep_trb) +
|
frame->actual_length = sum_trb_lengths(xhci, ep->ring, ep_trb) +
|
||||||
ep_trb_len - remaining;
|
ep_trb_len - remaining;
|
||||||
else
|
else
|
||||||
frame->actual_length = requested;
|
frame->actual_length = requested;
|
||||||
@@ -2290,15 +2288,12 @@ static int process_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||||
struct xhci_transfer_event *event,
|
|
||||||
struct xhci_virt_ep *ep, int *status)
|
struct xhci_virt_ep *ep, int *status)
|
||||||
{
|
{
|
||||||
struct xhci_ring *ep_ring;
|
|
||||||
struct urb_priv *urb_priv;
|
struct urb_priv *urb_priv;
|
||||||
struct usb_iso_packet_descriptor *frame;
|
struct usb_iso_packet_descriptor *frame;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
|
|
||||||
urb_priv = td->urb->hcpriv;
|
urb_priv = td->urb->hcpriv;
|
||||||
idx = urb_priv->num_tds_done;
|
idx = urb_priv->num_tds_done;
|
||||||
frame = &td->urb->iso_frame_desc[idx];
|
frame = &td->urb->iso_frame_desc[idx];
|
||||||
@@ -2310,11 +2305,11 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
|||||||
frame->actual_length = 0;
|
frame->actual_length = 0;
|
||||||
|
|
||||||
/* Update ring dequeue pointer */
|
/* Update ring dequeue pointer */
|
||||||
while (ep_ring->dequeue != td->last_trb)
|
while (ep->ring->dequeue != td->last_trb)
|
||||||
inc_deq(xhci, ep_ring);
|
inc_deq(xhci, ep->ring);
|
||||||
inc_deq(xhci, ep_ring);
|
inc_deq(xhci, ep->ring);
|
||||||
|
|
||||||
return xhci_td_cleanup(xhci, td, ep_ring, status);
|
return xhci_td_cleanup(xhci, td, ep->ring, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2693,7 +2688,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
|
|||||||
return -ESHUTDOWN;
|
return -ESHUTDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_isoc_td(xhci, td, event, ep, &status);
|
skip_isoc_td(xhci, td, ep, &status);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (trb_comp_code == COMP_SHORT_PACKET)
|
if (trb_comp_code == COMP_SHORT_PACKET)
|
||||||
|
Reference in New Issue
Block a user