--- /dev/null
+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
+@@ -4633,7 +4633,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;
+@@ -4923,23 +4923,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);