summaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2007-02-13 13:26:20 +0100
committerAndi Kleen <andi@basil.nowhere.org>2007-02-13 13:26:20 +0100
commit44de0203fab205417b24322272c53ee0883c36e7 (patch)
treec5dbfa7e373ab07f517fc91fd97ff45045ccbb1b /arch/i386
parent[PATCH] mmconfig: Fix x86_64 ioremap base_address (diff)
downloadlinux-44de0203fab205417b24322272c53ee0883c36e7.tar.xz
linux-44de0203fab205417b24322272c53ee0883c36e7.zip
[PATCH] mmconfig: Reject a broken MCFG tables on Asus etc
This rejects broken MCFG tables on Asus. When the table looks bogus just disable mmconfig Arjan and Andi suggested this. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andi Kleen <ak@suse.de>
Diffstat (limited to 'arch/i386')
-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 4757554b08cf..77de6de94f1f 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 97dcaaa0de0f..3325b79e651c 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;
}