Commit 7bc5e3f2be32ae6fb0c74cd0f707f986b3a01a26
Committed by
Jesse Barnes
1 parent
2fe2abf896
Exists in
master
and in
4 other branches
x86/PCI: use host bridge _CRS info by default on 2008 and newer machines
The main benefit of using ACPI host bridge window information is that we can do better resource allocation in systems with multiple host bridges, e.g., http://bugzilla.kernel.org/show_bug.cgi?id=14183 Sometimes we need _CRS information even if we only have one host bridge, e.g., https://bugs.launchpad.net/ubuntu/+source/linux/+bug/341681 Most of these systems are relatively new, so this patch turns on "pci=use_crs" only on machines with a BIOS date of 2008 or newer. Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Showing 7 changed files with 60 additions and 8 deletions Side-by-side Diff
Documentation/kernel-parameters.txt
... | ... | @@ -1948,8 +1948,12 @@ |
1948 | 1948 | IRQ routing is enabled. |
1949 | 1949 | noacpi [X86] Do not use ACPI for IRQ routing |
1950 | 1950 | or for PCI scanning. |
1951 | - use_crs [X86] Use _CRS for PCI resource | |
1952 | - allocation. | |
1951 | + use_crs [X86] Use PCI host bridge window information | |
1952 | + from ACPI. On BIOSes from 2008 or later, this | |
1953 | + is enabled by default. If you need to use this, | |
1954 | + please report a bug. | |
1955 | + nocrs [X86] Ignore PCI host bridge windows from ACPI. | |
1956 | + If you need to use this, please report a bug. | |
1953 | 1957 | routeirq Do IRQ routing for all PCI devices. |
1954 | 1958 | This is normally done in pci_enable_device(), |
1955 | 1959 | so this option is a temporary workaround |
arch/ia64/include/asm/acpi.h
... | ... | @@ -98,6 +98,7 @@ |
98 | 98 | #endif |
99 | 99 | #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ |
100 | 100 | static inline void disable_acpi(void) { } |
101 | +static inline void pci_acpi_crs_quirks(void) { } | |
101 | 102 | |
102 | 103 | const char *acpi_get_sysname (void); |
103 | 104 | int acpi_request_vector (u32 int_type); |
arch/x86/include/asm/pci_x86.h
arch/x86/pci/acpi.c
... | ... | @@ -15,6 +15,51 @@ |
15 | 15 | int busnum; |
16 | 16 | }; |
17 | 17 | |
18 | +static bool pci_use_crs = true; | |
19 | + | |
20 | +static int __init set_use_crs(const struct dmi_system_id *id) | |
21 | +{ | |
22 | + pci_use_crs = true; | |
23 | + return 0; | |
24 | +} | |
25 | + | |
26 | +static const struct dmi_system_id pci_use_crs_table[] __initconst = { | |
27 | + /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */ | |
28 | + { | |
29 | + .callback = set_use_crs, | |
30 | + .ident = "IBM System x3800", | |
31 | + .matches = { | |
32 | + DMI_MATCH(DMI_SYS_VENDOR, "IBM"), | |
33 | + DMI_MATCH(DMI_PRODUCT_NAME, "x3800"), | |
34 | + }, | |
35 | + }, | |
36 | + {} | |
37 | +}; | |
38 | + | |
39 | +void __init pci_acpi_crs_quirks(void) | |
40 | +{ | |
41 | + int year; | |
42 | + | |
43 | + if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) | |
44 | + pci_use_crs = false; | |
45 | + | |
46 | + dmi_check_system(pci_use_crs_table); | |
47 | + | |
48 | + /* | |
49 | + * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that | |
50 | + * takes precedence over anything we figured out above. | |
51 | + */ | |
52 | + if (pci_probe & PCI_ROOT_NO_CRS) | |
53 | + pci_use_crs = false; | |
54 | + else if (pci_probe & PCI_USE__CRS) | |
55 | + pci_use_crs = true; | |
56 | + | |
57 | + printk(KERN_INFO "PCI: %s host bridge windows from ACPI; " | |
58 | + "if necessary, use \"pci=%s\" and report a bug\n", | |
59 | + pci_use_crs ? "Using" : "Ignoring", | |
60 | + pci_use_crs ? "nocrs" : "use_crs"); | |
61 | +} | |
62 | + | |
18 | 63 | static acpi_status |
19 | 64 | resource_to_addr(struct acpi_resource *resource, |
20 | 65 | struct acpi_resource_address64 *addr) |
... | ... | @@ -106,7 +151,7 @@ |
106 | 151 | res->child = NULL; |
107 | 152 | align_resource(info->bridge, res); |
108 | 153 | |
109 | - if (!(pci_probe & PCI_USE__CRS)) { | |
154 | + if (!pci_use_crs) { | |
110 | 155 | dev_printk(KERN_DEBUG, &info->bridge->dev, |
111 | 156 | "host bridge window %pR (ignored)\n", res); |
112 | 157 | return AE_OK; |
113 | 158 | |
... | ... | @@ -137,12 +182,8 @@ |
137 | 182 | struct pci_root_info info; |
138 | 183 | size_t size; |
139 | 184 | |
140 | - if (pci_probe & PCI_USE__CRS) | |
185 | + if (pci_use_crs) | |
141 | 186 | pci_bus_remove_resources(bus); |
142 | - else | |
143 | - dev_info(&device->dev, | |
144 | - "ignoring host bridge windows from ACPI; " | |
145 | - "boot with \"pci=use_crs\" to use them\n"); | |
146 | 187 | |
147 | 188 | info.bridge = device; |
148 | 189 | info.bus = bus; |
arch/x86/pci/common.c
... | ... | @@ -520,6 +520,9 @@ |
520 | 520 | } else if (!strcmp(str, "use_crs")) { |
521 | 521 | pci_probe |= PCI_USE__CRS; |
522 | 522 | return NULL; |
523 | + } else if (!strcmp(str, "nocrs")) { | |
524 | + pci_probe |= PCI_ROOT_NO_CRS; | |
525 | + return NULL; | |
523 | 526 | } else if (!strcmp(str, "earlydump")) { |
524 | 527 | pci_early_dump_regs = 1; |
525 | 528 | return NULL; |
drivers/acpi/pci_root.c
include/acpi/acpi_drivers.h