aboutsummaryrefslogtreecommitdiff
path: root/arch/i386/pci
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/pci')
-rw-r--r--arch/i386/pci/mmconfig-shared.c24
-rw-r--r--arch/i386/pci/mmconfig.c9
2 files changed, 23 insertions, 10 deletions
diff --git a/arch/i386/pci/mmconfig-shared.c b/arch/i386/pci/mmconfig-shared.c
index 4757554b08c..77de6de94f1 100644
--- a/arch/i386/pci/mmconfig-shared.c
+++ b/arch/i386/pci/mmconfig-shared.c
@@ -197,6 +197,26 @@ static __init void pci_mmcfg_insert_resources(void)
}
}
+static void __init pci_mmcfg_reject_broken(void)
+{
+ typeof(pci_mmcfg_config[0]) *cfg = &pci_mmcfg_config[0];
+
+ /*
+ * Handle more broken MCFG tables on Asus etc.
+ * They only contain a single entry for bus 0-0.
+ */
+ if (pci_mmcfg_config_num == 1 &&
+ cfg->pci_segment == 0 &&
+ (cfg->start_bus_number | cfg->end_bus_number) == 0) {
+ kfree(pci_mmcfg_config);
+ pci_mmcfg_config = NULL;
+ pci_mmcfg_config_num = 0;
+
+ printk(KERN_ERR "PCI: start and end of bus number is 0. "
+ "Rejected as broken MCFG.");
+ }
+}
+
void __init pci_mmcfg_init(int type)
{
int known_bridge = 0;
@@ -207,8 +227,10 @@ void __init pci_mmcfg_init(int type)
if (type == 1 && pci_mmcfg_check_hostbridge())
known_bridge = 1;
- if (!known_bridge)
+ if (!known_bridge) {
acpi_table_parse(ACPI_SIG_MCFG, acpi_parse_mcfg);
+ pci_mmcfg_reject_broken();
+ }
if ((pci_mmcfg_config_num == 0) ||
(pci_mmcfg_config == NULL) ||
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c
index 97dcaaa0de0..3325b79e651 100644
--- a/arch/i386/pci/mmconfig.c
+++ b/arch/i386/pci/mmconfig.c
@@ -47,15 +47,6 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
return cfg->address;
}
- /* Handle more broken MCFG tables on Asus etc.
- They only contain a single entry for bus 0-0. Assume
- this applies to all busses. */
- cfg = &pci_mmcfg_config[0];
- if (pci_mmcfg_config_num == 1 &&
- cfg->pci_segment == 0 &&
- (cfg->start_bus_number | cfg->end_bus_number) == 0)
- return cfg->address;
-
/* Fall back to type 0 */
return 0;
}