Hi Bin, On 23 June 2017 at 03:54, Bin Meng <bmeng...@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...@gmail.com> > --- > > drivers/usb/host/xhci.c | 58 > +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 58 insertions(+) Reviewed-by: Simon Glass <s...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot