linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <v.anuragkumar@gmail.com>
To: Felipe Balbi <balbi@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<APANDEY@xilinx.com>, <v.anuragkumar@gmail.com>,
	<anuragku@xilinx.com>
Subject: [PATCH v2 2/2] usb: dwc3: gadget: Correct the logic for queuing sgs
Date: Tue, 27 Mar 2018 16:35:21 +0530	[thread overview]
Message-ID: <1522148721-5744-2-git-send-email-v.anuragkumar@gmail.com> (raw)
In-Reply-To: <1522148721-5744-1-git-send-email-v.anuragkumar@gmail.com>

From: Anurag Kumar Vulisha <anuragku@xilinx.com>

The present code correctly fetches the req which were previously not
queued from the started_list but fails to continue queuing from the sg
where it previously stopped queuing (because of the unavailable TRB's).
This patch correct's the code to continue queuing from the correct sg
present in the sglist.

For example, consider 5 sgs in req. Because of limited TRB's among the
5 sgs only 3 got queued. This patch corrects the code to start queuing
from correct sg i.e 4th sg when the TRBs are available.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
---
 Changes in v2:
	1. Split the single patch into 2 patches as suggested by Felipe Balbi
	2. Added dev_WARN_ONCE message when ((req->request.actual == length) &&
	   (req->num_pending_sgs > 0))
---
 drivers/usb/dwc3/core.h   |  2 ++
 drivers/usb/dwc3/gadget.c | 23 ++++++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 1406c4f..6bce913 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -720,6 +720,7 @@ struct dwc3_hwparams {
  * @sg: pointer to first incomplete sg
  * @start_sg: pointer to the sg which should be queued next
  * @num_pending_sgs: counter to pending sgs
+ * @num_queued_sgs: counter to the number of sgs which already got queued
  * @remaining: amount of data remaining
  * @epnum: endpoint number to which this request refers
  * @trb: pointer to struct dwc3_trb
@@ -738,6 +739,7 @@ struct dwc3_request {
 	struct scatterlist	*start_sg;
 
 	unsigned		num_pending_sgs;
+	unsigned int		num_queued_sgs;
 	unsigned		remaining;
 	u8			epnum;
 	struct dwc3_trb		*trb;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 330a4de..ff62e13 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1060,7 +1060,10 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 	struct scatterlist *s;
 	int		i;
 
-	for_each_sg(sg, s, req->num_pending_sgs, i) {
+	unsigned int remaining = req->request.num_mapped_sgs
+		- req->num_queued_sgs;
+
+	for_each_sg(sg, s, remaining, i) {
 		unsigned int length = req->request.length;
 		unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
 		unsigned int rem = length % maxp;
@@ -1099,6 +1102,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 		if (chain)
 			req->start_sg = sg_next(s);
 
+		req->num_queued_sgs++;
+
 		if (!dwc3_calc_trbs_left(dep))
 			break;
 	}
@@ -1190,6 +1195,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
 
 		req->sg			= req->request.sg;
 		req->start_sg		= req->sg;
+		req->num_queued_sgs	= 0;
 		req->num_pending_sgs	= req->request.num_mapped_sgs;
 
 		if (req->num_pending_sgs > 0)
@@ -2346,8 +2352,19 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
 
 		req->request.actual = length - req->remaining;
 
-		if ((req->request.actual < length) && req->num_pending_sgs)
-			return __dwc3_gadget_kick_transfer(dep);
+		if (req->request.actual < length || req->num_pending_sgs) {
+			/*
+			 * There could be a scenario where the whole req can't
+			 * be mapped into available TRB's. In that case, we need
+			 * to kick transfer again if (req->num_pending_sgs > 0)
+			 */
+			if (req->num_pending_sgs) {
+				dev_WARN_ONCE(dwc->dev,
+					      (req->request.actual == length),
+					      "There are some pending sg's that needs to be queued again\n");
+				return __dwc3_gadget_kick_transfer(dep);
+			}
+		}
 
 		dwc3_gadget_giveback(dep, req, status);
 
-- 
2.1.1


  reply	other threads:[~2018-03-27 11:05 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-27 11:05 [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists v.anuragkumar
2018-03-27 11:05 ` v.anuragkumar [this message]
2018-05-02 14:42 ` Anurag Kumar Vulisha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1522148721-5744-2-git-send-email-v.anuragkumar@gmail.com \
    --to=v.anuragkumar@gmail.com \
    --cc=APANDEY@xilinx.com \
    --cc=anuragku@xilinx.com \
    --cc=balbi@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).