From: Mathias Nyman <mathias.nyman@linux.intel.com>
To: <gregkh@linuxfoundation.org>
Cc: <linux-usb@vger.kernel.org>,
Niklas Neronin <niklas.neronin@linux.intel.com>,
Mathias Nyman <mathias.nyman@linux.intel.com>
Subject: [PATCH 13/15] usb: xhci: refactor DCBAA struct
Date: Wed, 3 Jun 2026 12:11:30 +0300 [thread overview]
Message-ID: <20260603091132.1110849-14-mathias.nyman@linux.intel.com> (raw)
In-Reply-To: <20260603091132.1110849-1-mathias.nyman@linux.intel.com>
From: Niklas Neronin <niklas.neronin@linux.intel.com>
Embed the 'xhci_device_context_array' structure directly within 'xhci_hcd'
instead of allocating it as a separate block. Only the array of device
context addresses is now allocated separately.
Since the device context addresses are no longer part of an array
structure, rename 'dev_context_ptrs' to 'ctx_array' for clearer access
semantics.
Also remove the redundant comment next to the 'ctx_array' allocation;
using dma_alloc_coherent() for 64-bit * N allocations guarantees both
physically contiguous and properly aligned for 64-byte boundaries.
The xHCI section (5.4.6) refers to DCBAAP instead of DCBAA (6.1).
This change does not modify the number of host controller slots but
simplifies memory management and prepares the driver for a variable number
of HC slots in the future.
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 40 ++++++++++++++++++------------------
drivers/usb/host/xhci-ring.c | 2 +-
drivers/usb/host/xhci.c | 6 +++---
drivers/usb/host/xhci.h | 13 +++++++-----
4 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 289461c06bf9..019dac47c5d6 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -877,8 +877,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, struct xhci_virt_device *dev,
/* If device ctx array still points to _this_ device, clear it */
if (dev->out_ctx &&
- xhci->dcbaa->dev_context_ptrs[slot_id] == cpu_to_le64(dev->out_ctx->dma))
- xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+ xhci->dcbaa.ctx_array[slot_id] == cpu_to_le64(dev->out_ctx->dma))
+ xhci->dcbaa.ctx_array[slot_id] = 0;
trace_xhci_free_virt_device(dev);
@@ -1016,11 +1016,11 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
dev->udev = udev;
/* Point to output device context in dcbaa. */
- xhci->dcbaa->dev_context_ptrs[slot_id] = cpu_to_le64(dev->out_ctx->dma);
+ xhci->dcbaa.ctx_array[slot_id] = cpu_to_le64(dev->out_ctx->dma);
xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
slot_id,
- &xhci->dcbaa->dev_context_ptrs[slot_id],
- le64_to_cpu(xhci->dcbaa->dev_context_ptrs[slot_id]));
+ &xhci->dcbaa.ctx_array[slot_id],
+ le64_to_cpu(xhci->dcbaa.ctx_array[slot_id]));
trace_xhci_alloc_virt_device(dev);
@@ -1671,7 +1671,7 @@ static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
if (!xhci->scratchpad->sp_buffers)
goto fail_sp3;
- xhci->dcbaa->dev_context_ptrs[0] = cpu_to_le64(xhci->scratchpad->sp_dma);
+ xhci->dcbaa.ctx_array[0] = cpu_to_le64(xhci->scratchpad->sp_dma);
for (i = 0; i < num_sp; i++) {
dma_addr_t dma;
void *buf = dma_alloc_coherent(dev, xhci->page_size, &dma,
@@ -1927,6 +1927,7 @@ void xhci_rh_bw_cleanup(struct xhci_hcd *xhci)
void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+ struct xhci_device_context_array *dcbaa;
int i;
cancel_delayed_work_sync(&xhci->cmd_timer);
@@ -1972,10 +1973,12 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Freed medium stream array pool");
- if (xhci->dcbaa)
- dma_free_coherent(dev, sizeof(*xhci->dcbaa),
- xhci->dcbaa, xhci->dcbaa->dma);
- xhci->dcbaa = NULL;
+ dcbaa = &xhci->dcbaa;
+ if (dcbaa->ctx_array) {
+ dma_free_coherent(dev, array_size(sizeof(*dcbaa->ctx_array), MAX_HC_SLOTS),
+ dcbaa->ctx_array, dcbaa->dma);
+ dcbaa->ctx_array = NULL;
+ }
scratchpad_free(xhci);
@@ -2403,23 +2406,20 @@ EXPORT_SYMBOL_GPL(xhci_create_secondary_interrupter);
int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
{
- struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
- dma_addr_t dma;
+ struct device *dev = xhci_to_hcd(xhci)->self.sysdev;
+ struct xhci_device_context_array *dcbaa = &xhci->dcbaa;
xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Starting %s", __func__);
- /*
- * xHCI section 5.4.6 - Device Context array must be
- * "physically contiguous and 64-byte (cache line) aligned".
- */
- xhci->dcbaa = dma_alloc_coherent(dev, sizeof(*xhci->dcbaa), &dma, flags);
- if (!xhci->dcbaa)
+ dcbaa->ctx_array =
+ dma_alloc_coherent(dev, array_size(sizeof(*dcbaa->ctx_array), MAX_HC_SLOTS),
+ &dcbaa->dma, flags);
+ if (!dcbaa->ctx_array)
goto fail;
- xhci->dcbaa->dma = dma;
xhci_dbg_trace(xhci, trace_xhci_dbg_init,
"Device context base array address = %pad (DMA), %p (virt)",
- &xhci->dcbaa->dma, xhci->dcbaa);
+ &dcbaa->dma, dcbaa->ctx_array);
/*
* Initialize the ring segment pool. The ring must be a contiguous
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 83209db29962..3c304372bad3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1613,7 +1613,7 @@ static void xhci_handle_cmd_disable_slot(struct xhci_hcd *xhci, int slot_id,
/* Delete default control endpoint resources */
xhci_free_device_endpoint_resources(xhci, virt_dev, true);
if (cmd_comp_code == COMP_SUCCESS) {
- xhci->dcbaa->dev_context_ptrs[slot_id] = 0;
+ xhci->dcbaa.ctx_array[slot_id] = 0;
xhci->devs[slot_id] = NULL;
}
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0646fedf2042..14d7f866f220 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -551,7 +551,7 @@ static void xhci_init(struct usb_hcd *hcd)
xhci_set_cmd_ring_deq(xhci);
/* Set Device Context Base Address Array pointer */
- xhci_write_64(xhci, xhci->dcbaa->dma, &xhci->op_regs->dcbaa_ptr);
+ xhci_write_64(xhci, xhci->dcbaa.dma, &xhci->op_regs->dcbaa_ptr);
/* Set Doorbell array pointer */
xhci_set_doorbell_ptr(xhci);
@@ -4457,9 +4457,9 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev,
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
"Slot ID %d dcbaa entry @%p = %#016llx",
udev->slot_id,
- &xhci->dcbaa->dev_context_ptrs[udev->slot_id],
+ &xhci->dcbaa.ctx_array[udev->slot_id],
(unsigned long long)
- le64_to_cpu(xhci->dcbaa->dev_context_ptrs[udev->slot_id]));
+ le64_to_cpu(xhci->dcbaa.ctx_array[udev->slot_id]));
xhci_dbg_trace(xhci, trace_xhci_dbg_address,
"Output Context DMA address = %#08llx",
(unsigned long long)virt_dev->out_ctx->dma);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index e73c498449e8..9d57def08ea6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -792,12 +792,15 @@ struct xhci_tt_bw_info {
/**
* struct xhci_device_context_array
- * @dev_context_ptr array of 64-bit DMA addresses for device contexts
+ * @ctx_array: Pointer to an array of addresses
+ * @dma: DMA address to @ctx_array
+ *
+ * Device Context Base Address Array (DCBAA) - Section 6.1.
+ * ctx_array[0]: Scratchpad Buffer Array Base Address
+ * ctx_array[1-MaxSlots]: Device Context Base Address
*/
struct xhci_device_context_array {
- /* 64-bit device addresses; we only write 32-bit addresses */
- __le64 dev_context_ptrs[MAX_HC_SLOTS];
- /* private xHCD pointers */
+ __le64 *ctx_array;
dma_addr_t dma;
};
/*
@@ -1531,7 +1534,7 @@ struct xhci_hcd {
/* optional reset controller */
struct reset_control *reset;
/* data structures */
- struct xhci_device_context_array *dcbaa;
+ struct xhci_device_context_array dcbaa;
struct xhci_interrupter **interrupters;
struct xhci_ring *cmd_ring;
unsigned int cmd_ring_state;
--
2.43.0
next prev parent reply other threads:[~2026-06-03 9:12 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-03 9:11 [PATCH 00/15] xhci features for usb-next Mathias Nyman
2026-06-03 9:11 ` [PATCH 01/15] usb: xhci: fix typo in xhci_set_port_power() comment Mathias Nyman
2026-06-03 9:11 ` [PATCH 02/15] usb: xhci: remove legacy 'num_trbs_free' tracking Mathias Nyman
2026-06-03 9:11 ` [PATCH 03/15] usb: xhci: Simplify xhci_quiesce() Mathias Nyman
2026-06-03 9:11 ` [PATCH 04/15] usb: xhci: Remove skip_isoc_td() Mathias Nyman
2026-06-03 9:11 ` [PATCH 05/15] usb: xhci: Remove isochronous URB_SHORT_NOT_OK handling Mathias Nyman
2026-06-03 9:11 ` [PATCH 06/15] usb: xhci: Improve Soft Retries after short transfers Mathias Nyman
2026-06-03 9:11 ` [PATCH 07/15] xhci: dbc: Fix sysfs ABI Documentation for xhci dbc states Mathias Nyman
2026-06-03 9:11 ` [PATCH 08/15] xhci: dbc: serialize enabling and disabling dbc Mathias Nyman
2026-06-15 6:11 ` Borah, Chaitanya Kumar
2026-06-15 8:47 ` Mathias Nyman
2026-06-15 8:55 ` [RFT PATCH] xhci: dbc: support runtime suspend while DbC is in enabled state Mathias Nyman
2026-06-15 12:14 ` Borah, Chaitanya Kumar
2026-06-03 9:11 ` [PATCH 09/15] xhci: dbc: add helper to set and clear DbC DCE enable bit Mathias Nyman
2026-06-03 9:11 ` [PATCH 10/15] xhci: dbc: add timestamps to DbC state changes in a new helper Mathias Nyman
2026-06-03 9:11 ` [PATCH 11/15] xhci: dbc: detect and recover hung DbC during enumeraton Mathias Nyman
2026-06-03 9:11 ` [PATCH 12/15] xhci: Prevent queuing new commands if xhci is inaccessible Mathias Nyman
2026-06-03 9:11 ` Mathias Nyman [this message]
2026-06-03 9:11 ` [PATCH 14/15] usb: xhci: allocate DCBAA based on host controller max slots Mathias Nyman
2026-06-03 9:11 ` [PATCH 15/15] usb: xhci: allocate internal DCBAA mirror dynamically Mathias Nyman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260603091132.1110849-14-mathias.nyman@linux.intel.com \
--to=mathias.nyman@linux.intel.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-usb@vger.kernel.org \
--cc=niklas.neronin@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox