Skip to content

Commit

Permalink
Revert some USB patches in RPi kernel to check if they break UZB Z-Wa…
Browse files Browse the repository at this point in the history
…ve stick
  • Loading branch information
sairon committed Mar 4, 2024
1 parent 8debb61 commit 9bfadeb
Show file tree
Hide file tree
Showing 4 changed files with 792 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
From ae3f17d9c0a3ee88366e5c1a211bcd358ca2051f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Mon, 4 Mar 2024 13:52:34 +0100
Subject: [PATCH v2 2/5] Revert "USB: core: Fix oversight in SuperSpeed
initialization"

This reverts commit f705617bab4766567874715eeed1b39dacb58671.
---
drivers/usb/core/hub.c | 36 ++++++++++++------------------------
1 file changed, 12 insertions(+), 24 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 574b8104a8199..ed1807169b47e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4719,7 +4719,7 @@ static int get_bMaxPacketSize0(struct usb_device *udev,
buf, size,
initial_descriptor_timeout);
switch (buf->bMaxPacketSize0) {
- case 8: case 16: case 32: case 64: case 9:
+ case 8: case 16: case 32: case 64: case 255:
if (buf->bDescriptorType == USB_DT_DEVICE) {
rc = buf->bMaxPacketSize0;
break;
@@ -5013,35 +5013,23 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
if (retval)
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 (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;
+ }
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);
--
2.34.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
From d7f961de2cf9c1451ea3da8c023ff2868935df99 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20=C4=8Cerm=C3=A1k?= <[email protected]>
Date: Mon, 4 Mar 2024 13:52:41 +0100
Subject: [PATCH v2 3/5] Revert "USB: core: Fix race by not overwriting
udev->descriptor in hub_port_init()"

This reverts commit 8186596a663506b1124bede9fde6f243ef9f37ee.
---
drivers/usb/core/hub.c | 114 ++++++++++++++++-------------------------
1 file changed, 44 insertions(+), 70 deletions(-)

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index ed1807169b47e..dd0aaf1a40bb2 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -4755,17 +4755,10 @@ static int get_bMaxPacketSize0(struct usb_device *udev,
* the port lock. For a newly detected device that is not accessible
* through any global pointers, it's not necessary to lock the device,
* but it is still necessary to lock the port.
- *
- * For a newly detected device, @dev_descr must be NULL. The device
- * descriptor retrieved from the device will then be stored in
- * @udev->descriptor. For an already existing device, @dev_descr
- * must be non-NULL. The device descriptor will be stored there,
- * not in @udev->descriptor, because descriptors for registered
- * devices are meant to be immutable.
*/
static int
hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
- int retry_counter, struct usb_device_descriptor *dev_descr)
+ int retry_counter)
{
struct usb_device *hdev = hub->hdev;
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
@@ -4777,7 +4770,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
int devnum = udev->devnum;
const char *driver_name;
bool do_new_scheme;
- const bool initial = !dev_descr;
int maxp0;
struct usb_device_descriptor *buf, *descr;

@@ -4816,34 +4808,32 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
}
oldspeed = udev->speed;

- if (initial) {
- /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
- * it's fixed size except for full speed devices.
- * For Wireless USB devices, ep0 max packet is always 512 (tho
- * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
+ /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ...
+ * it's fixed size except for full speed devices.
+ * For Wireless USB devices, ep0 max packet is always 512 (tho
+ * reported as 0xff in the device descriptor). WUSB1.0[4.8.1].
+ */
+ switch (udev->speed) {
+ case USB_SPEED_SUPER_PLUS:
+ case USB_SPEED_SUPER:
+ case USB_SPEED_WIRELESS: /* fixed at 512 */
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
+ break;
+ case USB_SPEED_HIGH: /* fixed at 64 */
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
+ break;
+ case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
+ /* to determine the ep0 maxpacket size, try to read
+ * the device descriptor to get bMaxPacketSize0 and
+ * then correct our initial guess.
*/
- switch (udev->speed) {
- case USB_SPEED_SUPER_PLUS:
- case USB_SPEED_SUPER:
- case USB_SPEED_WIRELESS: /* fixed at 512 */
- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512);
- break;
- case USB_SPEED_HIGH: /* fixed at 64 */
- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
- break;
- case USB_SPEED_FULL: /* 8, 16, 32, or 64 */
- /* to determine the ep0 maxpacket size, try to read
- * the device descriptor to get bMaxPacketSize0 and
- * then correct our initial guess.
- */
- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
- break;
- case USB_SPEED_LOW: /* fixed at 8 */
- udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
- break;
- default:
- goto fail;
- }
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64);
+ break;
+ case USB_SPEED_LOW: /* fixed at 8 */
+ udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8);
+ break;
+ default:
+ goto fail;
}

if (udev->speed == USB_SPEED_WIRELESS)
@@ -4866,24 +4856,22 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
if (udev->speed < USB_SPEED_SUPER)
dev_info(&udev->dev,
"%s %s USB device number %d using %s\n",
- (initial ? "new" : "reset"), speed,
+ (udev->config) ? "reset" : "new", speed,
devnum, driver_name);

- if (initial) {
- /* Set up TT records, if needed */
- if (hdev->tt) {
- udev->tt = hdev->tt;
- udev->ttport = hdev->ttport;
- } else if (udev->speed != USB_SPEED_HIGH
- && hdev->speed == USB_SPEED_HIGH) {
- if (!hub->tt.hub) {
- dev_err(&udev->dev, "parent hub has no TT\n");
- retval = -EINVAL;
- goto fail;
- }
- udev->tt = &hub->tt;
- udev->ttport = port1;
+ /* Set up TT records, if needed */
+ if (hdev->tt) {
+ udev->tt = hdev->tt;
+ udev->ttport = hdev->ttport;
+ } else if (udev->speed != USB_SPEED_HIGH
+ && hdev->speed == USB_SPEED_HIGH) {
+ if (!hub->tt.hub) {
+ dev_err(&udev->dev, "parent hub has no TT\n");
+ retval = -EINVAL;
+ goto fail;
}
+ udev->tt = &hub->tt;
+ udev->ttport = port1;
}

/* Why interleave GET_DESCRIPTOR and SET_ADDRESS this way?
@@ -4912,12 +4900,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,

maxp0 = get_bMaxPacketSize0(udev, buf,
GET_DESCRIPTOR_BUFSIZE, retries == 0);
- if (maxp0 > 0 && !initial &&
- maxp0 != udev->descriptor.bMaxPacketSize0) {
- dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n");
- retval = -ENODEV;
- goto fail;
- }

retval = hub_port_reset(hub, port1, udev, delay, false);
if (retval < 0) /* error or disconnect */
@@ -4991,12 +4973,6 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
} else {
u32 delay;

- if (!initial && maxp0 != udev->descriptor.bMaxPacketSize0) {
- dev_err(&udev->dev, "device reset changed ep0 maxpacket size!\n");
- retval = -ENODEV;
- goto fail;
- }
-
delay = udev->parent->hub_delay;
udev->hub_delay = min_t(u32, delay,
USB_TP_TRANSMISSION_DELAY_MAX);
@@ -5040,10 +5016,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
retval);
goto fail;
}
- if (initial)
- udev->descriptor = *descr;
- else
- *dev_descr = *descr;
+ udev->descriptor = *descr;
kfree(descr);

/*
@@ -5348,7 +5321,7 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
}

/* reset (non-USB 3.0 devices) and get descriptor */
- status = hub_port_init(hub, udev, port1, i, NULL);
+ status = hub_port_init(hub, udev, port1, i);
if (status < 0)
goto loop;

@@ -5974,7 +5947,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
struct usb_device *parent_hdev = udev->parent;
struct usb_hub *parent_hub;
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
- struct usb_device_descriptor descriptor;
+ struct usb_device_descriptor descriptor = udev->descriptor;
struct usb_host_bos *bos;
int i, j, ret = 0;
int port1 = udev->portnum;
@@ -6006,7 +5979,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
/* ep0 maxpacket size may change; let the HCD know about it.
* Other endpoints will be handled by re-enumeration. */
usb_ep0_reinit(udev);
- ret = hub_port_init(parent_hub, udev, port1, i, &descriptor);
+ ret = hub_port_init(parent_hub, udev, port1, i);
if (ret >= 0 || ret == -ENOTCONN || ret == -ENODEV)
break;
}
@@ -6018,6 +5991,7 @@ static int usb_reset_and_verify_device(struct usb_device *udev)
/* Device might have changed firmware (DFU or similar) */
if (descriptors_changed(udev, &descriptor, bos)) {
dev_info(&udev->dev, "device firmware changed\n");
+ udev->descriptor = descriptor; /* for disconnect() calls */
goto re_enumerate;
}

--
2.34.1

Loading

0 comments on commit 9bfadeb

Please sign in to comment.