]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
usb: dwc3: gadget: Submit endxfer command if delayed during disconnect
authorWesley Cheng <quic_wcheng@quicinc.com>
Thu, 1 Sep 2022 19:36:25 +0000 (12:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 23 Feb 2024 07:55:11 +0000 (08:55 +0100)
[ Upstream commit 8422b769fa46bd429dc0f324012629a4691f0dd9 ]

During a cable disconnect sequence, if ep0state is not in the SETUP phase,
then nothing will trigger any pending end transfer commands.  Force
stopping of any pending SETUP transaction, and move back to the SETUP
phase.

Reviewed-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com>
Link: https://lore.kernel.org/r/20220901193625.8727-6-quic_wcheng@quicinc.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 730e12fbec53 ("usb: dwc3: gadget: Handle EP0 request dequeuing properly")
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/usb/dwc3/gadget.c

index ba1b2e70b35197af25e5d0a83420dbb186f127c3..c61b6f49701ae306a79737fbd8af00d218e5fd4c 100644 (file)
@@ -3739,13 +3739,24 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
        reg &= ~DWC3_DCTL_INITU2ENA;
        dwc3_gadget_dctl_write_safe(dwc, reg);
 
+       dwc->connected = false;
+
        dwc3_disconnect_gadget(dwc);
 
        dwc->gadget->speed = USB_SPEED_UNKNOWN;
        dwc->setup_packet_pending = false;
        usb_gadget_set_state(dwc->gadget, USB_STATE_NOTATTACHED);
 
-       dwc->connected = false;
+       if (dwc->ep0state != EP0_SETUP_PHASE) {
+               unsigned int    dir;
+
+               dir = !!dwc->ep0_expect_in;
+               if (dwc->ep0state == EP0_DATA_PHASE)
+                       dwc3_ep0_end_control_data(dwc, dwc->eps[dir]);
+               else
+                       dwc3_ep0_end_control_data(dwc, dwc->eps[!dir]);
+               dwc3_ep0_stall_and_restart(dwc);
+       }
 }
 
 static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)