From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hans de Goede Date: Wed, 06 May 2015 00:02:06 +0200 Subject: [U-Boot] [PATCH 2/5] dm: usb: Add support for companion controllers In-Reply-To: References: <1430832500-7126-1-git-send-email-hdegoede@redhat.com> <1430832500-7126-3-git-send-email-hdegoede@redhat.com> Message-ID: <55493DDE.8060302@redhat.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Hi Simon, On 05/05/2015 11:46 PM, Simon Glass wrote: > Hi Hans, > > On 5 May 2015 at 07:28, Hans de Goede 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 >> --- >> 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 >