From: Greg Kroah-Hartman Date: Sun, 10 Sep 2023 14:59:00 +0000 (+0100) Subject: 6.1-stable patches X-Git-Tag: v6.1.53~33 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f545e1c72d5d8472ebfcf99cfdb0e0b59d4aa7d2;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: usb-core-fix-oversight-in-superspeed-initialization.patch --- diff --git a/queue-6.1/series b/queue-6.1/series index e5f1cd443ab..8faaf9477af 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -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 index 00000000000..66a692577d5 --- /dev/null +++ b/queue-6.1/usb-core-fix-oversight-in-superspeed-initialization.patch @@ -0,0 +1,100 @@ +From 59cf445754566984fd55af19ba7146c76e6627bc Mon Sep 17 00:00:00 2001 +From: Alan Stern +Date: Fri, 11 Aug 2023 13:38:46 -0400 +Subject: USB: core: Fix oversight in SuperSpeed initialization + +From: Alan Stern + +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 +Closes: https://lore.kernel.org/linux-usb/20230810002257.nadxmfmrobkaxgnz@synopsys.com/ +Signed-off-by: Alan Stern +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 +--- + 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);