From e330c8b83e8784d23614f80ca3f12b11ceb515d8 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sat, 21 Jan 2023 20:28:00 +0100 Subject: [PATCH] usb: xhci: Fix root hub descriptor When a system has multiple XHCI controllers, some of the properties described in the descriptor of the root hub (such as the number of ports) might differ between controllers. Fix this by switching from a single global hub descriptor to a hub descriptor per controller. Signed-off-by: Mark Kettenis Reviewed-by: Marek Vasut --- drivers/usb/host/xhci.c | 15 ++++++++------- include/usb/xhci.h | 1 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 440b0224b1..9e33c5d855 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -944,7 +944,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, case USB_DT_HUB: case USB_DT_SS_HUB: debug("USB_DT_HUB config\n"); - srcptr = &descriptor.hub; + srcptr = &ctrl->hub_desc; srclen = 0x8; break; default: @@ -1203,21 +1203,22 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl) /* initializing xhci data structures */ if (xhci_mem_init(ctrl, hccr, hcor) < 0) return -ENOMEM; + ctrl->hub_desc = descriptor.hub; reg = xhci_readl(&hccr->cr_hcsparams1); - descriptor.hub.bNbrPorts = HCS_MAX_PORTS(reg); - printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts); + ctrl->hub_desc.bNbrPorts = HCS_MAX_PORTS(reg); + printf("Register %x NbrPorts %d\n", reg, ctrl->hub_desc.bNbrPorts); /* Port Indicators */ reg = xhci_readl(&hccr->cr_hccparams); if (HCS_INDICATOR(reg)) - put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) - | 0x80, &descriptor.hub.wHubCharacteristics); + put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics) + | 0x80, &ctrl->hub_desc.wHubCharacteristics); /* Port Power Control */ if (HCC_PPC(reg)) - put_unaligned(get_unaligned(&descriptor.hub.wHubCharacteristics) - | 0x01, &descriptor.hub.wHubCharacteristics); + put_unaligned(get_unaligned(&ctrl->hub_desc.wHubCharacteristics) + | 0x01, &ctrl->hub_desc.wHubCharacteristics); if (xhci_start(hcor)) { xhci_reset(hcor); diff --git a/include/usb/xhci.h b/include/usb/xhci.h index 85c359fa1b..4a4ac10229 100644 --- a/include/usb/xhci.h +++ b/include/usb/xhci.h @@ -1222,6 +1222,7 @@ struct xhci_ctrl { struct xhci_erst_entry entry[ERST_NUM_SEGS]; struct xhci_scratchpad *scratchpad; struct xhci_virt_device *devs[MAX_HC_SLOTS]; + struct usb_hub_descriptor hub_desc; int rootdev; u16 hci_version; int page_size; -- 2.39.5