@@ -1675,6 +1675,16 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1675
1675
"still with TDs queued?\n" ,
1676
1676
TRB_TO_SLOT_ID (event -> flags ), ep_index );
1677
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
1688
default :
1679
1689
if (xhci_is_vendor_info_code (xhci , trb_comp_code )) {
1680
1690
status = 0 ;
@@ -1685,60 +1695,108 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1685
1695
goto cleanup ;
1686
1696
}
1687
1697
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 );
1695
- goto cleanup ;
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 )];
1698
+ do {
1699
+ /* This TRB should be in the TD at the head of this ring's
1700
+ * TD list.
1701
+ */
1702
+ if (list_empty (& ep_ring -> td_list )) {
1703
+ xhci_warn (xhci , "WARN Event TRB for slot %d ep %d "
1704
+ "with no TDs queued?\n" ,
1705
+ TRB_TO_SLOT_ID (event -> flags ), ep_index );
1706
+ xhci_dbg (xhci , "Event TRB with TRB type ID %u\n" ,
1707
+ (unsigned int ) (event -> flags & TRB_TYPE_BITMASK )>>10 );
1708
+ xhci_print_trb_offsets (xhci , (union xhci_trb * ) event );
1709
+ if (ep -> skip ) {
1710
+ ep -> skip = false;
1711
+ xhci_dbg (xhci , "td_list is empty while skip "
1712
+ "flag set. Clear skip flag.\n" );
1713
+ }
1714
+ ret = 0 ;
1715
+ goto cleanup ;
1716
+ }
1708
1717
1709
- /* Now update the urb's actual_length and give back to the core */
1710
- /* Was this a control transfer? */
1711
- if (usb_endpoint_xfer_control (& td -> urb -> ep -> desc ))
1712
- ret = process_ctrl_td (xhci , td , event_trb , event , ep ,
1713
- & status );
1714
- else
1715
- ret = process_bulk_intr_td (xhci , td , event_trb , event , ep ,
1716
- & status );
1718
+ td = list_entry (ep_ring -> td_list .next , struct xhci_td , td_list );
1719
+ /* Is this a TRB in the currently executing TD? */
1720
+ event_seg = trb_in_td (ep_ring -> deq_seg , ep_ring -> dequeue ,
1721
+ td -> last_trb , event_dma );
1722
+ if (event_seg && ep -> skip ) {
1723
+ xhci_dbg (xhci , "Found td. Clear skip flag.\n" );
1724
+ ep -> skip = false;
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
1718
- cleanup :
1719
- inc_deq (xhci , xhci -> event_ring , true);
1720
- xhci_set_hc_event_deq (xhci );
1734
+ if (event_seg ) {
1735
+ event_trb = & event_seg -> trbs [(event_dma -
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) */
1723
- if (ret ) {
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).
1751
+ /* Now update the urb's actual_length and give back to
1752
+ * the core
1729
1753
*/
1730
- if (usb_endpoint_xfer_control (& urb -> ep -> desc ) ||
1731
- (trb_comp_code != COMP_STALL &&
1732
- trb_comp_code != COMP_BABBLE ))
1733
- kfree (td );
1734
-
1735
- usb_hcd_unlink_urb_from_ep (xhci_to_hcd (xhci ), urb );
1736
- xhci_dbg (xhci , "Giveback URB %p, len = %d, status = %d\n" ,
1737
- urb , urb -> actual_length , status );
1738
- spin_unlock (& xhci -> lock );
1739
- usb_hcd_giveback_urb (xhci_to_hcd (xhci ), urb , status );
1740
- spin_lock (& xhci -> lock );
1741
- }
1754
+ if (usb_endpoint_xfer_control (& td -> urb -> ep -> desc ))
1755
+ ret = process_ctrl_td (xhci , td , event_trb , event , ep ,
1756
+ & status );
1757
+ else
1758
+ ret = process_bulk_intr_td (xhci , td , event_trb , event ,
1759
+ ep , & status );
1760
+
1761
+ cleanup :
1762
+ /*
1763
+ * Do not update event ring dequeue pointer if ep->skip is set.
1764
+ * Will roll back to continue process missed tds.
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
1800
return 0 ;
1743
1801
}
1744
1802
0 commit comments