Endpoint controller drivers may integrate auxiliary blocks (e.g. DMA
engines) whose register windows and descriptor memories metadata need to
be exposed to a remote peer. Endpoint function drivers need a generic
way to discover such resources without hard-coding controller-specific
helpers.
Add pci_epc_count_aux_resources() / pci_epc_get_aux_resources() and the
corresponding pci_epc_ops callbacks. The count helper returns the number
of available resources via an output parameter, while the get helper
fills a caller-provided array of resources described by type, physical
address and size, plus type-specific metadata.
Suggested-by: Manivannan Sadhasivam <mani@kernel.org>
Signed-off-by: Koichiro Den <den@valinux.co.jp>
---
Changes in v12:
- Add pci_epc_count_aux_resources() and pci_epc_ops.count_aux_resources
- Use pci_epc_function_is_valid() instead of open-coding
drivers/pci/endpoint/pci-epc-core.c | 83 +++++++++++++++++++++++++++++
include/linux/pci-epc.h | 53 ++++++++++++++++++
2 files changed, 136 insertions(+)
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
index 6c3c58185fc5..fded71a19d71 100644
--- a/drivers/pci/endpoint/pci-epc-core.c
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -156,6 +156,89 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
}
EXPORT_SYMBOL_GPL(pci_epc_get_features);
+/**
+ * pci_epc_count_aux_resources() - count EPC-provided auxiliary resources
+ * @epc: EPC device
+ * @func_no: function number
+ * @vfunc_no: virtual function number
+ * @num_resources: returned number of auxiliary resources
+ *
+ * Some EPC backends integrate auxiliary blocks (e.g. DMA engines) whose control
+ * registers and/or descriptor memories can be exposed to the host by mapping
+ * them into BAR space. This helper queries how many such resources the backend
+ * provides.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the backend does not support auxiliary
+ * resource queries, or another -errno on failure.
+ */
+int pci_epc_count_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ int *num_resources)
+{
+ int ret;
+
+ if (!num_resources)
+ return -EINVAL;
+
+ if (!epc || !epc->ops)
+ return -EINVAL;
+
+ if (!pci_epc_function_is_valid(epc, func_no, vfunc_no))
+ return -EINVAL;
+
+ if (!epc->ops->count_aux_resources)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&epc->lock);
+ ret = epc->ops->count_aux_resources(epc, func_no, vfunc_no,
+ num_resources);
+ mutex_unlock(&epc->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_count_aux_resources);
+
+/**
+ * pci_epc_get_aux_resources() - query EPC-provided auxiliary resources
+ * @epc: EPC device
+ * @func_no: function number
+ * @vfunc_no: virtual function number
+ * @resources: output array
+ * @num_resources: size of @resources array in entries
+ *
+ * Some EPC backends integrate auxiliary blocks (e.g. DMA engines) whose control
+ * registers and/or descriptor memories can be exposed to the host by mapping
+ * them into BAR space. This helper queries the backend for such resources.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if the backend does not support auxiliary
+ * resource queries, or another -errno on failure.
+ */
+int pci_epc_get_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ struct pci_epc_aux_resource *resources,
+ int num_resources)
+{
+ int ret;
+
+ if (!resources || num_resources <= 0)
+ return -EINVAL;
+
+ if (!epc || !epc->ops)
+ return -EINVAL;
+
+ if (!pci_epc_function_is_valid(epc, func_no, vfunc_no))
+ return -EINVAL;
+
+ if (!epc->ops->get_aux_resources)
+ return -EOPNOTSUPP;
+
+ mutex_lock(&epc->lock);
+ ret = epc->ops->get_aux_resources(epc, func_no, vfunc_no, resources,
+ num_resources);
+ mutex_unlock(&epc->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pci_epc_get_aux_resources);
+
/**
* pci_epc_stop() - stop the PCI link
* @epc: the link of the EPC device that has to be stopped
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
index 334c2b7578d0..d8b81fc6ca6a 100644
--- a/include/linux/pci-epc.h
+++ b/include/linux/pci-epc.h
@@ -61,6 +61,47 @@ struct pci_epc_map {
void __iomem *virt_addr;
};
+/**
+ * enum pci_epc_aux_resource_type - auxiliary resource type identifiers
+ * @PCI_EPC_AUX_DOORBELL_MMIO: Doorbell MMIO, that might be outside the DMA
+ * controller register window
+ *
+ * EPC backends may expose auxiliary blocks (e.g. DMA engines) by mapping their
+ * register windows and descriptor memories into BAR space. This enum
+ * identifies the type of each exposable resource.
+ */
+enum pci_epc_aux_resource_type {
+ PCI_EPC_AUX_DOORBELL_MMIO,
+};
+
+/**
+ * struct pci_epc_aux_resource - a physical auxiliary resource that may be
+ * exposed for peer use
+ * @type: resource type, see enum pci_epc_aux_resource_type
+ * @phys_addr: physical base address of the resource
+ * @size: size of the resource in bytes
+ * @bar: BAR number where this resource is already exposed to the RC
+ * (NO_BAR if not)
+ * @bar_offset: offset within @bar where the resource starts (valid iff
+ * @bar != NO_BAR)
+ * @u: type-specific metadata
+ */
+struct pci_epc_aux_resource {
+ enum pci_epc_aux_resource_type type;
+ phys_addr_t phys_addr;
+ resource_size_t size;
+ enum pci_barno bar;
+ resource_size_t bar_offset;
+
+ union {
+ /* PCI_EPC_AUX_DOORBELL_MMIO */
+ struct {
+ int irq; /* IRQ number for the doorbell handler */
+ u32 data; /* write value to ring the doorbell */
+ } db_mmio;
+ } u;
+};
+
/**
* struct pci_epc_ops - set of function pointers for performing EPC operations
* @write_header: ops to populate configuration space header
@@ -84,6 +125,8 @@ struct pci_epc_map {
* @start: ops to start the PCI link
* @stop: ops to stop the PCI link
* @get_features: ops to get the features supported by the EPC
+ * @count_aux_resources: ops to count controller-owned auxiliary resources
+ * @get_aux_resources: ops to retrieve controller-owned auxiliary resources
* @owner: the module owner containing the ops
*/
struct pci_epc_ops {
@@ -115,6 +158,11 @@ struct pci_epc_ops {
void (*stop)(struct pci_epc *epc);
const struct pci_epc_features* (*get_features)(struct pci_epc *epc,
u8 func_no, u8 vfunc_no);
+ int (*count_aux_resources)(struct pci_epc *epc, u8 func_no,
+ u8 vfunc_no, int *num_resources);
+ int (*get_aux_resources)(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ struct pci_epc_aux_resource *resources,
+ int num_resources);
struct module *owner;
};
@@ -339,6 +387,11 @@ int pci_epc_start(struct pci_epc *epc);
void pci_epc_stop(struct pci_epc *epc);
const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc,
u8 func_no, u8 vfunc_no);
+int pci_epc_count_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ int *num_resources);
+int pci_epc_get_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no,
+ struct pci_epc_aux_resource *resources,
+ int num_resources);
enum pci_barno
pci_epc_get_first_free_bar(const struct pci_epc_features *epc_features);
enum pci_barno pci_epc_get_next_free_bar(const struct pci_epc_features
--
2.51.0
On Fri, Mar 27, 2026 at 12:54:16PM +0900, Koichiro Den wrote: > Endpoint controller drivers may integrate auxiliary blocks (e.g. DMA > engines) whose register windows and descriptor memories metadata need to > be exposed to a remote peer. Endpoint function drivers need a generic > way to discover such resources without hard-coding controller-specific > helpers. > > Add pci_epc_count_aux_resources() / pci_epc_get_aux_resources() and the > corresponding pci_epc_ops callbacks. The count helper returns the number > of available resources via an output parameter, while the get helper > fills a caller-provided array of resources described by type, physical > address and size, plus type-specific metadata. > > Suggested-by: Manivannan Sadhasivam <mani@kernel.org> > Signed-off-by: Koichiro Den <den@valinux.co.jp> > --- > Changes in v12: > - Add pci_epc_count_aux_resources() and pci_epc_ops.count_aux_resources > - Use pci_epc_function_is_valid() instead of open-coding > > drivers/pci/endpoint/pci-epc-core.c | 83 +++++++++++++++++++++++++++++ > include/linux/pci-epc.h | 53 ++++++++++++++++++ > 2 files changed, 136 insertions(+) > > diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c > index 6c3c58185fc5..fded71a19d71 100644 > --- a/drivers/pci/endpoint/pci-epc-core.c > +++ b/drivers/pci/endpoint/pci-epc-core.c > @@ -156,6 +156,89 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, > } > EXPORT_SYMBOL_GPL(pci_epc_get_features); > > +/** > + * pci_epc_count_aux_resources() - count EPC-provided auxiliary resources > + * @epc: EPC device > + * @func_no: function number > + * @vfunc_no: virtual function number > + * @num_resources: returned number of auxiliary resources > + * > + * Some EPC backends integrate auxiliary blocks (e.g. DMA engines) whose control > + * registers and/or descriptor memories can be exposed to the host by mapping > + * them into BAR space. This helper queries how many such resources the backend > + * provides. > + * > + * Return: 0 on success, -EOPNOTSUPP if the backend does not support auxiliary > + * resource queries, or another -errno on failure. > + */ > +int pci_epc_count_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no, > + int *num_resources) Most like such kinds APIs return count directly, < 0, means error. >= 0, means how many resource. Frank
On Fri, Mar 27, 2026 at 12:31:09PM -0400, Frank Li wrote: > On Fri, Mar 27, 2026 at 12:54:16PM +0900, Koichiro Den wrote: > > Endpoint controller drivers may integrate auxiliary blocks (e.g. DMA > > engines) whose register windows and descriptor memories metadata need to > > be exposed to a remote peer. Endpoint function drivers need a generic > > way to discover such resources without hard-coding controller-specific > > helpers. > > > > Add pci_epc_count_aux_resources() / pci_epc_get_aux_resources() and the > > corresponding pci_epc_ops callbacks. The count helper returns the number > > of available resources via an output parameter, while the get helper > > fills a caller-provided array of resources described by type, physical > > address and size, plus type-specific metadata. > > > > Suggested-by: Manivannan Sadhasivam <mani@kernel.org> > > Signed-off-by: Koichiro Den <den@valinux.co.jp> > > --- > > Changes in v12: > > - Add pci_epc_count_aux_resources() and pci_epc_ops.count_aux_resources > > - Use pci_epc_function_is_valid() instead of open-coding > > > > drivers/pci/endpoint/pci-epc-core.c | 83 +++++++++++++++++++++++++++++ > > include/linux/pci-epc.h | 53 ++++++++++++++++++ > > 2 files changed, 136 insertions(+) > > > > diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c > > index 6c3c58185fc5..fded71a19d71 100644 > > --- a/drivers/pci/endpoint/pci-epc-core.c > > +++ b/drivers/pci/endpoint/pci-epc-core.c > > @@ -156,6 +156,89 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, > > } > > EXPORT_SYMBOL_GPL(pci_epc_get_features); > > > > +/** > > + * pci_epc_count_aux_resources() - count EPC-provided auxiliary resources > > + * @epc: EPC device > > + * @func_no: function number > > + * @vfunc_no: virtual function number > > + * @num_resources: returned number of auxiliary resources > > + * > > + * Some EPC backends integrate auxiliary blocks (e.g. DMA engines) whose control > > + * registers and/or descriptor memories can be exposed to the host by mapping > > + * them into BAR space. This helper queries how many such resources the backend > > + * provides. > > + * > > + * Return: 0 on success, -EOPNOTSUPP if the backend does not support auxiliary > > + * resource queries, or another -errno on failure. > > + */ > > +int pci_epc_count_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no, > > + int *num_resources) > > Most like such kinds APIs return count directly, > < 0, means error. > >= 0, means how many resource. I chose to return 0 on success here based on Mani's earlier feedback on v11: https://lore.kernel.org/linux-pci/lfbv6sjevz4xtjr6zt2hl3wap3bfwkvigqb6fdztqmutxgcvld@3t4x5gstr4nj/ I don't have a strong preference here, but since there seems to be no clear policy/convention across the kernel, I would prefer to follow what is most consistent and maintainable for the maintainers. Of course, I'm happy to switch and respin if preferred. Thanks for reviewing, Koichiro > > Frank
On Tue, Mar 31, 2026 at 10:56:34PM +0900, Koichiro Den wrote: > On Fri, Mar 27, 2026 at 12:31:09PM -0400, Frank Li wrote: > > On Fri, Mar 27, 2026 at 12:54:16PM +0900, Koichiro Den wrote: > > > Endpoint controller drivers may integrate auxiliary blocks (e.g. DMA > > > engines) whose register windows and descriptor memories metadata need to > > > be exposed to a remote peer. Endpoint function drivers need a generic > > > way to discover such resources without hard-coding controller-specific > > > helpers. > > > > > > Add pci_epc_count_aux_resources() / pci_epc_get_aux_resources() and the > > > corresponding pci_epc_ops callbacks. The count helper returns the number > > > of available resources via an output parameter, while the get helper > > > fills a caller-provided array of resources described by type, physical > > > address and size, plus type-specific metadata. > > > > > > Suggested-by: Manivannan Sadhasivam <mani@kernel.org> > > > Signed-off-by: Koichiro Den <den@valinux.co.jp> > > > --- > > > Changes in v12: > > > - Add pci_epc_count_aux_resources() and pci_epc_ops.count_aux_resources > > > - Use pci_epc_function_is_valid() instead of open-coding > > > > > > drivers/pci/endpoint/pci-epc-core.c | 83 +++++++++++++++++++++++++++++ > > > include/linux/pci-epc.h | 53 ++++++++++++++++++ > > > 2 files changed, 136 insertions(+) > > > > > > diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c > > > index 6c3c58185fc5..fded71a19d71 100644 > > > --- a/drivers/pci/endpoint/pci-epc-core.c > > > +++ b/drivers/pci/endpoint/pci-epc-core.c > > > @@ -156,6 +156,89 @@ const struct pci_epc_features *pci_epc_get_features(struct pci_epc *epc, > > > } > > > EXPORT_SYMBOL_GPL(pci_epc_get_features); > > > > > > +/** > > > + * pci_epc_count_aux_resources() - count EPC-provided auxiliary resources > > > + * @epc: EPC device > > > + * @func_no: function number > > > + * @vfunc_no: virtual function number > > > + * @num_resources: returned number of auxiliary resources > > > + * > > > + * Some EPC backends integrate auxiliary blocks (e.g. DMA engines) whose control > > > + * registers and/or descriptor memories can be exposed to the host by mapping > > > + * them into BAR space. This helper queries how many such resources the backend > > > + * provides. > > > + * > > > + * Return: 0 on success, -EOPNOTSUPP if the backend does not support auxiliary > > > + * resource queries, or another -errno on failure. > > > + */ > > > +int pci_epc_count_aux_resources(struct pci_epc *epc, u8 func_no, u8 vfunc_no, > > > + int *num_resources) > > > > Most like such kinds APIs return count directly, > > < 0, means error. > > >= 0, means how many resource. > > I chose to return 0 on success here based on Mani's earlier feedback on v11: > https://lore.kernel.org/linux-pci/lfbv6sjevz4xtjr6zt2hl3wap3bfwkvigqb6fdztqmutxgcvld@3t4x5gstr4nj/ I am okay for both, But may request Mani think 2nd. Most existing kernel API use return value for count of resource. Frank > > I don't have a strong preference here, but since there seems to be no clear > policy/convention across the kernel, I would prefer to follow what is most > consistent and maintainable for the maintainers. Of course, I'm happy to switch > and respin if preferred. > > Thanks for reviewing, > Koichiro > > > > > Frank
© 2016 - 2026 Red Hat, Inc.