diff options
| author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2005-08-31 00:16:53 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-01 13:50:29 -0400 |
| commit | 8085ce084c0f0144c353963853f81486fc331120 (patch) | |
| tree | 6821eb3b64158ec230982f4db5f027b326edd620 | |
| parent | 319e76a1ae835c34a2838c2bfebe3db4d5a6b387 (diff) | |
[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 713c78f3a65d..49bd21702314 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
| @@ -21,13 +21,21 @@ | |||
| 21 | * between the ROM and other resources, so enabling it may disable access | 21 | * between the ROM and other resources, so enabling it may disable access |
| 22 | * to MMIO registers or other card memory. | 22 | * to MMIO registers or other card memory. |
| 23 | */ | 23 | */ |
| 24 | static void pci_enable_rom(struct pci_dev *pdev) | 24 | static int pci_enable_rom(struct pci_dev *pdev) |
| 25 | { | 25 | { |
| 26 | struct resource *res = pdev->resource + PCI_ROM_RESOURCE; | ||
| 27 | struct pci_bus_region region; | ||
| 26 | u32 rom_addr; | 28 | u32 rom_addr; |
| 27 | 29 | ||
| 30 | if (!res->flags) | ||
| 31 | return -1; | ||
| 32 | |||
| 33 | pcibios_resource_to_bus(pdev, ®ion, res); | ||
| 28 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); | 34 | pci_read_config_dword(pdev, pdev->rom_base_reg, &rom_addr); |
| 29 | rom_addr |= PCI_ROM_ADDRESS_ENABLE; | 35 | rom_addr &= ~PCI_ROM_ADDRESS_MASK; |
| 36 | rom_addr |= region.start | PCI_ROM_ADDRESS_ENABLE; | ||
| 30 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); | 37 | pci_write_config_dword(pdev, pdev->rom_base_reg, rom_addr); |
| 38 | return 0; | ||
| 31 | } | 39 | } |
| 32 | 40 | ||
| 33 | /** | 41 | /** |
| @@ -71,19 +79,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
| 71 | } else { | 79 | } else { |
| 72 | if (res->flags & IORESOURCE_ROM_COPY) { | 80 | if (res->flags & IORESOURCE_ROM_COPY) { |
| 73 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | 81 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
| 74 | return (void __iomem *)pci_resource_start(pdev, PCI_ROM_RESOURCE); | 82 | return (void __iomem *)pci_resource_start(pdev, |
| 83 | PCI_ROM_RESOURCE); | ||
| 75 | } else { | 84 | } else { |
| 76 | /* assign the ROM an address if it doesn't have one */ | 85 | /* assign the ROM an address if it doesn't have one */ |
| 77 | if (res->parent == NULL) | 86 | if (res->parent == NULL && |
| 78 | pci_assign_resource(pdev, PCI_ROM_RESOURCE); | 87 | pci_assign_resource(pdev,PCI_ROM_RESOURCE)) |
| 79 | 88 | return NULL; | |
| 80 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); | 89 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); |
| 81 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | 90 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); |
| 82 | if (*size == 0) | 91 | if (*size == 0) |
| 83 | return NULL; | 92 | return NULL; |
| 84 | 93 | ||
| 85 | /* Enable ROM space decodes */ | 94 | /* Enable ROM space decodes */ |
| 86 | pci_enable_rom(pdev); | 95 | if (pci_enable_rom(pdev)) |
| 96 | return NULL; | ||
| 87 | } | 97 | } |
| 88 | } | 98 | } |
| 89 | 99 | ||
