| From bce395855b37503c7118a6915adef77a8b7f15da Mon Sep 17 00:00:00 2001 |
| From: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Date: Fri, 11 Nov 2016 15:13:22 +0200 |
| Subject: [PATCH 286/299] xhci: refactor handle_tx_event() urb giveback |
| |
| Move giving back the urb to a separate function |
| No functional changes |
| |
| Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| (cherry picked from commit 446b31419cb122f12900fe2004fb59e413008a8e) |
| Signed-off-by: Simon Horman <horms+renesas@verge.net.au> |
| --- |
| drivers/usb/host/xhci-ring.c | 61 ++++++++++++++++++++++--------------------- |
| 1 file changed, 32 insertions(+), 29 deletions(-) |
| |
| --- a/drivers/usb/host/xhci-ring.c |
| +++ b/drivers/usb/host/xhci-ring.c |
| @@ -622,6 +622,7 @@ static void xhci_stop_watchdog_timer_in_ |
| ep->stop_cmds_pending--; |
| } |
| |
| + |
| /* Must be called with xhci->lock held in interrupt context */ |
| static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, |
| struct xhci_td *cur_td, int status) |
| @@ -653,6 +654,35 @@ static void xhci_giveback_urb_in_irq(str |
| } |
| } |
| |
| +/* |
| + * giveback urb, must be called with xhci->lock held. |
| + * releases and re-aquires xhci->lock |
| + */ |
| +static void xhci_giveback_urb_locked(struct xhci_hcd *xhci, struct xhci_td *td, |
| + int status) |
| +{ |
| + struct urb *urb = td->urb; |
| + struct urb_priv *urb_priv = urb->hcpriv; |
| + |
| + xhci_urb_free_priv(urb_priv); |
| + |
| + usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
| + if ((urb->actual_length != urb->transfer_buffer_length && |
| + (urb->transfer_flags & URB_SHORT_NOT_OK)) || |
| + (status != 0 && !usb_endpoint_xfer_isoc(&urb->ep->desc))) |
| + xhci_dbg(xhci, "Giveback URB %p, len = %d, expected = %d, status = %d\n", |
| + urb, urb->actual_length, |
| + urb->transfer_buffer_length, status); |
| + spin_unlock(&xhci->lock); |
| + /* EHCI, UHCI, and OHCI always unconditionally set the |
| + * urb->status of an isochronous endpoint to 0. |
| + */ |
| + if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) |
| + status = 0; |
| + usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); |
| + spin_lock(&xhci->lock); |
| +} |
| + |
| static void xhci_unmap_td_bounce_buffer(struct xhci_hcd *xhci, |
| struct xhci_ring *ring, struct xhci_td *td) |
| { |
| @@ -2225,9 +2255,7 @@ static int handle_tx_event(struct xhci_h |
| dma_addr_t ep_trb_dma; |
| struct xhci_segment *ep_seg; |
| union xhci_trb *ep_trb; |
| - struct urb *urb = NULL; |
| int status = -EINPROGRESS; |
| - struct urb_priv *urb_priv; |
| struct xhci_ep_ctx *ep_ctx; |
| struct list_head *tmp; |
| u32 trb_comp_code; |
| @@ -2522,33 +2550,8 @@ cleanup: |
| if (!handling_skipped_tds) |
| inc_deq(xhci, xhci->event_ring); |
| |
| - if (ret) { |
| - urb = td->urb; |
| - urb_priv = urb->hcpriv; |
| - |
| - xhci_urb_free_priv(urb_priv); |
| - |
| - usb_hcd_unlink_urb_from_ep(bus_to_hcd(urb->dev->bus), urb); |
| - if ((urb->actual_length != urb->transfer_buffer_length && |
| - (urb->transfer_flags & |
| - URB_SHORT_NOT_OK)) || |
| - (status != 0 && |
| - !usb_endpoint_xfer_isoc(&urb->ep->desc))) |
| - xhci_dbg(xhci, "Giveback URB %p, len = %d, " |
| - "expected = %d, status = %d\n", |
| - urb, urb->actual_length, |
| - urb->transfer_buffer_length, |
| - status); |
| - spin_unlock(&xhci->lock); |
| - /* EHCI, UHCI, and OHCI always unconditionally set the |
| - * urb->status of an isochronous endpoint to 0. |
| - */ |
| - if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) |
| - status = 0; |
| - usb_hcd_giveback_urb(bus_to_hcd(urb->dev->bus), urb, status); |
| - spin_lock(&xhci->lock); |
| - } |
| - |
| + if (ret) |
| + xhci_giveback_urb_locked(xhci, td, status); |
| /* |
| * If ep->skip is set, it means there are missed tds on the |
| * endpoint ring need to take care of. |