summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci.c
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2016-11-01 09:58:54 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2016-11-03 07:12:10 +0100
commit589b62ac9c4e55b6ed38afeaa3a4a4d57a77ef0e (patch)
treea8ce379b81f8ee9ae0ead079f196fa567e762ac2 /drivers/pci/pci.c
parent18ee9aade879f0a48a1785ef3922d0e8738b9027 (diff)
downloadbarebox-589b62ac9c4e55b6ed38afeaa3a4a4d57a77ef0e.tar.gz
barebox-589b62ac9c4e55b6ed38afeaa3a4a4d57a77ef0e.tar.xz
PCI: align BAR address to BAR size
PCI BARs require their address to be at least aligned to their size, otherwise address decoding will fail as the base address gets rounded down. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/pci/pci.c')
-rw-r--r--drivers/pci/pci.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 19cda1f14..12aafccde 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -174,11 +174,12 @@ static void setup_device(struct pci_dev *dev, int max_bar)
continue;
}
pr_debug("pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
- if (last_io + size >
+ if (ALIGN(last_io, size) + size >
dev->bus->resource[PCI_BUS_RESOURCE_IO]->end) {
pr_debug("BAR does not fit within bus IO res\n");
return;
}
+ last_io = ALIGN(last_io, size);
pr_debug("pbar%d: allocated at 0x%08x\n", bar, last_io);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
dev->resource[bar].flags = IORESOURCE_IO;
@@ -193,11 +194,12 @@ static void setup_device(struct pci_dev *dev, int max_bar)
}
pr_debug("pbar%d: mask=%08x P memory %d bytes\n",
bar, mask, size);
- if (last_mem_pref + size >
+ if (ALIGN(last_mem_pref, size) + size >
dev->bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->end) {
pr_debug("BAR does not fit within bus p-mem res\n");
return;
}
+ last_mem_pref = ALIGN(last_mem_pref, size);
pr_debug("pbar%d: allocated at 0x%08x\n", bar, last_mem_pref);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem_pref);
dev->resource[bar].flags = IORESOURCE_MEM |
@@ -212,11 +214,12 @@ static void setup_device(struct pci_dev *dev, int max_bar)
}
pr_debug("pbar%d: mask=%08x NP memory %d bytes\n",
bar, mask, size);
- if (last_mem + size >
+ if (ALIGN(last_mem, size) + size >
dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
pr_debug("BAR does not fit within bus np-mem res\n");
return;
}
+ last_mem = ALIGN(last_mem, size);
pr_debug("pbar%d: allocated at 0x%08x\n", bar, last_mem);
pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
dev->resource[bar].flags = IORESOURCE_MEM;