Re: [PATCH 04/11] USB: musb: gadget: fix MUSB_TXMAXP and MUSB_RXMAXP configuration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Bob,

2010/11/10 Bob Liu <lliubbo@xxxxxxxxx>:
> Our spec said when double buffering enabled
> "
> Set up an ISR, sensitive to the SOF_B interrupt, that reads the
> FIFO_FULL_R bit, reads the USB_RXCOUNT status register, and finally
> removes one or two packets (equaling from the USB_RXCOUNT number
> of bytes) from the FIFO and clears RXPKTRDY.
>
> Set SOF_B=1 in USB_INTRUSBE to generate an interrupt on each start
> of frame.
> "

Suppose you meet data corruption issue in test #5, so it is bulk transfer,
and should not be related with SOF in principle.

>
> We didn't see g_ether problem on our platform without this patch, it works fine.
> Could you give detail step how to reproduce the g_ether problem?

Did you test g_ether and g_zero(test #6) at full speed?
I don't think the tests at fullspeed can be OK without my patch.

>
> After added this patch, double buffer will always auto enabled on our
> platform which will cause
> problem as our spec said on double buffer mode it use SOF_B interrupt
> and FIFO_FULL_R bit etc.

In fact, double buffer implementation inside chip should not be very difficult
and seems there should not be bugs here, so I guess musb IP doesn't
provide double buffer switch to disable the feature.

Could you apply the attachment patch against linus tree plus musb patches
submitted by Felipe to feedback the log when the data corruption is triggered
by test #5?

I remembered the similar problem touched me before, but was fixed by my
previous double buffer patches. Maybe bfin musb IP is newer version, and
something is not considered by previous patches.

The patch only adds some debug messages to dump csr against the last
patch sent to Bob.

Good luck

thanks,
-- 
Lei Ming
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 69797e5..a70523d 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -537,6 +537,25 @@ static inline void musb_configure_ep0(struct musb *musb)
 	musb->endpoints[0].is_shared_fifo = true;
 }
 
+static inline void musb_update_double_fifo(struct musb_ep *musb_ep,
+											int rx)
+{
+	struct musb_hw_ep   *hw_ep = musb_ep->hw_ep;
+
+	if (rx) {
+		if (hw_ep->max_packet_sz_rx >= (musb_ep->packet_sz * 2)) {
+			hw_ep->rx_double_buffered = 1;
+			hw_ep->max_packet_sz_rx >>= 1;
+		} else
+			hw_ep->rx_double_buffered = 0;
+	} else {
+		if (hw_ep->max_packet_sz_tx >= (musb_ep->packet_sz * 2)) {
+			hw_ep->tx_double_buffered = 1;
+			hw_ep->max_packet_sz_tx >>= 1;
+		} else
+			hw_ep->tx_double_buffered = 0;
+	}
+}
 #else
 
 static inline int musb_read_fifosize(struct musb *musb,
@@ -575,6 +594,11 @@ static inline void musb_configure_ep0(struct musb *musb)
 	musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE;
 	musb->endpoints[0].is_shared_fifo = true;
 }
+static inline void musb_update_double_fifo(struct musb_ep *musb_ep,
+											int rx)
+{
+
+}
 #endif /* CONFIG_BLACKFIN */
 
 
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index e98b3f4..c9fdf2c 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -657,6 +657,11 @@ static void rxstate(struct musb *musb, struct musb_request *req)
 
 	if (csr & MUSB_RXCSR_RXPKTRDY) {
 		len = musb_readw(epio, MUSB_RXCOUNT);
+		if (len != 512 && len != 1024) {
+			printk("%s:%d csr=%x rx_double_buffer=%d\n", 
+				__func__, __LINE__, csr,
+				hw_ep->rx_double_buffered);
+		}
 		if (request->actual < request->length) {
 #ifdef CONFIG_USB_INVENTRA_DMA
 			if (is_dma_capable() && musb_ep->dma) {
@@ -979,6 +984,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
 			goto fail;
 		}
 
+		musb_update_double_fifo(musb_ep, 0);
+
 		int_txe |= (1 << epnum);
 		musb_writew(mbase, MUSB_INTRTXE, int_txe);
 
@@ -1015,6 +1022,8 @@ static int musb_gadget_enable(struct usb_ep *ep,
 			goto fail;
 		}
 
+		musb_update_double_fifo(musb_ep, 1);
+
 		int_rxe |= (1 << epnum);
 		musb_writew(mbase, MUSB_INTRRXE, int_rxe);
 

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux