diff options
author | Lucas Stach <l.stach@pengutronix.de> | 2016-11-01 09:58:54 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2016-11-03 07:12:10 +0100 |
commit | 589b62ac9c4e55b6ed38afeaa3a4a4d57a77ef0e (patch) | |
tree | a8ce379b81f8ee9ae0ead079f196fa567e762ac2 /drivers | |
parent | 18ee9aade879f0a48a1785ef3922d0e8738b9027 (diff) | |
download | barebox-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')
-rw-r--r-- | drivers/pci/pci.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 19cda1f145..12aafccde5 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; |