All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists
@ 2018-03-27 11:05 ` v.anuragkumar
  0 siblings, 0 replies; 6+ messages in thread
From: v.anuragkumar @ 2018-03-27 11:05 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, APANDEY, v.anuragkumar, anuragku

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

The code logic in dwc3_prepare_one_trb() incorrectly uses the address
and length fields present in req packet for mapping TRB's instead of
using the address and length fields of scattergather lists. This patch
correct's the code to use sg->address and sg->length when scattergather
lists are present.

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. Renamed sg_to_start variable to start_sg 
---
 drivers/usb/dwc3/core.h   |  2 ++
 drivers/usb/dwc3/gadget.c | 25 ++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 860d2bc..1406c4f 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -718,6 +718,7 @@ struct dwc3_hwparams {
  * @list: a list_head used for request queueing
  * @dep: struct dwc3_ep owning this request
  * @sg: pointer to first incomplete sg
+ * @start_sg: pointer to the sg which should be queued next
  * @num_pending_sgs: counter to pending sgs
  * @remaining: amount of data remaining
  * @epnum: endpoint number to which this request refers
@@ -734,6 +735,7 @@ struct dwc3_request {
 	struct list_head	list;
 	struct dwc3_ep		*dep;
 	struct scatterlist	*sg;
+	struct scatterlist	*start_sg;
 
 	unsigned		num_pending_sgs;
 	unsigned		remaining;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2bda4eb..330a4de 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -978,11 +978,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 		struct dwc3_request *req, unsigned chain, unsigned node)
 {
 	struct dwc3_trb		*trb;
-	unsigned		length = req->request.length;
+	unsigned int		length;
+	dma_addr_t		dma;
 	unsigned		stream_id = req->request.stream_id;
 	unsigned		short_not_ok = req->request.short_not_ok;
 	unsigned		no_interrupt = req->request.no_interrupt;
-	dma_addr_t		dma = req->request.dma;
+
+	if (req->request.num_sgs > 0) {
+		length = sg_dma_len(req->start_sg);
+		dma = sg_dma_address(req->start_sg);
+	} else {
+		length = req->request.length;
+		dma = req->request.dma;
+	}
 
 	trb = &dep->trb_pool[dep->trb_enqueue];
 
@@ -1048,7 +1056,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
 static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 		struct dwc3_request *req)
 {
-	struct scatterlist *sg = req->sg;
+	struct scatterlist *sg = req->start_sg;
 	struct scatterlist *s;
 	int		i;
 
@@ -1081,6 +1089,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 			dwc3_prepare_one_trb(dep, req, chain, i);
 		}
 
+		/*
+		 * There can be a situation where all sgs in sglist are not
+		 * queued because of insufficient trb number. To handle this
+		 * case, update start_sg to next sg to be queued, so that
+		 * we have free trbs we can continue queuing from where we
+		 * previously stopped
+		 */
+		if (chain)
+			req->start_sg = sg_next(s);
+
 		if (!dwc3_calc_trbs_left(dep))
 			break;
 	}
@@ -1171,6 +1189,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
 			return;
 
 		req->sg			= req->request.sg;
+		req->start_sg		= req->sg;
 		req->num_pending_sgs	= req->request.num_mapped_sgs;
 
 		if (req->num_pending_sgs > 0)
-- 
2.1.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [v2,1/2] usb: dwc3: gadget: Correct handling of scattergather lists
@ 2018-03-27 11:05 ` v.anuragkumar
  0 siblings, 0 replies; 6+ messages in thread
From: v.anuragkumar @ 2018-03-27 11:05 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, APANDEY, v.anuragkumar, anuragku

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

The code logic in dwc3_prepare_one_trb() incorrectly uses the address
and length fields present in req packet for mapping TRB's instead of
using the address and length fields of scattergather lists. This patch
correct's the code to use sg->address and sg->length when scattergather
lists are present.

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. Renamed sg_to_start variable to start_sg 
---
 drivers/usb/dwc3/core.h   |  2 ++
 drivers/usb/dwc3/gadget.c | 25 ++++++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 860d2bc..1406c4f 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -718,6 +718,7 @@ struct dwc3_hwparams {
  * @list: a list_head used for request queueing
  * @dep: struct dwc3_ep owning this request
  * @sg: pointer to first incomplete sg
+ * @start_sg: pointer to the sg which should be queued next
  * @num_pending_sgs: counter to pending sgs
  * @remaining: amount of data remaining
  * @epnum: endpoint number to which this request refers
@@ -734,6 +735,7 @@ struct dwc3_request {
 	struct list_head	list;
 	struct dwc3_ep		*dep;
 	struct scatterlist	*sg;
+	struct scatterlist	*start_sg;
 
 	unsigned		num_pending_sgs;
 	unsigned		remaining;
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2bda4eb..330a4de 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -978,11 +978,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
 		struct dwc3_request *req, unsigned chain, unsigned node)
 {
 	struct dwc3_trb		*trb;
-	unsigned		length = req->request.length;
+	unsigned int		length;
+	dma_addr_t		dma;
 	unsigned		stream_id = req->request.stream_id;
 	unsigned		short_not_ok = req->request.short_not_ok;
 	unsigned		no_interrupt = req->request.no_interrupt;
-	dma_addr_t		dma = req->request.dma;
+
+	if (req->request.num_sgs > 0) {
+		length = sg_dma_len(req->start_sg);
+		dma = sg_dma_address(req->start_sg);
+	} else {
+		length = req->request.length;
+		dma = req->request.dma;
+	}
 
 	trb = &dep->trb_pool[dep->trb_enqueue];
 
@@ -1048,7 +1056,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
 static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 		struct dwc3_request *req)
 {
-	struct scatterlist *sg = req->sg;
+	struct scatterlist *sg = req->start_sg;
 	struct scatterlist *s;
 	int		i;
 
@@ -1081,6 +1089,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 			dwc3_prepare_one_trb(dep, req, chain, i);
 		}
 
+		/*
+		 * There can be a situation where all sgs in sglist are not
+		 * queued because of insufficient trb number. To handle this
+		 * case, update start_sg to next sg to be queued, so that
+		 * we have free trbs we can continue queuing from where we
+		 * previously stopped
+		 */
+		if (chain)
+			req->start_sg = sg_next(s);
+
 		if (!dwc3_calc_trbs_left(dep))
 			break;
 	}
@@ -1171,6 +1189,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
 			return;
 
 		req->sg			= req->request.sg;
+		req->start_sg		= req->sg;
 		req->num_pending_sgs	= req->request.num_mapped_sgs;
 
 		if (req->num_pending_sgs > 0)

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/2] usb: dwc3: gadget: Correct the logic for queuing sgs
@ 2018-03-27 11:05   ` v.anuragkumar
  0 siblings, 0 replies; 6+ messages in thread
From: v.anuragkumar @ 2018-03-27 11:05 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, APANDEY, v.anuragkumar, anuragku

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


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [v2,2/2] usb: dwc3: gadget: Correct the logic for queuing sgs
@ 2018-03-27 11:05   ` v.anuragkumar
  0 siblings, 0 replies; 6+ messages in thread
From: v.anuragkumar @ 2018-03-27 11:05 UTC (permalink / raw)
  To: Felipe Balbi, Greg Kroah-Hartman
  Cc: linux-usb, linux-kernel, APANDEY, v.anuragkumar, anuragku

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

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* RE: [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists
@ 2018-05-02 14:42   ` Anurag Kumar Vulisha
  0 siblings, 0 replies; 6+ messages in thread
From: Anurag Kumar Vulisha @ 2018-05-02 14:42 UTC (permalink / raw)
  To: v.anuragkumar, Felipe Balbi, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel

Hi All,

Please let me know if the changes in this patch are okay . If the changes looks fine , can we proceed with this patch. 
 
Thanks,
Anurag Kumar Vulisha

>-----Original Message-----
>From: v.anuragkumar@gmail.com [mailto:v.anuragkumar@gmail.com]
>Sent: Tuesday, March 27, 2018 4:35 PM
>To: Felipe Balbi <balbi@kernel.org>; Greg Kroah-Hartman
><gregkh@linuxfoundation.org>
>Cc: linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; Ajay Yugalkishore
>Pandey <APANDEY@xilinx.com>; v.anuragkumar@gmail.com; Anurag Kumar Vulisha
><anuragku@xilinx.com>
>Subject: [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists
>
>From: Anurag Kumar Vulisha <anuragku@xilinx.com>
>
>The code logic in dwc3_prepare_one_trb() incorrectly uses the address and length
>fields present in req packet for mapping TRB's instead of using the address and length
>fields of scattergather lists. This patch correct's the code to use sg->address and sg-
>>length when scattergather lists are present.
>
>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. Renamed sg_to_start variable to start_sg
>---
> drivers/usb/dwc3/core.h   |  2 ++
> drivers/usb/dwc3/gadget.c | 25 ++++++++++++++++++++++---
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index
>860d2bc..1406c4f 100644
>--- a/drivers/usb/dwc3/core.h
>+++ b/drivers/usb/dwc3/core.h
>@@ -718,6 +718,7 @@ struct dwc3_hwparams {
>  * @list: a list_head used for request queueing
>  * @dep: struct dwc3_ep owning this request
>  * @sg: pointer to first incomplete sg
>+ * @start_sg: pointer to the sg which should be queued next
>  * @num_pending_sgs: counter to pending sgs
>  * @remaining: amount of data remaining
>  * @epnum: endpoint number to which this request refers @@ -734,6 +735,7 @@
>struct dwc3_request {
> 	struct list_head	list;
> 	struct dwc3_ep		*dep;
> 	struct scatterlist	*sg;
>+	struct scatterlist	*start_sg;
>
> 	unsigned		num_pending_sgs;
> 	unsigned		remaining;
>diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index
>2bda4eb..330a4de 100644
>--- a/drivers/usb/dwc3/gadget.c
>+++ b/drivers/usb/dwc3/gadget.c
>@@ -978,11 +978,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
> 		struct dwc3_request *req, unsigned chain, unsigned node)  {
> 	struct dwc3_trb		*trb;
>-	unsigned		length = req->request.length;
>+	unsigned int		length;
>+	dma_addr_t		dma;
> 	unsigned		stream_id = req->request.stream_id;
> 	unsigned		short_not_ok = req->request.short_not_ok;
> 	unsigned		no_interrupt = req->request.no_interrupt;
>-	dma_addr_t		dma = req->request.dma;
>+
>+	if (req->request.num_sgs > 0) {
>+		length = sg_dma_len(req->start_sg);
>+		dma = sg_dma_address(req->start_sg);
>+	} else {
>+		length = req->request.length;
>+		dma = req->request.dma;
>+	}
>
> 	trb = &dep->trb_pool[dep->trb_enqueue];
>
>@@ -1048,7 +1056,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
>static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
> 		struct dwc3_request *req)
> {
>-	struct scatterlist *sg = req->sg;
>+	struct scatterlist *sg = req->start_sg;
> 	struct scatterlist *s;
> 	int		i;
>
>@@ -1081,6 +1089,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep
>*dep,
> 			dwc3_prepare_one_trb(dep, req, chain, i);
> 		}
>
>+		/*
>+		 * There can be a situation where all sgs in sglist are not
>+		 * queued because of insufficient trb number. To handle this
>+		 * case, update start_sg to next sg to be queued, so that
>+		 * we have free trbs we can continue queuing from where we
>+		 * previously stopped
>+		 */
>+		if (chain)
>+			req->start_sg = sg_next(s);
>+
> 		if (!dwc3_calc_trbs_left(dep))
> 			break;
> 	}
>@@ -1171,6 +1189,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
> 			return;
>
> 		req->sg			= req->request.sg;
>+		req->start_sg		= req->sg;
> 		req->num_pending_sgs	= req->request.num_mapped_sgs;
>
> 		if (req->num_pending_sgs > 0)
>--
>2.1.1

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [v2,1/2] usb: dwc3: gadget: Correct handling of scattergather lists
@ 2018-05-02 14:42   ` Anurag Kumar Vulisha
  0 siblings, 0 replies; 6+ messages in thread
From: Anurag Kumar Vulisha @ 2018-05-02 14:42 UTC (permalink / raw)
  To: v.anuragkumar, Felipe Balbi, Greg Kroah-Hartman; +Cc: linux-usb, linux-kernel

Hi All,

Please let me know if the changes in this patch are okay . If the changes looks fine , can we proceed with this patch. 
 
Thanks,
Anurag Kumar Vulisha

>-----Original Message-----
>From: v.anuragkumar@gmail.com [mailto:v.anuragkumar@gmail.com]
>Sent: Tuesday, March 27, 2018 4:35 PM
>To: Felipe Balbi <balbi@kernel.org>; Greg Kroah-Hartman
><gregkh@linuxfoundation.org>
>Cc: linux-usb@vger.kernel.org; linux-kernel@vger.kernel.org; Ajay Yugalkishore
>Pandey <APANDEY@xilinx.com>; v.anuragkumar@gmail.com; Anurag Kumar Vulisha
><anuragku@xilinx.com>
>Subject: [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists
>
>From: Anurag Kumar Vulisha <anuragku@xilinx.com>
>
>The code logic in dwc3_prepare_one_trb() incorrectly uses the address and length
>fields present in req packet for mapping TRB's instead of using the address and length
>fields of scattergather lists. This patch correct's the code to use sg->address and sg-
>>length when scattergather lists are present.
>
>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. Renamed sg_to_start variable to start_sg
>---
> drivers/usb/dwc3/core.h   |  2 ++
> drivers/usb/dwc3/gadget.c | 25 ++++++++++++++++++++++---
> 2 files changed, 24 insertions(+), 3 deletions(-)
>
>diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h index
>860d2bc..1406c4f 100644
>--- a/drivers/usb/dwc3/core.h
>+++ b/drivers/usb/dwc3/core.h
>@@ -718,6 +718,7 @@ struct dwc3_hwparams {
>  * @list: a list_head used for request queueing
>  * @dep: struct dwc3_ep owning this request
>  * @sg: pointer to first incomplete sg
>+ * @start_sg: pointer to the sg which should be queued next
>  * @num_pending_sgs: counter to pending sgs
>  * @remaining: amount of data remaining
>  * @epnum: endpoint number to which this request refers @@ -734,6 +735,7 @@
>struct dwc3_request {
> 	struct list_head	list;
> 	struct dwc3_ep		*dep;
> 	struct scatterlist	*sg;
>+	struct scatterlist	*start_sg;
>
> 	unsigned		num_pending_sgs;
> 	unsigned		remaining;
>diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index
>2bda4eb..330a4de 100644
>--- a/drivers/usb/dwc3/gadget.c
>+++ b/drivers/usb/dwc3/gadget.c
>@@ -978,11 +978,19 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
> 		struct dwc3_request *req, unsigned chain, unsigned node)  {
> 	struct dwc3_trb		*trb;
>-	unsigned		length = req->request.length;
>+	unsigned int		length;
>+	dma_addr_t		dma;
> 	unsigned		stream_id = req->request.stream_id;
> 	unsigned		short_not_ok = req->request.short_not_ok;
> 	unsigned		no_interrupt = req->request.no_interrupt;
>-	dma_addr_t		dma = req->request.dma;
>+
>+	if (req->request.num_sgs > 0) {
>+		length = sg_dma_len(req->start_sg);
>+		dma = sg_dma_address(req->start_sg);
>+	} else {
>+		length = req->request.length;
>+		dma = req->request.dma;
>+	}
>
> 	trb = &dep->trb_pool[dep->trb_enqueue];
>
>@@ -1048,7 +1056,7 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
>static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
> 		struct dwc3_request *req)
> {
>-	struct scatterlist *sg = req->sg;
>+	struct scatterlist *sg = req->start_sg;
> 	struct scatterlist *s;
> 	int		i;
>
>@@ -1081,6 +1089,16 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep
>*dep,
> 			dwc3_prepare_one_trb(dep, req, chain, i);
> 		}
>
>+		/*
>+		 * There can be a situation where all sgs in sglist are not
>+		 * queued because of insufficient trb number. To handle this
>+		 * case, update start_sg to next sg to be queued, so that
>+		 * we have free trbs we can continue queuing from where we
>+		 * previously stopped
>+		 */
>+		if (chain)
>+			req->start_sg = sg_next(s);
>+
> 		if (!dwc3_calc_trbs_left(dep))
> 			break;
> 	}
>@@ -1171,6 +1189,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
> 			return;
>
> 		req->sg			= req->request.sg;
>+		req->start_sg		= req->sg;
> 		req->num_pending_sgs	= req->request.num_mapped_sgs;
>
> 		if (req->num_pending_sgs > 0)
>--
>2.1.1
---
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2018-05-02 14:42 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-27 11:05 [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists v.anuragkumar
2018-03-27 11:05 ` [v2,1/2] " v.anuragkumar
2018-03-27 11:05 ` [PATCH v2 2/2] usb: dwc3: gadget: Correct the logic for queuing sgs v.anuragkumar
2018-03-27 11:05   ` [v2,2/2] " v.anuragkumar
2018-05-02 14:42 ` [PATCH v2 1/2] usb: dwc3: gadget: Correct handling of scattergather lists Anurag Kumar Vulisha
2018-05-02 14:42   ` [v2,1/2] " Anurag Kumar Vulisha

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.