mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-13 22:14:20 +08:00
usb: host: xhci: introduce xhci_td_cleanup()
By extracting xhci_td_cleanup() from finish_td(), code before clearer and easier to follow. There are no functional changes with this patch. It's merely a cleanup. Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com> Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
be0f50c2e3
commit
55fa4396b2
@ -1822,6 +1822,55 @@ int xhci_is_vendor_info_code(struct xhci_hcd *xhci, unsigned int trb_comp_code)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xhci_td_cleanup(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
struct xhci_ring *ep_ring, int *status)
|
||||
{
|
||||
struct urb_priv *urb_priv;
|
||||
struct urb *urb = NULL;
|
||||
|
||||
/* Clean up the endpoint's TD list */
|
||||
urb = td->urb;
|
||||
urb_priv = urb->hcpriv;
|
||||
|
||||
/* if a bounce buffer was used to align this td then unmap it */
|
||||
if (td->bounce_seg)
|
||||
xhci_unmap_td_bounce_buffer(xhci, ep_ring, td);
|
||||
|
||||
/* Do one last check of the actual transfer length.
|
||||
* If the host controller said we transferred more data than the buffer
|
||||
* length, urb->actual_length will be a very big number (since it's
|
||||
* unsigned). Play it safe and say we didn't transfer anything.
|
||||
*/
|
||||
if (urb->actual_length > urb->transfer_buffer_length) {
|
||||
xhci_warn(xhci, "URB req %u and actual %u transfer length mismatch\n",
|
||||
urb->transfer_buffer_length, urb->actual_length);
|
||||
urb->actual_length = 0;
|
||||
*status = 0;
|
||||
}
|
||||
list_del_init(&td->td_list);
|
||||
/* Was this TD slated to be cancelled but completed anyway? */
|
||||
if (!list_empty(&td->cancelled_td_list))
|
||||
list_del_init(&td->cancelled_td_list);
|
||||
|
||||
inc_td_cnt(urb);
|
||||
/* Giveback the urb when all the tds are completed */
|
||||
if (last_td_in_urb(td)) {
|
||||
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);
|
||||
|
||||
/* set isoc urb status to 0 just as EHCI, UHCI, and OHCI */
|
||||
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
|
||||
*status = 0;
|
||||
xhci_giveback_urb_in_irq(xhci, td, *status);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
union xhci_trb *ep_trb, struct xhci_transfer_event *event,
|
||||
struct xhci_virt_ep *ep, int *status, bool skip)
|
||||
@ -1829,8 +1878,6 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
struct xhci_virt_device *xdev;
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct xhci_ring *ep_ring;
|
||||
struct urb_priv *urb_priv;
|
||||
struct urb *urb = NULL;
|
||||
unsigned int slot_id;
|
||||
u32 trb_comp_code;
|
||||
int ep_index;
|
||||
@ -1873,46 +1920,7 @@ static int finish_td(struct xhci_hcd *xhci, struct xhci_td *td,
|
||||
}
|
||||
|
||||
td_cleanup:
|
||||
/* Clean up the endpoint's TD list */
|
||||
urb = td->urb;
|
||||
urb_priv = urb->hcpriv;
|
||||
|
||||
/* if a bounce buffer was used to align this td then unmap it */
|
||||
if (td->bounce_seg)
|
||||
xhci_unmap_td_bounce_buffer(xhci, ep_ring, td);
|
||||
|
||||
/* Do one last check of the actual transfer length.
|
||||
* If the host controller said we transferred more data than the buffer
|
||||
* length, urb->actual_length will be a very big number (since it's
|
||||
* unsigned). Play it safe and say we didn't transfer anything.
|
||||
*/
|
||||
if (urb->actual_length > urb->transfer_buffer_length) {
|
||||
xhci_warn(xhci, "URB req %u and actual %u transfer length mismatch\n",
|
||||
urb->transfer_buffer_length, urb->actual_length);
|
||||
urb->actual_length = 0;
|
||||
*status = 0;
|
||||
}
|
||||
list_del_init(&td->td_list);
|
||||
/* Was this TD slated to be cancelled but completed anyway? */
|
||||
if (!list_empty(&td->cancelled_td_list))
|
||||
list_del_init(&td->cancelled_td_list);
|
||||
|
||||
inc_td_cnt(urb);
|
||||
/* Giveback the urb when all the tds are completed */
|
||||
if (last_td_in_urb(td)) {
|
||||
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);
|
||||
|
||||
/* set isoc urb status to 0 just as EHCI, UHCI, and OHCI */
|
||||
if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS)
|
||||
*status = 0;
|
||||
xhci_giveback_urb_in_irq(xhci, td, *status);
|
||||
}
|
||||
return 0;
|
||||
return xhci_td_cleanup(xhci, td, ep_ring, status);
|
||||
}
|
||||
|
||||
/* sum trb lengths from ring dequeue up to stop_trb, _excluding_ stop_trb */
|
||||
|
Loading…
Reference in New Issue
Block a user