diff mbox series

[v3] usb: warm-reset ports on hub resume, if requested

Message ID 1547658452-18036-1-git-send-email-glogow@fbihome.de (mailing list archive)
State Superseded
Headers show
Series [v3] usb: warm-reset ports on hub resume, if requested | expand

Commit Message

Jan-Marek Glogowski Jan. 16, 2019, 5:07 p.m. UTC
On plug-in of my USB-C device, its USB_SS_PORT_LS_SS_INACTIVE
link state bit is set. Greping all the kernel for this bit shows
that the port status requests a warm-reset this way.

This just happens, if its the only device on that hub and the
hub resumes, so we don't call port_event, which would otherwise
warm-reset ports. The device works ok without this patch, if
there is already any other device connected to the hub.

Signed-off-by: Jan-Marek Glogowski <glogow@fbihome.de>
---

v1: This always warm-resets the ports in hub_activate, independent of the
"enum hub_activation_type". Just had a single device to test.

v2: I had the idea about the working device, if there is already a device
connected to the hub and that a resume only on "type == HUB_RESUME" should
be sufficient. This still works for me, but I didn't follow all the
hub_activate callers everywhere and I'm definitly still missing a lot of
knowledge about USB stuff. There is also HUB_RESET_RESUME with a slightly
different code path. I don't know how to trigger this.

v3: code unchanged to v2, so I could abandon my explanation mail, which I
was typing when Gregs mail arrived.

---
 drivers/usb/core/hub.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

Comments

Jan-Marek Glogowski Jan. 18, 2019, 11:28 a.m. UTC | #1
Just adding some CC of commit signers from get_maintainer.pl

Am 16.01.19 um 18:07 schrieb Jan-Marek Glogowski:
> On plug-in of my USB-C device, its USB_SS_PORT_LS_SS_INACTIVE
> link state bit is set. Greping all the kernel for this bit shows
> that the port status requests a warm-reset this way.
> 
> This just happens, if its the only device on that hub and the 
> hub resumes, so we don't call port_event, which would otherwise
> warm-reset ports. The device works ok without this patch, if
> there is already any other device connected to the hub.
> 
> Signed-off-by: Jan-Marek Glogowski <glogow@fbihome.de>
> ---
> 
> v1: This always warm-resets the ports in hub_activate, independent of the
> "enum hub_activation_type". Just had a single device to test.
> 
> v2: I had the idea about the working device, if there is already a device
> connected to the hub and that a resume only on "type == HUB_RESUME" should
> be sufficient. This still works for me, but I didn't follow all the
> hub_activate callers everywhere and I'm definitly still missing a lot of
> knowledge about USB stuff. There is also HUB_RESET_RESUME with a slightly
> different code path. I don't know how to trigger this.
> 
> v3: code unchanged to v2, so I could abandon my explanation mail, which I
> was typing when Gregs mail arrived.
> 
> ---
>  drivers/usb/core/hub.c | 21 +++++++++++++++------
>  1 file changed, 15 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index 1d1e61e..e0cc740 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -108,6 +108,16 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
>  static void hub_release(struct kref *kref);
>  static int usb_reset_and_verify_device(struct usb_device *udev);
>  static int hub_port_disable(struct usb_hub *hub, int port1, int set_state);
> +static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1,
> +		u16 portstatus);
> +static int hub_port_reset(struct usb_hub *hub, int port1,
> +			struct usb_device *udev, unsigned int delay, bool warm);
> +
> +#define HUB_ROOT_RESET_TIME	60	/* times are in msec */
> +#define HUB_SHORT_RESET_TIME	10
> +#define HUB_BH_RESET_TIME	50
> +#define HUB_LONG_RESET_TIME	200
> +#define HUB_RESET_TIMEOUT	800
>  
>  static inline char *portspeed(struct usb_hub *hub, int portstatus)
>  {
> @@ -1122,6 +1132,11 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
>  						USB_SS_PORT_LS_POLLING))
>  			need_debounce_delay = true;
>  
> +		if (type == HUB_RESUME &&
> +		    hub_port_warm_reset_required(hub, port1, portstatus))
> +			hub_port_reset(hub, port1, udev,
> +					HUB_BH_RESET_TIME, true);
> +
>  		/* Clear status-change flags; we'll debounce later */
>  		if (portchange & USB_PORT_STAT_C_CONNECTION) {
>  			need_debounce_delay = true;
> @@ -2653,12 +2668,6 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
>  #define SET_CONFIG_TRIES	(2 * (use_both_schemes + 1))
>  #define USE_NEW_SCHEME(i, scheme)	((i) / 2 == (int)scheme)
>  
> -#define HUB_ROOT_RESET_TIME	60	/* times are in msec */
> -#define HUB_SHORT_RESET_TIME	10
> -#define HUB_BH_RESET_TIME	50
> -#define HUB_LONG_RESET_TIME	200
> -#define HUB_RESET_TIMEOUT	800
> -
>  /*
>   * "New scheme" enumeration causes an extra state transition to be
>   * exposed to an xhci host and causes USB3 devices to receive control
>
Mathias Nyman Jan. 25, 2019, 3:14 p.m. UTC | #2
On 18.01.2019 13:28, Jan-Marek Glogowski wrote:
> Just adding some CC of commit signers from get_maintainer.pl
> 
> Am 16.01.19 um 18:07 schrieb Jan-Marek Glogowski:
>> On plug-in of my USB-C device, its USB_SS_PORT_LS_SS_INACTIVE
>> link state bit is set. Greping all the kernel for this bit shows
>> that the port status requests a warm-reset this way.
>>
>> This just happens, if its the only device on that hub and the
>> hub resumes, so we don't call port_event, which would otherwise
>> warm-reset ports. The device works ok without this patch, if
>> there is already any other device connected to the hub.
>>

I've heard about issues with bad port redrivers/retimers causing similar issues
at resume.

One reason why port_event() isn't called is that hub thread failed to report
any activity for those ports.

At bus resume we start polling the roothub, which calls
xhci_hub_status_data(). This function will check if there are any interesting
changes going on, and mark these ports.
If no activity then it asks usb core to stop roothub polling.

xhci_hub_status_data() does not check for USB_PORT_LS_SS_INACTIVE, or compliance mode,
or USB3 polling state, which all would need more attention.

Could make sense to add those.
Does the below code help your situation?

diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index e2eece6..70f9b26 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -1458,7 +1458,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
         struct xhci_hcd *xhci = hcd_to_xhci(hcd);
         int max_ports;
         struct xhci_bus_state *bus_state;
-       bool reset_change = false;
+       bool poll_roothub = false;
         struct xhci_hub *rhub;
         struct xhci_port **ports;
  
@@ -1491,16 +1491,23 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
                 trace_xhci_hub_status_data(i, temp);
  
                 if ((temp & mask) != 0 ||
-                       (bus_state->port_c_suspend & 1 << i) ||
-                       (bus_state->resume_done[i] && time_after_eq(
+                   (bus_state->port_c_suspend & 1 << i) ||
+                   (temp & PORT_PLS_MASK) == XDEV_COMP_MODE ||
+                   (temp & PORT_PLS_MASK) == XDEV_INACTIVE ||
+                   (bus_state->resume_done[i] && time_after_eq(
                             jiffies, bus_state->resume_done[i]))) {
                         buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
                         status = 1;
                 }
-               if ((temp & PORT_RC))
-                       reset_change = true;
+               /*
+                * don't stop roothub polling if port is in polling state as it
+                * can end up in compliance mode without issuing any event
+                */
+               if ((temp & PORT_RC) ||
+                   (temp & PORT_PLS_MASK) == XDEV_POLLING)
+                       poll_roothub = true;
         }
-       if (!status && !reset_change) {
+       if (!status && !poll_roothub) {
                 xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
                 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
         }

-Mathias
Jan-Marek Glogowski Jan. 25, 2019, 4:21 p.m. UTC | #3
Am 25.01.19 um 16:14 schrieb Mathias Nyman:
> On 18.01.2019 13:28, Jan-Marek Glogowski wrote:
>> Just adding some CC of commit signers from get_maintainer.pl
>>
>> Am 16.01.19 um 18:07 schrieb Jan-Marek Glogowski:
>>> On plug-in of my USB-C device, its USB_SS_PORT_LS_SS_INACTIVE
>>> link state bit is set. Greping all the kernel for this bit shows
>>> that the port status requests a warm-reset this way.
>>>
>>> This just happens, if its the only device on that hub and the
>>> hub resumes, so we don't call port_event, which would otherwise
>>> warm-reset ports. The device works ok without this patch, if
>>> there is already any other device connected to the hub.
>>>
> 
> I've heard about issues with bad port redrivers/retimers causing similar issues
> at resume.
> 
> One reason why port_event() isn't called is that hub thread failed to report
> any activity for those ports.
> 
> At bus resume we start polling the roothub, which calls
> xhci_hub_status_data(). This function will check if there are any interesting
> changes going on, and mark these ports.
> If no activity then it asks usb core to stop roothub polling.
> 
> xhci_hub_status_data() does not check for USB_PORT_LS_SS_INACTIVE, or compliance mode,
> or USB3 polling state, which all would need more attention.
> 
> Could make sense to add those.
> Does the below code help your situation?
> 
> diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
> index e2eece6..70f9b26 100644
> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -1458,7 +1458,7 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
>         struct xhci_hcd *xhci = hcd_to_xhci(hcd);
>         int max_ports;
>         struct xhci_bus_state *bus_state;
> -       bool reset_change = false;
> +       bool poll_roothub = false;
>         struct xhci_hub *rhub;
>         struct xhci_port **ports;
>  
> @@ -1491,16 +1491,23 @@ int xhci_hub_status_data(struct usb_hcd *hcd, char *buf)
>                 trace_xhci_hub_status_data(i, temp);
>  
>                 if ((temp & mask) != 0 ||
> -                       (bus_state->port_c_suspend & 1 << i) ||
> -                       (bus_state->resume_done[i] && time_after_eq(
> +                   (bus_state->port_c_suspend & 1 << i) ||
> +                   (temp & PORT_PLS_MASK) == XDEV_COMP_MODE ||
> +                   (temp & PORT_PLS_MASK) == XDEV_INACTIVE ||
> +                   (bus_state->resume_done[i] && time_after_eq(
>                             jiffies, bus_state->resume_done[i]))) {
>                         buf[(i + 1) / 8] |= 1 << (i + 1) % 8;
>                         status = 1;
>                 }
> -               if ((temp & PORT_RC))
> -                       reset_change = true;
> +               /*
> +                * don't stop roothub polling if port is in polling state as it
> +                * can end up in compliance mode without issuing any event
> +                */
> +               if ((temp & PORT_RC) ||
> +                   (temp & PORT_PLS_MASK) == XDEV_POLLING)
> +                       poll_roothub = true;
>         }
> -       if (!status && !reset_change) {
> +       if (!status && !poll_roothub) {
>                 xhci_dbg(xhci, "%s: stopping port polling.\n", __func__);
>                 clear_bit(HCD_FLAG_POLL_RH, &hcd->flags);
>         }
> 

No changes for me with this patch. This is still from 5.0rc2.

>>>> Test-Script (./r)
#!/bin/sh

set -e

LSMOD="$(lsmod)"

rm_mod()
{
	if echo "$LSMOD" | grep -q "$1"; then
		sudo rmmod "$1"
	fi
}

rm_mod uas
rm_mod usb_storage
rm_mod xhci_pci
rm_mod xhci_hcd
rm_mod usbcore

if [ "$#" -eq 1 ]; then
	sudo dmesg -C
	sudo insmod core/usbcore.ko dyndbg=+mfp
	sudo insmod xhci-hcd.ko dyndbg=+mfp
	sudo insmod xhci-pci.ko dyndbg=+mfp
fi
<<<<

Run "./r 1"
[ 2311.984239] ACPI: bus type USB registered
[ 2311.984255] usbcore: registered new interface driver usbfs
[ 2311.984260] usbcore: registered new interface driver hub
[ 2311.984277] usbcore: registered new device driver usb
[ 2312.006999] xhci_hcd 0000:00:14.0: xHCI Host Controller
[ 2312.007003] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1
[ 2312.007016] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Halt the HC
[ 2312.007020] xhci_hcd:xhci_gen_setup: xhci_hcd 0000:00:14.0: Resetting HCD
[ 2312.007021] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Reset the HC
[ 2312.008020] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Wait for controller to be ready for doorbell rings
[ 2312.008021] xhci_hcd:xhci_gen_setup: xhci_hcd 0000:00:14.0: Reset complete
[ 2312.008023] xhci_hcd:xhci_gen_setup: xhci_hcd 0000:00:14.0: Enabling 64-bit DMA addresses.
[ 2312.008023] xhci_hcd:xhci_gen_setup: xhci_hcd 0000:00:14.0: Calling HCD init
[ 2312.008024] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: xhci_init
[ 2312.008026] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: xHCI doesn't need link TRB QUIRK
[ 2312.008028] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Supported page size register = 0x1
[ 2312.008029] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Supported page size of 4K
[ 2312.008030] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: HCD page size set to 4K
[ 2312.008032] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // xHC can handle at most 64 device slots.
[ 2312.008033] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Setting Max device slots reg = 0x40.
[ 2312.008036] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Device context base array address = 0x44f2c9000 (DMA), 000000000d5687b1 (virt)
[ 2312.008038] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Allocated command ring at 0000000004285dce
[ 2312.008039] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: First segment DMA is 0x44ebd4000
[ 2312.008041] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Setting command ring address to 0x000000044ebd4001
[ 2312.008044] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Doorbell array is located at offset 0x3000 from cap regs base addr
[ 2312.008045] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Allocating event ring
[ 2312.008047] xhci_hcd:xhci_check_trb_in_td_math: xhci_hcd 0000:00:14.0: TRB math tests passed.
[ 2312.008049] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Write ERST size = 1 to ir_set 0 (some bits preserved)
[ 2312.008050] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Set ERST entries to point to event ring.
[ 2312.008051] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Set ERST base address for ir_set 0 = 0x45324d000
[ 2312.008055] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Write event ring dequeue pointer, preserving EHB bit
[ 2312.008056] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Wrote ERST address to ir_set 0.
[ 2312.008057] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Allocating 34 scratchpad buffers
[ 2312.008084] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Ext Cap 0000000059b07030, port offset = 1, count = 16, revision = 0x2
[ 2312.008086] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:1 PSIE:2 PLT:0 PFD:0 LP:0 PSIM:12
[ 2312.008088] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:2 PSIE:1 PLT:0 PFD:0 LP:0 PSIM:1500
[ 2312.008090] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:3 PSIE:2 PLT:0 PFD:0 LP:0 PSIM:480
[ 2312.008091] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: xHCI 1.0: support USB2 hardware lpm
[ 2312.008094] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Ext Cap 0000000061bddd60, port offset = 17, count = 6, revision = 0x3
[ 2312.008096] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:4 PSIE:3 PLT:0 PFD:1 LP:0 PSIM:5
[ 2312.008098] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:5 PSIE:3 PLT:0 PFD:1 LP:0 PSIM:10
[ 2312.008100] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:6 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:1248
[ 2312.008102] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:7 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:2496
[ 2312.008103] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:8 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:4992
[ 2312.008105] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:9 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:1457
[ 2312.008107] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:10 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:2915
[ 2312.008109] xhci_hcd:xhci_add_in_port: xhci_hcd 0000:00:14.0: PSIV:11 PSIE:2 PLT:0 PFD:1 LP:0 PSIM:5830
[ 2312.008110] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Found 16 USB 2.0 ports and 6 USB 3.0 ports.
[ 2312.008112] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Finished xhci_init
[ 2312.008113] xhci_hcd:xhci_gen_setup: xhci_hcd 0000:00:14.0: Called HCD init
[ 2312.008114] xhci_hcd 0000:00:14.0: hcc params 0x20007fc1 hci version 0x110 quirks 0x0000000000009810
[ 2312.008115] xhci_pci:xhci_pci_setup: xhci_hcd 0000:00:14.0: Got SBRN 49
[ 2312.008118] xhci_hcd 0000:00:14.0: cache line size of 64 is not supported
[ 2312.008119] xhci_pci:xhci_pci_reinit: xhci_hcd 0000:00:14.0: Finished xhci_pci_reinit
[ 2312.008120] usbcore:usb_add_hcd: xhci_hcd 0000:00:14.0: supports USB remote wakeup
[ 2312.008121] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: xhci_run
[ 2312.008123] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Failed to enable MSI-X
[ 2312.008165] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: ERST deq = 64'h453d7b000
[ 2312.008166] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Set the interrupt modulation register
[ 2312.008169] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Enable interrupts, cmd = 0x4.
[ 2312.008171] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Enabling event ring interrupter 00000000e794492e by writing 0x2 to irq_pending
[ 2312.008172] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Finished xhci_run for USB2 roothub
[ 2312.008267] usbcore:usb_get_langid: usb usb1: default language 0x0409
[ 2312.008273] usbcore:usb_new_device: usb usb1: udev 1, busnum 1, minor = 0
[ 2312.008275] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.00
[ 2312.008276] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2312.008277] usb usb1: Product: xHCI Host Controller
[ 2312.008277] usb usb1: Manufacturer: Linux 5.0.0-rc2+ xhci-hcd
[ 2312.008278] usb usb1: SerialNumber: 0000:00:14.0
[ 2312.008336] usbcore:usb_probe_device: usb usb1: usb_probe_device
[ 2312.008337] usbcore:usb_choose_configuration: usb usb1: configuration #1 chosen from 1 choice
[ 2312.008339] xhci_hcd:xhci_check_args: xHCI xhci_add_endpoint called for root hub
[ 2312.008340] xhci_hcd:xhci_check_args: xHCI xhci_check_bandwidth called for root hub
[ 2312.008345] usbcore:usb_set_configuration: usb usb1: adding 1-0:1.0 (config #1, interface 0)
[ 2312.008359] usbcore:usb_probe_interface: hub 1-0:1.0: usb_probe_interface
[ 2312.008360] usbcore:usb_probe_interface: hub 1-0:1.0: usb_probe_interface - got id
[ 2312.008361] hub 1-0:1.0: USB hub found
[ 2312.008377] hub 1-0:1.0: 16 ports detected
[ 2312.008378] usbcore:hub_configure: hub 1-0:1.0: standalone hub
[ 2312.008379] usbcore:hub_configure: hub 1-0:1.0: no power switching (usb 1.0)
[ 2312.008380] usbcore:hub_configure: hub 1-0:1.0: individual port over-current protection
[ 2312.008381] usbcore:hub_configure: hub 1-0:1.0: Single TT
[ 2312.008382] usbcore:hub_configure: hub 1-0:1.0: TT requires at most 8 FS bit times (666 ns)
[ 2312.008383] usbcore:hub_configure: hub 1-0:1.0: power on to power good time: 20ms
[ 2312.008387] usbcore:hub_configure: hub 1-0:1.0: local power source is good
[ 2312.014022] usbcore:hub_power_on: hub 1-0:1.0: trying to enable port power on non-switchable hub
[ 2312.014038] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 0 status  = 0x2a0
[ 2312.014045] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 1 status  = 0x2a0
[ 2312.014050] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 2 status  = 0x2a0
[ 2312.014056] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 3 status  = 0x2a0
[ 2312.014061] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 4 status  = 0x2a0
[ 2312.014066] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 5 status  = 0x2a0
[ 2312.014071] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 6 status  = 0x2a0
[ 2312.014076] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 7 status  = 0x2a0
[ 2312.014081] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 8 status  = 0x2a0
[ 2312.014086] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 9 status  = 0x2a0
[ 2312.014092] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 10 status  = 0x2a0
[ 2312.014097] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 11 status  = 0x2a0
[ 2312.014102] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 12 status  = 0x2a0
[ 2312.014107] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 13 status  = 0x2a0
[ 2312.014112] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 14 status  = 0x2a0
[ 2312.014117] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 15 status  = 0x2a0
[ 2312.014203] xhci_hcd 0000:00:14.0: xHCI Host Controller
[ 2312.014206] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 2
[ 2312.014208] xhci_hcd 0000:00:14.0: Host supports USB 3.1 Enhanced SuperSpeed
[ 2312.014209] usbcore:usb_add_hcd: xhci_hcd 0000:00:14.0: supports USB remote wakeup
[ 2312.014214] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: // Turn on HC, cmd = 0x5.
[ 2312.014216] xhci_hcd:xhci_dbg_trace: xhci_hcd 0000:00:14.0: Finished xhci_run for USB3 roothub
[ 2312.014231] usbcore:usb_parse_endpoint: usb usb2: skipped 1 descriptor after endpoint
[ 2312.014234] usbcore:usb_get_langid: usb usb2: default language 0x0409
[ 2312.014240] usbcore:usb_new_device: usb usb2: udev 1, busnum 2, minor = 128
[ 2312.014242] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 5.00
[ 2312.014243] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2312.014244] usb usb2: Product: xHCI Host Controller
[ 2312.014245] usb usb2: Manufacturer: Linux 5.0.0-rc2+ xhci-hcd
[ 2312.014246] usb usb2: SerialNumber: 0000:00:14.0
[ 2312.014298] usbcore:usb_probe_device: usb usb2: usb_probe_device
[ 2312.014300] usbcore:usb_choose_configuration: usb usb2: configuration #1 chosen from 1 choice
[ 2312.014302] xhci_hcd:xhci_check_args: xHCI xhci_add_endpoint called for root hub
[ 2312.014303] xhci_hcd:xhci_check_args: xHCI xhci_check_bandwidth called for root hub
[ 2312.014309] usbcore:usb_set_configuration: usb usb2: adding 2-0:1.0 (config #1, interface 0)
[ 2312.014323] usbcore:usb_probe_interface: hub 2-0:1.0: usb_probe_interface
[ 2312.014324] usbcore:usb_probe_interface: hub 2-0:1.0: usb_probe_interface - got id
[ 2312.014325] hub 2-0:1.0: USB hub found
[ 2312.014337] hub 2-0:1.0: 6 ports detected
[ 2312.014338] usbcore:hub_configure: hub 2-0:1.0: standalone hub
[ 2312.014339] usbcore:hub_configure: hub 2-0:1.0: no power switching (usb 1.0)
[ 2312.014340] usbcore:hub_configure: hub 2-0:1.0: individual port over-current protection
[ 2312.014341] usbcore:hub_configure: hub 2-0:1.0: TT requires at most 8 FS bit times (666 ns)
[ 2312.014342] usbcore:hub_configure: hub 2-0:1.0: power on to power good time: 20ms
[ 2312.014346] usbcore:hub_configure: hub 2-0:1.0: local power source is good
[ 2312.014433] usbcore:link_peers_report: usb usb2-port1: peered to usb1-port1
[ 2312.014515] usbcore:link_peers_report: usb usb2-port2: peered to usb1-port6
[ 2312.014765] usbcore:link_peers_report: usb usb2-port3: peered to usb1-port3
[ 2312.015100] usbcore:link_peers: usb: failed to peer usb2-port4 and usb1-port1 by location (usb2-port4:none) (usb1-port1:usb2-port1)
[ 2312.015102] usbcore:link_peers_report: usb usb2-port4: failed to peer to usb1-port1 (-16)
[ 2312.015102] usb: port power management may be unreliable
[ 2312.015258] usbcore:link_peers_report: usb usb2-port5: peered to usb1-port5
[ 2312.015403] usbcore:link_peers: usb: failed to peer usb2-port6 and usb1-port3 by location (usb2-port6:none) (usb1-port3:usb2-port3)
[ 2312.015404] usbcore:link_peers_report: usb usb2-port6: failed to peer to usb1-port3 (-16)
[ 2312.015408] usbcore:hub_power_on: hub 2-0:1.0: trying to enable port power on non-switchable hub
[ 2312.015420] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 0 status  = 0x802a0
[ 2312.015431] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 1 status  = 0x802a0
[ 2312.015437] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 2 status  = 0x2a0
[ 2312.015443] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 3 status  = 0x802a0
[ 2312.015449] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 4 status  = 0x802a0
[ 2312.015455] xhci_hcd:xhci_set_port_power: xhci_hcd 0000:00:14.0: set port power, actual port 5 status  = 0x802a0
[ 2312.121249] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 0 status  = 0x802a0
[ 2312.121254] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2002a0
[ 2312.121270] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 0 status  = 0x2a0
[ 2312.121276] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121352] xhci_hcd:xhci_clear_port_change_bit: xhci_hcd 0000:00:14.0: clear port warm(BH) reset change, actual port 0 status  = 0x2a0
[ 2312.121372] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 1 status  = 0x2a0
[ 2312.121377] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121441] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 1 status  = 0x802a0
[ 2312.121446] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2002a0
[ 2312.121463] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 2 status  = 0x2a0
[ 2312.121468] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121524] xhci_hcd:xhci_clear_port_change_bit: xhci_hcd 0000:00:14.0: clear port warm(BH) reset change, actual port 1 status  = 0x2a0
[ 2312.121546] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 3 status  = 0x2a0
[ 2312.121551] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121611] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 2 status  = 0x2a0
[ 2312.121615] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2312.121632] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 4 status  = 0x2a0
[ 2312.121637] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121692] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 3 status  = 0x802a0
[ 2312.121697] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2002a0
[ 2312.121719] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 5 status  = 0x2a0
[ 2312.121724] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121785] xhci_hcd:xhci_clear_port_change_bit: xhci_hcd 0000:00:14.0: clear port warm(BH) reset change, actual port 3 status  = 0x2a0
[ 2312.121804] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 6 status  = 0x2a0
[ 2312.121809] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121862] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 4 status  = 0x802a0
[ 2312.121867] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2002a0
[ 2312.121889] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 7 status  = 0x2a0
[ 2312.121894] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.121940] xhci_hcd:xhci_clear_port_change_bit: xhci_hcd 0000:00:14.0: clear port warm(BH) reset change, actual port 4 status  = 0x2a0
[ 2312.121972] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 8 status  = 0x2a0
[ 2312.121977] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122011] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 5 status  = 0x802a0
[ 2312.122016] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2002a0
[ 2312.122064] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 9 status  = 0x2a0
[ 2312.122069] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122090] xhci_hcd:xhci_clear_port_change_bit: xhci_hcd 0000:00:14.0: clear port warm(BH) reset change, actual port 5 status  = 0x2a0
[ 2312.122145] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 10 status  = 0x2a0
[ 2312.122150] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122230] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 11 status  = 0x2a0
[ 2312.122234] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122311] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 12 status  = 0x2a0
[ 2312.122317] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122351] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 13 status  = 0x2a0
[ 2312.122355] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122380] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 14 status  = 0x2a0
[ 2312.122384] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122407] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 15 status  = 0x2a0
[ 2312.122411] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x100
[ 2312.122438] usbcore:hub_event: hub 1-0:1.0: state 7 ports 16 chg 0000 evt 0000
[ 2312.122450] usbcore:hub_suspend: hub 1-0:1.0: hub_suspend
[ 2312.122465] usbcore:hcd_bus_suspend: usb usb1: bus auto-suspend, wakeup 1
[ 2312.122504] xhci_hcd:xhci_hub_status_data: xhci_hcd 0000:00:14.0: xhci_hub_status_data: stopping port polling.
[ 2312.225254] usbcore:hub_event: hub 2-0:1.0: state 7 ports 6 chg 0000 evt 0000
[ 2312.225284] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 0 status  = 0xe0002a0
[ 2312.225319] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 1 status  = 0xe0002a0
[ 2312.225339] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 2 status  = 0xe0002a0
[ 2312.225360] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 3 status  = 0xe0002a0
[ 2312.225378] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 4 status  = 0xe0002a0
[ 2312.225396] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 5 status  = 0xe0002a0
[ 2312.225408] usbcore:hub_suspend: hub 2-0:1.0: hub_suspend
[ 2312.225423] usbcore:hcd_bus_suspend: usb usb2: bus auto-suspend, wakeup 1
[ 2312.225447] xhci_hcd:xhci_hub_status_data: xhci_hcd 0000:00:14.0: xhci_hub_status_data: stopping port polling.

USB device is plugged here

[ 2316.733514] xhci_hcd:handle_port_status: xhci_hcd 0000:00:14.0: Port Status Change Event for port 19
[ 2316.733525] xhci_hcd:handle_port_status: xhci_hcd 0000:00:14.0: resume root hub
[ 2316.733540] xhci_hcd:handle_port_status: xhci_hcd 0000:00:14.0: handle_port_status: starting port polling.
[ 2316.733604] usbcore:usb_remote_wakeup: usb usb2: usb wakeup-resume
[ 2316.733613] usbcore:hcd_bus_resume: usb usb2: usb auto-resume
[ 2316.733634] usbcore:hub_resume: hub 2-0:1.0: hub_resume
[ 2316.733651] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 0 status  = 0x2a0
[ 2316.733656] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.733686] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 1 status  = 0x2a0
[ 2316.733690] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.733705] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 2 status  = 0x4002c0
[ 2316.733710] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x4002c0
[ 2316.733728] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 3 status  = 0x2a0
[ 2316.733732] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.733747] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 4 status  = 0x2a0
[ 2316.733751] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.733768] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 5 status  = 0x2a0
[ 2316.733772] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.733796] usbcore:hub_event: hub 2-0:1.0: state 7 ports 6 chg 0000 evt 0000
[ 2316.733812] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 0 status  = 0xe0002a0
[ 2316.733835] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 1 status  = 0xe0002a0
[ 2316.733850] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 2 status  = 0xe4002c0
[ 2316.733867] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 3 status  = 0xe0002a0
[ 2316.733883] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 4 status  = 0xe0002a0
[ 2316.733899] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 5 status  = 0xe0002a0
[ 2316.733911] usbcore:hub_suspend: hub 2-0:1.0: hub_suspend
[ 2316.733926] usbcore:hcd_bus_suspend: usb usb2: bus auto-suspend, wakeup 1
[ 2316.733945] usbcore:hcd_bus_suspend: usb usb2: suspend raced with wakeup event
[ 2316.733950] usbcore:hcd_bus_resume: usb usb2: usb auto-resume
[ 2316.749178] usbcore:hub_resume: hub 2-0:1.0: hub_resume
[ 2316.749193] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 0 status  = 0x2a0
[ 2316.749197] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.749227] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 1 status  = 0x2a0
[ 2316.749231] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.749247] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 2 status  = 0x4002c0
[ 2316.749251] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x4002c0
[ 2316.749266] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 3 status  = 0x2a0
[ 2316.749270] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.749283] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 4 status  = 0x2a0
[ 2316.749288] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.749303] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: get port status, actual port 5 status  = 0x2a0
[ 2316.749307] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: Get port status returned 0x2a0
[ 2316.749328] usbcore:hub_event: hub 2-0:1.0: state 7 ports 6 chg 0000 evt 0000
[ 2316.749345] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 0 status  = 0xe0002a0
[ 2316.749361] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 1 status  = 0xe0002a0
[ 2316.749376] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 2 status  = 0xe4002c0
[ 2316.749391] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 3 status  = 0xe0002a0
[ 2316.749407] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 4 status  = 0xe0002a0
[ 2316.749422] xhci_hcd:xhci_hub_control: xhci_hcd 0000:00:14.0: set port remote wake mask, actual port 5 status  = 0xe0002a0
....
diff mbox series

Patch

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1d1e61e..e0cc740 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -108,6 +108,16 @@  EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
 static void hub_release(struct kref *kref);
 static int usb_reset_and_verify_device(struct usb_device *udev);
 static int hub_port_disable(struct usb_hub *hub, int port1, int set_state);
+static bool hub_port_warm_reset_required(struct usb_hub *hub, int port1,
+		u16 portstatus);
+static int hub_port_reset(struct usb_hub *hub, int port1,
+			struct usb_device *udev, unsigned int delay, bool warm);
+
+#define HUB_ROOT_RESET_TIME	60	/* times are in msec */
+#define HUB_SHORT_RESET_TIME	10
+#define HUB_BH_RESET_TIME	50
+#define HUB_LONG_RESET_TIME	200
+#define HUB_RESET_TIMEOUT	800
 
 static inline char *portspeed(struct usb_hub *hub, int portstatus)
 {
@@ -1122,6 +1132,11 @@  static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
 						USB_SS_PORT_LS_POLLING))
 			need_debounce_delay = true;
 
+		if (type == HUB_RESUME &&
+		    hub_port_warm_reset_required(hub, port1, portstatus))
+			hub_port_reset(hub, port1, udev,
+					HUB_BH_RESET_TIME, true);
+
 		/* Clear status-change flags; we'll debounce later */
 		if (portchange & USB_PORT_STAT_C_CONNECTION) {
 			need_debounce_delay = true;
@@ -2653,12 +2668,6 @@  static unsigned hub_is_wusb(struct usb_hub *hub)
 #define SET_CONFIG_TRIES	(2 * (use_both_schemes + 1))
 #define USE_NEW_SCHEME(i, scheme)	((i) / 2 == (int)scheme)
 
-#define HUB_ROOT_RESET_TIME	60	/* times are in msec */
-#define HUB_SHORT_RESET_TIME	10
-#define HUB_BH_RESET_TIME	50
-#define HUB_LONG_RESET_TIME	200
-#define HUB_RESET_TIMEOUT	800
-
 /*
  * "New scheme" enumeration causes an extra state transition to be
  * exposed to an xhci host and causes USB3 devices to receive control