Patch "usb: new quirk to reduce the SET_ADDRESS request timeout" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    usb: new quirk to reduce the SET_ADDRESS request timeout

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     usb-new-quirk-to-reduce-the-set_address-request-time.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit b52ff4d6e0e27e1358005cc32d49be6877e54fc7
Author: Hardik Gajjar <hgajjar@xxxxxxxxxxxxxx>
Date:   Fri Oct 27 17:20:29 2023 +0200

    usb: new quirk to reduce the SET_ADDRESS request timeout
    
    [ Upstream commit 5a1ccf0c72cf917ff3ccc131d1bb8d19338ffe52 ]
    
    This patch introduces a new USB quirk,
    USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT, which modifies the timeout value
    for the SET_ADDRESS request. The standard timeout for USB request/command
    is 5000 ms, as recommended in the USB 3.2 specification (section 9.2.6.1).
    
    However, certain scenarios, such as connecting devices through an APTIV
    hub, can lead to timeout errors when the device enumerates as full speed
    initially and later switches to high speed during chirp negotiation.
    
    In such cases, USB analyzer logs reveal that the bus suspends for
    5 seconds due to incorrect chirp parsing and resumes only after two
    consecutive timeout errors trigger a hub driver reset.
    
    Packet(54) Dir(?) Full Speed J(997.100 us) Idle(  2.850 us)
    _______| Time Stamp(28 . 105 910 682)
    _______|_____________________________________________________________Ch0
    Packet(55) Dir(?) Full Speed J(997.118 us) Idle(  2.850 us)
    _______| Time Stamp(28 . 106 910 632)
    _______|_____________________________________________________________Ch0
    Packet(56) Dir(?) Full Speed J(399.650 us) Idle(222.582 us)
    _______| Time Stamp(28 . 107 910 600)
    _______|_____________________________________________________________Ch0
    Packet(57) Dir Chirp J( 23.955 ms) Idle(115.169 ms)
    _______| Time Stamp(28 . 108 532 832)
    _______|_____________________________________________________________Ch0
    Packet(58) Dir(?) Full Speed J (Suspend)( 5.347 sec) Idle(  5.366 us)
    _______| Time Stamp(28 . 247 657 600)
    _______|_____________________________________________________________Ch0
    
    This 5-second delay in device enumeration is undesirable, particularly
    in automotive applications where quick enumeration is crucial
    (ideally within 3 seconds).
    
    The newly introduced quirks provide the flexibility to align with a
    3-second time limit, as required in specific contexts like automotive
    applications.
    
    By reducing the SET_ADDRESS request timeout to 500 ms, the
    system can respond more swiftly to errors, initiate rapid recovery, and
    ensure efficient device enumeration. This change is vital for scenarios
    where rapid smartphone enumeration and screen projection are essential.
    
    To use the quirk, please write "vendor_id:product_id:p" to
    /sys/bus/usb/drivers/hub/module/parameter/quirks
    
    For example,
    echo "0x2c48:0x0132:p" > /sys/bus/usb/drivers/hub/module/parameters/quirks"
    
    Signed-off-by: Hardik Gajjar <hgajjar@xxxxxxxxxxxxxx>
    Reviewed-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
    Link: https://lore.kernel.org/r/20231027152029.104363-2-hgajjar@xxxxxxxxxxxxxx
    Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index aebbe2981241a..e6f0570cf4900 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -6603,6 +6603,9 @@
 					pause after every control message);
 				o = USB_QUIRK_HUB_SLOW_RESET (Hub needs extra
 					delay after resetting its port);
+				p = USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT
+					(Reduce timeout of the SET_ADDRESS
+					request from 5000 ms to 500 ms);
 			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 a661f6ac1ad14..dea110241ee71 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -60,6 +60,12 @@
 #define USB_PING_RESPONSE_TIME		400	/* ns */
 #define USB_REDUCE_FRAME_INTR_BINTERVAL	9
 
+/*
+ * The SET_ADDRESS request timeout will be 500 ms when
+ * USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT quirk flag is set.
+ */
+#define USB_SHORT_SET_ADDRESS_REQ_TIMEOUT	500  /* ms */
+
 /* Protect struct usb_device->state and ->children members
  * Note: Both are also protected by ->dev.sem, except that ->state can
  * change to USB_STATE_NOTATTACHED even when the semaphore isn't held. */
@@ -4648,7 +4654,12 @@ EXPORT_SYMBOL_GPL(usb_ep0_reinit);
 static int hub_set_address(struct usb_device *udev, int devnum)
 {
 	int retval;
+	unsigned int timeout_ms = USB_CTRL_SET_TIMEOUT;
 	struct usb_hcd *hcd = bus_to_hcd(udev->bus);
+	struct usb_hub *hub = usb_hub_to_struct_hub(udev->parent);
+
+	if (hub->hdev->quirks & USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT)
+		timeout_ms = USB_SHORT_SET_ADDRESS_REQ_TIMEOUT;
 
 	/*
 	 * The host controller will choose the device address,
@@ -4661,11 +4672,11 @@ static int hub_set_address(struct usb_device *udev, int devnum)
 	if (udev->state != USB_STATE_DEFAULT)
 		return -EINVAL;
 	if (hcd->driver->address_device)
-		retval = hcd->driver->address_device(hcd, udev, USB_CTRL_SET_TIMEOUT);
+		retval = hcd->driver->address_device(hcd, udev, timeout_ms);
 	else
 		retval = usb_control_msg(udev, usb_sndaddr0pipe(),
 				USB_REQ_SET_ADDRESS, 0, devnum, 0,
-				NULL, 0, USB_CTRL_SET_TIMEOUT);
+				NULL, 0, timeout_ms);
 	if (retval == 0) {
 		update_devnum(udev, devnum);
 		/* Device now using proper address. */
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
index 15e9bd180a1d2..b4783574b8e66 100644
--- a/drivers/usb/core/quirks.c
+++ b/drivers/usb/core/quirks.c
@@ -138,6 +138,9 @@ static int quirks_param_set(const char *value, const struct kernel_param *kp)
 			case 'o':
 				flags |= USB_QUIRK_HUB_SLOW_RESET;
 				break;
+			case 'p':
+				flags |= USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT;
+				break;
 			/* Ignore unrecognized flag characters */
 			}
 		}
@@ -527,6 +530,10 @@ static const struct usb_device_id usb_quirk_list[] = {
 
 	{ USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },
 
+	/* APTIV AUTOMOTIVE HUB */
+	{ USB_DEVICE(0x2c48, 0x0132), .driver_info =
+			USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT },
+
 	/* DJI CineSSD */
 	{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },
 
diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
index eeb7c2157c72f..59409c1fc3dee 100644
--- a/include/linux/usb/quirks.h
+++ b/include/linux/usb/quirks.h
@@ -72,4 +72,7 @@
 /* device has endpoints that should be ignored */
 #define USB_QUIRK_ENDPOINT_IGNORE		BIT(15)
 
+/* short SET_ADDRESS request timeout */
+#define USB_QUIRK_SHORT_SET_ADDRESS_REQ_TIMEOUT	BIT(16)
+
 #endif /* __LINUX_USB_QUIRKS_H */




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux