From 3de7a67bc6da6b5db9133ed4d5bd4557614758ee Mon Sep 17 00:00:00 2001 From: Swaminathan S Date: Mon, 28 Dec 2009 13:40:37 +0200 Subject: [PATCH] --- yaml --- r: 185285 b: refs/heads/master c: 5274dab6cb99c529b2e7f16bbc8ff9a79be46e7f h: refs/heads/master i: 185283: b52929e8c6bea5512c526f30a4a6e76c23c3d15a v: v3 --- [refs] | 2 +- trunk/drivers/usb/musb/musb_host.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f79ba6464fa4..0187be1d3bbf 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f933a0c0fe0ea5f49a35bcd45e3e4850e0606cba +refs/heads/master: 5274dab6cb99c529b2e7f16bbc8ff9a79be46e7f diff --git a/trunk/drivers/usb/musb/musb_host.c b/trunk/drivers/usb/musb/musb_host.c index 74c4c3698f1e..c3fdd6d69f5e 100644 --- a/trunk/drivers/usb/musb/musb_host.c +++ b/trunk/drivers/usb/musb/musb_host.c @@ -1771,6 +1771,9 @@ static int musb_schedule( int best_end, epnum; struct musb_hw_ep *hw_ep = NULL; struct list_head *head = NULL; + u8 toggle; + u8 txtype; + struct urb *urb = next_urb(qh); /* use fixed hardware for control and bulk */ if (qh->type == USB_ENDPOINT_XFER_CONTROL) { @@ -1809,6 +1812,27 @@ static int musb_schedule( diff -= (qh->maxpacket * qh->hb_mult); if (diff >= 0 && best_diff > diff) { + + /* + * Mentor controller has a bug in that if we schedule + * a BULK Tx transfer on an endpoint that had earlier + * handled ISOC then the BULK transfer has to start on + * a zero toggle. If the BULK transfer starts on a 1 + * toggle then this transfer will fail as the mentor + * controller starts the Bulk transfer on a 0 toggle + * irrespective of the programming of the toggle bits + * in the TXCSR register. Check for this condition + * while allocating the EP for a Tx Bulk transfer. If + * so skip this EP. + */ + hw_ep = musb->endpoints + epnum; + toggle = usb_gettoggle(urb->dev, qh->epnum, !is_in); + txtype = (musb_readb(hw_ep->regs, MUSB_TXTYPE) + >> 4) & 0x3; + if (!is_in && (qh->type == USB_ENDPOINT_XFER_BULK) && + toggle && (txtype == USB_ENDPOINT_XFER_ISOC)) + continue; + best_diff = diff; best_end = epnum; }