diff options
author | Ahmad Fatoum <a.fatoum@pengutronix.de> | 2024-02-19 14:38:30 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2024-02-20 12:07:03 +0100 |
commit | cb1ead123c454f93da50574a1d98697c1741851c (patch) | |
tree | 1692dd8c888cb1dee4a2bbca25b4ce6854de9b6f | |
parent | be01454be27a4aff1c66d27b30aebb5af0322eeb (diff) | |
download | barebox-cb1ead123c45.tar.gz barebox-cb1ead123c45.tar.xz |
usb: xhci: Fix root hub descriptor
This ports U-Boot commit e330c8b83e8784d23614f80ca3f12b11ceb515d8:
| Author: Mark Kettenis <kettenis@openbsd.org>
| 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@openbsd.org>
and additionally marks the descriptor template const, so it's safe
against future inadvertent modification.
Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
Link: https://lore.barebox.org/20240219133835.3886399-11-a.fatoum@pengutronix.de
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
-rw-r--r-- | drivers/usb/host/xhci.c | 19 | ||||
-rw-r--r-- | 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 2c923b9869..c5c21a526a 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 e676116f42..4a08f3f9e0 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; }; |