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); |