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 | ||