Currently, there is a Kconfig (CONFIG_USB_FEW_INIT_RETRIES) to reduce retries when the port initialization is failed. The retry times are fixed and assigned in compile time. To improve the flexibility, this patch add four module parameters: port_reset_tries, set_address_tries, get_descriptor_tries, and get_maxpacket0_tries, to replace the original default values. The default value of module parameters is the same as before to preserve the existing behavior. Signed-off-by: Ray Chi <raychi@xxxxxxxxxx> --- .../admin-guide/kernel-parameters.txt | 16 ++++++++++ drivers/usb/core/hub.c | 31 ++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 8090130b544b..c467b2778128 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -6277,6 +6277,22 @@ USB_REQ_GET_DESCRIPTOR request in milliseconds (default 5000 = 5.0 seconds). + usbcore.port_reset_tries= + [USB] Set the retry time of port reset for each + port initialization (default PORT_RESET_TRIES = 5). + + usbcore.set_address_tries= + [USB] set the retry time of set address for each + port initialization (default SET_ADDRESS_TRIES = 2). + + usbcore.get_descriptor_tries= + [USB] set the retry time of set address for each + port initialization (default GET_DESCRIPTOR_TRIES = 2). + + usbcore.get_maxpacket0_tries= + [USB] set the retry time of get maxpacket0 for each + port initialization (default GET_MAXPACKET0_TRIES = 3). + usbcore.nousb [USB] Disable the USB subsystem usbcore.quirks= diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index b7f66dcd1fe0..c5c695886424 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2788,6 +2788,27 @@ static unsigned hub_is_wusb(struct usb_hub *hub) #define HUB_LONG_RESET_TIME 200 #define HUB_RESET_TIMEOUT 800 +/* define retry time for port reset */ +static int port_reset_tries = PORT_RESET_TRIES; +module_param(port_reset_tries, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(port_reset_tries, "retry times of port reset for each port initialization"); + +/* define retry time of set address */ +static int set_address_tries = SET_ADDRESS_TRIES; +module_param(set_address_tries, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(set_address_tries, "retry times of set address for each port initialization"); + +/* define retry time of get descriptor */ +static int get_descriptor_tries = GET_DESCRIPTOR_TRIES; +module_param(get_descriptor_tries, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(get_descriptor_tries, "retry times of set address for each port initialization"); + +/* define retry time of get maxpacket0 */ +static int get_maxpacket0_tries = GET_MAXPACKET0_TRIES; +module_param(get_maxpacket0_tries, int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(get_maxpacket0_tries, + "retry times of get maxpacket0 for each port initialization"); + static bool use_new_scheme(struct usb_device *udev, int retry, struct usb_port *port_dev) { @@ -2965,7 +2986,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, clear_bit(port1, hub->warm_reset_bits); /* Reset the port */ - for (i = 0; i < PORT_RESET_TRIES; i++) { + for (i = 0; i < port_reset_tries; i++) { status = set_port_feature(hub->hdev, port1, (warm ? USB_PORT_FEAT_BH_PORT_RESET : USB_PORT_FEAT_RESET)); @@ -2989,7 +3010,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, * reset attempts to avoid warm reset loop. */ if (status == 0 || status == -ENOTCONN || status == -ENODEV || - (status == -EBUSY && i == PORT_RESET_TRIES - 1)) { + (status == -EBUSY && i == port_reset_tries - 1)) { usb_clear_port_feature(hub->hdev, port1, USB_PORT_FEAT_C_RESET); @@ -4788,7 +4809,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, */ do_new_scheme = use_new_scheme(udev, retry_counter, port_dev); - for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) { + for (retries = 0; retries < get_descriptor_tries; (++retries, msleep(100))) { if (do_new_scheme) { struct usb_device_descriptor *buf; int r = 0; @@ -4812,7 +4833,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, * 255 is for WUSB devices, we actually need to use * 512 (WUSB1.0[4.8.1]). */ - for (operations = 0; operations < GET_MAXPACKET0_TRIES; + for (operations = 0; operations < get_maxpacket0_tries; ++operations) { buf->bMaxPacketSize0 = 0; r = usb_control_msg(udev, usb_rcvaddr0pipe(), @@ -4873,7 +4894,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1, * authorization will assign the final address. */ if (udev->wusb == 0) { - for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) { + for (operations = 0; operations < set_address_tries; ++operations) { retval = hub_set_address(udev, devnum); if (retval >= 0) break; -- 2.36.1.476.g0c4daa206d-goog