[PATCH v2 1/2] usb: hub: allow to increase HUB_DEBOUNCE_TIMEOUT

Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com --- Hi,
V2 of previous patch [1] after Marek request to a add a CONFIG_.
I think this patch solves a general issue because a 1s timeout for USB connection is too short on problematic USB keys / USB HUB. The issue was introduced by the commit c998da0d6709 ("usb: Change power-on / scanning timeout handling")
Patching usb_hub allows to avoid to patch in each board/driver.
For example, commit 0417169054cb ("imx: ventana: add usb_pgood_delay 2sec default") => use pgood_delay = 2s !?
or ("ARM: stm32: Increase USB power-good delay on DHSOM") https://patchwork.ozlabs.org/project/uboot/patch/20211113022444.231801-1-mar...
or commit 2bf352f0c1b7 ("usb: dwc2: Add delay to fix the USB detection problem on SoCFPGA") => patch in USB DWC2 driver to add a timeout in driver
The commit 319418c01c95 ("usb: hub: allow pgood_delay to be specified via env") introduces an env variable for warm-up times managed by hub->query_delay.
But it is not linked to the connect timeout after power on managed by hub->connect_timeout.
This patch allow to increase the boot time for some board when USB device is not available; the default value = 1s of the config CONFIG_USB_HUB_DEBOUNCE_TIMEOUT allow to keep the current behavior.
This issue appears with DWC2 and USB HUB used in STM32MP135F-DK board; pgood_delay=2 is not enough to solved all the USB key detection issues.
[1] [2/2] usb: hub: increase HUB_DEBOUNCE_TIMEOUT http://patchwork.ozlabs.org/project/uboot/patch/20220704124540.2.I5eabf3f9fd...
Patrick
Changes in v2: - allow defconfig configuration by CONFIG_USB_HUB_DEBOUNCE_TIMEOUT
common/Kconfig | 12 ++++++++++++ common/usb_hub.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/common/Kconfig b/common/Kconfig index e7914ca750a..fedb643ea58 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -992,3 +992,15 @@ config FDT_SIMPLEFB These functions can be used by board to indicate to the OS the presence of the simple frame buffer with associated reserved memory + +config USB_HUB_DEBOUNCE_TIMEOUT + int "Timeout in milliseconds for USB HUB connection" + depends on USB + default 1000 + help + Value in milliseconds of the USB connection timeout, the max delay to + wait the hub port status to be connected steadily after being powered + off and powered on in the usb hub driver. + This define allows to increase the HUB_DEBOUNCE_TIMEOUT default + value = 1s because some usb device needs around 1.5s to be initialized + and a 2s value should solve detection issue on problematic USB keys. diff --git a/common/usb_hub.c b/common/usb_hub.c index d73638950b9..87fd93c55db 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -47,7 +47,7 @@ #define HUB_SHORT_RESET_TIME 20 #define HUB_LONG_RESET_TIME 200
-#define HUB_DEBOUNCE_TIMEOUT 1000 +#define HUB_DEBOUNCE_TIMEOUT CONFIG_USB_HUB_DEBOUNCE_TIMEOUT
#define PORT_OVERCURRENT_MAX_SCAN_COUNT 3

With some USB devices connected on USB HUB for the STMicroelectronics boards, set the usb_pgood_delay=2 is not enough to ensure a correct detection for all cases; but it is solved with USB_HUB_DEBOUNCE_TIMEOUT=2s.
For example, issue encountered with the USB flash disk: ID 058f:6387 Alcor Micro Corp. Flash Drive
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com ---
Changes in v2: - force CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2s for stm32mp15 defconfig
configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 3 files changed, 3 insertions(+)
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index 33680dc25e9..efb506c1172 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -46,6 +46,7 @@ CONFIG_SPL_POWER=y CONFIG_SPL_SPI_FLASH_MTD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index fd2a5de8d13..ba87b511974 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -22,6 +22,7 @@ CONFIG_FIT=y CONFIG_BOOTDELAY=1 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 1154eec210c..6644ea4c81f 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -23,6 +23,7 @@ CONFIG_FIT=y CONFIG_BOOTDELAY=1 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y

Hi Patrick
On 9/9/22 11:45, Patrick Delaunay wrote:
With some USB devices connected on USB HUB for the STMicroelectronics boards, set the usb_pgood_delay=2 is not enough to ensure a correct detection for all cases; but it is solved with USB_HUB_DEBOUNCE_TIMEOUT=2s.
For example, issue encountered with the USB flash disk: ID 058f:6387 Alcor Micro Corp. Flash Drive
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
Changes in v2:
- force CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2s for stm32mp15 defconfig
configs/stm32mp15_basic_defconfig | 1 + configs/stm32mp15_defconfig | 1 + configs/stm32mp15_trusted_defconfig | 1 + 3 files changed, 3 insertions(+)
diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index 33680dc25e9..efb506c1172 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -46,6 +46,7 @@ CONFIG_SPL_POWER=y CONFIG_SPL_SPI_FLASH_MTD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x80000 CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y diff --git a/configs/stm32mp15_defconfig b/configs/stm32mp15_defconfig index fd2a5de8d13..ba87b511974 100644 --- a/configs/stm32mp15_defconfig +++ b/configs/stm32mp15_defconfig @@ -22,6 +22,7 @@ CONFIG_FIT=y CONFIG_BOOTDELAY=1 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y diff --git a/configs/stm32mp15_trusted_defconfig b/configs/stm32mp15_trusted_defconfig index 1154eec210c..6644ea4c81f 100644 --- a/configs/stm32mp15_trusted_defconfig +++ b/configs/stm32mp15_trusted_defconfig @@ -23,6 +23,7 @@ CONFIG_FIT=y CONFIG_BOOTDELAY=1 CONFIG_BOOTCOMMAND="run bootcmd_stm32mp" CONFIG_FDT_SIMPLEFB=y +CONFIG_USB_HUB_DEBOUNCE_TIMEOUT=2000 CONFIG_SYS_PBSIZE=1050 CONFIG_SYS_BOOTM_LEN=0x2000000 CONFIG_CMD_ADTIMG=y
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice

On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
I realized this has one problem -- what happens if you have multiple USB controllers in your system ? The answer is, all of them are affected by the increased delay, possibly even those which do not require the extra delay.
Would it be possible to configure this per-controller (or should this even be per-device?) in DT ? In fact, I wonder whether this is not becoming a Vbus regulator ramp-up time kind of delay here ?

Hi,
On 9/9/22 14:24, Marek Vasut wrote:
On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
I realized this has one problem -- what happens if you have multiple USB controllers in your system ? The answer is, all of them are affected by the increased delay, possibly even those which do not require the extra delay.
Would it be possible to configure this per-controller (or should this even be per-device?) in DT ? In fact, I wonder whether this is not becoming a Vbus regulator ramp-up time kind of delay here ?
Yes, but I don't think, it is blocking.
This timeout will be common for all the USB HUB in the system, as it is done in Linux kernel.
And I don't thing the issue is linked to VBUS regulator rampup, because
- with USB analyser we check that the answer for the problematic key are really slow,
no answer in the 1s normal delay
- and any issue on vbus can be handled by query_delay = pgood delay =
the power is stablized before the devices are queried.
But For our use case, increasing pgood delay is not enought the problematic
(low cost / poor quality / slow) USB keys.
So this CONFIG is used to support some slow USB devices on any USB HUB,
and it is not a workaround for HUB issue.
For my point of view 1s is a little penalty for usb start to support more USB devices on all
the USB HUB on the system, even when the 1s delay defined by the spec is not supported.
For kernel this delay is not managed by the device tree but hardcoded in the USB HUB driver
drivers/usb/core/hub.c
#define HUB_DEBOUNCE_TIMEOUT 2000
/* USB 2.0 spec, 7.1.7.3 / fig 7-29: * * Between connect detection and reset signaling there must be a delay * of 100ms at least for debounce and power-settling. The corresponding * timer shall restart whenever the downstream port detects a disconnect. * * Apparently there are some bluetooth and irda-dongles and a number of * low-speed devices for which this debounce period may last over a second. * Not covered by the spec - but easy to deal with. * * This implementation uses a 1500ms total debounce timeout; if the * connection isn't stable by then it returns -ETIMEDOUT. It checks * every 25ms for transient disconnects. When the port status has been * unchanged for 100ms it returns the port status. */ inthub_port_debounce(structusb_hub *hub, intport1, boolmust_be_connected)
For me in U-Boot driver this debounce is managed as Linux kernel (with 1s <=> 2s)
=> in U-Boot the connect_timeout is used in usb_scan_port():
1- the port is removed from the list when usb_get_port_status() return a error
during the connect_timeout
2- the port is removed when the when usb_get_port_status() return no error
and the connection change happened,
=> no issue when the PORT is become ready and connected
the usb_get_port_status() will be return no error and the portstatus (answer of USB_REQ_GET_STATUS)
is handled by usb_scan_port()
=> the potential issue for timeout is when the PORT is ready (no error for usb_get_port_status()) and not connection detected portchange = 0 / portstatus = 0 after reset
in usb_scan_port():
/* * No connection change happened, wait a bit more. * * For some situation, the hub reports no connection change but a * device is connected to the port (eg: CCS bit is set but CSC is not * in the PORTSC register of a root hub), ignore such case. */ if (!(portchange & USB_PORT_STAT_C_CONNECTION) && !(portstatus & USB_PORT_STAT_CONNECTION)) { if (get_timer(0) >= hub->connect_timeout) { debug("devnum=%d port=%d: timeout\n", dev->devnum, i + 1); /* Remove this device from scanning list */ list_del(&usb_scan->list); free(usb_scan); return 0; } return 0; }
I think the "connect_timeout" could be not used here
as TIMEOUT for "No connection change happened, wait a bit more."
In linux kernel a other timeout is used: HUB_DEBOUNCE_STABLE = 100ms
for this condition...
when usb_get_port_status() return not error and the the connectio
is STABLE during this duration, it is enought.
Perhaps a optimization can be done here....
but I think it is a other subject and I am not enought expert on USB
to propose something
so I don't see the issue here: I just increase the CONNECTION TIMEOUT to 2s
with Kconfig, aligned on Linux value and only for STMicrolectronics defconfig
=> no impact on other boards
=> common for all USB HUB used on the STM32MP boards
Patrick

On 9/12/22 15:37, Patrick DELAUNAY wrote:
Hi,
Hi,
On 9/9/22 14:24, Marek Vasut wrote:
On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
I realized this has one problem -- what happens if you have multiple USB controllers in your system ? The answer is, all of them are affected by the increased delay, possibly even those which do not require the extra delay.
Would it be possible to configure this per-controller (or should this even be per-device?) in DT ? In fact, I wonder whether this is not becoming a Vbus regulator ramp-up time kind of delay here ?
Yes, but I don't think, it is blocking.
This timeout will be common for all the USB HUB in the system, as it is done in Linux kernel.
I just realized this is not the same delay as the usb_pgood_delay, right ?
This is actually the maximum wait for a device to start communicating, i.e. even if this timeout is set to a very high value, most devices will not take that long and will start communicating in shorter time anyway, so the time of completion for e.g. '=> usb reset' is not affected by this change on very much all systems, correct ?

Hi,
On 9/24/22 19:04, Marek Vasut wrote:
On 9/12/22 15:37, Patrick DELAUNAY wrote:
Hi,
Hi,
On 9/9/22 14:24, Marek Vasut wrote:
On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
I realized this has one problem -- what happens if you have multiple USB controllers in your system ? The answer is, all of them are affected by the increased delay, possibly even those which do not require the extra delay.
Would it be possible to configure this per-controller (or should this even be per-device?) in DT ? In fact, I wonder whether this is not becoming a Vbus regulator ramp-up time kind of delay here ?
Yes, but I don't think, it is blocking.
This timeout will be common for all the USB HUB in the system, as it is done in Linux kernel.
I just realized this is not the same delay as the usb_pgood_delay, right ?
Yes it is 2 different timeout in USB stack, usb_scan_port()
1/ pgood_delay used in
hub->query_delay = get_timer(0) + max(100, (int)pgood_delay);
=> time before the devices are queried
* Don't talk to the device before the query delay is expired. * This is needed for voltages to stabalize.
2/ HUB_DEBOUNCE_TIMEOUT used in
hub->connect_timeout = hub->query_delay + HUB_DEBOUNCE_TIMEOUT
=> timeout (max) for usb_get_port_status() answer OR No connection change happened (portchange/portstatus)
This is actually the maximum wait for a device to start communicating, i.e. even if this timeout is set to a very high value, most devices will not take that long and will start communicating in shorter time anyway, so the time of completion for e.g. '=> usb reset' is not affected by this change on very much all systems, correct ?
Yes as it is a max value, it is a protection timeout for problematic devices,
it should not occur for normal use case, but only when the device are correctly detected on the HUB port...
I think the the 'usb reset' sequence is impacted:
usb_init => usb_new_device => usb_hub_probe => usb_hub_configure =
- usb_hub_power_on()
-usb_device_list_scan()
But as it is a CONFIG it is a platform choice.
Regards
Uboot-stm32 mailing list Uboot-stm32@st-md-mailman.stormreply.com https://st-md-mailman.stormreply.com/mailman/listinfo/uboot-stm32

Hi Patrick
On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
Hi,
V2 of previous patch [1] after Marek request to a add a CONFIG_.
I think this patch solves a general issue because a 1s timeout for USB connection is too short on problematic USB keys / USB HUB. The issue was introduced by the commit c998da0d6709 ("usb: Change power-on / scanning timeout handling")
Patching usb_hub allows to avoid to patch in each board/driver.
For example, commit 0417169054cb ("imx: ventana: add usb_pgood_delay 2sec default") => use pgood_delay = 2s !?
or ("ARM: stm32: Increase USB power-good delay on DHSOM") https://patchwork.ozlabs.org/project/uboot/patch/20211113022444.231801-1-mar...
or commit 2bf352f0c1b7 ("usb: dwc2: Add delay to fix the USB detection problem on SoCFPGA") => patch in USB DWC2 driver to add a timeout in driver
The commit 319418c01c95 ("usb: hub: allow pgood_delay to be specified via env") introduces an env variable for warm-up times managed by hub->query_delay.
But it is not linked to the connect timeout after power on managed by hub->connect_timeout.
This patch allow to increase the boot time for some board when USB device is not available; the default value = 1s of the config CONFIG_USB_HUB_DEBOUNCE_TIMEOUT allow to keep the current behavior.
This issue appears with DWC2 and USB HUB used in STM32MP135F-DK board; pgood_delay=2 is not enough to solved all the USB key detection issues.
[1] [2/2] usb: hub: increase HUB_DEBOUNCE_TIMEOUT http://patchwork.ozlabs.org/project/uboot/patch/20220704124540.2.I5eabf3f9fd...
Patrick
Changes in v2:
- allow defconfig configuration by CONFIG_USB_HUB_DEBOUNCE_TIMEOUT
common/Kconfig | 12 ++++++++++++ common/usb_hub.c | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/common/Kconfig b/common/Kconfig index e7914ca750a..fedb643ea58 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -992,3 +992,15 @@ config FDT_SIMPLEFB These functions can be used by board to indicate to the OS the presence of the simple frame buffer with associated reserved memory
+config USB_HUB_DEBOUNCE_TIMEOUT
- int "Timeout in milliseconds for USB HUB connection"
- depends on USB
- default 1000
- help
Value in milliseconds of the USB connection timeout, the max delay to
wait the hub port status to be connected steadily after being powered
off and powered on in the usb hub driver.
This define allows to increase the HUB_DEBOUNCE_TIMEOUT default
value = 1s because some usb device needs around 1.5s to be initialized
and a 2s value should solve detection issue on problematic USB keys.
diff --git a/common/usb_hub.c b/common/usb_hub.c index d73638950b9..87fd93c55db 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -47,7 +47,7 @@ #define HUB_SHORT_RESET_TIME 20 #define HUB_LONG_RESET_TIME 200
-#define HUB_DEBOUNCE_TIMEOUT 1000 +#define HUB_DEBOUNCE_TIMEOUT CONFIG_USB_HUB_DEBOUNCE_TIMEOUT
#define PORT_OVERCURRENT_MAX_SCAN_COUNT 3
Reviewed-by: Patrice Chotard patrice.chotard@foss.st.com
Thanks Patrice

On 9/9/22 11:45, Patrick Delaunay wrote:
Add a new CONFIG_USB_HUB_DEBOUNCE_TIMEOUT to increase the HUB_DEBOUNCE_TIMEOUT value, for example to 2s because some usb device needs around 1.5s or more to make the hub port status to be connected steadily after being powered off and powered on.
This 2s value is aligned with Linux driver and avoids to configure "usb_pgood_delay" as a workaround for connection timeout on some USB device; normally the env variable "usb_pgood_delay" is used to delay the first query after power ON and thus the device answer, but this variable not used to increase the connection timeout delay.
Signed-off-by: Patrick Delaunay patrick.delaunay@foss.st.com
Applied to usb/master, thanks
participants (4)
-
Marek Vasut
-
Patrice CHOTARD
-
Patrick DELAUNAY
-
Patrick Delaunay