On Tue, Jul 20, 2010 at 04:49:14PM +0800, Andiry Xu wrote: > >From 1c80de2ef77e9aafe43f1207ef1d15d53ad0119b Mon Sep 17 00:00:00 2001 > From: Andiry Xu <andiry.xu@xxxxxxx> > Date: Thu, 15 Jul 2010 14:20:15 +0800 > Subject: [PATCH 02/10] xHCI: handle_tx_event() refactor: process_ctrl_td > > This patch moves the ctrl td processing part in handle_tx_event() > into a separate function process_ctrl_td(). > > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> > --- > drivers/usb/host/xhci-ring.c | 184 ++++++++++++++++++++++++------------------ > 1 files changed, 106 insertions(+), 78 deletions(-) > > diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c > index 691a108..e28cfd1 100644 > --- a/drivers/usb/host/xhci-ring.c > +++ b/drivers/usb/host/xhci-ring.c > @@ -1356,6 +1356,109 @@ td_cleanup: > } > > /* > + * Process control tds, update urb status and actual_length. > + */ > +static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td, > + union xhci_trb *event_trb, struct xhci_transfer_event *event, > + struct xhci_virt_ep *ep, int *status) > +{ > + struct xhci_virt_device *xdev; > + struct xhci_ring *ep_ring; > + unsigned int slot_id; > + int ep_index; > + struct xhci_ep_ctx *ep_ctx; > + u32 trb_comp_code; > + > + slot_id = TRB_TO_SLOT_ID(event->flags); > + xdev = xhci->devs[slot_id]; > + ep_index = TRB_TO_EP_ID(event->flags) - 1; > + ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); > + ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); > + trb_comp_code = GET_COMP_CODE(event->transfer_len); > + > + xhci_debug_trb(xhci, xhci->event_ring->dequeue); > + switch (trb_comp_code) { > + case COMP_SUCCESS: > + if (event_trb == ep_ring->dequeue) { > + xhci_warn(xhci, "WARN: Success on ctrl setup TRB " > + "without IOC set??\n"); > + *status = -ESHUTDOWN; > + } else if (event_trb != td->last_trb) { > + xhci_warn(xhci, "WARN: Success on ctrl data TRB " > + "without IOC set??\n"); > + *status = -ESHUTDOWN; > + } else { > + xhci_dbg(xhci, "Successful control transfer!\n"); > + *status = 0; > + } > + break; > + case COMP_SHORT_TX: > + xhci_warn(xhci, "WARN: short transfer on control ep\n"); > + if (td->urb->transfer_flags & URB_SHORT_NOT_OK) > + *status = -EREMOTEIO; > + else > + *status = 0; > + break; > + default: > + if (!xhci_requires_manual_halt_cleanup(xhci, > + ep_ctx, trb_comp_code)) > + break; > + xhci_dbg(xhci, "TRB error code %u, " > + "halted endpoint index = %u\n", > + trb_comp_code, ep_index); > + /* else fall through */ > + case COMP_STALL: > + /* Did we transfer part of the data (middle) phase? */ > + if (event_trb != ep_ring->dequeue && > + event_trb != td->last_trb) > + td->urb->actual_length = > + td->urb->transfer_buffer_length > + - TRB_LEN(event->transfer_len); > + else > + td->urb->actual_length = 0; > + > + xhci_cleanup_halted_endpoint(xhci, > + slot_id, ep_index, 0, td, event_trb); > + return finish_td(xhci, td, event_trb, event, ep, status, true); > + } > + /* > + * Did we transfer any data, despite the errors that might have > + * happened? I.e. did we get past the setup stage? > + */ > + if (event_trb != ep_ring->dequeue) { > + /* The event was for the status stage */ > + if (event_trb == td->last_trb) { > + if (td->urb->actual_length != 0) { > + /* Don't overwrite a previously set error code > + */ > + if ((*status == -EINPROGRESS || *status == 0) && > + (td->urb->transfer_flags > + & URB_SHORT_NOT_OK)) > + /* Did we already see a short data > + * stage? */ > + *status = -EREMOTEIO; > + } else { > + td->urb->actual_length = > + td->urb->transfer_buffer_length; > + } > + } else { > + /* Maybe the event was for the data stage? */ > + if (trb_comp_code != COMP_STOP_INVAL) { > + /* We didn't stop on a link TRB in the middle */ > + td->urb->actual_length = > + td->urb->transfer_buffer_length - > + TRB_LEN(event->transfer_len); > + xhci_dbg(xhci, "Waiting for status " > + "stage event\n"); > + return 0; > + } > + } > + } > + > + return finish_td(xhci, td, event_trb, event, ep, status, false); > +} > + > +/* > * If this function returns an error condition, it means it got a Transfer > * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. > * At this point, the host controller is probably hosed and should be reset. > @@ -1482,84 +1585,9 @@ static int handle_tx_event(struct xhci_hcd *xhci, > /* Now update the urb's actual_length and give back to the core */ > /* Was this a control transfer? */ > if (usb_endpoint_xfer_control(&td->urb->ep->desc)) { > - xhci_debug_trb(xhci, xhci->event_ring->dequeue); > - switch (trb_comp_code) { > - case COMP_SUCCESS: > - if (event_trb == ep_ring->dequeue) { > - xhci_warn(xhci, "WARN: Success on ctrl setup TRB without IOC set??\n"); > - status = -ESHUTDOWN; > - } else if (event_trb != td->last_trb) { > - xhci_warn(xhci, "WARN: Success on ctrl data TRB without IOC set??\n"); > - status = -ESHUTDOWN; > - } else { > - xhci_dbg(xhci, "Successful control transfer!\n"); > - status = 0; > - } > - break; > - case COMP_SHORT_TX: > - xhci_warn(xhci, "WARN: short transfer on control ep\n"); > - if (td->urb->transfer_flags & URB_SHORT_NOT_OK) > - status = -EREMOTEIO; > - else > - status = 0; > - break; > - > - default: > - if (!xhci_requires_manual_halt_cleanup(xhci, > - ep_ctx, trb_comp_code)) > - break; > - xhci_dbg(xhci, "TRB error code %u, " > - "halted endpoint index = %u\n", > - trb_comp_code, ep_index); > - /* else fall through */ > - case COMP_STALL: > - /* Did we transfer part of the data (middle) phase? */ > - if (event_trb != ep_ring->dequeue && > - event_trb != td->last_trb) > - td->urb->actual_length = > - td->urb->transfer_buffer_length > - - TRB_LEN(event->transfer_len); > - else > - td->urb->actual_length = 0; > - > - xhci_cleanup_halted_endpoint(xhci, > - slot_id, ep_index, 0, td, event_trb); > - > - ret = finish_td(xhci, td, event_trb, event, ep, > - &status, true); > - goto cleanup; > - } > - /* > - * Did we transfer any data, despite the errors that might have > - * happened? I.e. did we get past the setup stage? > - */ > - if (event_trb != ep_ring->dequeue) { > - /* The event was for the status stage */ > - if (event_trb == td->last_trb) { > - if (td->urb->actual_length != 0) { > - /* Don't overwrite a previously set error code */ > - if ((status == -EINPROGRESS || > - status == 0) && > - (td->urb->transfer_flags > - & URB_SHORT_NOT_OK)) > - /* Did we already see a short data stage? */ > - status = -EREMOTEIO; > - } else { > - td->urb->actual_length = > - td->urb->transfer_buffer_length; > - } > - } else { > - /* Maybe the event was for the data stage? */ > - if (trb_comp_code != COMP_STOP_INVAL) { > - /* We didn't stop on a link TRB in the middle */ > - td->urb->actual_length = > - td->urb->transfer_buffer_length - > - TRB_LEN(event->transfer_len); > - xhci_dbg(xhci, "Waiting for status stage event\n"); > - goto cleanup; > - } > - } > - } > + ret = process_ctrl_td(xhci, td, event_trb, event, ep, > + &status); > + goto cleanup; > } else { > switch (trb_comp_code) { > case COMP_SUCCESS: > -- > 1.7.0.4 > > > -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html