Re: [RFC/PATCH 4/5] usb: musb: host: enable DMA for RX

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

 



Hello.

Heikki Krogerus wrote:

  I only have a few comments at this point:

Signed-off-by: Heikki Krogerus <ext-heikki.krogerus@xxxxxxxxx>
---
 drivers/usb/musb/musb_host.c |   69 ++++++++++++++++++++++++++++++++----------
 drivers/usb/musb/musb_host.h |    2 +
 2 files changed, 55 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index d72969f..8557e22 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
[...]
@@ -1318,27 +1326,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 	bool			iso_err = false;
 	bool			done = false;
 	u32			status;
+	struct dma_channel	*dma = hw_ep->rx_channel;
musb_ep_select(mbase, epnum); - urb = qtd->urb;
 	status = 0;
 	xfer_len = 0;
rx_csr = musb_readw(epio, MUSB_RXCSR);
 	val = rx_csr;
- if (unlikely(!urb)) {
-		/* REVISIT -- THIS SHOULD NEVER HAPPEN ... but, at least
-		 * usbtest #11 (unlinks) triggers it regularly, sometimes
-		 * with fifo full.  (Only with DMA??)
-		 */

  Why are you removing this comment? Have you fixed what was described?

+	if (list_empty(&qh->qtd_list)) {
+		if (musb_readw(epio, MUSB_RXCOUNT))
+			qh->rx_pending = true;
 		DBG(3, "BOGUS RX%d ready, csr %04x, count %d\n", epnum, val,
 			musb_readw(epio, MUSB_RXCOUNT));
-		musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
 		return;
 	}
+ qtd = musb_qh_get_qtd(qh);
+	urb = qtd->urb;
 	pipe = urb->pipe;
DBG(5, "<== hw %d rxcsr %04x, urb actual %d\n",
@@ -1395,20 +1402,29 @@ void musb_host_rx(struct musb *musb, u8 epnum)
/* faults abort the transfer */
 	if (status) {
+		/* clean up dma and collect transfer count */
+		if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+			dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+			(void) musb->dma_controller->channel_abort(dma);
+			xfer_len = dma->actual_len;
+		}
 		musb_h_flush_rxfifo(hw_ep, MUSB_RXCSR_CLRDATATOG);
 		musb_writeb(epio, MUSB_RXINTERVAL, 0);
 		done = true;
 		goto finish;
 	}
- /* thorough shutdown for now ... given more precise fault handling
-	 * and better queueing support, we might keep a DMA pipeline going
-	 * while processing this irq for earlier completions.
-	 */
-
-	/* FIXME this is _way_ too much in-line logic for Mentor DMA */

This FIXME should have been removed when removing the existing DMA support, no?

+	if (dma && (rx_csr & MUSB_RXCSR_DMAENAB)) {
+		musb->dma_controller->channel_abort(dma);
- if (urb->status == -EINPROGRESS) {
+		xfer_len = dma->actual_len;
+		done = (urb->actual_length + xfer_len >=
+				urb->transfer_buffer_length);
+		stop_dma(musb, qtd);
+		/* REVISIT the remaining data is left in fifo and musb is
+		 * allowed generate the endpoint interrupt for it.

 Only "allowed to generate".

+		 */
+	} else if (urb->status == -EINPROGRESS) {
 		/* if no errors, be sure a packet is ready for unloading */
 		if (unlikely(!(rx_csr & MUSB_RXCSR_RXPKTRDY))) {
 			status = -EPROTO;
@@ -1425,6 +1441,10 @@ void musb_host_rx(struct musb *musb, u8 epnum)
 		}
/* we are expecting IN packets */
+		if (is_dma_capable()) {
+			if (start_dma(musb, qtd) == 0)
+				goto finish;
+		}

  Why not simply?

		if (is_dma_capable() && start_dma(musb, qtd) == 0)

			goto finish;

WBR, Sergei

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

  Powered by Linux