Re: [PATCH v3 08/11] PCI: dwc: ep: Report integrated DWC eDMA remote resources
From: Koichiro Den <hidden>
Date: 2026-02-05 06:58:38
Also in:
dmaengine, lkml
On Wed, Feb 04, 2026 at 01:06:27PM -0500, Frank Li wrote:
On Wed, Feb 04, 2026 at 11:54:36PM +0900, Koichiro Den wrote:quoted
Implement pci_epc_ops.get_remote_resources() for the DesignWare PCIe endpoint controller. Report: - the integrated eDMA control MMIO window - the per-channel linked-list regions for read/write engines This allows endpoint function drivers to discover and map or inform these resources to a remote peer using the generic EPC API. Signed-off-by: Koichiro Den <redacted> --- .../pci/controller/dwc/pcie-designware-ep.c | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+)diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 7e7844ff0f7e..5c0dcbf18d07 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c@@ -808,6 +808,79 @@ dw_pcie_ep_get_features(struct pci_epc *epc, u8 func_no, u8 vfunc_no) return ep->ops->get_features(ep); } +static int +dw_pcie_ep_get_remote_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no, + struct pci_epc_remote_resource *resources, + int num_resources) +{ + struct dw_pcie_ep *ep = epc_get_drvdata(epc); + struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + struct dw_edma_chip *edma = &pci->edma; + int ll_cnt = 0, needed, idx = 0; + resource_size_t dma_size; + phys_addr_t dma_phys; + unsigned int i; + + if (!pci->edma_reg_size) + return 0; + + dma_phys = pci->edma_reg_phys; + dma_size = pci->edma_reg_size; + + for (i = 0; i < edma->ll_wr_cnt; i++) + if (edma->ll_region_wr[i].sz) + ll_cnt++; + + for (i = 0; i < edma->ll_rd_cnt; i++) + if (edma->ll_region_rd[i].sz) + ll_cnt++; + + needed = 1 + ll_cnt; + + /* Count query mode */ + if (!resources || !num_resources) + return needed;
^[1] count-query implementation
quoted
+ + if (num_resources < needed) + return -ENOSPC;How to predict how many 'num_resources' needs? provide dw_pcie_ep_get_resource_number()? Or dw_pcie_ep_get_remote_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no, struct pci_epc_remote_resource *resources, int *num_resources) return number_resource validate. if resources is NULL, just return how many resource needed.
This is already supported by the current implementation: in
dw_pcie_ep_get_remote_resources(), if resources is NULL (or num_resources
is 0), it returns the number of entries required (see [1] above). Callers
can therefore first query the count and then call again with a properly
sized array.
This behavior is also documented in the core API added in [PATCH v3 06/11]
(pci_epc_get_remote_resources()).
+ * Return:
> + * * >= 0: number of resources returned (or required, if @resources is NULL)
+ * * -EOPNOTSUPP: backend does not support remote resource queries
+ * * other -errno on failure
+ */
+int pci_epc_get_remote_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ struct pci_epc_remote_resource *resources,
+ int num_resources)
Thanks,
Koichiro
Frankquoted
+ + resources[idx++] = (struct pci_epc_remote_resource) { + .type = PCI_EPC_RR_DMA_CTRL_MMIO, + .phys_addr = dma_phys, + .size = dma_size, + }; + + /* One LL region per write channel */ + for (i = 0; i < edma->ll_wr_cnt; i++) { + if (!edma->ll_region_wr[i].sz) + continue; + + resources[idx++] = (struct pci_epc_remote_resource) { + .type = PCI_EPC_RR_DMA_CHAN_DESC, + .phys_addr = edma->ll_region_wr[i].paddr, + .size = edma->ll_region_wr[i].sz, + .u.dma_chan_desc.hw_chan_id = i, + .u.dma_chan_desc.ep2rc = true, + }; + } + + /* One LL region per read channel */ + for (i = 0; i < edma->ll_rd_cnt; i++) { + if (!edma->ll_region_rd[i].sz) + continue; + + resources[idx++] = (struct pci_epc_remote_resource) { + .type = PCI_EPC_RR_DMA_CHAN_DESC, + .phys_addr = edma->ll_region_rd[i].paddr, + .size = edma->ll_region_rd[i].sz, + .u.dma_chan_desc.hw_chan_id = i, + .u.dma_chan_desc.ep2rc = false, + }; + } + + return idx; +} + static const struct pci_epc_ops epc_ops = { .write_header = dw_pcie_ep_write_header, .set_bar = dw_pcie_ep_set_bar,@@ -823,6 +896,7 @@ static const struct pci_epc_ops epc_ops = { .start = dw_pcie_ep_start, .stop = dw_pcie_ep_stop, .get_features = dw_pcie_ep_get_features, + .get_remote_resources = dw_pcie_ep_get_remote_resources, }; /** --2.51.0