[U-Boot] [PATCH v2 4/9] dm: usb: Fix finding of first upstream usb-2 hub in the ehci dm code

Simon Glass sjg at chromium.org
Sun May 3 18:59:57 CEST 2015


On 1 May 2015 at 04:04, Hans de Goede <hdegoede at redhat.com> wrote:
> The ehci driver model code for finding the first upstream usb-2 hub before
> this commit has a number of issues:
>
> 1) "if (!ttdev->speed != USB_SPEED_HIGH)" does not work because the '!'
>    takes presedence over the '!=' this should simply be
>    "if (ttdev->speed == USB_SPEED_HIGH)"
> 2) It makes ttdev point to the first upstream usb-2 hub, but ttdev should
>    point to the last usb-1 device before the first usb-2 hub (when going
>    upstream from the device), as ttdev is used to find the port of the
>    first usb-2 hub to which the the last usb-1 device is connected.
> 3) parent_devnum however should be set to the devnum of the first usb-2
>    hub, so we need to keep pointers around to both usb_device structs.
>
> To complicate things further during enumeration usb_device.dev will point
> to the parent udevice, where as during normal use it will point to
> the actual udevice, we must handle both cases correctly.
>
> This commit fixes all this making usb-1 devices attached to usb-2 hubs,
> including usb-1 devices attached to usb-1 hubs attached to usb-2 hubs, work.
>
> Signed-off-by: Hans de Goede <hdegoede at redhat.com>

I'm pleased that you understand this logic.

Acked-by: Simon Glass <sjg at chromium.org>

> ---
>  drivers/usb/host/ehci-hcd.c | 34 ++++++++++++++++++++++------------
>  1 file changed, 22 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
> index 85adbf4..9471bcb 100644
> --- a/drivers/usb/host/ehci-hcd.c
> +++ b/drivers/usb/host/ehci-hcd.c
> @@ -303,23 +303,33 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
>          * in the tree before that one!
>          */
>  #ifdef CONFIG_DM_USB
> +       /*
> +        * When called from usb-uclass.c: usb_scan_device() udev->dev points
> +        * to the parent udevice, not the actual udevice belonging to the
> +        * udev as the device is not instantiated yet. So when searching
> +        * for the first usb-2 parent start with udev->dev not
> +        * udev->dev->parent .
> +        */
>         struct udevice *parent;
> +       struct usb_device *uparent;
> +
> +       ttdev = udev;
> +       parent = udev->dev;
> +       uparent = dev_get_parentdata(parent);
>
> -       for (ttdev = udev; ; ) {
> -               struct udevice *dev = ttdev->dev;
> +       while (uparent->speed != USB_SPEED_HIGH) {
> +               struct udevice *dev = parent;
>
> -               if (dev->parent &&
> -                   device_get_uclass_id(dev->parent) == UCLASS_USB_HUB)
> -                       parent = dev->parent;
> -               else
> -                       parent = NULL;
> -               if (!parent)
> +               if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
> +                       printf("ehci: Error cannot find high speed parent of usb-1 device\n");
>                         return;
> -               ttdev = dev_get_parentdata(parent);
> -               if (!ttdev->speed != USB_SPEED_HIGH)
> -                       break;
> +               }
> +
> +               ttdev = dev_get_parentdata(dev);
> +               parent = dev->parent;
> +               uparent = dev_get_parentdata(parent);
>         }
> -       parent_devnum = ttdev->devnum;
> +       parent_devnum = uparent->devnum;
>  #else
>         ttdev = udev;
>         while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
> --
> 2.3.6
>


More information about the U-Boot mailing list