]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
usb: xhci: allocate internal DCBAA mirror dynamically
authorNiklas Neronin <niklas.neronin@linux.intel.com>
Wed, 3 Jun 2026 09:11:32 +0000 (12:11 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Jun 2026 17:23:30 +0000 (19:23 +0200)
Allocate the internal virtual device array dynamically based on the
maximum number of slots reported by the host controller. Previously,
the array was always allocated to the absolute maximum of 255 entries.

Repurpose the 'MAX_HC_SLOTS' macro to limit the number of enabled slots.
This mirrors how the maximum number of ports and interrupters are handled.

The allocation now uses kcalloc_node(), which zeroes the memory
automatically, making the explicit memset() call unnecessary.

Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Link: https://patch.msgid.link/20260603091132.1110849-16-mathias.nyman@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h

index 939151e5440efff735850f960d4ea0b2b6616107..a5e7f363922f92a13e3d2a82dd862fcaf70207b4 100644 (file)
@@ -1947,8 +1947,11 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Freed command ring");
        xhci_cleanup_command_queue(xhci);
 
-       for (i = xhci->max_slots; i > 0; i--)
-               xhci_free_virt_devices_depth_first(xhci, i);
+       if (xhci->devs) {
+               for (i = xhci->max_slots; i > 0; i--)
+                       xhci_free_virt_devices_depth_first(xhci, i);
+               kfree(xhci->devs);
+       }
 
        dma_pool_destroy(xhci->segment_pool);
        xhci->segment_pool = NULL;
@@ -2005,6 +2008,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
        xhci->rh_bw = NULL;
        xhci->port_caps = NULL;
        xhci->interrupters = NULL;
+       xhci->devs = NULL;
 
        xhci->usb2_rhub.bus_state.bus_suspended = 0;
        xhci->usb3_rhub.bus_state.bus_suspended = 0;
@@ -2411,6 +2415,12 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
        xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Starting %s", __func__);
 
+       xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Allocating internal virtual device array");
+       xhci->devs = kcalloc_node(xhci->max_slots + 1, sizeof(*xhci->devs), flags,
+                                 dev_to_node(dev));
+       if (!xhci->devs)
+               goto fail;
+
        xhci->dcbaa.ctx_array =
                dma_alloc_coherent(dev, array_size(sizeof(*dcbaa->ctx_array), xhci->max_slots + 1),
                                   &dcbaa->dma, flags);
index 14d7f866f220aedf245c2a05e0f130bdac729859..6922cc5496c18257928965808dd911cda9bdbec0 100644 (file)
@@ -5457,7 +5457,7 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
        if (xhci->hci_version > 0x100)
                xhci->hcc_params2 = readl(&xhci->cap_regs->hcc_params2);
 
-       xhci->max_slots = HCS_MAX_SLOTS(hcs_params1);
+       xhci->max_slots = min(HCS_MAX_SLOTS(hcs_params1), MAX_HC_SLOTS);
        xhci->max_ports = min(HCS_MAX_PORTS(hcs_params1), MAX_HC_PORTS);
        /* xhci-plat or xhci-pci might have set max_interrupters already */
        if (!xhci->max_interrupters)
@@ -5530,8 +5530,6 @@ int xhci_gen_setup(struct usb_hcd *hcd, xhci_get_quirks_t get_quirks)
        init_completion(&xhci->cmd_ring_stop_completion);
        xhci_hcd_page_size(xhci);
 
-       memset(xhci->devs, 0, MAX_HC_SLOTS * sizeof(*xhci->devs));
-
        /* Allocate xHCI data structures */
        retval = xhci_mem_init(xhci, GFP_KERNEL);
        if (retval)
index cb80acac97d4f2abf17e7956dbb8c981f541c03b..d02046a573e45b14746c76eed3429a4d77ec2f7f 100644 (file)
 /* xHCI PCI Configuration Registers */
 #define XHCI_SBRN_OFFSET       (0x60)
 
-/* Max number of USB devices for any host controller - limit in section 6.1 */
-#define MAX_HC_SLOTS           256
+/*
+ * Max number of Devices Slots. xHCI specification section 5.3.3
+ * Valid values are in the range of 1 to 255.
+ */
+#define MAX_HC_SLOTS           255
 /*
  * Max Number of Ports. xHCI specification section 5.3.3
  * Valid values are in the range of 1 to 255.
@@ -1551,7 +1554,7 @@ struct xhci_hcd {
        /* these are not thread safe so use mutex */
        struct mutex mutex;
        /* Internal mirror of the HW's dcbaa */
-       struct xhci_virt_device *devs[MAX_HC_SLOTS];
+       struct xhci_virt_device **devs;
        /* For keeping track of bandwidth domains per roothub. */
        struct xhci_root_port_bw_info   *rh_bw;