Introduce pci_epf_get_bar_required_size() to retrieve the required BAR
size. Prepare for adding support to set an MMIO address to a specific BAR.
No functional changes.
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
change in v2
- new patch
---
drivers/pci/endpoint/pci-epf-core.c | 52 ++++++++++++++++++++++++-------------
1 file changed, 34 insertions(+), 18 deletions(-)
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
index d54e18872aefc07c655c94c104a347328ff7a432..4281067d4a62da6fbf6c2fb807b0f1b5afd1f45b 100644
--- a/drivers/pci/endpoint/pci-epf-core.c
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -248,6 +248,36 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
}
EXPORT_SYMBOL_GPL(pci_epf_free_space);
+static size_t
+pci_epf_get_bar_required_size(struct pci_epf *epf, size_t size,
+ enum pci_barno bar,
+ const struct pci_epc_features *epc_features,
+ enum pci_epc_interface_type type)
+{
+ u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
+
+ if (size < 128)
+ size = 128;
+
+ /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */
+ if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M)
+ size = SZ_1M;
+
+ if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
+ if (size > bar_fixed_size) {
+ dev_err(&epf->dev,
+ "requested BAR size is larger than fixed size\n");
+ return 0;
+ }
+ size = bar_fixed_size;
+ } else {
+ /* BAR size must be power of two */
+ size = roundup_pow_of_two(size);
+ }
+
+ return size;
+}
+
/**
* pci_epf_alloc_space() - allocate memory for the PCI EPF register space
* @epf: the EPF device to whom allocate the memory
@@ -264,7 +294,6 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
const struct pci_epc_features *epc_features,
enum pci_epc_interface_type type)
{
- u64 bar_fixed_size = epc_features->bar[bar].fixed_size;
size_t aligned_size, align = epc_features->align;
struct pci_epf_bar *epf_bar;
dma_addr_t phys_addr;
@@ -272,24 +301,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
struct device *dev;
void *space;
- if (size < 128)
- size = 128;
-
- /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */
- if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M)
- size = SZ_1M;
+ size = pci_epf_get_bar_required_size(epf, size, bar,
+ epc_features, type);
- if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) {
- if (size > bar_fixed_size) {
- dev_err(&epf->dev,
- "requested BAR size is larger than fixed size\n");
- return NULL;
- }
- size = bar_fixed_size;
- } else {
- /* BAR size must be power of two */
- size = roundup_pow_of_two(size);
- }
+ if (size == 0)
+ return NULL;
/*
* Allocate enough memory to accommodate the iATU alignment
--
2.34.1
On Mon, Sep 15, 2025 at 06:22:44PM -0400, Frank Li wrote: > Introduce pci_epf_get_bar_required_size() to retrieve the required BAR > size. Prepare for adding support to set an MMIO address to a specific BAR. > > No functional changes. > > Signed-off-by: Frank Li <Frank.Li@nxp.com> > --- > change in v2 > - new patch > --- > drivers/pci/endpoint/pci-epf-core.c | 52 ++++++++++++++++++++++++------------- > 1 file changed, 34 insertions(+), 18 deletions(-) > > diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c > index d54e18872aefc07c655c94c104a347328ff7a432..4281067d4a62da6fbf6c2fb807b0f1b5afd1f45b 100644 > --- a/drivers/pci/endpoint/pci-epf-core.c > +++ b/drivers/pci/endpoint/pci-epf-core.c > @@ -248,6 +248,36 @@ void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, > } > EXPORT_SYMBOL_GPL(pci_epf_free_space); > > +static size_t s/size_t/int to return errno. > +pci_epf_get_bar_required_size(struct pci_epf *epf, size_t size, Rename this helper to pci_epf_align_bar_size() and pass 'size' pointer. > + enum pci_barno bar, > + const struct pci_epc_features *epc_features, > + enum pci_epc_interface_type type) > +{ > + u64 bar_fixed_size = epc_features->bar[bar].fixed_size; > + > + if (size < 128) > + size = 128; > + > + /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */ > + if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M) > + size = SZ_1M; > + > + if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) { > + if (size > bar_fixed_size) { > + dev_err(&epf->dev, > + "requested BAR size is larger than fixed size\n"); > + return 0; Return value of 0 should not be considered as an error. Return the errno here, which is -ENOMEM. > + } > + size = bar_fixed_size; > + } else { > + /* BAR size must be power of two */ > + size = roundup_pow_of_two(size); > + } > + > + return size; return 0; > +} > + > /** > * pci_epf_alloc_space() - allocate memory for the PCI EPF register space > * @epf: the EPF device to whom allocate the memory > @@ -264,7 +294,6 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, > const struct pci_epc_features *epc_features, > enum pci_epc_interface_type type) > { > - u64 bar_fixed_size = epc_features->bar[bar].fixed_size; > size_t aligned_size, align = epc_features->align; > struct pci_epf_bar *epf_bar; > dma_addr_t phys_addr; > @@ -272,24 +301,11 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar, > struct device *dev; > void *space; > > - if (size < 128) > - size = 128; > - > - /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */ > - if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M) > - size = SZ_1M; > + size = pci_epf_get_bar_required_size(epf, size, bar, > + epc_features, type); > > - if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) { > - if (size > bar_fixed_size) { > - dev_err(&epf->dev, > - "requested BAR size is larger than fixed size\n"); > - return NULL; > - } > - size = bar_fixed_size; > - } else { > - /* BAR size must be power of two */ > - size = roundup_pow_of_two(size); > - } > + if (size == 0) > + return NULL; int ret; ret = pci_epf_align_bar_size(..., &size, ...); if (ret < 0) return NULL; - Mani -- மணிவண்ணன் சதாசிவம்
© 2016 - 2025 Red Hat, Inc.