[U-Boot] [PATCH 14/16] usb: xhci: Implement update_hub_device() operation

Simon Glass sjg at chromium.org
Thu Jul 6 04:50:01 UTC 2017


Hi Bin,

On 23 June 2017 at 03:54, Bin Meng <bmeng.cn at gmail.com> wrote:
> There is no way to know whether the attached device is a hub or
> not in advance before device's descriptor is fetched. But once

nits:

before the device's

> we know it's a high speed hub, per xHCI spec, we need tell xHC

per the xHCI

we need to tell

> it's a hub device by initializing hub related fields in the

hub-related

> input slot context.
>
> Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
> ---
>
>  drivers/usb/host/xhci.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)

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

>
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 1148127..a82502c 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -1170,6 +1170,63 @@ static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev)
>         return _xhci_alloc_device(udev);
>  }
>
> +static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
> +{
> +       struct xhci_ctrl *ctrl = dev_get_priv(dev);
> +       struct usb_hub_device *hub = dev_get_uclass_priv(udev->dev);
> +       struct xhci_virt_device *virt_dev;
> +       struct xhci_input_control_ctx *ctrl_ctx;
> +       struct xhci_container_ctx *out_ctx;
> +       struct xhci_container_ctx *in_ctx;
> +       struct xhci_slot_ctx *slot_ctx;
> +       int slot_id = udev->slot_id;
> +       unsigned think_time;
> +
> +       debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
> +
> +       /* Ignore root hubs */
> +       if (usb_hub_is_root_hub(udev->dev))
> +               return 0;
> +
> +       virt_dev = ctrl->devs[slot_id];
> +       BUG_ON(!virt_dev);
> +
> +       out_ctx = virt_dev->out_ctx;
> +       in_ctx = virt_dev->in_ctx;
> +
> +       ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
> +       /* Initialize the input context control */
> +       ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
> +       ctrl_ctx->drop_flags = 0;
> +
> +       xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
> +
> +       /* slot context */
> +       xhci_slot_copy(ctrl, in_ctx, out_ctx);
> +       slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
> +
> +       /* Update hub related fields */
> +       slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
> +       if (hub->tt.multi && udev->speed == USB_SPEED_HIGH)
> +               slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
> +       slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild));
> +       /*
> +        * Set TT think time - convert from ns to FS bit times.
> +        *
> +        * 0 =  8 FS bit times, 1 = 16 FS bit times,
> +        * 2 = 24 FS bit times, 3 = 32 FS bit times.
> +        *
> +        * This field shall be 0 if the device is not a high-spped hub.
> +        */
> +       think_time = hub->tt.think_time;
> +       if (think_time != 0)
> +               think_time = (think_time / 666) - 1;

What is 666? Can you add a comment?

> +       if (udev->speed == USB_SPEED_HIGH)
> +               slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time));
> +
> +       return xhci_configure_endpoints(udev, false);
> +}
> +
>  int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
>                   struct xhci_hcor *hcor)
>  {
> @@ -1222,6 +1279,7 @@ struct dm_usb_ops xhci_usb_ops = {
>         .bulk = xhci_submit_bulk_msg,
>         .interrupt = xhci_submit_int_msg,
>         .alloc_device = xhci_alloc_device,
> +       .update_hub_device = xhci_update_hub_device,
>  };
>
>  #endif
> --
> 2.9.2
>

Regards,
Simon


More information about the U-Boot mailing list