diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2016-11-11 15:13:22 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-11-14 10:18:22 +0100 |
commit | 446b31419cb122f12900fe2004fb59e413008a8e (patch) | |
tree | ca9e2c22918a3c5cc8c4586f982b8bb4d12df039 /drivers/usb/host/xhci-ring.c | |
parent | 2d6d5769f82dc266e86a06f70eaae23265f757d6 (diff) | |
download | lwn-446b31419cb122f12900fe2004fb59e413008a8e.tar.gz lwn-446b31419cb122f12900fe2004fb59e413008a8e.zip |
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>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 2df6e17af51a..d0227f47465d 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -555,6 +555,7 @@ static void xhci_stop_watchdog_timer_in_irq(struct xhci_hcd *xhci, 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) @@ -586,6 +587,35 @@ static void xhci_giveback_urb_in_irq(struct xhci_hcd *xhci, } } +/* + * 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) { @@ -2200,9 +2230,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, 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; @@ -2497,33 +2525,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. |