Message ID | 1430832500-7126-3-git-send-email-hdegoede@redhat.com |
---|---|
State | Changes Requested |
Delegated to: | Simon Glass |
Headers | show |
Hi Hans, On 5 May 2015 at 07:28, Hans de Goede <hdegoede@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@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. Also are the companions associated with a separate device, or the same one? I'm a bit confused... > + 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
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@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@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 >
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); + 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 */ struct usb_bus_priv { int next_addr; bool desc_before_addr; + bool companion; }; /**
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, and then companion controllers. Signed-off-by: Hans de Goede <hdegoede@redhat.com> --- drivers/usb/host/usb-uclass.c | 30 +++++++++++++++++++++++++----- include/usb.h | 2 ++ 2 files changed, 27 insertions(+), 5 deletions(-)