[PATCH 12/22] 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>
Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxx>
---
 drivers/usb/musb/musb_gadget.c |   32 +++++++++++++++++++++++---------
 drivers/usb/musb/musb_gadget.h |    6 +++++-
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c
index eb1b765..6a4087d 100644
--- a/drivers/usb/musb/musb_gadget.c
+++ b/drivers/usb/musb/musb_gadget.c
@@ -450,13 +450,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);
-	return;
+		musb_ep->rx_pending = true;
+	}
 }
 
 /* ------------------------------------------------------------ */
@@ -691,10 +692,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,
@@ -746,9 +744,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);
@@ -869,6 +881,8 @@ static int musb_gadget_set_halt(struct usb_ep *ep, int value)
 		musb_writew(epio, MUSB_RXCSR, csr);
 	}
 
+	musb_ep->stalled = value;
+
 	/* maybe start the first request in the queue */
 	if (!musb_ep->busy && !value && request) {
 		DBG(3, "restarting the request\n");
diff --git a/drivers/usb/musb/musb_gadget.h b/drivers/usb/musb/musb_gadget.h
index c8b1403..3a0899b 100644
--- a/drivers/usb/musb/musb_gadget.h
+++ b/drivers/usb/musb/musb_gadget.h
@@ -78,7 +78,11 @@ struct musb_ep {
 	u8				wedged;
 
 	/* 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.6.rc0

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