Skip to content

Commit f3a2964

Browse files
Ajay Agarwalkwilczynski
authored andcommitted
PCI: dwc: Strengthen the MSI address allocation logic
There can be platforms that do not use/have 32-bit DMA addresses. The current implementation of 32-bit IOVA allocation can fail for such platforms, eventually leading to the probe failure. Try to allocate a 32-bit msi_data. If this allocation fails, attempt a 64-bit address allocation. Please note that if the 64-bit MSI address is allocated, then the EPs supporting 32-bit MSI address only will not work. Link: https://lore.kernel.org/linux-pci/[email protected] Tested-by: Will McVicker <[email protected]> Signed-off-by: Ajay Agarwal <[email protected]> Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]> Reviewed-by: Serge Semin <[email protected]> Reviewed-by: Will McVicker <[email protected]>
1 parent 6613476 commit f3a2964

File tree

1 file changed

+13
-8
lines changed

1 file changed

+13
-8
lines changed

drivers/pci/controller/dwc/pcie-designware-host.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
328328
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
329329
struct device *dev = pci->dev;
330330
struct platform_device *pdev = to_platform_device(dev);
331-
u64 *msi_vaddr;
331+
u64 *msi_vaddr = NULL;
332332
int ret;
333333
u32 ctrl, num_ctrls;
334334

@@ -379,15 +379,20 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
379379
* memory.
380380
*/
381381
ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
382-
if (ret)
383-
dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");
382+
if (!ret)
383+
msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
384+
GFP_KERNEL);
384385

385-
msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
386-
GFP_KERNEL);
387386
if (!msi_vaddr) {
388-
dev_err(dev, "Failed to alloc and map MSI data\n");
389-
dw_pcie_free_msi(pp);
390-
return -ENOMEM;
387+
dev_warn(dev, "Failed to allocate 32-bit MSI address\n");
388+
dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
389+
msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,
390+
GFP_KERNEL);
391+
if (!msi_vaddr) {
392+
dev_err(dev, "Failed to allocate MSI address\n");
393+
dw_pcie_free_msi(pp);
394+
return -ENOMEM;
395+
}
391396
}
392397

393398
return 0;

0 commit comments

Comments
 (0)