Browse Source

USB: musb: disable double buffering for older RTL versions

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>
Cliff Cai 15 years ago
parent
commit
9f445cb299
2 changed files with 23 additions and 4 deletions
  1. 15 2
      drivers/usb/musb/musb_gadget.c
  2. 8 2
      drivers/usb/musb/musb_host.c

+ 15 - 2
drivers/usb/musb/musb_gadget.c

@@ -895,7 +895,14 @@ static int musb_gadget_enable(struct usb_ep *ep,
 		/* REVISIT if can_bulk_split(), use by updating "tmp";
 		/* REVISIT if can_bulk_split(), use by updating "tmp";
 		 * likewise high bandwidth periodic tx
 		 * 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;
 		csr = MUSB_TXCSR_MODE | MUSB_TXCSR_CLRDATATOG;
 		if (musb_readw(regs, MUSB_TXCSR)
 		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"
 		/* REVISIT if can_bulk_combine() use by updating "tmp"
 		 * likewise high bandwidth periodic rx
 		 * 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 */
 		/* force shared fifo to OUT-only mode */
 		if (hw_ep->is_shared_fifo) {
 		if (hw_ep->is_shared_fifo) {

+ 8 - 2
drivers/usb/musb/musb_host.c

@@ -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_RXTYPE, qh->type_reg);
 	musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
 	musb_writeb(ep->regs, MUSB_RXINTERVAL, qh->intv_reg);
 	/* NOTE: bulk combining rewrites high bits of maxpacket */
 	/* 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;
 	ep->rx_reinit = 0;
 }
 }