[SRU] [B/C] [PATCH 0/1] Fix Terminus USB hub that may breaks connected USB devices after S3

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[SRU] [B/C] [PATCH 0/1] Fix Terminus USB hub that may breaks connected USB devices after S3

Kai-Heng Feng
BugLink: https://bugs.launchpad.net/bugs/1806850

[Impact]
USB devices connected to Terminus USB hub stop working after S3.

[Fix]
The Terminus hub seems to have a rather slow reset command, so we need
to wait for extra time before doing any further action.

[Test]
After applying the fix, USB devices connected to the HUB no longer stop
functioning after S3.

[Regression Potential]
Low. Although the fix affects all devices connect to the HUB, it has no
functional change other than imposes longer delay time.

Kai-Heng Feng (1):
  USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky
    hub

 Documentation/admin-guide/kernel-parameters.txt |  2 ++
 drivers/usb/core/hub.c                          | 14 +++++++++++---
 drivers/usb/core/quirks.c                       |  6 ++++++
 include/linux/usb/quirks.h                      |  3 +++
 4 files changed, 22 insertions(+), 3 deletions(-)

--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[Bionic] [PATCH] USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub

Kai-Heng Feng
BugLink: https://bugs.launchpad.net/bugs/1806850

Devices connected under Terminus Technology Inc. Hub (1a40:0101) may
fail to work after the system resumes from suspend:
[  206.063325] usb 3-2.4: reset full-speed USB device number 4 using xhci_hcd
[  206.143691] usb 3-2.4: device descriptor read/64, error -32
[  206.351671] usb 3-2.4: device descriptor read/64, error -32

Info for this hub:
T:  Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=480 MxCh= 4
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1a40 ProdID=0101 Rev=01.11
S:  Product=USB 2.0 Hub
C:  #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub

Some expirements indicate that the USB devices connected to the hub are
innocent, it's the hub itself is to blame. The hub needs extra delay
time after it resets its port.

Hence wait for extra delay, if the device is connected to this quirky
hub.

Signed-off-by: Kai-Heng Feng <[hidden email]>
Cc: stable <[hidden email]>
Acked-by: Alan Stern <[hidden email]>
Signed-off-by: Greg Kroah-Hartman <[hidden email]>
(backported from commit 781f0766cc41a9dd2e5d118ef4b1d5d89430257b)
Signed-off-by: Kai-Heng Feng <[hidden email]>
---
 Documentation/admin-guide/kernel-parameters.txt |  2 ++
 drivers/usb/core/hub.c                          | 10 +++++++++-
 drivers/usb/core/quirks.c                       |  6 ++++++
 include/linux/usb/quirks.h                      |  3 +++
 4 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index c163c3ce2902..551e635f1097 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4557,6 +4557,8 @@
  prevent spurious wakeup);
  n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a
  pause after every control message);
+ o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra
+ delay after resetting its port);
  Example: quirks=0781:5580:bk,0a5c:5834:gij
 
  usbhid.mousepoll=
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1bcd1755f97d..3b4afe3a4bc3 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2756,6 +2756,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
  int i, status;
  u16 portchange, portstatus;
  struct usb_port *port_dev = hub->ports[port1 - 1];
+ int reset_recovery_time;
 
  if (!hub_is_superspeed(hub->hdev)) {
  if (warm) {
@@ -2848,7 +2849,14 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 done:
  if (status == 0) {
  /* TRSTRCY = 10 ms; plus some extra */
- msleep(10 + 40);
+ reset_recovery_time = 10 + 40;
+
+ /* Hub needs extra delay after resetting its port. */
+ if (hub->hdev->quirks & USB_QUIRK_HUB_SLOW_RESET)
+ reset_recovery_time += 100;
+
+ msleep(reset_recovery_time);
+
  if (udev) {
  struct usb_hcd *hcd = bus_to_hcd(udev->bus);
 
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 7909262a715d..fe1f2d5db289 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -128,6 +128,9 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
  case 'n':
  flags |= USB_QUIRK_DELAY_CTRL_MSG;
  break;
+ case 'o':
+ flags |= USB_QUIRK_HUB_SLOW_RESET;
+ break;
  /* Ignore unrecognized flag characters */
  }
  }
@@ -376,6 +379,9 @@ static const struct usb_device_id usb_quirk_list[] = {
  { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
  USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+ /* Terminus Technology Inc. Hub */
+ { USB_DEVICE(0x1a40, 0x0101), .driver_info = USB_QUIRK_HUB_SLOW_RESET },
+
  /* Corsair K70 RGB */
  { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index b7a99ce56bc9..a1be64c9940f 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -66,4 +66,7 @@
 /* Device needs a pause after every control message. */
 #define USB_QUIRK_DELAY_CTRL_MSG BIT(13)
 
+/* Hub needs extra delay after resetting its port. */
+#define USB_QUIRK_HUB_SLOW_RESET BIT(14)
+
 #endif /* __LINUX_USB_QUIRKS_H */
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[Cosmic] [PATCH 1/1] USB: Wait for extra delay time after USB_PORT_FEAT_RESET for quirky hub

Kai-Heng Feng
In reply to this post by Kai-Heng Feng
BugLink: https://bugs.launchpad.net/bugs/1806850

Devices connected under Terminus Technology Inc. Hub (1a40:0101) may
fail to work after the system resumes from suspend:
[  206.063325] usb 3-2.4: reset full-speed USB device number 4 using xhci_hcd
[  206.143691] usb 3-2.4: device descriptor read/64, error -32
[  206.351671] usb 3-2.4: device descriptor read/64, error -32

Info for this hub:
T:  Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#=  2 Spd=480 MxCh= 4
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=1a40 ProdID=0101 Rev=01.11
S:  Product=USB 2.0 Hub
C:  #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=100mA
I:  If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub

Some expirements indicate that the USB devices connected to the hub are
innocent, it's the hub itself is to blame. The hub needs extra delay
time after it resets its port.

Hence wait for extra delay, if the device is connected to this quirky
hub.

Signed-off-by: Kai-Heng Feng <[hidden email]>
Cc: stable <[hidden email]>
Acked-by: Alan Stern <[hidden email]>
Signed-off-by: Greg Kroah-Hartman <[hidden email]>
(cherry picked from commit 781f0766cc41a9dd2e5d118ef4b1d5d89430257b)
Signed-off-by: Kai-Heng Feng <[hidden email]>
---
 Documentation/admin-guide/kernel-parameters.txt |  2 ++
 drivers/usb/core/hub.c                          | 14 +++++++++++---
 drivers/usb/core/quirks.c                       |  6 ++++++
 include/linux/usb/quirks.h                      |  3 +++
 4 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 9587a2f1137e..1d8aba0bed2c 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4614,6 +4614,8 @@
  prevent spurious wakeup);
  n = USB_QUIRK_DELAY_CTRL_MSG (Device needs a
  pause after every control message);
+ o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra
+ delay after resetting its port);
  Example: quirks=0781:5580:bk,0a5c:5834:gij
 
  usbhid.mousepoll=
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 1fb266809966..16a592c73876 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2791,6 +2791,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
  int i, status;
  u16 portchange, portstatus;
  struct usb_port *port_dev = hub->ports[port1 - 1];
+ int reset_recovery_time;
 
  if (!hub_is_superspeed(hub->hdev)) {
  if (warm) {
@@ -2882,11 +2883,18 @@ static int hub_port_reset(struct usb_hub *hub, int port1,
 
 done:
  if (status == 0) {
- /* TRSTRCY = 10 ms; plus some extra */
  if (port_dev->quirks & USB_PORT_QUIRK_FAST_ENUM)
  usleep_range(10000, 12000);
- else
- msleep(10 + 40);
+ else {
+ /* TRSTRCY = 10 ms; plus some extra */
+ reset_recovery_time = 10 + 40;
+
+ /* Hub needs extra delay after resetting its port. */
+ if (hub->hdev->quirks & USB_QUIRK_HUB_SLOW_RESET)
+ reset_recovery_time += 100;
+
+ msleep(reset_recovery_time);
+ }
 
  if (udev) {
  struct usb_hcd *hcd = bus_to_hcd(udev->bus);
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 178d6c6063c0..4d7d948eae63 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -128,6 +128,9 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
  case 'n':
  flags |= USB_QUIRK_DELAY_CTRL_MSG;
  break;
+ case 'o':
+ flags |= USB_QUIRK_HUB_SLOW_RESET;
+ break;
  /* Ignore unrecognized flag characters */
  }
  }
@@ -380,6 +383,9 @@ static const struct usb_device_id usb_quirk_list[] = {
  { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
  USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
 
+ /* Terminus Technology Inc. Hub */
+ { USB_DEVICE(0x1a40, 0x0101), .driver_info = USB_QUIRK_HUB_SLOW_RESET },
+
  /* Corsair K70 RGB */
  { USB_DEVICE(0x1b1c, 0x1b13), .driver_info = USB_QUIRK_DELAY_INIT },
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index b7a99ce56bc9..a1be64c9940f 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -66,4 +66,7 @@
 /* Device needs a pause after every control message. */
 #define USB_QUIRK_DELAY_CTRL_MSG BIT(13)
 
+/* Hub needs extra delay after resetting its port. */
+#define USB_QUIRK_HUB_SLOW_RESET BIT(14)
+
 #endif /* __LINUX_USB_QUIRKS_H */
--
2.17.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK/APPLIED[OEM-B]: [SRU] [B/C] [PATCH 0/1] Fix Terminus USB hub that may breaks connected USB devices after S3

AceLan Kao
In reply to this post by Kai-Heng Feng
Applied on Ubuntu-oem-4.15.0-1030.35

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team