]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
usb: dwc3: gadget: clear DWC3_EP_TRANSFER_STARTED on cmd complete
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 21 Jan 2019 10:58:27 +0000 (12:58 +0200)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Fri, 1 Feb 2019 06:30:44 +0000 (08:30 +0200)
We must wait until End Transfer completes in order to clear
DWC3_EP_TRANSFER_STARTED, otherwise we may confuse the driver.

This patch is in preparation to fix a rare race condition that happens
upon Disconnect Interrupt.

Tested-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/gadget.c

index 189605df6bd2a82945aebc6e634a4d1293a90bfa..f9b44302199a91debc5504b7e2fb55af57a5b3cf 100644 (file)
@@ -384,19 +384,9 @@ int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned cmd,
 
        trace_dwc3_gadget_ep_cmd(dep, cmd, params, cmd_status);
 
-       if (ret == 0) {
-               switch (DWC3_DEPCMD_CMD(cmd)) {
-               case DWC3_DEPCMD_STARTTRANSFER:
-                       dep->flags |= DWC3_EP_TRANSFER_STARTED;
-                       dwc3_gadget_ep_get_transfer_index(dep);
-                       break;
-               case DWC3_DEPCMD_ENDTRANSFER:
-                       dep->flags &= ~DWC3_EP_TRANSFER_STARTED;
-                       break;
-               default:
-                       /* nothing */
-                       break;
-               }
+       if (ret == 0 && DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_STARTTRANSFER) {
+               dep->flags |= DWC3_EP_TRANSFER_STARTED;
+               dwc3_gadget_ep_get_transfer_index(dep);
        }
 
        if (saved_config) {
@@ -2578,7 +2568,8 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc,
                cmd = DEPEVT_PARAMETER_CMD(event->parameters);
 
                if (cmd == DWC3_DEPCMD_ENDTRANSFER) {
-                       dep->flags &= ~DWC3_EP_END_TRANSFER_PENDING;
+                       dep->flags &= ~(DWC3_EP_END_TRANSFER_PENDING |
+                                       DWC3_EP_TRANSFER_STARTED);
                        dwc3_gadget_ep_cleanup_cancelled_requests(dep);
                }
                break;