Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-04-28 Thread Stefan Roese
On 28.04.2016 01:07, Marek Vasut wrote:
> On 04/02/2016 11:21 PM, Hans de Goede wrote:
>> Hi,
> 
> Hi!
> 
>> On 04/02/2016 12:22 AM, Marek Vasut wrote:
>>> On 03/15/2016 01:59 PM, Stefan Roese wrote:
 This patch changes the USB port scanning procedure and timeout
 handling in the following ways:

 a)
 The power-on delay in usb_hub_power_on() is now reduced to a value of
 max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
 using mdelay, instead usb_hub_power_on() will wait before querying
 the device in the scanning loop later. The total timeout for this
 hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
 and will be used in the following per-port scanning loop as the timeout
 to detect active USB devices on this hub.

 b)
 Don't delay the minimum delay (for power to stabilize) in
 usb_hub_power_on(). Instead skip querying these devices in the scannig
 loop until the delay time is reached.

 c)
 The ports are now scanned in a quasi parallel way. The current code did
 wait for each (unconnected) port to reach its timeout and only then
 continue with the next port. This patch now changes this to scan all
 ports of all USB hubs quasi simultaneously. For this, all ports are
 added
 to a scanning list. This list is scanned until all ports are ready
 by either a) reaching the connection timeout (calculated earlier), or
 by b) detecting a USB device. This results in a faster USB scan time as
 the recursive scanning of USB hubs connected to the hub that's currently
 being scanned will start earlier.

 One small functional change to the original code is, that ports with
 overcurrent detection will now get rescanned multiple times
 (PORT_OVERCURRENT_MAX_SCAN_COUNT).

 Without this patch:
 starting USB...
 USB0:   USB EHCI 1.00
 scanning bus 0 for devices... 9 USB Device(s) found

 time: 20.163 seconds

 With this patch:
 starting USB...
 USB0:   USB EHCI 1.00
 scanning bus 0 for devices... 9 USB Device(s) found

 time: 1.822 seconds

 So ~18.3 seconds of USB scanning time reduction.

 Signed-off-by: Stefan Roese 
 Acked-by: Hans de Goede 
 Tested-by: Stephen Warren 
>>>
>>> This breaks DWC2 on SoCkit, I can no longer detect any USB device.
>>> USB works without this patch though. Ideas?
>>
>> Have you tried simply adding a large sleep before the
>> initial uart, or doing an "usb reset" after the initial
>> scan ?
> 
> Yeah, that doesn't help. But I also sent a few fixes for the DWC2
> controller, so let's see. I also finally got Stefan a working board,
> so he can start poking around :)

Okay, here my collection of tests with numerous USB keys on SoCFPGA
(SoCrates). All these tests were made with current mainline U-Boot
and the following patches applied:

http://patchwork.ozlabs.org/patch/614747/

http://patchwork.ozlabs.org/patch/615647/
http://patchwork.ozlabs.org/patch/615650/
http://patchwork.ozlabs.org/patch/615649/
http://patchwork.ozlabs.org/patch/615651/

a) With current mainline (USB scanning enhancement patch included)

and

b) USB scanning enhancement patch reverted (usb: Change power-on /
scanning timeout handling

I've used the following command to test the USB sticks:

dcache off;time usb start;usb tree


1. Kingston DataTraveler 2.0 (64GiB):
-
a)
starting USB...
USB0:   Core Release: 2.93a
scanning bus 0 for devices... Device NOT ready
   Request Sense returned 00 00 00
2 USB Device(s) found

time: 2 minutes, 1.880 seconds
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |   U-Boot Root Hub
  |
  +-2  Mass Storage (480 Mb/s, 200mA)
   Kingston DataTraveler 2.0 50E549C688C4BE7189942766


b)
starting USB...
USB0:   Core Release: 2.93a
scanning bus 0 for devices... Device NOT ready
   Request Sense returned 00 00 00
2 USB Device(s) found

time: 2 minutes, 2.784 seconds
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |   U-Boot Root Hub
  |
  +-2  Mass Storage (480 Mb/s, 200mA)
   Kingston DataTraveler 2.0 50E549C688C4BE7189942766


2. "Paradise" (USBest Technology USB Mass Storage Device) 4GiB:
---
a)
starting USB...
USB0:   Core Release: 2.93a
scanning bus 0 for devices... 2 USB Device(s) found

time: 0.936 seconds
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |   U-Boot Root Hub
  |
  +-2  Mass Storage (480 Mb/s, 98mA)
   USBest Technology USB Mass Storage Device 09092207fbf0c4

b)
starting USB...
USB0:   Core Release: 2.93a
scanning bus 0 for devices... 2 USB Device(s) found

time: 1.571 seconds
USB device tree:
  1  Hub (480 Mb/s, 0mA)
  |   U-Boot Root Hub
  |
  +-2  Mass Storage (480 Mb/s, 98mA)
   USBest Technology USB Mass Storage Device 09092207fbf0c4


3. Intenso Alu Line 16GiB:

Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-04-27 Thread Marek Vasut
On 04/02/2016 11:21 PM, Hans de Goede wrote:
> Hi,

Hi!

> On 04/02/2016 12:22 AM, Marek Vasut wrote:
>> On 03/15/2016 01:59 PM, Stefan Roese wrote:
>>> This patch changes the USB port scanning procedure and timeout
>>> handling in the following ways:
>>>
>>> a)
>>> The power-on delay in usb_hub_power_on() is now reduced to a value of
>>> max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
>>> using mdelay, instead usb_hub_power_on() will wait before querying
>>> the device in the scanning loop later. The total timeout for this
>>> hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
>>> and will be used in the following per-port scanning loop as the timeout
>>> to detect active USB devices on this hub.
>>>
>>> b)
>>> Don't delay the minimum delay (for power to stabilize) in
>>> usb_hub_power_on(). Instead skip querying these devices in the scannig
>>> loop until the delay time is reached.
>>>
>>> c)
>>> The ports are now scanned in a quasi parallel way. The current code did
>>> wait for each (unconnected) port to reach its timeout and only then
>>> continue with the next port. This patch now changes this to scan all
>>> ports of all USB hubs quasi simultaneously. For this, all ports are
>>> added
>>> to a scanning list. This list is scanned until all ports are ready
>>> by either a) reaching the connection timeout (calculated earlier), or
>>> by b) detecting a USB device. This results in a faster USB scan time as
>>> the recursive scanning of USB hubs connected to the hub that's currently
>>> being scanned will start earlier.
>>>
>>> One small functional change to the original code is, that ports with
>>> overcurrent detection will now get rescanned multiple times
>>> (PORT_OVERCURRENT_MAX_SCAN_COUNT).
>>>
>>> Without this patch:
>>> starting USB...
>>> USB0:   USB EHCI 1.00
>>> scanning bus 0 for devices... 9 USB Device(s) found
>>>
>>> time: 20.163 seconds
>>>
>>> With this patch:
>>> starting USB...
>>> USB0:   USB EHCI 1.00
>>> scanning bus 0 for devices... 9 USB Device(s) found
>>>
>>> time: 1.822 seconds
>>>
>>> So ~18.3 seconds of USB scanning time reduction.
>>>
>>> Signed-off-by: Stefan Roese 
>>> Acked-by: Hans de Goede 
>>> Tested-by: Stephen Warren 
>>
>> This breaks DWC2 on SoCkit, I can no longer detect any USB device.
>> USB works without this patch though. Ideas?
> 
> Have you tried simply adding a large sleep before the
> initial uart, or doing an "usb reset" after the initial
> scan ?

Yeah, that doesn't help. But I also sent a few fixes for the DWC2
controller, so let's see. I also finally got Stefan a working board,
so he can start poking around :)

> The biggest change here is the change in timing ...
> 
> Also try defining debug printf in usb_hub.c and see what
> output you get ?

I'll be offloading this to Stefan :)

> Regards,
> 
> Hans


-- 
Best regards,
Marek Vasut
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-04-02 Thread Hans de Goede

Hi,

On 04/02/2016 12:22 AM, Marek Vasut wrote:

On 03/15/2016 01:59 PM, Stefan Roese wrote:

This patch changes the USB port scanning procedure and timeout
handling in the following ways:

a)
The power-on delay in usb_hub_power_on() is now reduced to a value of
max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
using mdelay, instead usb_hub_power_on() will wait before querying
the device in the scanning loop later. The total timeout for this
hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
and will be used in the following per-port scanning loop as the timeout
to detect active USB devices on this hub.

b)
Don't delay the minimum delay (for power to stabilize) in
usb_hub_power_on(). Instead skip querying these devices in the scannig
loop until the delay time is reached.

c)
The ports are now scanned in a quasi parallel way. The current code did
wait for each (unconnected) port to reach its timeout and only then
continue with the next port. This patch now changes this to scan all
ports of all USB hubs quasi simultaneously. For this, all ports are added
to a scanning list. This list is scanned until all ports are ready
by either a) reaching the connection timeout (calculated earlier), or
by b) detecting a USB device. This results in a faster USB scan time as
the recursive scanning of USB hubs connected to the hub that's currently
being scanned will start earlier.

One small functional change to the original code is, that ports with
overcurrent detection will now get rescanned multiple times
(PORT_OVERCURRENT_MAX_SCAN_COUNT).

Without this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 20.163 seconds

With this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 1.822 seconds

So ~18.3 seconds of USB scanning time reduction.

Signed-off-by: Stefan Roese 
Acked-by: Hans de Goede 
Tested-by: Stephen Warren 


This breaks DWC2 on SoCkit, I can no longer detect any USB device.
USB works without this patch though. Ideas?


Have you tried simply adding a large sleep before the
initial uart, or doing an "usb reset" after the initial
scan ?

The biggest change here is the change in timing ...

Also try defining debug printf in usb_hub.c and see what
output you get ?

Regards,

Hans
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-04-01 Thread Marek Vasut
On 03/15/2016 01:59 PM, Stefan Roese wrote:
> This patch changes the USB port scanning procedure and timeout
> handling in the following ways:
> 
> a)
> The power-on delay in usb_hub_power_on() is now reduced to a value of
> max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
> using mdelay, instead usb_hub_power_on() will wait before querying
> the device in the scanning loop later. The total timeout for this
> hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
> and will be used in the following per-port scanning loop as the timeout
> to detect active USB devices on this hub.
> 
> b)
> Don't delay the minimum delay (for power to stabilize) in
> usb_hub_power_on(). Instead skip querying these devices in the scannig
> loop until the delay time is reached.
> 
> c)
> The ports are now scanned in a quasi parallel way. The current code did
> wait for each (unconnected) port to reach its timeout and only then
> continue with the next port. This patch now changes this to scan all
> ports of all USB hubs quasi simultaneously. For this, all ports are added
> to a scanning list. This list is scanned until all ports are ready
> by either a) reaching the connection timeout (calculated earlier), or
> by b) detecting a USB device. This results in a faster USB scan time as
> the recursive scanning of USB hubs connected to the hub that's currently
> being scanned will start earlier.
> 
> One small functional change to the original code is, that ports with
> overcurrent detection will now get rescanned multiple times
> (PORT_OVERCURRENT_MAX_SCAN_COUNT).
> 
> Without this patch:
> starting USB...
> USB0:   USB EHCI 1.00
> scanning bus 0 for devices... 9 USB Device(s) found
> 
> time: 20.163 seconds
> 
> With this patch:
> starting USB...
> USB0:   USB EHCI 1.00
> scanning bus 0 for devices... 9 USB Device(s) found
> 
> time: 1.822 seconds
> 
> So ~18.3 seconds of USB scanning time reduction.
> 
> Signed-off-by: Stefan Roese 
> Acked-by: Hans de Goede 
> Tested-by: Stephen Warren 

This breaks DWC2 on SoCkit, I can no longer detect any USB device.
USB works without this patch though. Ideas?

Best regards,
Marek Vasut
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-03-15 Thread Bin Meng
On Tue, Mar 15, 2016 at 8:59 PM, Stefan Roese  wrote:
> This patch changes the USB port scanning procedure and timeout
> handling in the following ways:
>
> a)
> The power-on delay in usb_hub_power_on() is now reduced to a value of
> max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
> using mdelay, instead usb_hub_power_on() will wait before querying
> the device in the scanning loop later. The total timeout for this
> hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
> and will be used in the following per-port scanning loop as the timeout
> to detect active USB devices on this hub.
>
> b)
> Don't delay the minimum delay (for power to stabilize) in
> usb_hub_power_on(). Instead skip querying these devices in the scannig
> loop until the delay time is reached.
>
> c)
> The ports are now scanned in a quasi parallel way. The current code did
> wait for each (unconnected) port to reach its timeout and only then
> continue with the next port. This patch now changes this to scan all
> ports of all USB hubs quasi simultaneously. For this, all ports are added
> to a scanning list. This list is scanned until all ports are ready
> by either a) reaching the connection timeout (calculated earlier), or
> by b) detecting a USB device. This results in a faster USB scan time as
> the recursive scanning of USB hubs connected to the hub that's currently
> being scanned will start earlier.
>
> One small functional change to the original code is, that ports with
> overcurrent detection will now get rescanned multiple times
> (PORT_OVERCURRENT_MAX_SCAN_COUNT).
>
> Without this patch:
> starting USB...
> USB0:   USB EHCI 1.00
> scanning bus 0 for devices... 9 USB Device(s) found
>
> time: 20.163 seconds
>
> With this patch:
> starting USB...
> USB0:   USB EHCI 1.00
> scanning bus 0 for devices... 9 USB Device(s) found
>
> time: 1.822 seconds
>
> So ~18.3 seconds of USB scanning time reduction.
>
> Signed-off-by: Stefan Roese 
> Acked-by: Hans de Goede 
> Tested-by: Stephen Warren 
>
> ---
>
> Changes in v5:
> - Removed superfluous debug output from usb_scan_port()
> - Replaced usb_hub_power_on() with usb_set_port_feature() in case
>   of overcurrent detection. This is whats really needed here.
> - Added a per-port overcurrent counter and stop re-scanning of
>   a device that exceeds the PORT_OVERCURRENT_MAX_SCAN_COUNT
> - Moved list_del() to end of loop in usb_scan_port()
> - Moved timeout / delay variables from USB dev to hub struct
>   as they are hub specific
> - Moved state_get_skip_delays() to usb_hub_power_on() so that
>   the timeouts are not set there
>
> Changes in v4:
> - Moved check for query_delay into usb_scan_port() as suggested by Hans
> - Correct list handling (drop INIT_LIST_HEAD)
> - Added some missing free() calls
> - Changed connect_timeout calculation as suggested by Stephen
> - Moved usb_scan_list to other globals to be cleaned up in a later patch
> - Added timeout check for non-functional ports (usb_get_port_status
>   return error
> - Reverted if logic in loop to remove an indentation level
> - Moved debug() output
> - Removed unnecessary if when already connected
> - Added Hans's Acked-by
> - Added Stephen's Tested-by
> - Minor rewording / fixes of the commit text
>
> Changes in v3:
> - Introduced scanning list containing all USB devices of one USB
>   controller that need to get scanned
> - Don't delay in usb_hub_power_on(). Instead skip querying these devices
>   until the delay time is reached.
>
> Changes in v2:
> - Remove static USB port configuration patch (for now)
>
>  common/usb_hub.c | 317 
> ++-
>  include/usb.h|   4 +
>  2 files changed, 227 insertions(+), 94 deletions(-)
>

Tested-by: Bin Meng 
___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-03-15 Thread Stephen Warren

On 03/15/2016 06:59 AM, Stefan Roese wrote:

This patch changes the USB port scanning procedure and timeout
handling in the following ways:

a)
The power-on delay in usb_hub_power_on() is now reduced to a value of
max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
using mdelay, instead usb_hub_power_on() will wait before querying
the device in the scanning loop later. The total timeout for this
hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
and will be used in the following per-port scanning loop as the timeout
to detect active USB devices on this hub.

b)
Don't delay the minimum delay (for power to stabilize) in
usb_hub_power_on(). Instead skip querying these devices in the scannig
loop until the delay time is reached.

c)
The ports are now scanned in a quasi parallel way. The current code did
wait for each (unconnected) port to reach its timeout and only then
continue with the next port. This patch now changes this to scan all
ports of all USB hubs quasi simultaneously. For this, all ports are added
to a scanning list. This list is scanned until all ports are ready
by either a) reaching the connection timeout (calculated earlier), or
by b) detecting a USB device. This results in a faster USB scan time as
the recursive scanning of USB hubs connected to the hub that's currently
being scanned will start earlier.

One small functional change to the original code is, that ports with
overcurrent detection will now get rescanned multiple times
(PORT_OVERCURRENT_MAX_SCAN_COUNT).

Without this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 20.163 seconds

With this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 1.822 seconds

So ~18.3 seconds of USB scanning time reduction.

Signed-off-by: Stefan Roese 
Acked-by: Hans de Goede 
Tested-by: Stephen Warren 


This version still works for me (the timing numbers I sent a few minutes 
ago were with this version too).

___
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot


Re: [U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-03-15 Thread Hans de Goede

Hi,

On 15-03-16 13:59, Stefan Roese wrote:

This patch changes the USB port scanning procedure and timeout
handling in the following ways:

a)
The power-on delay in usb_hub_power_on() is now reduced to a value of
max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
using mdelay, instead usb_hub_power_on() will wait before querying
the device in the scanning loop later. The total timeout for this
hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
and will be used in the following per-port scanning loop as the timeout
to detect active USB devices on this hub.

b)
Don't delay the minimum delay (for power to stabilize) in
usb_hub_power_on(). Instead skip querying these devices in the scannig
loop until the delay time is reached.

c)
The ports are now scanned in a quasi parallel way. The current code did
wait for each (unconnected) port to reach its timeout and only then
continue with the next port. This patch now changes this to scan all
ports of all USB hubs quasi simultaneously. For this, all ports are added
to a scanning list. This list is scanned until all ports are ready
by either a) reaching the connection timeout (calculated earlier), or
by b) detecting a USB device. This results in a faster USB scan time as
the recursive scanning of USB hubs connected to the hub that's currently
being scanned will start earlier.

One small functional change to the original code is, that ports with
overcurrent detection will now get rescanned multiple times
(PORT_OVERCURRENT_MAX_SCAN_COUNT).

Without this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 20.163 seconds

With this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 1.822 seconds

So ~18.3 seconds of USB scanning time reduction.

Signed-off-by: Stefan Roese 
Acked-by: Hans de Goede 
Tested-by: Stephen Warren 

---

Changes in v5:
- Removed superfluous debug output from usb_scan_port()
- Replaced usb_hub_power_on() with usb_set_port_feature() in case
   of overcurrent detection. This is whats really needed here.
- Added a per-port overcurrent counter and stop re-scanning of
   a device that exceeds the PORT_OVERCURRENT_MAX_SCAN_COUNT
- Moved list_del() to end of loop in usb_scan_port()
- Moved timeout / delay variables from USB dev to hub struct
   as they are hub specific
- Moved state_get_skip_delays() to usb_hub_power_on() so that
   the timeouts are not set there


Looks good to me, my Acked-by still stands. Thanks for doing a v5.

Regards,

Hans


Changes in v4:
- Moved check for query_delay into usb_scan_port() as suggested by Hans
- Correct list handling (drop INIT_LIST_HEAD)
- Added some missing free() calls
- Changed connect_timeout calculation as suggested by Stephen
- Moved usb_scan_list to other globals to be cleaned up in a later patch
- Added timeout check for non-functional ports (usb_get_port_status
   return error
- Reverted if logic in loop to remove an indentation level
- Moved debug() output
- Removed unnecessary if when already connected
- Added Hans's Acked-by
- Added Stephen's Tested-by
- Minor rewording / fixes of the commit text

Changes in v3:
- Introduced scanning list containing all USB devices of one USB
   controller that need to get scanned
- Don't delay in usb_hub_power_on(). Instead skip querying these devices
   until the delay time is reached.

Changes in v2:
- Remove static USB port configuration patch (for now)

  common/usb_hub.c | 317 ++-
  include/usb.h|   4 +
  2 files changed, 227 insertions(+), 94 deletions(-)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index d621f50..e6a2cdb 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -30,6 +30,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #ifdef CONFIG_SANDBOX
  #include 
@@ -49,9 +50,19 @@ DECLARE_GLOBAL_DATA_PTR;
  #define HUB_SHORT_RESET_TIME  20
  #define HUB_LONG_RESET_TIME   200

+#define PORT_OVERCURRENT_MAX_SCAN_COUNT3
+
+struct usb_device_scan {
+   struct usb_device *dev; /* USB hub device to scan */
+   struct usb_hub_device *hub; /* USB hub struct */
+   int port;   /* USB port to scan */
+   struct list_head list;
+};
+
  /* TODO(s...@chromium.org): Remove this when CONFIG_DM_USB is defined */
  static struct usb_hub_device hub_dev[USB_MAX_HUB];
  static int usb_hub_index;
+static LIST_HEAD(usb_scan_list);

  __weak void usb_hub_reset_devices(int port)
  {
@@ -109,6 +120,15 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
debug("port %d returns %lX\n", i + 1, dev->status);
}

+#ifdef CONFIG_SANDBOX
+   /*
+* Don't set timeout / delay values here. This results
+* in these values still being reset to 0.
+*/
+   if (state_get_skip_delays())
+  

[U-Boot] [PATCH v5 4/4] usb: Change power-on / scanning timeout handling

2016-03-15 Thread Stefan Roese
This patch changes the USB port scanning procedure and timeout
handling in the following ways:

a)
The power-on delay in usb_hub_power_on() is now reduced to a value of
max(100ms, "hub->desc.bPwrOn2PwrGood * 2"). The code does not wait
using mdelay, instead usb_hub_power_on() will wait before querying
the device in the scanning loop later. The total timeout for this
hub, which is 1 second + "hub->desc.bPwrOn2PwrGood * 2" is calculated
and will be used in the following per-port scanning loop as the timeout
to detect active USB devices on this hub.

b)
Don't delay the minimum delay (for power to stabilize) in
usb_hub_power_on(). Instead skip querying these devices in the scannig
loop until the delay time is reached.

c)
The ports are now scanned in a quasi parallel way. The current code did
wait for each (unconnected) port to reach its timeout and only then
continue with the next port. This patch now changes this to scan all
ports of all USB hubs quasi simultaneously. For this, all ports are added
to a scanning list. This list is scanned until all ports are ready
by either a) reaching the connection timeout (calculated earlier), or
by b) detecting a USB device. This results in a faster USB scan time as
the recursive scanning of USB hubs connected to the hub that's currently
being scanned will start earlier.

One small functional change to the original code is, that ports with
overcurrent detection will now get rescanned multiple times
(PORT_OVERCURRENT_MAX_SCAN_COUNT).

Without this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 20.163 seconds

With this patch:
starting USB...
USB0:   USB EHCI 1.00
scanning bus 0 for devices... 9 USB Device(s) found

time: 1.822 seconds

So ~18.3 seconds of USB scanning time reduction.

Signed-off-by: Stefan Roese 
Acked-by: Hans de Goede 
Tested-by: Stephen Warren 

---

Changes in v5:
- Removed superfluous debug output from usb_scan_port()
- Replaced usb_hub_power_on() with usb_set_port_feature() in case
  of overcurrent detection. This is whats really needed here.
- Added a per-port overcurrent counter and stop re-scanning of
  a device that exceeds the PORT_OVERCURRENT_MAX_SCAN_COUNT
- Moved list_del() to end of loop in usb_scan_port()
- Moved timeout / delay variables from USB dev to hub struct
  as they are hub specific
- Moved state_get_skip_delays() to usb_hub_power_on() so that
  the timeouts are not set there

Changes in v4:
- Moved check for query_delay into usb_scan_port() as suggested by Hans
- Correct list handling (drop INIT_LIST_HEAD)
- Added some missing free() calls
- Changed connect_timeout calculation as suggested by Stephen
- Moved usb_scan_list to other globals to be cleaned up in a later patch
- Added timeout check for non-functional ports (usb_get_port_status
  return error
- Reverted if logic in loop to remove an indentation level
- Moved debug() output
- Removed unnecessary if when already connected
- Added Hans's Acked-by
- Added Stephen's Tested-by
- Minor rewording / fixes of the commit text

Changes in v3:
- Introduced scanning list containing all USB devices of one USB
  controller that need to get scanned
- Don't delay in usb_hub_power_on(). Instead skip querying these devices
  until the delay time is reached.

Changes in v2:
- Remove static USB port configuration patch (for now)

 common/usb_hub.c | 317 ++-
 include/usb.h|   4 +
 2 files changed, 227 insertions(+), 94 deletions(-)

diff --git a/common/usb_hub.c b/common/usb_hub.c
index d621f50..e6a2cdb 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #ifdef CONFIG_SANDBOX
 #include 
@@ -49,9 +50,19 @@ DECLARE_GLOBAL_DATA_PTR;
 #define HUB_SHORT_RESET_TIME   20
 #define HUB_LONG_RESET_TIME200
 
+#define PORT_OVERCURRENT_MAX_SCAN_COUNT3
+
+struct usb_device_scan {
+   struct usb_device *dev; /* USB hub device to scan */
+   struct usb_hub_device *hub; /* USB hub struct */
+   int port;   /* USB port to scan */
+   struct list_head list;
+};
+
 /* TODO(s...@chromium.org): Remove this when CONFIG_DM_USB is defined */
 static struct usb_hub_device hub_dev[USB_MAX_HUB];
 static int usb_hub_index;
+static LIST_HEAD(usb_scan_list);
 
 __weak void usb_hub_reset_devices(int port)
 {
@@ -109,6 +120,15 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
debug("port %d returns %lX\n", i + 1, dev->status);
}
 
+#ifdef CONFIG_SANDBOX
+   /*
+* Don't set timeout / delay values here. This results
+* in these values still being reset to 0.
+*/
+   if (state_get_skip_delays())
+   return;
+#endif
+
/*
 * Wait for power to become stable,
 * plus spec-defined max time for device to connect
@@ -120,12