]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Sep 2023 14:59:00 +0000 (15:59 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 10 Sep 2023 14:59:00 +0000 (15:59 +0100)
added patches:
usb-core-fix-oversight-in-superspeed-initialization.patch

queue-6.1/series
queue-6.1/usb-core-fix-oversight-in-superspeed-initialization.patch [new file with mode: 0644]

index e5f1cd443ab9694c216c5b4ffa77b3ece6ec7427..8faaf9477af94af86bedd74411e012e45dadab56 100644 (file)
@@ -583,5 +583,6 @@ usb-typec-bus-verify-partner-exists-in-typec_altmode_attention.patch
 usb-core-unite-old-scheme-and-new-scheme-descriptor-reads.patch
 usb-core-change-usb_get_device_descriptor-api.patch
 usb-core-fix-race-by-not-overwriting-udev-descriptor-in-hub_port_init.patch
+usb-core-fix-oversight-in-superspeed-initialization.patch
 serial-sc16is7xx-remove-obsolete-out_thread-label.patch
 serial-sc16is7xx-fix-regression-with-gpio-configurat.patch
diff --git a/queue-6.1/usb-core-fix-oversight-in-superspeed-initialization.patch b/queue-6.1/usb-core-fix-oversight-in-superspeed-initialization.patch
new file mode 100644 (file)
index 0000000..66a6925
--- /dev/null
@@ -0,0 +1,100 @@
+From 59cf445754566984fd55af19ba7146c76e6627bc Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 11 Aug 2023 13:38:46 -0400
+Subject: USB: core: Fix oversight in SuperSpeed initialization
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 59cf445754566984fd55af19ba7146c76e6627bc upstream.
+
+Commit 85d07c556216 ("USB: core: Unite old scheme and new scheme
+descriptor reads") altered the way USB devices are enumerated
+following detection, and in the process it messed up the
+initialization of SuperSpeed (or faster) devices:
+
+[   31.650759] usb 2-1: new SuperSpeed Plus Gen 2x1 USB device number 2 using xhci_hcd
+[   31.663107] usb 2-1: device descriptor read/8, error -71
+[   31.952697] usb 2-1: new SuperSpeed Plus Gen 2x1 USB device number 3 using xhci_hcd
+[   31.965122] usb 2-1: device descriptor read/8, error -71
+[   32.080991] usb usb2-port1: attempt power cycle
+...
+
+The problem was caused by the commit forgetting that in SuperSpeed or
+faster devices, the device descriptor uses a logarithmic encoding of
+the bMaxPacketSize0 value.  (For some reason I thought the 255 case in
+the switch statement was meant for these devices, but it isn't -- it
+was meant for Wireless USB and is no longer needed.)
+
+We can fix the oversight by testing for buf->bMaxPacketSize0 = 9
+(meaning 512, the actual maxpacket size for ep0 on all SuperSpeed
+devices) and straightening out the logic that checks and adjusts our
+initial guesses of the maxpacket value.
+
+Reported-and-tested-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Closes: https://lore.kernel.org/linux-usb/20230810002257.nadxmfmrobkaxgnz@synopsys.com/
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Fixes: 85d07c556216 ("USB: core: Unite old scheme and new scheme descriptor reads")
+Link: https://lore.kernel.org/r/8809e6c5-59d5-4d2d-ac8f-6d106658ad73@rowland.harvard.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/core/hub.c |   36 ++++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -4700,7 +4700,7 @@ static int get_bMaxPacketSize0(struct us
+                               buf, size,
+                               initial_descriptor_timeout);
+               switch (buf->bMaxPacketSize0) {
+-              case 8: case 16: case 32: case 64: case 255:
++              case 8: case 16: case 32: case 64: case 9:
+                       if (buf->bDescriptorType == USB_DT_DEVICE) {
+                               rc = buf->bMaxPacketSize0;
+                               break;
+@@ -4994,23 +4994,35 @@ hub_port_init(struct usb_hub *hub, struc
+       if (retval)
+               goto fail;
+-      if (maxp0 == 0xff || udev->speed >= USB_SPEED_SUPER)
+-              i = 512;
+-      else
+-              i = maxp0;
+-      if (usb_endpoint_maxp(&udev->ep0.desc) != i) {
+-              if (udev->speed == USB_SPEED_LOW ||
+-                              !(i == 8 || i == 16 || i == 32 || i == 64)) {
+-                      dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", i);
+-                      retval = -EMSGSIZE;
+-                      goto fail;
+-              }
++      /*
++       * Check the ep0 maxpacket guess and correct it if necessary.
++       * maxp0 is the value stored in the device descriptor;
++       * i is the value it encodes (logarithmic for SuperSpeed or greater).
++       */
++      i = maxp0;
++      if (udev->speed >= USB_SPEED_SUPER) {
++              if (maxp0 <= 16)
++                      i = 1 << maxp0;
++              else
++                      i = 0;          /* Invalid */
++      }
++      if (usb_endpoint_maxp(&udev->ep0.desc) == i) {
++              ;       /* Initial ep0 maxpacket guess is right */
++      } else if ((udev->speed == USB_SPEED_FULL ||
++                              udev->speed == USB_SPEED_HIGH) &&
++                      (i == 8 || i == 16 || i == 32 || i == 64)) {
++              /* Initial guess is wrong; use the descriptor's value */
+               if (udev->speed == USB_SPEED_FULL)
+                       dev_dbg(&udev->dev, "ep0 maxpacket = %d\n", i);
+               else
+                       dev_warn(&udev->dev, "Using ep0 maxpacket: %d\n", i);
+               udev->ep0.desc.wMaxPacketSize = cpu_to_le16(i);
+               usb_ep0_reinit(udev);
++      } else {
++              /* Initial guess is wrong and descriptor's value is invalid */
++              dev_err(&udev->dev, "Invalid ep0 maxpacket: %d\n", maxp0);
++              retval = -EMSGSIZE;
++              goto fail;
+       }
+       descr = usb_get_device_descriptor(udev);