2020-08-10 14:11:32

by Kai-Heng Feng

[permalink] [raw]
Subject: [PATCH] xhci: Do warm-reset when both CAS and XDEV_RESUME are set

Sometimes re-plugging a USB device during system sleep renders the device
useless:
[ 173.418345] xhci_hcd 0000:00:14.0: Get port status 2-4 read: 0x14203e2, return 0x10262
...
[ 176.496485] usb 2-4: Waited 2000ms for CONNECT
[ 176.496781] usb usb2-port4: status 0000.0262 after resume, -19
[ 176.497103] usb 2-4: can't resume, status -19
[ 176.497438] usb usb2-port4: logical disconnect

Because PLS equals to XDEV_RESUME, xHCI driver reports U3 to usbcore,
despite of CAS bit is flagged.

So proritize CAS over XDEV_RESUME to let usbcore handle warm-reset for
the port.

Signed-off-by: Kai-Heng Feng <[email protected]>
---
drivers/usb/host/xhci-hub.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index c3554e37e09f..4e14e164cb68 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -740,15 +740,6 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
{
u32 pls = status_reg & PORT_PLS_MASK;

- /* resume state is a xHCI internal state.
- * Do not report it to usb core, instead, pretend to be U3,
- * thus usb core knows it's not ready for transfer
- */
- if (pls == XDEV_RESUME) {
- *status |= USB_SS_PORT_LS_U3;
- return;
- }
-
/* When the CAS bit is set then warm reset
* should be performed on port
*/
@@ -770,6 +761,16 @@ static void xhci_hub_report_usb3_link_state(struct xhci_hcd *xhci,
*/
pls |= USB_PORT_STAT_CONNECTION;
} else {
+ /*
+ * Resume state is an xHCI internal state. Do not report it to
+ * usb core, instead, pretend to be U3, thus usb core knows
+ * it's not ready for transfer.
+ */
+ if (pls == XDEV_RESUME) {
+ *status |= USB_SS_PORT_LS_U3;
+ return;
+ }
+
/*
* If CAS bit isn't set but the Port is already at
* Compliance Mode, fake a connection so the USB core
--
2.17.1


2020-08-11 08:50:25

by Mathias Nyman

[permalink] [raw]
Subject: Re: [PATCH] xhci: Do warm-reset when both CAS and XDEV_RESUME are set

On 10.8.2020 17.07, Kai-Heng Feng wrote:
> Sometimes re-plugging a USB device during system sleep renders the device
> useless:
> [ 173.418345] xhci_hcd 0000:00:14.0: Get port status 2-4 read: 0x14203e2, return 0x10262
> ...
> [ 176.496485] usb 2-4: Waited 2000ms for CONNECT
> [ 176.496781] usb usb2-port4: status 0000.0262 after resume, -19
> [ 176.497103] usb 2-4: can't resume, status -19
> [ 176.497438] usb usb2-port4: logical disconnect
>
> Because PLS equals to XDEV_RESUME, xHCI driver reports U3 to usbcore,
> despite of CAS bit is flagged.
>
> So proritize CAS over XDEV_RESUME to let usbcore handle warm-reset for
> the port.
>
> Signed-off-by: Kai-Heng Feng <[email protected]>
> ---

Thanks, nice catch.
Adding to queue

-Mathias