Message ID | 98a900ae65d11e2bca6addcfc16675de1d665d59.1355396006.git.vipin.kumar@st.com |
---|---|
State | Accepted |
Delegated to: | Marek Vasut |
Headers | show |
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
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 >
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);