stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb()
@ 2017-01-09 11:03 Felipe Balbi
  2017-01-09 11:03 ` [BACKPORT PATCH 2/3] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() Felipe Balbi
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Felipe Balbi @ 2017-01-09 11:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: stable, Felipe Balbi

commit 7931ec86c1b738e4e90e58c6d95e5f720d45ee56 upstream.

For now this is just a cleanup patch, no functional
changes. We will be using the new function to fix a
bug introduced long ago by commit 0416e494ce7d
("usb: dwc3: ep0: correct cache sync issue in case
of ep0_bounced") and further worsened by commit
c0bd5456a470 ("usb: dwc3: ep0: handle non maxpacket
aligned transfers > 512")

Cc: <stable@vger.kernel.org>
Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
 drivers/usb/dwc3/ep0.c | 30 ++++++++++++++++++------------
 1 file changed, 18 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fe79d771dee4..7c05e64b3ef7 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -55,20 +55,13 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
 	}
 }
 
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
-		u32 len, u32 type, bool chain)
+static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum,
+		dma_addr_t buf_dma, u32 len, u32 type, bool chain)
 {
-	struct dwc3_gadget_ep_cmd_params params;
 	struct dwc3_trb			*trb;
 	struct dwc3_ep			*dep;
 
-	int				ret;
-
 	dep = dwc->eps[epnum];
-	if (dep->flags & DWC3_EP_BUSY) {
-		dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
-		return 0;
-	}
 
 	trb = &dwc->ep0_trb[dep->trb_enqueue];
 
@@ -89,15 +82,28 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
 		trb->ctrl |= (DWC3_TRB_CTRL_IOC
 				| DWC3_TRB_CTRL_LST);
 
-	if (chain)
+	trace_dwc3_prepare_trb(dep, trb);
+}
+
+static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
+		u32 len, u32 type, bool chain)
+{
+	struct dwc3_gadget_ep_cmd_params params;
+	struct dwc3_ep			*dep;
+	int				ret;
+
+	dep = dwc->eps[epnum];
+	if (dep->flags & DWC3_EP_BUSY) {
+		dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
 		return 0;
+	}
+
+	dwc3_ep0_prepare_one_trb(dwc, epnum, buf_dma, len, type, chain);
 
 	memset(&params, 0, sizeof(params));
 	params.param0 = upper_32_bits(dwc->ep0_trb_addr);
 	params.param1 = lower_32_bits(dwc->ep0_trb_addr);
 
-	trace_dwc3_prepare_trb(dep, trb);
-
 	ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params);
 	if (ret < 0) {
 		dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed",
-- 
2.11.0


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

* [BACKPORT PATCH 2/3] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb()
  2017-01-09 11:03 [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Felipe Balbi
@ 2017-01-09 11:03 ` Felipe Balbi
  2017-01-09 11:03 ` [BACKPORT PATCH 3/3] usb: dwc3: gadget: always unmap EP0 requests Felipe Balbi
  2017-01-09 11:23 ` [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Greg Kroah-Hartman
  2 siblings, 0 replies; 5+ messages in thread
From: Felipe Balbi @ 2017-01-09 11:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: stable, Felipe Balbi

commit 19ec31230eb3084431bc2e565fd085f79f564274 upstream.

Let's call dwc3_ep0_prepare_one_trb() explicitly
because there are occasions where we will need more
than one TRB to handle an EP0 transfer.

A follow-up patch will fix one bug related to
multiple-TRB Data Phases when it comes to
mapping/unmapping requests for DMA.

Cc: <stable@vger.kernel.org>
Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
 drivers/usb/dwc3/ep0.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 7c05e64b3ef7..2331469f943d 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -85,8 +85,7 @@ static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum,
 	trace_dwc3_prepare_trb(dep, trb);
 }
 
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
-		u32 len, u32 type, bool chain)
+static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum)
 {
 	struct dwc3_gadget_ep_cmd_params params;
 	struct dwc3_ep			*dep;
@@ -98,8 +97,6 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
 		return 0;
 	}
 
-	dwc3_ep0_prepare_one_trb(dwc, epnum, buf_dma, len, type, chain);
-
 	memset(&params, 0, sizeof(params));
 	params.param0 = upper_32_bits(dwc->ep0_trb_addr);
 	params.param1 = lower_32_bits(dwc->ep0_trb_addr);
@@ -314,8 +311,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
 {
 	int				ret;
 
-	ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
+	dwc3_ep0_prepare_one_trb(dwc, 0, dwc->ctrl_req_addr, 8,
 			DWC3_TRBCTL_CONTROL_SETUP, false);
+	ret = dwc3_ep0_start_trans(dwc, 0);
 	WARN_ON(ret < 0);
 }
 
@@ -886,9 +884,9 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
 			dwc->ep0_next_event = DWC3_EP0_COMPLETE;
 
-			ret = dwc3_ep0_start_trans(dwc, epnum,
-					dwc->ctrl_req_addr, 0,
-					DWC3_TRBCTL_CONTROL_DATA, false);
+			dwc3_ep0_prepare_one_trb(dwc, epnum, dwc->ctrl_req_addr,
+					0, DWC3_TRBCTL_CONTROL_DATA, false);
+			ret = dwc3_ep0_start_trans(dwc, epnum);
 			WARN_ON(ret < 0);
 		}
 	}
@@ -972,9 +970,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 	req->direction = !!dep->number;
 
 	if (req->request.length == 0) {
-		ret = dwc3_ep0_start_trans(dwc, dep->number,
+		dwc3_ep0_prepare_one_trb(dwc, dep->number,
 				dwc->ctrl_req_addr, 0,
 				DWC3_TRBCTL_CONTROL_DATA, false);
+		ret = dwc3_ep0_start_trans(dwc, dep->number);
 	} else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
 			&& (dep->number == 0)) {
 		u32	transfer_size = 0;
@@ -992,7 +991,7 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 		if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
 			transfer_size = ALIGN(req->request.length - maxpacket,
 					      maxpacket);
-			ret = dwc3_ep0_start_trans(dwc, dep->number,
+			dwc3_ep0_prepare_one_trb(dwc, dep->number,
 						   req->request.dma,
 						   transfer_size,
 						   DWC3_TRBCTL_CONTROL_DATA,
@@ -1004,9 +1003,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 
 		dwc->ep0_bounced = true;
 
-		ret = dwc3_ep0_start_trans(dwc, dep->number,
+		dwc3_ep0_prepare_one_trb(dwc, dep->number,
 				dwc->ep0_bounce_addr, transfer_size,
 				DWC3_TRBCTL_CONTROL_DATA, false);
+		ret = dwc3_ep0_start_trans(dwc, dep->number);
 	} else {
 		ret = usb_gadget_map_request(&dwc->gadget, &req->request,
 				dep->number);
@@ -1015,9 +1015,10 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
 			return;
 		}
 
-		ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
+		dwc3_ep0_prepare_one_trb(dwc, dep->number, req->request.dma,
 				req->request.length, DWC3_TRBCTL_CONTROL_DATA,
 				false);
+		ret = dwc3_ep0_start_trans(dwc, dep->number);
 	}
 
 	WARN_ON(ret < 0);
@@ -1031,8 +1032,9 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
 	type = dwc->three_stage_setup ? DWC3_TRBCTL_CONTROL_STATUS3
 		: DWC3_TRBCTL_CONTROL_STATUS2;
 
-	return dwc3_ep0_start_trans(dwc, dep->number,
+	dwc3_ep0_prepare_one_trb(dwc, dep->number,
 			dwc->ctrl_req_addr, 0, type, false);
+	return dwc3_ep0_start_trans(dwc, dep->number);
 }
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
-- 
2.11.0


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

* [BACKPORT PATCH 3/3] usb: dwc3: gadget: always unmap EP0 requests
  2017-01-09 11:03 [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Felipe Balbi
  2017-01-09 11:03 ` [BACKPORT PATCH 2/3] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() Felipe Balbi
@ 2017-01-09 11:03 ` Felipe Balbi
  2017-01-09 11:23 ` [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Greg Kroah-Hartman
  2 siblings, 0 replies; 5+ messages in thread
From: Felipe Balbi @ 2017-01-09 11:03 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: stable, Felipe Balbi

commit d62145929992f331fdde924d5963ab49588ccc7d upstream.

commit 0416e494ce7d ("usb: dwc3: ep0: correct cache
sync issue in case of ep0_bounced") introduced a bug
where we would leak DMA resources which would cause
us to starve the system of them resulting in failing
DMA transfers.

Fix the bug by making sure that we always unmap EP0
requests since those are *always* mapped.

Fixes: 0416e494ce7d ("usb: dwc3: ep0: correct cache
	sync issue in case of ep0_bounced")
Cc: <stable@vger.kernel.org>
Tested-by: Tomasz Medrek <tomaszx.medrek@intel.com>
Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
---
 drivers/usb/dwc3/gadget.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index b3687e223e00..9470bf6394cb 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -182,11 +182,11 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req,
 	if (req->request.status == -EINPROGRESS)
 		req->request.status = status;
 
-	if (dwc->ep0_bounced && dep->number == 0)
+	if (dwc->ep0_bounced && dep->number <= 1)
 		dwc->ep0_bounced = false;
-	else
-		usb_gadget_unmap_request(&dwc->gadget, &req->request,
-				req->direction);
+
+	usb_gadget_unmap_request(&dwc->gadget, &req->request,
+			req->direction);
 
 	trace_dwc3_gadget_giveback(req);
 
-- 
2.11.0


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

* Re: [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb()
  2017-01-09 11:23 ` [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Greg Kroah-Hartman
@ 2017-01-09 11:22   ` Felipe Balbi
  0 siblings, 0 replies; 5+ messages in thread
From: Felipe Balbi @ 2017-01-09 11:22 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: stable

[-- Attachment #1: Type: text/plain, Size: 1021 bytes --]


Hi,

Greg Kroah-Hartman <gregkh@linuxfoundation.org> writes:
> On Mon, Jan 09, 2017 at 01:03:31PM +0200, Felipe Balbi wrote:
>> commit 7931ec86c1b738e4e90e58c6d95e5f720d45ee56 upstream.
>> 
>> For now this is just a cleanup patch, no functional
>> changes. We will be using the new function to fix a
>> bug introduced long ago by commit 0416e494ce7d
>> ("usb: dwc3: ep0: correct cache sync issue in case
>> of ep0_bounced") and further worsened by commit
>> c0bd5456a470 ("usb: dwc3: ep0: handle non maxpacket
>> aligned transfers > 512")
>> 
>> Cc: <stable@vger.kernel.org>
>> Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com>
>> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
>> ---
>>  drivers/usb/dwc3/ep0.c | 30 ++++++++++++++++++------------
>>  1 file changed, 18 insertions(+), 12 deletions(-)
>
> Thanks for these three patches, I got them to work on 4.4 as well :)

cool :-) I was about to backport them to v4.4. Glad I don't have to do
it :-)

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

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

* Re: [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb()
  2017-01-09 11:03 [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Felipe Balbi
  2017-01-09 11:03 ` [BACKPORT PATCH 2/3] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() Felipe Balbi
  2017-01-09 11:03 ` [BACKPORT PATCH 3/3] usb: dwc3: gadget: always unmap EP0 requests Felipe Balbi
@ 2017-01-09 11:23 ` Greg Kroah-Hartman
  2017-01-09 11:22   ` Felipe Balbi
  2 siblings, 1 reply; 5+ messages in thread
From: Greg Kroah-Hartman @ 2017-01-09 11:23 UTC (permalink / raw)
  To: Felipe Balbi; +Cc: stable

On Mon, Jan 09, 2017 at 01:03:31PM +0200, Felipe Balbi wrote:
> commit 7931ec86c1b738e4e90e58c6d95e5f720d45ee56 upstream.
> 
> For now this is just a cleanup patch, no functional
> changes. We will be using the new function to fix a
> bug introduced long ago by commit 0416e494ce7d
> ("usb: dwc3: ep0: correct cache sync issue in case
> of ep0_bounced") and further worsened by commit
> c0bd5456a470 ("usb: dwc3: ep0: handle non maxpacket
> aligned transfers > 512")
> 
> Cc: <stable@vger.kernel.org>
> Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com>
> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
> ---
>  drivers/usb/dwc3/ep0.c | 30 ++++++++++++++++++------------
>  1 file changed, 18 insertions(+), 12 deletions(-)

Thanks for these three patches, I got them to work on 4.4 as well :)

greg k-h

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

end of thread, other threads:[~2017-01-09 11:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-09 11:03 [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Felipe Balbi
2017-01-09 11:03 ` [BACKPORT PATCH 2/3] usb: dwc3: ep0: explicitly call dwc3_ep0_prepare_one_trb() Felipe Balbi
2017-01-09 11:03 ` [BACKPORT PATCH 3/3] usb: dwc3: gadget: always unmap EP0 requests Felipe Balbi
2017-01-09 11:23 ` [BACKPORT PATCH 1/3] usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb() Greg Kroah-Hartman
2017-01-09 11:22   ` Felipe Balbi

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