]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
authorStefan Wahren <wahrenst@gmx.net>
Mon, 2 Dec 2024 00:16:30 +0000 (01:16 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Dec 2024 15:30:05 +0000 (16:30 +0100)
On Rasperry Pis without onboard USB hub the power cycle during
power connect init only disable the port but never enabled it again:

  usb usb1-port1: attempt power cycle

The port relevant part in dwc2_hcd_hub_control() is skipped in case
port_connect_status = 0 under the assumption the core is or will be soon
in device mode. But this assumption is wrong, because after ClearPortFeature
USB_PORT_FEAT_POWER the port_connect_status will also be 0 and
SetPortFeature (incl. USB_PORT_FEAT_POWER) will be a no-op.

Fix the behavior of dwc2_hcd_hub_control() by replacing the
port_connect_status check with dwc2_is_device_mode().

Link: https://github.com/raspberrypi/linux/issues/6247
Fixes: 7359d482eb4d ("staging: HCD files for the DWC2 driver")
Signed-off-by: Stefan Wahren <wahrenst@gmx.net>
Link: https://lore.kernel.org/r/20241202001631.75473-3-wahrenst@gmx.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/dwc2/hcd.c

index 26a320c1979aa8cc3c0ae6e405a1c7294fc32cc6..fb4fbd8c43df6d65c221c8a4429839925fca44ef 100644 (file)
@@ -3546,11 +3546,9 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
                        port_status |= USB_PORT_STAT_C_OVERCURRENT << 16;
                }
 
-               if (!hsotg->flags.b.port_connect_status) {
+               if (dwc2_is_device_mode(hsotg)) {
                        /*
-                        * The port is disconnected, which means the core is
-                        * either in device mode or it soon will be. Just
-                        * return 0's for the remainder of the port status
+                        * Just return 0's for the remainder of the port status
                         * since the port register can't be read if the core
                         * is in device mode.
                         */
@@ -3620,13 +3618,11 @@ static int dwc2_hcd_hub_control(struct dwc2_hsotg *hsotg, u16 typereq,
                if (wvalue != USB_PORT_FEAT_TEST && (!windex || windex > 1))
                        goto error;
 
-               if (!hsotg->flags.b.port_connect_status) {
+               if (dwc2_is_device_mode(hsotg)) {
                        /*
-                        * The port is disconnected, which means the core is
-                        * either in device mode or it soon will be. Just
-                        * return without doing anything since the port
-                        * register can't be written if the core is in device
-                        * mode.
+                        * Just return 0's for the remainder of the port status
+                        * since the port register can't be read if the core
+                        * is in device mode.
                         */
                        break;
                }