aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/pci/mmconfig-shared.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/i386/pci/mmconfig-shared.c
index 473db6257013..747d8c63b0c4 100644
--- a/arch/i386/pci/mmconfig-shared.c
+++ b/arch/i386/pci/mmconfig-shared.c
@@ -191,9 +191,16 @@ static void __init pci_mmcfg_insert_resources(void)
191 } 191 }
192} 192}
193 193
194static void __init pci_mmcfg_reject_broken(void) 194static void __init pci_mmcfg_reject_broken(int type)
195{ 195{
196 typeof(pci_mmcfg_config[0]) *cfg = &pci_mmcfg_config[0]; 196 typeof(pci_mmcfg_config[0]) *cfg;
197
198 if ((pci_mmcfg_config_num == 0) ||
199 (pci_mmcfg_config == NULL) ||
200 (pci_mmcfg_config[0].address == 0))
201 return;
202
203 cfg = &pci_mmcfg_config[0];
197 204
198 /* 205 /*
199 * Handle more broken MCFG tables on Asus etc. 206 * Handle more broken MCFG tables on Asus etc.
@@ -202,13 +209,29 @@ static void __init pci_mmcfg_reject_broken(void)
202 if (pci_mmcfg_config_num == 1 && 209 if (pci_mmcfg_config_num == 1 &&
203 cfg->pci_segment == 0 && 210 cfg->pci_segment == 0 &&
204 (cfg->start_bus_number | cfg->end_bus_number) == 0) { 211 (cfg->start_bus_number | cfg->end_bus_number) == 0) {
205 kfree(pci_mmcfg_config);
206 pci_mmcfg_config = NULL;
207 pci_mmcfg_config_num = 0;
208
209 printk(KERN_ERR "PCI: start and end of bus number is 0. " 212 printk(KERN_ERR "PCI: start and end of bus number is 0. "
210 "Rejected as broken MCFG."); 213 "Rejected as broken MCFG.\n");
214 goto reject;
215 }
216
217 /*
218 * Only do this check when type 1 works. If it doesn't work
219 * assume we run on a Mac and always use MCFG
220 */
221 if (type == 1 && !e820_all_mapped(cfg->address,
222 cfg->address + MMCONFIG_APER_MIN,
223 E820_RESERVED)) {
224 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not"
225 " E820-reserved\n", cfg->address);
226 goto reject;
211 } 227 }
228 return;
229
230reject:
231 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
232 kfree(pci_mmcfg_config);
233 pci_mmcfg_config = NULL;
234 pci_mmcfg_config_num = 0;
212} 235}
213 236
214void __init pci_mmcfg_init(int type) 237void __init pci_mmcfg_init(int type)
@@ -223,7 +246,7 @@ void __init pci_mmcfg_init(int type)
223 246
224 if (!known_bridge) { 247 if (!known_bridge) {
225 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg); 248 acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
226 pci_mmcfg_reject_broken(); 249 pci_mmcfg_reject_broken(type);
227 } 250 }
228 251
229 if ((pci_mmcfg_config_num == 0) || 252 if ((pci_mmcfg_config_num == 0) ||
@@ -231,18 +254,6 @@ void __init pci_mmcfg_init(int type)
231 (pci_mmcfg_config[0].address == 0)) 254 (pci_mmcfg_config[0].address == 0))
232 return; 255 return;
233 256
234 /* Only do this check when type 1 works. If it doesn't work
235 assume we run on a Mac and always use MCFG */
236 if (type == 1 && !known_bridge &&
237 !e820_all_mapped(pci_mmcfg_config[0].address,
238 pci_mmcfg_config[0].address + MMCONFIG_APER_MIN,
239 E820_RESERVED)) {
240 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not E820-reserved\n",
241 pci_mmcfg_config[0].address);
242 printk(KERN_ERR "PCI: Not using MMCONFIG.\n");
243 return;
244 }
245
246 if (pci_mmcfg_arch_init()) { 257 if (pci_mmcfg_arch_init()) {
247 if (type == 1) 258 if (type == 1)
248 unreachable_devices(); 259 unreachable_devices();