Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: endpoint: Add pci_epf_get_required_bar_size() helper

Introduce pci_epf_get_required_bar_size() helper to get the required BAR
size and backing memory size. This helper will be used to set a fixed MMIO
address as the backing memory for a BAR.

Since this helper returns both BAR size and the aligned memory size, use
two parameters, 'bar_size' and 'aligned_mem_size' to avoid confusion.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
[mani: renamed helper to pci_epf_get_required_bar_size(), reworded description]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Reviewed-by: Niklas Cassel <cassel@kernel.org>
Link: https://patch.msgid.link/20251015-vntb_msi_doorbell-v6-2-9230298b1910@nxp.com

authored by

Frank Li and committed by
Manivannan Sadhasivam
f71e2b67 48376884

+46 -28
+46 -28
drivers/pci/endpoint/pci-epf-core.c
··· 208 208 } 209 209 EXPORT_SYMBOL_GPL(pci_epf_remove_vepf); 210 210 211 + static int pci_epf_get_required_bar_size(struct pci_epf *epf, size_t *bar_size, 212 + size_t *aligned_mem_size, 213 + enum pci_barno bar, 214 + const struct pci_epc_features *epc_features, 215 + enum pci_epc_interface_type type) 216 + { 217 + u64 bar_fixed_size = epc_features->bar[bar].fixed_size; 218 + size_t align = epc_features->align; 219 + size_t size = *bar_size; 220 + 221 + if (size < 128) 222 + size = 128; 223 + 224 + /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */ 225 + if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M) 226 + size = SZ_1M; 227 + 228 + if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) { 229 + if (size > bar_fixed_size) { 230 + dev_err(&epf->dev, 231 + "requested BAR size is larger than fixed size\n"); 232 + return -ENOMEM; 233 + } 234 + size = bar_fixed_size; 235 + } else { 236 + /* BAR size must be power of two */ 237 + size = roundup_pow_of_two(size); 238 + } 239 + 240 + *bar_size = size; 241 + 242 + /* 243 + * The EPC's BAR start address must meet alignment requirements. In most 244 + * cases, the alignment will match the BAR size. However, differences 245 + * can occur—for example, when the fixed BAR size (e.g., 128 bytes) is 246 + * smaller than the required alignment (e.g., 4 KB). 247 + */ 248 + *aligned_mem_size = align ? ALIGN(size, align) : size; 249 + 250 + return 0; 251 + } 252 + 211 253 /** 212 254 * pci_epf_free_space() - free the allocated PCI EPF register space 213 255 * @epf: the EPF device from whom to free the memory ··· 306 264 const struct pci_epc_features *epc_features, 307 265 enum pci_epc_interface_type type) 308 266 { 309 - u64 bar_fixed_size = epc_features->bar[bar].fixed_size; 310 - size_t mem_size, align = epc_features->align; 311 267 struct pci_epf_bar *epf_bar; 312 268 dma_addr_t phys_addr; 313 269 struct pci_epc *epc; 314 270 struct device *dev; 271 + size_t mem_size; 315 272 void *space; 316 273 317 - if (size < 128) 318 - size = 128; 319 - 320 - /* According to PCIe base spec, min size for a resizable BAR is 1 MB. */ 321 - if (epc_features->bar[bar].type == BAR_RESIZABLE && size < SZ_1M) 322 - size = SZ_1M; 323 - 324 - if (epc_features->bar[bar].type == BAR_FIXED && bar_fixed_size) { 325 - if (size > bar_fixed_size) { 326 - dev_err(&epf->dev, 327 - "requested BAR size is larger than fixed size\n"); 328 - return NULL; 329 - } 330 - size = bar_fixed_size; 331 - } else { 332 - /* BAR size must be power of two */ 333 - size = roundup_pow_of_two(size); 334 - } 335 - 336 - /* 337 - * Allocate enough memory to accommodate the iATU alignment 338 - * requirement. In most cases, this will be the same as .size but 339 - * it might be different if, for example, the fixed size of a BAR 340 - * is smaller than align. 341 - */ 342 - mem_size = align ? ALIGN(size, align) : size; 274 + if (pci_epf_get_required_bar_size(epf, &size, &mem_size, bar, 275 + epc_features, type)) 276 + return NULL; 343 277 344 278 if (type == PRIMARY_INTERFACE) { 345 279 epc = epf->epc;