Patchwork [U-Boot,v3] usbh/ehci: Increase timeout for enumeration

login
register
mail settings
Submitter Vipin Kumar
Date Dec. 13, 2012, 10:55 a.m.
Message ID <98a900ae65d11e2bca6addcfc16675de1d665d59.1355396006.git.vipin.kumar@st.com>
Download mbox | patch
Permalink /patch/205801/
State Accepted
Delegated to: Marek Vasut
Headers show

Comments

Vipin Kumar - Dec. 13, 2012, 10:55 a.m.
The current logic reads the port status just once after usb_hub_power_on and
expects the portstatus and portchange to report the connection status
immediately and correctly.

Few pen drives are not able to report both of them immediately ie. those pens
report the connection change but not the connected state after the first read.
This opportunity once lost is gone for ever because the u-boot, unlike linux or
any other OS, works in polling mode.

This patch modifies the logic to read the port status continuously until the
portstatus and portchange both report a connection change as well as a connected
state or no connection change and no connection. This logic is placed in a
timeout of 10 sec. At the end of it, the pen drive would have either reported a
ONE or a ZERO in bit 1 of portstatus as well as portchange.

It enhances the set of pen drives which can eventually be detected by u-boot

Note: This 10 second timeout is based purely on several experiments done with
the broken pen drives

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
Acked-by: Igor Grinberg <grinberg@compulab.co.il>
---
Changes in v3
 Added comment (in patch comment as well as code) for the reasons for choosing
 10 seconds as timeout

 common/usb_hub.c | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)
Marek Vasut - Dec. 13, 2012, 1:11 p.m.
Dear Vipin Kumar,

> The current logic reads the port status just once after usb_hub_power_on
> and expects the portstatus and portchange to report the connection status
> immediately and correctly.
> 
> Few pen drives are not able to report both of them immediately ie. those
> pens report the connection change but not the connected state after the
> first read. This opportunity once lost is gone for ever because the
> u-boot, unlike linux or any other OS, works in polling mode.
> 
> This patch modifies the logic to read the port status continuously until
> the portstatus and portchange both report a connection change as well as a
> connected state or no connection change and no connection. This logic is
> placed in a timeout of 10 sec. At the end of it, the pen drive would have
> either reported a ONE or a ZERO in bit 1 of portstatus as well as
> portchange.
> 
> It enhances the set of pen drives which can eventually be detected by
> u-boot
> 
> Note: This 10 second timeout is based purely on several experiments done
> with the broken pen drives
> 
> Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
> Acked-by: Igor Grinberg <grinberg@compulab.co.il>

Applied, tested. Thanks

Best regards,
Marek Vasut
Vipin Kumar - Dec. 14, 2012, 8:58 a.m.
On 12/13/2012 6:41 PM, Marek Vasut wrote:
> Dear Vipin Kumar,
>
>> The current logic reads the port status just once after usb_hub_power_on
>> and expects the portstatus and portchange to report the connection status
>> immediately and correctly.
>>
>> Few pen drives are not able to report both of them immediately ie. those
>> pens report the connection change but not the connected state after the
>> first read. This opportunity once lost is gone for ever because the
>> u-boot, unlike linux or any other OS, works in polling mode.
>>
>> This patch modifies the logic to read the port status continuously until
>> the portstatus and portchange both report a connection change as well as a
>> connected state or no connection change and no connection. This logic is
>> placed in a timeout of 10 sec. At the end of it, the pen drive would have
>> either reported a ONE or a ZERO in bit 1 of portstatus as well as
>> portchange.
>>
>> It enhances the set of pen drives which can eventually be detected by
>> u-boot
>>
>> Note: This 10 second timeout is based purely on several experiments done
>> with the broken pen drives
>>
>> Signed-off-by: Vipin Kumar<vipin.kumar@st.com>
>> Acked-by: Igor Grinberg<grinberg@compulab.co.il>
>
> Applied, tested. Thanks
>

Thanks Marek

> Best regards,
> Marek Vasut
>

Patch

diff --git a/common/usb_hub.c b/common/usb_hub.c
index e4a1201..4d75b90 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -396,14 +396,37 @@  static int usb_hub_configure(struct usb_device *dev)
 	for (i = 0; i < dev->maxchild; i++) {
 		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
+		int ret;
+		ulong start = get_timer(0);
+
+		/*
+		 * Wait for (whichever finishes first)
+		 *  - A maximum of 10 seconds
+		 *    This is a purely observational value driven by connecting
+		 *    a few broken pen drives and taking the max * 1.5 approach
+		 *  - connection_change and connection state to report same
+		 *    state
+		 */
+		do {
+			ret = usb_get_port_status(dev, i + 1, portsts);
+			if (ret < 0) {
+				USB_HUB_PRINTF("get_port_status failed\n");
+				break;
+			}
+
+			portstatus = le16_to_cpu(portsts->wPortStatus);
+			portchange = le16_to_cpu(portsts->wPortChange);
+
+			if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
+				(portstatus & USB_PORT_STAT_CONNECTION))
+				break;
+
+			mdelay(100);
+		} while (get_timer(start) < CONFIG_SYS_HZ * 10);
 
-		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
-			USB_HUB_PRINTF("get_port_status failed\n");
+		if (ret < 0)
 			continue;
-		}
 
-		portstatus = le16_to_cpu(portsts->wPortStatus);
-		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);