diff options
Diffstat (limited to 'arch/i386')
-rw-r--r-- | arch/i386/pci/common.c | 59 | ||||
-rw-r--r-- | arch/i386/pci/pci.h | 7 |
2 files changed, 64 insertions, 2 deletions
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 68bce194e688..6d5ace845e44 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c | |||
@@ -20,6 +20,7 @@ | |||
20 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | | 20 | unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | |
21 | PCI_PROBE_MMCONF; | 21 | PCI_PROBE_MMCONF; |
22 | 22 | ||
23 | int pci_bf_sort; | ||
23 | int pci_routeirq; | 24 | int pci_routeirq; |
24 | int pcibios_last_bus = -1; | 25 | int pcibios_last_bus = -1; |
25 | unsigned long pirq_table_addr; | 26 | unsigned long pirq_table_addr; |
@@ -118,6 +119,20 @@ void __devinit pcibios_fixup_bus(struct pci_bus *b) | |||
118 | } | 119 | } |
119 | 120 | ||
120 | /* | 121 | /* |
122 | * Only use DMI information to set this if nothing was passed | ||
123 | * on the kernel command line (which was parsed earlier). | ||
124 | */ | ||
125 | |||
126 | static int __devinit set_bf_sort(struct dmi_system_id *d) | ||
127 | { | ||
128 | if (pci_bf_sort == pci_bf_sort_default) { | ||
129 | pci_bf_sort = pci_dmi_bf; | ||
130 | printk(KERN_INFO "PCI: %s detected, enabling pci=bfsort.\n", d->ident); | ||
131 | } | ||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | /* | ||
121 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) | 136 | * Enable renumbering of PCI bus# ranges to reach all PCI busses (Cardbus) |
122 | */ | 137 | */ |
123 | #ifdef __i386__ | 138 | #ifdef __i386__ |
@@ -130,11 +145,11 @@ static int __devinit assign_all_busses(struct dmi_system_id *d) | |||
130 | } | 145 | } |
131 | #endif | 146 | #endif |
132 | 147 | ||
148 | static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | ||
149 | #ifdef __i386__ | ||
133 | /* | 150 | /* |
134 | * Laptops which need pci=assign-busses to see Cardbus cards | 151 | * Laptops which need pci=assign-busses to see Cardbus cards |
135 | */ | 152 | */ |
136 | static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | ||
137 | #ifdef __i386__ | ||
138 | { | 153 | { |
139 | .callback = assign_all_busses, | 154 | .callback = assign_all_busses, |
140 | .ident = "Samsung X20 Laptop", | 155 | .ident = "Samsung X20 Laptop", |
@@ -144,6 +159,38 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = { | |||
144 | }, | 159 | }, |
145 | }, | 160 | }, |
146 | #endif /* __i386__ */ | 161 | #endif /* __i386__ */ |
162 | { | ||
163 | .callback = set_bf_sort, | ||
164 | .ident = "Dell PowerEdge 1950", | ||
165 | .matches = { | ||
166 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
167 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1950"), | ||
168 | }, | ||
169 | }, | ||
170 | { | ||
171 | .callback = set_bf_sort, | ||
172 | .ident = "Dell PowerEdge 1955", | ||
173 | .matches = { | ||
174 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
175 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1955"), | ||
176 | }, | ||
177 | }, | ||
178 | { | ||
179 | .callback = set_bf_sort, | ||
180 | .ident = "Dell PowerEdge 2900", | ||
181 | .matches = { | ||
182 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
183 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2900"), | ||
184 | }, | ||
185 | }, | ||
186 | { | ||
187 | .callback = set_bf_sort, | ||
188 | .ident = "Dell PowerEdge 2950", | ||
189 | .matches = { | ||
190 | DMI_MATCH(DMI_SYS_VENDOR, "Dell"), | ||
191 | DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), | ||
192 | }, | ||
193 | }, | ||
147 | {} | 194 | {} |
148 | }; | 195 | }; |
149 | 196 | ||
@@ -189,6 +236,8 @@ static int __init pcibios_init(void) | |||
189 | 236 | ||
190 | pcibios_resource_survey(); | 237 | pcibios_resource_survey(); |
191 | 238 | ||
239 | if (pci_bf_sort >= pci_force_bf) | ||
240 | pci_sort_breadthfirst(); | ||
192 | #ifdef CONFIG_PCI_BIOS | 241 | #ifdef CONFIG_PCI_BIOS |
193 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) | 242 | if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) |
194 | pcibios_sort(); | 243 | pcibios_sort(); |
@@ -203,6 +252,12 @@ char * __devinit pcibios_setup(char *str) | |||
203 | if (!strcmp(str, "off")) { | 252 | if (!strcmp(str, "off")) { |
204 | pci_probe = 0; | 253 | pci_probe = 0; |
205 | return NULL; | 254 | return NULL; |
255 | } else if (!strcmp(str, "bfsort")) { | ||
256 | pci_bf_sort = pci_force_bf; | ||
257 | return NULL; | ||
258 | } else if (!strcmp(str, "nobfsort")) { | ||
259 | pci_bf_sort = pci_force_nobf; | ||
260 | return NULL; | ||
206 | } | 261 | } |
207 | #ifdef CONFIG_PCI_BIOS | 262 | #ifdef CONFIG_PCI_BIOS |
208 | else if (!strcmp(str, "bios")) { | 263 | else if (!strcmp(str, "bios")) { |
diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index 1814f74569c6..ad065cebd7b9 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h | |||
@@ -30,6 +30,13 @@ | |||
30 | extern unsigned int pci_probe; | 30 | extern unsigned int pci_probe; |
31 | extern unsigned long pirq_table_addr; | 31 | extern unsigned long pirq_table_addr; |
32 | 32 | ||
33 | enum pci_bf_sort_state { | ||
34 | pci_bf_sort_default, | ||
35 | pci_force_nobf, | ||
36 | pci_force_bf, | ||
37 | pci_dmi_bf, | ||
38 | }; | ||
39 | |||
33 | /* pci-i386.c */ | 40 | /* pci-i386.c */ |
34 | 41 | ||
35 | extern unsigned int pcibios_max_latency; | 42 | extern unsigned int pcibios_max_latency; |