[U-Boot] [PATCH 2/5] dm: usb: Add support for companion controllers

Hans de Goede hdegoede at redhat.com
Wed May 6 00:02:06 CEST 2015


Hi Simon,

On 05/05/2015 11:46 PM, Simon Glass wrote:
> Hi Hans,
>
> On 5 May 2015 at 07:28, Hans de Goede <hdegoede at redhat.com> wrote:
>> USB companion controllers must be scanned after the main controller has
>> been scanned, so that any devices which the main controller which to hand
>> over to the companion have actually been handed over before we scan the
>> companion.
>>
>> As there are no guarantees that this will magically happen in the right
>> order, split the scanning of the busses in 2 phases, first main controllers,
>
> buses
>
>> and then companion controllers.
>>
>> Signed-off-by: Hans de Goede <hdegoede at redhat.com>
>> ---
>>   drivers/usb/host/usb-uclass.c | 30 +++++++++++++++++++++++++-----
>>   include/usb.h                 |  2 ++
>>   2 files changed, 27 insertions(+), 5 deletions(-)
>>
>> diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
>> index ad778b4..d745c1c 100644
>> --- a/drivers/usb/host/usb-uclass.c
>> +++ b/drivers/usb/host/usb-uclass.c
>> @@ -157,6 +157,9 @@ static void usb_scan_bus(struct udevice *bus, bool recurse)
>>
>>          assert(recurse);        /* TODO: Support non-recusive */
>>
>> +       if (!device_active(bus))
>> +               return;
>> +
>>          printf("scanning bus %d for devices... ", bus->seq);
>>          debug("\n");
>>          ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev);
>> @@ -171,6 +174,7 @@ static void usb_scan_bus(struct udevice *bus, bool recurse)
>>   int usb_init(void)
>>   {
>>          int controllers_initialized = 0;
>> +       struct usb_bus_priv *priv;
>>          struct udevice *bus;
>>          struct uclass *uc;
>>          int count = 0;
>> @@ -198,15 +202,31 @@ int usb_init(void)
>>                          printf("probe failed, error %d\n", ret);
>>                          continue;
>>                  }
>> -               /*
>> -                * lowlevel init is OK, now scan the bus for devices
>> -                * i.e. search HUBs and configure them
>> -                */
>>                  controllers_initialized++;
>> -               usb_scan_bus(bus, true);
>>                  usb_started = true;
>>          }
>>
>> +       /*
>> +        * lowlevel init done, now scan the bus for devices i.e. search HUBs
>> +        * and configure them, first scan primary controllers.
>> +        */
>> +       uclass_foreach_dev(bus, uc) {
>> +               priv = dev_get_uclass_priv(bus);
>
> Need to check device_active() first in case the probe failed.

Ah right, I cannot deref priv before the check, so adding the check to
usb_scan_bus() is no good, will fix.

> Also are the companions associated with a separate device, or the same
> one? I'm a bit confused...

With a traditional usb-2 setup each usb-2 controller (ehci controller)
has one or more usb-1 companions controllers (ohci or uhci) to deal with
usb-1 devices which get handed over to the companion by the usb-2 controller
on a per port basis.

E.g. older intel chipsets have a 6 port ehci controller with 3 2 port uhci
companions. For a total of 4 pci devices for the entire usb cluster.

I hope this clarifies things.

Regards,

Hans

>
>> +               if (!priv->companion)
>> +                       usb_scan_bus(bus, true);
>> +       }
>> +
>> +       /*
>> +        * Now that the primary controllers have been scanned and have handed
>> +        * over any devices they do not understand to their companions, scan
>> +        * the companions.
>> +        */
>> +       uclass_foreach_dev(bus, uc) {
>> +               priv = dev_get_uclass_priv(bus);
>> +               if (priv->companion)
>> +                       usb_scan_bus(bus, true);
>> +       }
>> +
>>          debug("scan end\n");
>>          /* if we were not able to find at least one working bus, bail out */
>>          if (!count)
>> diff --git a/include/usb.h b/include/usb.h
>> index 7b55844..b81e796 100644
>> --- a/include/usb.h
>> +++ b/include/usb.h
>> @@ -608,10 +608,12 @@ struct usb_dev_platdata {
>>    * @desc_before_addr:  true if we can read a device descriptor before it
>>    *             has been assigned an address. For XHCI this is not possible
>>    *             so this will be false.
>> + * @companion:  True if this is a companion controler to another USB controller
>
> controller
>
>>    */
>>   struct usb_bus_priv {
>>          int next_addr;
>>          bool desc_before_addr;
>> +       bool companion;
>>   };
>>
>>   /**
>> --
>> 2.3.6
>>
>
> Regards,
> Simon
>


More information about the U-Boot mailing list