diff options
Diffstat (limited to 'drivers/pci/rom.c')
-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 */ |