[PATCH] usb: xhci: Fix bNbrPorts overwritten by another controller
m13738176232
13738176232 at 163.com
Mon Jun 29 08:25:41 CEST 2026
For the `struct descriptor`, only the `hub` part (`bNbrPorts` and `wHubCharacteristics`) is different for each controller; the other five members (device, config, interface, endpoint,ep_companion)are identical for all XHCI root hubs.
My previous patch only fixed the dynamic reading of `bNbrPorts`, but `wHubCharacteristics` is also different for each controller and will be overridden by the last controller.
New patch as below for referrence.
Signed-off-by: Beibei Yang <13738176232 at 163.com>
Index: drivers/usb/host/xhci.c
===================================================================
--- drivers/usb/host/xhci.c (revision 10446)
+++ drivers/usb/host/xhci.c (working copy)
@@ -954,13 +954,7 @@
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:
@@ -1221,20 +1215,21 @@
return -ENOMEM;
reg = xhci_readl(&hccr->cr_hcsparams1);
- descriptor.hub.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >>
- HCS_MAX_PORTS_SHIFT);
- printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
+ ctrl->hub_desc = descriptor.hub;
+ ctrl->hub_desc.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >>
+ HCS_MAX_PORTS_SHIFT);
+ 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);
Index: include/usb/xhci.h
===================================================================
--- include/usb/xhci.h (revision 10446)
+++ include/usb/xhci.h (working copy)
@@ -21,6 +21,7 @@
#include <asm/io.h>
#include <linux/list.h>
#include <linux/compat.h>
+#include <usb.h>
#define MAX_EP_CTX_NUM 31
#define XHCI_ALIGNMENT 64
@@ -1229,6 +1230,7 @@
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;
};
---- Replied Message ----
| From | Marek Vasut<marek.vasut at mailbox.org> |
| Date | 06/28/2026 04:10 |
| To | Beibei Yang<13738176232 at 163.com>、u-boot at lists.denx.de |
| Cc | bmeng.cn at gmail.com |
| Subject | Re: [PATCH] usb: xhci: Fix bNbrPorts overwritten by another controller |
On 6/27/26 2:37 PM, Beibei Yang wrote:
> 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.
How about having one descriptor per controller ?
This is probably easily doable in xhci_lowlevel_init() with some
ctrl->hub_desc = kmemdup(descriptor.hub,...); and related tweaks.
What do you think ?
More information about the U-Boot
mailing list