diff options
Diffstat (limited to 'drivers/usb/musb/musb_host.c')
-rw-r--r-- | drivers/usb/musb/musb_host.c | 24 |
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 | } |