Skip to content

Commit

Permalink
usb: dwc2: hcd: Fix GetPortStatus & SetPortFeature
Browse files Browse the repository at this point in the history
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: #6247
Fixes: 7359d48 ("staging: HCD files for the DWC2 driver")
Signed-off-by: Stefan Wahren <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
lategoodbye authored and gregkh committed Dec 4, 2024
1 parent 336f72d commit a8d3e4a
Showing 1 changed file with 6 additions and 10 deletions.
16 changes: 6 additions & 10 deletions drivers/usb/dwc2/hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit a8d3e4a

Please sign in to comment.