diff options
Diffstat (limited to 'arch/x86_64/pci/mmconfig.c')
-rw-r--r-- | arch/x86_64/pci/mmconfig.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 3c55c76c6fd5..2d48a7941d48 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/acpi.h> | 10 | #include <linux/acpi.h> |
11 | #include <linux/bitmap.h> | 11 | #include <linux/bitmap.h> |
12 | #include <linux/dmi.h> | ||
12 | #include <asm/e820.h> | 13 | #include <asm/e820.h> |
13 | 14 | ||
14 | #include "pci.h" | 15 | #include "pci.h" |
@@ -164,11 +165,33 @@ static __init void unreachable_devices(void) | |||
164 | } | 165 | } |
165 | } | 166 | } |
166 | 167 | ||
168 | static int disable_mcfg(struct dmi_system_id *d) | ||
169 | { | ||
170 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
171 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
176 | /* Has broken MCFG table that makes the system hang when used */ | ||
177 | { | ||
178 | .callback = disable_mcfg, | ||
179 | .ident = "Intel D3C5105 SDV", | ||
180 | .matches = { | ||
181 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
182 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
183 | }, | ||
184 | }, | ||
185 | {} | ||
186 | }; | ||
187 | |||
167 | void __init pci_mmcfg_init(void) | 188 | void __init pci_mmcfg_init(void) |
168 | { | 189 | { |
169 | int i; | 190 | int i; |
170 | 191 | ||
171 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 192 | dmi_check_system(dmi_bad_mcfg); |
193 | |||
194 | if ((pci_probe & (PCI_PROBE_MMCONF|PCI_PROBE_MMCONF_FORCE)) == 0) | ||
172 | return; | 195 | return; |
173 | 196 | ||
174 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 197 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
@@ -177,15 +200,6 @@ void __init pci_mmcfg_init(void) | |||
177 | (pci_mmcfg_config[0].base_address == 0)) | 200 | (pci_mmcfg_config[0].base_address == 0)) |
178 | return; | 201 | return; |
179 | 202 | ||
180 | if (!e820_all_mapped(pci_mmcfg_config[0].base_address, | ||
181 | pci_mmcfg_config[0].base_address + MMCONFIG_APER_MIN, | ||
182 | E820_RESERVED)) { | ||
183 | printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %x is not E820-reserved\n", | ||
184 | pci_mmcfg_config[0].base_address); | ||
185 | printk(KERN_ERR "PCI: Not using MMCONFIG.\n"); | ||
186 | return; | ||
187 | } | ||
188 | |||
189 | /* RED-PEN i386 doesn't do _nocache right now */ | 203 | /* RED-PEN i386 doesn't do _nocache right now */ |
190 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); | 204 | pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); |
191 | if (pci_mmcfg_virt == NULL) { | 205 | if (pci_mmcfg_virt == NULL) { |