This ports U-Boot commit e330c8b83e8784d23614f80ca3f12b11ceb515d8: | Author: Mark Kettenis <kettenis@xxxxxxxxxxx> | AuthorDate: Sat Jan 21 20:28:00 2023 +0100 | | 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 <kettenis@xxxxxxxxxxx> and additionally marks the descriptor template const, so it's safe against future inadvertent modification. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- drivers/usb/host/xhci.c | 19 +++++++++++-------- drivers/usb/host/xhci.h | 1 + 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 2c923b9869ae..c5c21a526a29 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -30,7 +30,7 @@ #include "xhci.h" -static struct descriptor { +static const struct descriptor { struct usb_hub_descriptor hub; struct usb_device_descriptor device; struct usb_config_descriptor config; @@ -861,7 +861,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, { uint8_t tmpbuf[4]; u16 typeReq; - void *srcptr = NULL; + const void *srcptr = NULL; int len, srclen; uint32_t reg; volatile uint32_t *status_reg; @@ -929,7 +929,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe, case USB_DT_HUB: case USB_DT_SS_HUB: dev_dbg(&udev->dev, "USB_DT_HUB config\n"); - srcptr = &descriptor.hub; + srcptr = &ctrl->hub_desc; srclen = 0x8; break; default: @@ -1188,20 +1188,23 @@ 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); + ctrl->hub_desc.bNbrPorts = HCS_MAX_PORTS(reg); + + dev_dbg(ctrl->dev, "Register 0x%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(ctrl)) { xhci_reset(ctrl); diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index e676116f4266..4a08f3f9e0d2 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1223,6 +1223,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; void *bounce_buffer; int rootdev; }; -- 2.39.2