|
@@ -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;
|
|
|
}
|