From 01c10880d24291a96a4ab0da773e3c5ce4d12da8 Mon Sep 17 00:00:00 2001 From: Bo He Date: Mon, 14 Jan 2019 09:48:32 +0200 Subject: usb: dwc3: gadget: synchronize_irq dwc irq in suspend We see dwc3 endpoint stopped by unwanted irq during suspend resume test, which is caused dwc3 ep can't be started with error "No Resource". Here, add synchronize_irq before suspend to sync the pending IRQ handlers complete. Signed-off-by: Bo He Signed-off-by: Yu Wang Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 07bd31bb2f8a..851fd44d56ad 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -3379,6 +3379,8 @@ int dwc3_gadget_suspend(struct dwc3 *dwc) dwc3_disconnect_gadget(dwc); __dwc3_gadget_stop(dwc); + synchronize_irq(dwc->irq_gadget); + return 0; } -- cgit v1.2.3-58-ga151 From bd6742249b9ca918565e4e3abaa06665e587f4b5 Mon Sep 17 00:00:00 2001 From: Jack Pham Date: Thu, 10 Jan 2019 12:39:55 -0800 Subject: usb: dwc3: gadget: Clear req->needs_extra_trb flag on cleanup OUT endpoint requests may somtimes have this flag set when preparing to be submitted to HW indicating that there is an additional TRB chained to the request for alignment purposes. If that request is removed before the controller can execute the transfer (e.g. ep_dequeue/ep_disable), the request will not go through the dwc3_gadget_ep_cleanup_completed_request() handler and will not have its needs_extra_trb flag cleared when dwc3_gadget_giveback() is called. This same request could be later requeued for a new transfer that does not require an extra TRB and if it is successfully completed, the cleanup and TRB reclamation will incorrectly process the additional TRB which belongs to the next request, and incorrectly advances the TRB dequeue pointer, thereby messing up calculation of the next requeust's actual/remaining count when it completes. The right thing to do here is to ensure that the flag is cleared before it is given back to the function driver. A good place to do that is in dwc3_gadget_del_and_unmap_request(). Fixes: c6267a51639b ("usb: dwc3: gadget: align transfers to wMaxPacketSize") Cc: stable@vger.kernel.org Signed-off-by: Jack Pham Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 851fd44d56ad..6e2b6d6369aa 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -177,6 +177,7 @@ static void dwc3_gadget_del_and_unmap_request(struct dwc3_ep *dep, req->started = false; list_del(&req->list); req->remaining = 0; + req->needs_extra_trb = false; if (req->request.status == -EINPROGRESS) req->request.status = status; -- cgit v1.2.3-58-ga151 From 88b1bb1f3b88e0bf20b05d543a53a5b99bd7ceb6 Mon Sep 17 00:00:00 2001 From: Zeng Tao Date: Wed, 26 Dec 2018 19:22:00 +0800 Subject: usb: dwc3: gadget: Fix the uninitialized link_state when udc starts Currently the link_state is uninitialized and the default value is 0(U0) before the first time we start the udc, and after we start the udc then stop the udc, the link_state will be undefined. We may have the following warnings if we start the udc again with an undefined link_state: WARNING: CPU: 0 PID: 327 at drivers/usb/dwc3/gadget.c:294 dwc3_send_gadget_ep_cmd+0x304/0x308 dwc3 100e0000.hidwc3_0: wakeup failed --> -22 [...] Call Trace: [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [] (show_stack) from [] (dump_stack+0x84/0x98) [] (dump_stack) from [] (__warn+0xe8/0x100) [] (__warn) from [](warn_slowpath_fmt+0x38/0x48) [] (warn_slowpath_fmt) from [](dwc3_send_gadget_ep_cmd+0x304/0x308) [] (dwc3_send_gadget_ep_cmd) from [](dwc3_ep0_start_trans+0x48/0xf4) [] (dwc3_ep0_start_trans) from [](dwc3_ep0_out_start+0x64/0x80) [] (dwc3_ep0_out_start) from [](__dwc3_gadget_start+0x1e0/0x278) [] (__dwc3_gadget_start) from [](dwc3_gadget_start+0x88/0x10c) [] (dwc3_gadget_start) from [](udc_bind_to_driver+0x88/0xbc) [] (udc_bind_to_driver) from [](usb_gadget_probe_driver+0xf8/0x140) [] (usb_gadget_probe_driver) from [](gadget_dev_desc_UDC_store+0xac/0xc4 [libcomposite]) [] (gadget_dev_desc_UDC_store [libcomposite]) from[] (configfs_write_file+0xd4/0x160) [] (configfs_write_file) from [] (__vfs_write+0x1c/0x114) [] (__vfs_write) from [] (vfs_write+0xa4/0x168) [] (vfs_write) from [] (SyS_write+0x3c/0x90) [] (SyS_write) from [] (ret_fast_syscall+0x0/0x3c) Signed-off-by: Zeng Tao Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/usb/dwc3') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 6e2b6d6369aa..bed2ff42780b 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1985,6 +1985,7 @@ static int __dwc3_gadget_start(struct dwc3 *dwc) /* begin to receive SETUP packets */ dwc->ep0state = EP0_SETUP_PHASE; + dwc->link_state = DWC3_LINK_STATE_SS_DIS; dwc3_ep0_out_start(dwc); dwc3_gadget_enable_irq(dwc); -- cgit v1.2.3-58-ga151