USB: musb: disable double buffering for older RTL versions
authorCliff Cai <cliff.cai@analog.com>
Fri, 29 Jan 2010 01:44:18 +0000 (20:44 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Mar 2010 22:54:48 +0000 (14:54 -0800)
Trying to use double buffer modes in RTL versions <2.0 may result in
infinite hangs or data corruption.  So avoid them with older versions.

Signed-off-by: Cliff Cai <cliff.cai@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Felipe Balbi <felipe.balbi@nokia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/musb/musb_gadget.c
drivers/usb/musb/musb_host.c

index cbcf14a236e6e3a19e80bfcd8e19af257ce5a727..41de3a9031522fe39733ad070e3e1372a2e4551f 100644 (file)
@@ -895,7 +895,14 @@ static int musb_gadget_enable(struct usb_ep *ep,
                /* REVISIT if can_bulk_split(), use by updating "tmp";
                 * likewise high bandwidth periodic tx
                 */
-               musb_writew(regs, MUSB_TXMAXP, tmp);
+               /* Set TXMAXP with the FIFO size of the endpoint
+                * to disable double buffering mode. Currently, It seems that double
+                * buffering has problem if musb RTL revision number < 2.0.
+                */
+               if (musb->hwvers < MUSB_HWVERS_2000)
+                       musb_writew(regs, MUSB_TXMAXP, hw_ep->max_packet_sz_tx);
+               else
+                       musb_writew(regs, MUSB_TXMAXP, tmp);
 
                csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
                if (musb_readw(regs, MUSB_TXCSR)
@@ -925,7 +932,13 @@ static int musb_gadget_enable(struct usb_ep *ep,
                /* REVISIT if can_bulk_combine() use by updating "tmp"
                 * likewise high bandwidth periodic rx
                 */
-               musb_writew(regs, MUSB_RXMAXP, tmp);
+               /* Set RXMAXP with the FIFO size of the endpoint
+                * to disable double buffering mode.
+                */
+               if (musb->hwvers < MUSB_HWVERS_2000)
+                       musb_writew(regs, MUSB_RXMAXP, hw_ep->max_packet_sz_rx);
+               else
+                       musb_writew(regs, MUSB_RXMAXP, tmp);
 
                /* force shared fifo to OUT-only mode */
                if (hw_ep->is_shared_fifo) {
index c3fdd6d69f5eafa75515dd594aedec0001d302dd..3421cf9858b5100ee3eddd2093af35aaf1dc7f25 100644 (file)
@@ -605,8 +605,14 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, struct musb_hw_ep *ep)
        musb_writeb(ep->regs, MUSB_RXTYPE, qh->type_reg);
        musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
        /* NOTE: bulk combining rewrites high bits of maxpacket */
-       musb_writew(ep->regs, MUSB_RXMAXP,
-                       qh->maxpacket | ((qh->hb_mult - 1) << 11));
+       /* Set RXMAXP with the FIFO size of the endpoint
+        * to disable double buffer mode.
+        */
+       if (musb->hwvers < MUSB_HWVERS_2000)
+               musb_writew(ep->regs, MUSB_RXMAXP, ep->max_packet_sz_rx);
+       else
+               musb_writew(ep->regs, MUSB_RXMAXP,
+                               qh->maxpacket | ((qh->hb_mult - 1) << 11));
 
        ep->rx_reinit = 0;
 }