In a system with multiple XHCI controllers, the global descriptor.hub (bNbrPorts) can be overwritten by a later initialized controller, causing the root hub of an earlier controller to report wrong port numbers.
Fix this by dynamically setting bNbrPorts from the current controller's hcsparams1 in the USB_DT_HUB request handler, instead of relying on a stale global value. Signed-off-by: Beibei Yang <[email protected]> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index dbeb88a..f7984de 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -942,6 +942,12 @@ 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"); + /* Dynamically set bNbrPorts from this controller's + * hcsparams1, because the global descriptor.hub + * may have been overwritten by another controller + * that initialized after this one. */ + descriptor.hub.bNbrPorts = + HCS_MAX_PORTS(xhci_readl(&hccr->cr_hcsparams1)); srcptr = &descriptor.hub; srclen = 0x8; break;

