diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 2 | ||||
| -rw-r--r-- | arch/i386/pci/common.c | 5 | ||||
| -rw-r--r-- | arch/i386/pci/mmconfig.c | 25 | ||||
| -rw-r--r-- | arch/i386/pci/pci.h | 3 | ||||
| -rw-r--r-- | arch/x86_64/pci/mmconfig.c | 25 |
5 files changed, 57 insertions, 3 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index b50595a0550f..7947cede8712 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1183,6 +1183,8 @@ running once the system is up. | |||
| 1183 | Mechanism 2. | 1183 | Mechanism 2. |
| 1184 | nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI | 1184 | nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI |
| 1185 | Configuration | 1185 | Configuration |
| 1186 | mmconf [IA-32,X86_64] Force MMCONFIG. This is useful | ||
| 1187 | to override the builtin blacklist. | ||
| 1186 | nomsi [MSI] If the PCI_MSI kernel config parameter is | 1188 | nomsi [MSI] If the PCI_MSI kernel config parameter is |
| 1187 | enabled, this kernel boot option can be used to | 1189 | enabled, this kernel boot option can be used to |
| 1188 | disable the use of MSI interrupts system-wide. | 1190 | disable the use of MSI interrupts system-wide. |
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 0a362e3aeac5..1220dd828ce3 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
| @@ -237,6 +237,11 @@ char * __devinit pcibios_setup(char *str) | |||
| 237 | pci_probe &= ~PCI_PROBE_MMCONF; | 237 | pci_probe &= ~PCI_PROBE_MMCONF; |
| 238 | return NULL; | 238 | return NULL; |
| 239 | } | 239 | } |
| 240 | /* override DMI blacklist */ | ||
| 241 | else if (!strcmp(str, "mmconf")) { | ||
| 242 | pci_probe |= PCI_PROBE_MMCONF_FORCE; | ||
| 243 | return NULL; | ||
| 244 | } | ||
| 240 | #endif | 245 | #endif |
| 241 | else if (!strcmp(str, "noacpi")) { | 246 | else if (!strcmp(str, "noacpi")) { |
| 242 | acpi_noirq_set(); | 247 | acpi_noirq_set(); |
diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 5effb2e663ed..ef5a2faa7d82 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/pci.h> | 12 | #include <linux/pci.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/acpi.h> | 14 | #include <linux/acpi.h> |
| 15 | #include <linux/dmi.h> | ||
| 15 | #include <asm/e820.h> | 16 | #include <asm/e820.h> |
| 16 | #include "pci.h" | 17 | #include "pci.h" |
| 17 | 18 | ||
| @@ -187,9 +188,31 @@ static __init void unreachable_devices(void) | |||
| 187 | } | 188 | } |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 191 | static int disable_mcfg(struct dmi_system_id *d) | ||
| 192 | { | ||
| 193 | printk("PCI: %s detected. Disabling MCFG.\n", d->ident); | ||
| 194 | pci_probe &= ~PCI_PROBE_MMCONF; | ||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | static struct dmi_system_id __initdata dmi_bad_mcfg[] = { | ||
| 199 | /* Has broken MCFG table that makes the system hang when used */ | ||
| 200 | { | ||
| 201 | .callback = disable_mcfg, | ||
| 202 | .ident = "Intel D3C5105 SDV", | ||
| 203 | .matches = { | ||
| 204 | DMI_MATCH(DMI_BIOS_VENDOR, "Intel"), | ||
| 205 | DMI_MATCH(DMI_BOARD_NAME, "D26928"), | ||
| 206 | }, | ||
| 207 | }, | ||
| 208 | {} | ||
| 209 | }; | ||
| 210 | |||
| 190 | void __init pci_mmcfg_init(void) | 211 | void __init pci_mmcfg_init(void) |
| 191 | { | 212 | { |
| 192 | if ((pci_probe & PCI_PROBE_MMCONF) == 0) | 213 | dmi_check_system(dmi_bad_mcfg); |
| 214 | |||
| 215 | if ((pci_probe & (PCI_PROBE_MMCONF_FORCE|PCI_PROBE_MMCONF)) == 0) | ||
| 193 | return; | 216 | return; |
| 194 | 217 | ||
| 195 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); | 218 | acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index bf4e79335388..49a849b3a241 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
| @@ -16,7 +16,8 @@ | |||
| 16 | #define PCI_PROBE_CONF1 0x0002 | 16 | #define PCI_PROBE_CONF1 0x0002 |
| 17 | #define PCI_PROBE_CONF2 0x0004 | 17 | #define PCI_PROBE_CONF2 0x0004 |
| 18 | #define PCI_PROBE_MMCONF 0x0008 | 18 | #define PCI_PROBE_MMCONF 0x0008 |
| 19 | #define PCI_PROBE_MASK 0x000f | 19 | #define PCI_PROBE_MMCONF_FORCE 0x0010 |
| 20 | #define PCI_PROBE_MASK 0x00ff | ||
| 20 | 21 | ||
| 21 | #define PCI_NO_SORT 0x0100 | 22 | #define PCI_NO_SORT 0x0100 |
| 22 | #define PCI_BIOS_SORT 0x0200 | 23 | #define PCI_BIOS_SORT 0x0200 |
diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 8a4a0f9263ce..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); |
