diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-08-31 14:16:53 +1000 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-01 10:50:29 -0700 |
commit | 8085ce084c0f0144c353963853f81486fc331120 (patch) | |
tree | 6821eb3b64158ec230982f4db5f027b326edd620 | |
parent | 319e76a1ae835c34a2838c2bfebe3db4d5a6b387 (diff) | |
download | linux-3.10-8085ce084c0f0144c353963853f81486fc331120.tar.gz linux-3.10-8085ce084c0f0144c353963853f81486fc331120.tar.bz2 linux-3.10-8085ce084c0f0144c353963853f81486fc331120.zip |
[PATCH] Fix PCI ROM mapping
This fixes a problem with pci_map_rom() which doesn't properly
update the ROM BAR value with the address thas allocated for it by the
PCI code. This problem, among other, breaks boot on Mac laptops.
It'ss a new version based on Linus latest one with better error
checking.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/pci/rom.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index 713c78f3a65..49bd2170231 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -21,13 +21,21 @@ * between the ROM and other resources, so enabling it may disable access * to MMIO registers or other card memory. */ -static void pci_enable_rom(struct pci_dev *pdev) +static int pci_enable_rom(struct pci_dev *pdev) { + struct resource *res = pdev->resource + PCI_ROM_RESOURCE; + struct pci_bus_region region; u32 rom_addr; + if (!res->flags) + return -1; + + pcibios_resource_to_bus(pdev, ®ion, res); pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); - rom_addr |= PCI_ROM_ADDRESS_ENABLE; + rom_addr &= ~PCI_ROM_ADDRESS_MASK; + rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE; pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); + return 0; } /** @@ -71,19 +79,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) } else { if (res->flags & IORESOURCE_ROM_COPY) { *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE); + return (void __iomem *)pci_resource_start(pdev, + PCI_ROM_RESOURCE); } else { /* assign the ROM an address if it doesn't have one */ - if (res->parent == NULL) - pci_assign_resource(pdev, PCI_ROM_RESOURCE); - + if (res->parent == NULL && + pci_assign_resource(pdev,PCI_ROM_RESOURCE)) + return NULL; start = pci_resource_start(pdev, PCI_ROM_RESOURCE); *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); if (*size == 0) return NULL; /* Enable ROM space decodes */ - pci_enable_rom(pdev); + if (pci_enable_rom(pdev)) + return NULL; } } |