[PATCH 3/3][SRU][OEM-5.10/U] UBUNTU: SAUCE: (no-up) USB: reset-resume the Realtek hub if suspend timeout

Krzysztof Kozlowski krzysztof.kozlowski at canonical.com
Mon May 17 12:41:34 UTC 2021


On 16/05/2021 14:14, chris.chiu at canonical.com wrote:
> From: Chris Chiu <chris.chiu at canonical.com>
> 
> BugLink: https://bugs.launchpad.net/bugs/1928242
> 
> In Dell WD19 dock, there're a super-speed hub and a high-speed hub.
> When the high-speed hub hit the timeout problem when suspending the
> port which has wakeup enabled descendants, the super-speed hub will
> also hit the timeout when there's super-speed device connecting to
> the exposed Type-A port for unknown reason. If the super speed device
> connects to Type-C port, there's no such problem.
> 
> The port status of the super-speed hub doesn't indicate it's suspended.
> However, if no ClearPortFeature invoked during resume for the port,
> the hub will then fail to activate and all devices connected to the
> super-speedhub will be lost.
> 
> This commit reset-resume the downstream hub of the superspeed hub
> only if suspend timeout happens even the port is not suspended.
> Since it only happens in particular circumstance, we do not like
> RESET_RESUME quirk to reset-resume all the time which lose the
> runtime pm capability. And it's unable to be upstream because no
> good explanation for why the Type-A port with a super-speed device
> connected cause the super-speed hub suspend timeout at the same
> time when high-speed hub timeout during suspend.
> 
> Signed-off-by: Chris Chiu <chris.chiu at canonical.com>
> ---
>  drivers/usb/core/hub.c | 7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index e739f7b5991a..740d84028757 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -3391,6 +3391,7 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
>  		if (status == -ETIMEDOUT) {
>  			int ret;
>  			u16 portstatus, portchange;
> +			u16 vid = le16_to_cpu(udev->descriptor.idVendor);
>  
>  			portstatus = portchange = 0;
>  			ret = hub_port_status(hub, port1, &portstatus,
> @@ -3403,6 +3404,12 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
>  				status = 0;
>  				goto suspend_done;
>  			}
> +
> +			// reset_resume the downstream Realtek hub
> +			if (vid == 0x0bda && usb_hub_to_struct_hub(udev)) {

This looks very hacky. I think an upstreamable solution would be better
than hard-coding Realtek VID in generic hub code..

Best regards,
Krzysztof



More information about the kernel-team mailing list