diff options
| -rw-r--r-- | drivers/pci/rom.c | 55 |
1 files changed, 35 insertions, 20 deletions
diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index ab886b7ee327..b41ac7756a4b 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c | |||
| @@ -100,6 +100,27 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
| 100 | return min((size_t)(image - rom), size); | 100 | return min((size_t)(image - rom), size); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size) | ||
| 104 | { | ||
| 105 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | ||
| 106 | loff_t start; | ||
| 107 | |||
| 108 | /* assign the ROM an address if it doesn't have one */ | ||
| 109 | if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE)) | ||
| 110 | return 0; | ||
| 111 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); | ||
| 112 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
| 113 | |||
| 114 | if (*size == 0) | ||
| 115 | return 0; | ||
| 116 | |||
| 117 | /* Enable ROM space decodes */ | ||
| 118 | if (pci_enable_rom(pdev)) | ||
| 119 | return 0; | ||
| 120 | |||
| 121 | return start; | ||
| 122 | } | ||
| 123 | |||
| 103 | /** | 124 | /** |
| 104 | * pci_map_rom - map a PCI ROM to kernel space | 125 | * pci_map_rom - map a PCI ROM to kernel space |
| 105 | * @pdev: pointer to pci device struct | 126 | * @pdev: pointer to pci device struct |
| @@ -114,21 +135,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) | |||
| 114 | void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | 135 | void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) |
| 115 | { | 136 | { |
| 116 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; | 137 | struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; |
| 117 | loff_t start; | 138 | loff_t start = 0; |
| 118 | void __iomem *rom; | 139 | void __iomem *rom; |
| 119 | 140 | ||
| 120 | /* | 141 | /* |
| 121 | * Some devices may provide ROMs via a source other than the BAR | ||
| 122 | */ | ||
| 123 | if (pdev->rom && pdev->romlen) { | ||
| 124 | *size = pdev->romlen; | ||
| 125 | return phys_to_virt(pdev->rom); | ||
| 126 | /* | ||
| 127 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy | 142 | * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy |
| 128 | * memory map if the VGA enable bit of the Bridge Control register is | 143 | * memory map if the VGA enable bit of the Bridge Control register is |
| 129 | * set for embedded VGA. | 144 | * set for embedded VGA. |
| 130 | */ | 145 | */ |
| 131 | } else if (res->flags & IORESOURCE_ROM_SHADOW) { | 146 | if (res->flags & IORESOURCE_ROM_SHADOW) { |
| 132 | /* primary video rom always starts here */ | 147 | /* primary video rom always starts here */ |
| 133 | start = (loff_t)0xC0000; | 148 | start = (loff_t)0xC0000; |
| 134 | *size = 0x20000; /* cover C000:0 through E000:0 */ | 149 | *size = 0x20000; /* cover C000:0 through E000:0 */ |
| @@ -139,21 +154,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) | |||
| 139 | return (void __iomem *)(unsigned long) | 154 | return (void __iomem *)(unsigned long) |
| 140 | pci_resource_start(pdev, PCI_ROM_RESOURCE); | 155 | pci_resource_start(pdev, PCI_ROM_RESOURCE); |
| 141 | } else { | 156 | } else { |
| 142 | /* assign the ROM an address if it doesn't have one */ | 157 | start = pci_find_rom(pdev, size); |
| 143 | if (res->parent == NULL && | ||
| 144 | pci_assign_resource(pdev,PCI_ROM_RESOURCE)) | ||
| 145 | return NULL; | ||
| 146 | start = pci_resource_start(pdev, PCI_ROM_RESOURCE); | ||
| 147 | *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); | ||
| 148 | if (*size == 0) | ||
| 149 | return NULL; | ||
| 150 | |||
| 151 | /* Enable ROM space decodes */ | ||
| 152 | if (pci_enable_rom(pdev)) | ||
| 153 | return NULL; | ||
| 154 | } | 158 | } |
| 155 | } | 159 | } |
| 156 | 160 | ||
| 161 | /* | ||
| 162 | * Some devices may provide ROMs via a source other than the BAR | ||
| 163 | */ | ||
| 164 | if (!start && pdev->rom && pdev->romlen) { | ||
| 165 | *size = pdev->romlen; | ||
| 166 | return phys_to_virt(pdev->rom); | ||
| 167 | } | ||
| 168 | |||
| 169 | if (!start) | ||
| 170 | return NULL; | ||
| 171 | |||
| 157 | rom = ioremap(start, *size); | 172 | rom = ioremap(start, *size); |
| 158 | if (!rom) { | 173 | if (!rom) { |
| 159 | /* restore enable if ioremap fails */ | 174 | /* restore enable if ioremap fails */ |
