* [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(¶ms, 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, ¶ms);
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(¶ms, 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: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
* 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
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).