aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-ring.c
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-07-22 18:23:20 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:41 -0400
commit986a92d44810cad915279fdc942e2fd2c2857499 (patch)
tree25acf06086d9c57048eabdc089a408d5decdd8e9 /drivers/usb/host/xhci-ring.c
parent7fec3253edeb62ab7fc1a82d246196e72e9afdac (diff)
USB: 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@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/xhci-ring.c')
-rw-r--r--drivers/usb/host/xhci-ring.c76
1 files changed, 52 insertions, 24 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 44730eca5fd9..5bb12fed9d2d 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,
1605 ep = &xdev->eps[ep_index]; 1605 ep = &xdev->eps[ep_index];
1606 ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); 1606 ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer);
1607 ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index); 1607 ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
1608 if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) { 1608 if (!ep_ring ||
1609 (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
1609 xhci_err(xhci, "ERROR Transfer event for disabled endpoint " 1610 xhci_err(xhci, "ERROR Transfer event for disabled endpoint "
1610 "or incorrect stream ring\n"); 1611 "or incorrect stream ring\n");
1611 return -ENODEV; 1612 return -ENODEV;
1612 } 1613 }
1613 1614
1614 event_dma = event->buffer; 1615 event_dma = event->buffer;
1615 /* This TRB should be in the TD at the head of this ring's TD list */
1616 if (list_empty(&ep_ring->td_list)) {
1617 xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
1618 TRB_TO_SLOT_ID(event->flags), ep_index);
1619 xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
1620 (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10);
1621 xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
1622 goto cleanup;
1623 }
1624 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list);
1625
1626 /* Is this a TRB in the currently executing TD? */
1627 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
1628 td->last_trb, event_dma);
1629 if (!event_seg) {
1630 /* HC is busted, give up! */
1631 xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n");
1632 return -ESHUTDOWN;
1633 }
1634 event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)];
1635
1636 /* Look for common error cases */
1637 trb_comp_code = GET_COMP_CODE(event->transfer_len); 1616 trb_comp_code = GET_COMP_CODE(event->transfer_len);
1617 /* Look for common error cases */
1638 switch (trb_comp_code) { 1618 switch (trb_comp_code) {
1639 /* Skip codes that require special handling depending on 1619 /* Skip codes that require special handling depending on
1640 * transfer type 1620 * transfer type
@@ -1670,14 +1650,62 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1670 xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n"); 1650 xhci_warn(xhci, "WARN: HC couldn't access mem fast enough\n");
1671 status = -ENOSR; 1651 status = -ENOSR;
1672 break; 1652 break;
1653 case COMP_BW_OVER:
1654 xhci_warn(xhci, "WARN: bandwidth overrun event on endpoint\n");
1655 break;
1656 case COMP_BUFF_OVER:
1657 xhci_warn(xhci, "WARN: buffer overrun event on endpoint\n");
1658 break;
1659 case COMP_UNDERRUN:
1660 /*
1661 * When the Isoch ring is empty, the xHC will generate
1662 * a Ring Overrun Event for IN Isoch endpoint or Ring
1663 * Underrun Event for OUT Isoch endpoint.
1664 */
1665 xhci_dbg(xhci, "underrun event on endpoint\n");
1666 if (!list_empty(&ep_ring->td_list))
1667 xhci_dbg(xhci, "Underrun Event for slot %d ep %d "
1668 "still with TDs queued?\n",
1669 TRB_TO_SLOT_ID(event->flags), ep_index);
1670 goto cleanup;
1671 case COMP_OVERRUN:
1672 xhci_dbg(xhci, "overrun event on endpoint\n");
1673 if (!list_empty(&ep_ring->td_list))
1674 xhci_dbg(xhci, "Overrun Event for slot %d ep %d "
1675 "still with TDs queued?\n",
1676 TRB_TO_SLOT_ID(event->flags), ep_index);
1677 goto cleanup;
1673 default: 1678 default:
1674 if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { 1679 if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
1675 status = 0; 1680 status = 0;
1676 break; 1681 break;
1677 } 1682 }
1678 xhci_warn(xhci, "ERROR Unknown event condition, HC probably busted\n"); 1683 xhci_warn(xhci, "ERROR Unknown event condition, HC probably "
1684 "busted\n");
1685 goto cleanup;
1686 }
1687
1688 /* This TRB should be in the TD at the head of this ring's TD list */
1689 if (list_empty(&ep_ring->td_list)) {
1690 xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n",
1691 TRB_TO_SLOT_ID(event->flags), ep_index);
1692 xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
1693 (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10);
1694 xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
1679 goto cleanup; 1695 goto cleanup;
1680 } 1696 }
1697 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list);
1698
1699 /* Is this a TRB in the currently executing TD? */
1700 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
1701 td->last_trb, event_dma);
1702 if (!event_seg) {
1703 /* HC is busted, give up! */
1704 xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n");
1705 return -ESHUTDOWN;
1706 }
1707 event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)];
1708
1681 /* Now update the urb's actual_length and give back to the core */ 1709 /* Now update the urb's actual_length and give back to the core */
1682 /* Was this a control transfer? */ 1710 /* Was this a control transfer? */
1683 if (usb_endpoint_xfer_control(&td->urb->ep->desc)) 1711 if (usb_endpoint_xfer_control(&td->urb->ep->desc))