On Tue, Jul 20, 2010 at 04:49:23PM +0800, Andiry Xu wrote: > >From 3fa49daae266581fc55a4ba3f828a1576ecb47b0 Mon Sep 17 00:00:00 2001 > From: Andiry Xu <andiry.xu@xxxxxxx> > Date: Thu, 24 Jun 2010 14:19:19 +0800 > Subject: [PATCH 05/10] xHCI: adds new cases to trb_comp_code switch > > This patch adds new cases to trb_comp_code switch, and moves > the switch judgment ahead of fetching td. > > Signed-off-by: Andiry Xu <andiry.xu@xxxxxxx> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx> > --- > drivers/usb/host/xhci-ring.c | 76 ++++++++++++++++++++++++++++------------- > 1 files changed, 52 insertions(+), 24 deletions(-) > > diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c > index 44730ec..5bb12fe 100644 > --- a/drivers/usb/host/xhci-ring.c > +++ b/drivers/usb/host/xhci-ring.c > @@ -1605,36 +1605,16 @@ static int handle_tx_event(struct xhci_hcd *xhci, > ep = &xdev->eps[ep_index]; > ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); > ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); > - if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) { > + if (!ep_ring || > + (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) { > xhci_err(xhci, "ERROR Transfer event for disabled endpoint " > "or incorrect stream ring\n"); > return -ENODEV; > } > > event_dma = event->buffer; > - /* This TRB should be in the TD at the head of this ring's TD list */ > - if (list_empty(&ep_ring->td_list)) { > - xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", > - TRB_TO_SLOT_ID(event->flags), ep_index); > - xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", > - (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10); > - xhci_print_trb_offsets(xhci, (union xhci_trb *) event); > - goto cleanup; > - } > - td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); > - > - /* Is this a TRB in the currently executing TD? */ > - event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, > - td->last_trb, event_dma); > - if (!event_seg) { > - /* HC is busted, give up! */ > - xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n"); > - return -ESHUTDOWN; > - } > - event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)]; > - > - /* Look for common error cases */ > trb_comp_code = GET_COMP_CODE(event->transfer_len); > + /* Look for common error cases */ > switch (trb_comp_code) { > /* Skip codes that require special handling depending on > * transfer type > @@ -1670,14 +1650,62 @@ static int handle_tx_event(struct xhci_hcd *xhci, > xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n"); > status = -ENOSR; > break; > + case COMP_BW_OVER: > + xhci_warn(xhci, "WARN: bandwidth overrun event on endpoint\n"); > + break; > + case COMP_BUFF_OVER: > + xhci_warn(xhci, "WARN: buffer overrun event on endpoint\n"); > + break; > + case COMP_UNDERRUN: > + /* > + * When the Isoch ring is empty, the xHC will generate > + * a Ring Overrun Event for IN Isoch endpoint or Ring > + * Underrun Event for OUT Isoch endpoint. > + */ > + xhci_dbg(xhci, "underrun event on endpoint\n"); > + if (!list_empty(&ep_ring->td_list)) > + xhci_dbg(xhci, "Underrun Event for slot %d ep %d " > + "still with TDs queued?\n", > + TRB_TO_SLOT_ID(event->flags), ep_index); > + goto cleanup; > + case COMP_OVERRUN: > + xhci_dbg(xhci, "overrun event on endpoint\n"); > + if (!list_empty(&ep_ring->td_list)) > + xhci_dbg(xhci, "Overrun Event for slot %d ep %d " > + "still with TDs queued?\n", > + TRB_TO_SLOT_ID(event->flags), ep_index); > + goto cleanup; > default: > if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { > status = 0; > break; > } > - xhci_warn(xhci, "ERROR Unknown event condition, HC probably busted\n"); > + xhci_warn(xhci, "ERROR Unknown event condition, HC probably " > + "busted\n"); > + goto cleanup; > + } > + > + /* This TRB should be in the TD at the head of this ring's TD list */ > + if (list_empty(&ep_ring->td_list)) { > + xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", > + TRB_TO_SLOT_ID(event->flags), ep_index); > + xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", > + (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10); > + xhci_print_trb_offsets(xhci, (union xhci_trb *) event); > goto cleanup; > } > + td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); > + > + /* Is this a TRB in the currently executing TD? */ > + event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, > + td->last_trb, event_dma); > + if (!event_seg) { > + /* HC is busted, give up! */ > + xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n"); > + return -ESHUTDOWN; > + } > + event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)]; > + > /* 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)) > -- > 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 -- 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