aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/xhci-mem.c1
-rw-r--r--drivers/usb/host/xhci-ring.c158
-rw-r--r--drivers/usb/host/xhci.h8
3 files changed, 117 insertions, 50 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 6d8f7e32932a..64d036804715 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1124,6 +1124,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
1124 virt_dev->num_rings_cached--; 1124 virt_dev->num_rings_cached--;
1125 xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); 1125 xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring);
1126 } 1126 }
1127 virt_dev->eps[ep_index].skip = false;
1127 ep_ring = virt_dev->eps[ep_index].new_ring; 1128 ep_ring = virt_dev->eps[ep_index].new_ring;
1128 ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; 1129 ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state;
1129 1130
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5bb12fed9d2d..4c3501003b8e 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1675,6 +1675,16 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1675 "still with TDs queued?\n", 1675 "still with TDs queued?\n",
1676 TRB_TO_SLOT_ID(event->flags), ep_index); 1676 TRB_TO_SLOT_ID(event->flags), ep_index);
1677 goto cleanup; 1677 goto cleanup;
1678 case COMP_MISSED_INT:
1679 /*
1680 * When encounter missed service error, one or more isoc tds
1681 * may be missed by xHC.
1682 * Set skip flag of the ep_ring; Complete the missed tds as
1683 * short transfer when process the ep_ring next time.
1684 */
1685 ep->skip = true;
1686 xhci_dbg(xhci, "Miss service interval error, set skip flag\n");
1687 goto cleanup;
1678 default: 1688 default:
1679 if (xhci_is_vendor_info_code(xhci, trb_comp_code)) { 1689 if (xhci_is_vendor_info_code(xhci, trb_comp_code)) {
1680 status = 0; 1690 status = 0;
@@ -1685,60 +1695,108 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1685 goto cleanup; 1695 goto cleanup;
1686 } 1696 }
1687 1697
1688 /* This TRB should be in the TD at the head of this ring's TD list */ 1698 do {
1689 if (list_empty(&ep_ring->td_list)) { 1699 /* This TRB should be in the TD at the head of this ring's
1690 xhci_warn(xhci, "WARN Event TRB for slot %d ep %d with no TDs queued?\n", 1700 * TD list.
1691 TRB_TO_SLOT_ID(event->flags), ep_index); 1701 */
1692 xhci_dbg(xhci, "Event TRB with TRB type ID %u\n", 1702 if (list_empty(&ep_ring->td_list)) {
1693 (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10); 1703 xhci_warn(xhci, "WARN Event TRB for slot %d ep %d "
1694 xhci_print_trb_offsets(xhci, (union xhci_trb *) event); 1704 "with no TDs queued?\n",
1695 goto cleanup; 1705 TRB_TO_SLOT_ID(event->flags), ep_index);
1696 } 1706 xhci_dbg(xhci, "Event TRB with TRB type ID %u\n",
1697 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list); 1707 (unsigned int) (event->flags & TRB_TYPE_BITMASK)>>10);
1698 1708 xhci_print_trb_offsets(xhci, (union xhci_trb *) event);
1699 /* Is this a TRB in the currently executing TD? */ 1709 if (ep->skip) {
1700 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue, 1710 ep->skip = false;
1701 td->last_trb, event_dma); 1711 xhci_dbg(xhci, "td_list is empty while skip "
1702 if (!event_seg) { 1712 "flag set. Clear skip flag.\n");
1703 /* HC is busted, give up! */ 1713 }
1704 xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not part of current TD\n"); 1714 ret = 0;
1705 return -ESHUTDOWN; 1715 goto cleanup;
1706 } 1716 }
1707 event_trb = &event_seg->trbs[(event_dma - event_seg->dma) / sizeof(*event_trb)];
1708 1717
1709 /* Now update the urb's actual_length and give back to the core */ 1718 td = list_entry(ep_ring->td_list.next, struct xhci_td, td_list);
1710 /* Was this a control transfer? */ 1719 /* Is this a TRB in the currently executing TD? */
1711 if (usb_endpoint_xfer_control(&td->urb->ep->desc)) 1720 event_seg = trb_in_td(ep_ring->deq_seg, ep_ring->dequeue,
1712 ret = process_ctrl_td(xhci, td, event_trb, event, ep, 1721 td->last_trb, event_dma);
1713 &status); 1722 if (event_seg && ep->skip) {
1714 else 1723 xhci_dbg(xhci, "Found td. Clear skip flag.\n");
1715 ret = process_bulk_intr_td(xhci, td, event_trb, event, ep, 1724 ep->skip = false;
1716 &status); 1725 }
1726 if (!event_seg &&
1727 (!ep->skip || !usb_endpoint_xfer_isoc(&td->urb->ep->desc))) {
1728 /* HC is busted, give up! */
1729 xhci_err(xhci, "ERROR Transfer event TRB DMA ptr not "
1730 "part of current TD\n");
1731 return -ESHUTDOWN;
1732 }
1717 1733
1718cleanup: 1734 if (event_seg) {
1719 inc_deq(xhci, xhci->event_ring, true); 1735 event_trb = &event_seg->trbs[(event_dma -
1720 xhci_set_hc_event_deq(xhci); 1736 event_seg->dma) / sizeof(*event_trb)];
1737 /*
1738 * No-op TRB should not trigger interrupts.
1739 * If event_trb is a no-op TRB, it means the
1740 * corresponding TD has been cancelled. Just ignore
1741 * the TD.
1742 */
1743 if ((event_trb->generic.field[3] & TRB_TYPE_BITMASK)
1744 == TRB_TYPE(TRB_TR_NOOP)) {
1745 xhci_dbg(xhci, "event_trb is a no-op TRB. "
1746 "Skip it\n");
1747 goto cleanup;
1748 }
1749 }
1721 1750
1722 /* FIXME for multi-TD URBs (who have buffers bigger than 64MB) */ 1751 /* Now update the urb's actual_length and give back to
1723 if (ret) { 1752 * the core
1724 urb = td->urb;
1725 /* Leave the TD around for the reset endpoint function to use
1726 * (but only if it's not a control endpoint, since we already
1727 * queued the Set TR dequeue pointer command for stalled
1728 * control endpoints).
1729 */ 1753 */
1730 if (usb_endpoint_xfer_control(&urb->ep->desc) || 1754 if (usb_endpoint_xfer_control(&td->urb->ep->desc))
1731 (trb_comp_code != COMP_STALL && 1755 ret = process_ctrl_td(xhci, td, event_trb, event, ep,
1732 trb_comp_code != COMP_BABBLE)) 1756 &status);
1733 kfree(td); 1757 else
1734 1758 ret = process_bulk_intr_td(xhci, td, event_trb, event,
1735 usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb); 1759 ep, &status);
1736 xhci_dbg(xhci, "Giveback URB %p, len = %d, status = %d\n", 1760
1737 urb, urb->actual_length, status); 1761cleanup:
1738 spin_unlock(&xhci->lock); 1762 /*
1739 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status); 1763 * Do not update event ring dequeue pointer if ep->skip is set.
1740 spin_lock(&xhci->lock); 1764 * Will roll back to continue process missed tds.
1741 } 1765 */
1766 if (trb_comp_code == COMP_MISSED_INT || !ep->skip) {
1767 inc_deq(xhci, xhci->event_ring, true);
1768 xhci_set_hc_event_deq(xhci);
1769 }
1770
1771 if (ret) {
1772 urb = td->urb;
1773 /* Leave the TD around for the reset endpoint function
1774 * to use(but only if it's not a control endpoint,
1775 * since we already queued the Set TR dequeue pointer
1776 * command for stalled control endpoints).
1777 */
1778 if (usb_endpoint_xfer_control(&urb->ep->desc) ||
1779 (trb_comp_code != COMP_STALL &&
1780 trb_comp_code != COMP_BABBLE))
1781 kfree(td);
1782
1783 usb_hcd_unlink_urb_from_ep(xhci_to_hcd(xhci), urb);
1784 xhci_dbg(xhci, "Giveback URB %p, len = %d, "
1785 "status = %d\n",
1786 urb, urb->actual_length, status);
1787 spin_unlock(&xhci->lock);
1788 usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, status);
1789 spin_lock(&xhci->lock);
1790 }
1791
1792 /*
1793 * If ep->skip is set, it means there are missed tds on the
1794 * endpoint ring need to take care of.
1795 * Process them as short transfer until reach the td pointed by
1796 * the event.
1797 */
1798 } while (ep->skip && trb_comp_code != COMP_MISSED_INT);
1799
1742 return 0; 1800 return 0;
1743} 1801}
1744 1802
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 5bc03d1c2beb..f4dfb26a65aa 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -720,6 +720,14 @@ struct xhci_virt_ep {
720 struct timer_list stop_cmd_timer; 720 struct timer_list stop_cmd_timer;
721 int stop_cmds_pending; 721 int stop_cmds_pending;
722 struct xhci_hcd *xhci; 722 struct xhci_hcd *xhci;
723 /*
724 * Sometimes the xHC can not process isochronous endpoint ring quickly
725 * enough, and it will miss some isoc tds on the ring and generate
726 * a Missed Service Error Event.
727 * Set skip flag when receive a Missed Service Error Event and
728 * process the missed tds on the endpoint ring.
729 */
730 bool skip;
723}; 731};
724 732
725struct xhci_virt_device { 733struct xhci_virt_device {