aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/host/ehci-sched.c58
1 files changed, 42 insertions, 16 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
index dce305bd62a5..1c771045ccaa 100644
--- a/drivers/usb/host/ehci-sched.c
+++ b/drivers/usb/host/ehci-sched.c
@@ -1565,6 +1565,16 @@ itd_link_urb (
1565 1565
1566#define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) 1566#define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
1567 1567
1568/* Process and recycle a completed ITD. Return true iff its urb completed,
1569 * and hence its completion callback probably added things to the hardware
1570 * schedule.
1571 *
1572 * Note that we carefully avoid recycling this descriptor until after any
1573 * completion callback runs, so that it won't be reused quickly. That is,
1574 * assuming (a) no more than two urbs per frame on this endpoint, and also
1575 * (b) only this endpoint's completions submit URBs. It seems some silicon
1576 * corrupts things if you reuse completed descriptors very quickly...
1577 */
1568static unsigned 1578static unsigned
1569itd_complete ( 1579itd_complete (
1570 struct ehci_hcd *ehci, 1580 struct ehci_hcd *ehci,
@@ -1577,6 +1587,7 @@ itd_complete (
1577 int urb_index = -1; 1587 int urb_index = -1;
1578 struct ehci_iso_stream *stream = itd->stream; 1588 struct ehci_iso_stream *stream = itd->stream;
1579 struct usb_device *dev; 1589 struct usb_device *dev;
1590 unsigned retval = false;
1580 1591
1581 /* for each uframe with a packet */ 1592 /* for each uframe with a packet */
1582 for (uframe = 0; uframe < 8; uframe++) { 1593 for (uframe = 0; uframe < 8; uframe++) {
@@ -1610,15 +1621,9 @@ itd_complete (
1610 } 1621 }
1611 } 1622 }
1612 1623
1613 usb_put_urb (urb);
1614 itd->urb = NULL;
1615 itd->stream = NULL;
1616 list_move (&itd->itd_list, &stream->free_list);
1617 iso_stream_put (ehci, stream);
1618
1619 /* handle completion now? */ 1624 /* handle completion now? */
1620 if (likely ((urb_index + 1) != urb->number_of_packets)) 1625 if (likely ((urb_index + 1) != urb->number_of_packets))
1621 return 0; 1626 goto done;
1622 1627
1623 /* ASSERT: it's really the last itd for this urb 1628 /* ASSERT: it's really the last itd for this urb
1624 list_for_each_entry (itd, &stream->td_list, itd_list) 1629 list_for_each_entry (itd, &stream->td_list, itd_list)
@@ -1628,6 +1633,7 @@ itd_complete (
1628 /* give urb back to the driver ... can be out-of-order */ 1633 /* give urb back to the driver ... can be out-of-order */
1629 dev = urb->dev; 1634 dev = urb->dev;
1630 ehci_urb_done(ehci, urb, 0); 1635 ehci_urb_done(ehci, urb, 0);
1636 retval = true;
1631 urb = NULL; 1637 urb = NULL;
1632 1638
1633 /* defer stopping schedule; completion can submit */ 1639 /* defer stopping schedule; completion can submit */
@@ -1645,8 +1651,15 @@ itd_complete (
1645 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); 1651 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
1646 } 1652 }
1647 iso_stream_put (ehci, stream); 1653 iso_stream_put (ehci, stream);
1654 /* OK to recycle this ITD now that its completion callback ran. */
1655done:
1656 usb_put_urb(urb);
1657 itd->urb = NULL;
1658 itd->stream = NULL;
1659 list_move(&itd->itd_list, &stream->free_list);
1660 iso_stream_put(ehci, stream);
1648 1661
1649 return 1; 1662 return retval;
1650} 1663}
1651 1664
1652/*-------------------------------------------------------------------------*/ 1665/*-------------------------------------------------------------------------*/
@@ -1950,6 +1963,16 @@ sitd_link_urb (
1950#define SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \ 1963#define SITD_ERRS (SITD_STS_ERR | SITD_STS_DBE | SITD_STS_BABBLE \
1951 | SITD_STS_XACT | SITD_STS_MMF) 1964 | SITD_STS_XACT | SITD_STS_MMF)
1952 1965
1966/* Process and recycle a completed SITD. Return true iff its urb completed,
1967 * and hence its completion callback probably added things to the hardware
1968 * schedule.
1969 *
1970 * Note that we carefully avoid recycling this descriptor until after any
1971 * completion callback runs, so that it won't be reused quickly. That is,
1972 * assuming (a) no more than two urbs per frame on this endpoint, and also
1973 * (b) only this endpoint's completions submit URBs. It seems some silicon
1974 * corrupts things if you reuse completed descriptors very quickly...
1975 */
1953static unsigned 1976static unsigned
1954sitd_complete ( 1977sitd_complete (
1955 struct ehci_hcd *ehci, 1978 struct ehci_hcd *ehci,
@@ -1961,6 +1984,7 @@ sitd_complete (
1961 int urb_index = -1; 1984 int urb_index = -1;
1962 struct ehci_iso_stream *stream = sitd->stream; 1985 struct ehci_iso_stream *stream = sitd->stream;
1963 struct usb_device *dev; 1986 struct usb_device *dev;
1987 unsigned retval = false;
1964 1988
1965 urb_index = sitd->index; 1989 urb_index = sitd->index;
1966 desc = &urb->iso_frame_desc [urb_index]; 1990 desc = &urb->iso_frame_desc [urb_index];
@@ -1981,17 +2005,11 @@ sitd_complete (
1981 desc->status = 0; 2005 desc->status = 0;
1982 desc->actual_length = desc->length - SITD_LENGTH (t); 2006 desc->actual_length = desc->length - SITD_LENGTH (t);
1983 } 2007 }
1984
1985 usb_put_urb (urb);
1986 sitd->urb = NULL;
1987 sitd->stream = NULL;
1988 list_move (&sitd->sitd_list, &stream->free_list);
1989 stream->depth -= stream->interval << 3; 2008 stream->depth -= stream->interval << 3;
1990 iso_stream_put (ehci, stream);
1991 2009
1992 /* handle completion now? */ 2010 /* handle completion now? */
1993 if ((urb_index + 1) != urb->number_of_packets) 2011 if ((urb_index + 1) != urb->number_of_packets)
1994 return 0; 2012 goto done;
1995 2013
1996 /* ASSERT: it's really the last sitd for this urb 2014 /* ASSERT: it's really the last sitd for this urb
1997 list_for_each_entry (sitd, &stream->td_list, sitd_list) 2015 list_for_each_entry (sitd, &stream->td_list, sitd_list)
@@ -2001,6 +2019,7 @@ sitd_complete (
2001 /* give urb back to the driver */ 2019 /* give urb back to the driver */
2002 dev = urb->dev; 2020 dev = urb->dev;
2003 ehci_urb_done(ehci, urb, 0); 2021 ehci_urb_done(ehci, urb, 0);
2022 retval = true;
2004 urb = NULL; 2023 urb = NULL;
2005 2024
2006 /* defer stopping schedule; completion can submit */ 2025 /* defer stopping schedule; completion can submit */
@@ -2018,8 +2037,15 @@ sitd_complete (
2018 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); 2037 (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out");
2019 } 2038 }
2020 iso_stream_put (ehci, stream); 2039 iso_stream_put (ehci, stream);
2040 /* OK to recycle this SITD now that its completion callback ran. */
2041done:
2042 usb_put_urb(urb);
2043 sitd->urb = NULL;
2044 sitd->stream = NULL;
2045 list_move(&sitd->sitd_list, &stream->free_list);
2046 iso_stream_put(ehci, stream);
2021 2047
2022 return 1; 2048 return retval;
2023} 2049}
2024 2050
2025 2051