aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/musb/musb_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/musb/musb_host.c')
-rw-r--r--drivers/usb/musb/musb_host.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 74c4c3698f1e..c3fdd6d69f5e 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -1771,6 +1771,9 @@ static int musb_schedule(
1771 int best_end, epnum; 1771 int best_end, epnum;
1772 struct musb_hw_ep *hw_ep = NULL; 1772 struct musb_hw_ep *hw_ep = NULL;
1773 struct list_head *head = NULL; 1773 struct list_head *head = NULL;
1774 u8 toggle;
1775 u8 txtype;
1776 struct urb *urb = next_urb(qh);
1774 1777
1775 /* use fixed hardware for control and bulk */ 1778 /* use fixed hardware for control and bulk */
1776 if (qh->type == USB_ENDPOINT_XFER_CONTROL) { 1779 if (qh->type == USB_ENDPOINT_XFER_CONTROL) {
@@ -1809,6 +1812,27 @@ static int musb_schedule(
1809 diff -= (qh->maxpacket * qh->hb_mult); 1812 diff -= (qh->maxpacket * qh->hb_mult);
1810 1813
1811 if (diff >= 0 && best_diff > diff) { 1814 if (diff >= 0 && best_diff > diff) {
1815
1816 /*
1817 * Mentor controller has a bug in that if we schedule
1818 * a BULK Tx transfer on an endpoint that had earlier
1819 * handled ISOC then the BULK transfer has to start on
1820 * a zero toggle. If the BULK transfer starts on a 1
1821 * toggle then this transfer will fail as the mentor
1822 * controller starts the Bulk transfer on a 0 toggle
1823 * irrespective of the programming of the toggle bits
1824 * in the TXCSR register. Check for this condition
1825 * while allocating the EP for a Tx Bulk transfer. If
1826 * so skip this EP.
1827 */
1828 hw_ep = musb->endpoints + epnum;
1829 toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in);
1830 txtype = (musb_readb(hw_ep->regs, MUSB_TXTYPE)
1831 >> 4) & 0x3;
1832 if (!is_in && (qh->type == USB_ENDPOINT_XFER_BULK) &&
1833 toggle && (txtype == USB_ENDPOINT_XFER_ISOC))
1834 continue;
1835
1812 best_diff = diff; 1836 best_diff = diff;
1813 best_end = epnum; 1837 best_end = epnum;
1814 } 1838 }