[rfc/rft/patch v2 05/19] usb: musb_gadget: Tie rx path to interrupt event

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

 



From: Arnaud Mandy <ext-arnaud.2.mandy@xxxxxxxxx>

calling rx routine directly if request is still pending.
removing the use of m_ep_restart for rx.

Signed-off-by: Arnaud Mandy <ext-arnaud.2.mandy@xxxxxxxxx>

[ make it actually compile and do something useful ]

Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 drivers/usb/musb/musb_gadget.c |   34 ++++++++++++++++++++++------------
 drivers/usb/musb/musb_gadget.h |    6 +++++-
 2 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index 9e4ba68..ad6b735 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -430,7 +430,7 @@ void musb_g_rx(struct musb *musb, u8 epnum)
 
 		if (request)
 			musb_g_giveback(musb_ep, request, -EPIPE);
-		goto done;
+		return;
 	}
 
 	if (csr & MUSB_RXCSR_P_OVERRUN) {
@@ -448,15 +448,14 @@ void musb_g_rx(struct musb *musb, u8 epnum)
 	}
 
 	/* analyze request if the ep is hot */
-	if (request)
+	if (request) {
 		do_pio_rx(musb, to_musb_request(request));
-	else
+	} else {
 		DBG(3, "packet waiting for %s%s request\n",
 				musb_ep->desc ? "" : "inactive ",
 				musb_ep->end_point.name);
-
-done:
-	return;
+		musb_ep->rx_pending = true;
+	}
 }
 
 /* ------------------------------------------------------------ */
@@ -690,10 +689,7 @@ static void musb_ep_restart(struct musb *musb, struct musb_request *req)
 		&req->request, req->request.length, req->epnum);
 
 	musb_ep_select(musb->mregs, req->epnum);
-	if (req->tx)
-		do_pio_tx(musb, req);
-	else
-		do_pio_rx(musb, req);
+	do_pio_tx(musb, req);
 }
 
 static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
@@ -745,9 +741,23 @@ static int musb_gadget_queue(struct usb_ep *ep, struct usb_request *req,
 	/* add request to the list */
 	list_add_tail(&(request->request.list), &(musb_ep->req_list));
 
-	/* it this is the head of the queue, start i/o ... */
-	if (!musb_ep->busy && &request->request.list == musb_ep->req_list.next)
+	/* we can only start i/o if this is the head of the queue and
+	 * endpoint is not stalled (halted) or busy
+	 */
+	if (!musb_ep->stalled && !musb_ep->busy &&
+	    &request->request.list == musb_ep->req_list.next &&
+	    request->tx) {
+		DBG(1, "restarting\n");
 		musb_ep_restart(musb, request);
+	}
+
+	/* if we received an RX packet before the request was queued,
+	 * process it here. */
+	if (!request->tx && musb_ep->rx_pending) {
+		DBG(1, "processing pending RX\n");
+		musb_ep->rx_pending = false;
+		musb_g_rx(musb, musb_ep->current_epnum);
+	}
 
 cleanup:
 	spin_unlock_irqrestore(&musb->lock, lockflags);
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
index 59502da..f9cb3a8 100644
--- a/drivers/usb/musb/musb_gadget.h
+++ b/drivers/usb/musb/musb_gadget.h
@@ -76,7 +76,11 @@ struct musb_ep {
 	struct list_head		req_list;
 
 	/* true if lock must be dropped but req_list may not be advanced */
-	u8				busy;
+	u8				busy:1;
+	u8				rx_pending:1;
+
+	/* true if endpoint is stalled */
+	u8				stalled:1;
 };
 
 static inline struct musb_ep *to_musb_ep(struct usb_ep *ep)
-- 
1.6.4.2.253.g0b1fac

--
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