aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:24:54 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-21 19:24:54 -0400
commit3bb07f1b73ea6313b843807063e183e168c9182a (patch)
treef0e2ab77b8bc993a843a0edede00668c589863cc /arch/x86
parent6326c71fd2fb3bef5fa33951479298b683da35fe (diff)
parent5420e46d4d79bcd5d5952df98d022c8412385d32 (diff)
Merge tag 'pci-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI changes from Bjorn Helgaas: - Host bridge cleanups from Yinghai - Disable Bus Master bit on PCI device shutdown (kexec-related) - Stratus ftServer fix - pci_dev_reset() locking fix - IvyBridge graphics erratum workaround * tag 'pci-for-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (21 commits) microblaze/PCI: fix "io_offset undeclared" error x86/PCI: only check for spinlock being held in SMP kernels resources: add resource_overlaps() PCI: fix uninitialized variable 'cap_mask' MAINTAINERS: update PCI git tree and patchwork PCI: disable Bus Master on PCI device shutdown PCI: work around IvyBridge internal graphics FLR erratum x86/PCI: fix unused variable warning in amd_bus.c PCI: move mutex locking out of pci_dev_reset function PCI: work around Stratus ftServer broken PCIe hierarchy x86/PCI: merge pcibios_scan_root() and pci_scan_bus_on_node() x86/PCI: dynamically allocate pci_root_info for native host bridge drivers x86/PCI: embed pci_sysdata into pci_root_info on ACPI path x86/PCI: embed name into pci_root_info struct x86/PCI: add host bridge resource release for _CRS path x86/PCI: refactor get_current_resources() PCI: add host bridge release support PCI: add generic device into pci_host_bridge struct PCI: rename pci_host_bridge() to find_pci_root_bridge() x86/PCI: fix memleak with get_current_resources() ...
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/pci/acpi.c128
-rw-r--r--arch/x86/pci/amd_bus.c91
-rw-r--r--arch/x86/pci/broadcom_bus.c12
-rw-r--r--arch/x86/pci/bus_numa.c69
-rw-r--r--arch/x86/pci/bus_numa.h18
-rw-r--r--arch/x86/pci/common.c43
-rw-r--r--arch/x86/pci/i386.c2
7 files changed, 191 insertions, 172 deletions
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index ed2835e148b5..fc09c2754e08 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -9,11 +9,11 @@
9 9
10struct pci_root_info { 10struct pci_root_info {
11 struct acpi_device *bridge; 11 struct acpi_device *bridge;
12 char *name; 12 char name[16];
13 unsigned int res_num; 13 unsigned int res_num;
14 struct resource *res; 14 struct resource *res;
15 struct list_head *resources;
16 int busnum; 15 int busnum;
16 struct pci_sysdata sd;
17}; 17};
18 18
19static bool pci_use_crs = true; 19static bool pci_use_crs = true;
@@ -245,13 +245,6 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
245 return AE_OK; 245 return AE_OK;
246} 246}
247 247
248static bool resource_contains(struct resource *res, resource_size_t point)
249{
250 if (res->start <= point && point <= res->end)
251 return true;
252 return false;
253}
254
255static void coalesce_windows(struct pci_root_info *info, unsigned long type) 248static void coalesce_windows(struct pci_root_info *info, unsigned long type)
256{ 249{
257 int i, j; 250 int i, j;
@@ -272,10 +265,7 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
272 * our resources no longer match the ACPI _CRS, but 265 * our resources no longer match the ACPI _CRS, but
273 * the kernel resource tree doesn't allow overlaps. 266 * the kernel resource tree doesn't allow overlaps.
274 */ 267 */
275 if (resource_contains(res1, res2->start) || 268 if (resource_overlaps(res1, res2)) {
276 resource_contains(res1, res2->end) ||
277 resource_contains(res2, res1->start) ||
278 resource_contains(res2, res1->end)) {
279 res1->start = min(res1->start, res2->start); 269 res1->start = min(res1->start, res2->start);
280 res1->end = max(res1->end, res2->end); 270 res1->end = max(res1->end, res2->end);
281 dev_info(&info->bridge->dev, 271 dev_info(&info->bridge->dev,
@@ -287,7 +277,8 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
287 } 277 }
288} 278}
289 279
290static void add_resources(struct pci_root_info *info) 280static void add_resources(struct pci_root_info *info,
281 struct list_head *resources)
291{ 282{
292 int i; 283 int i;
293 struct resource *res, *root, *conflict; 284 struct resource *res, *root, *conflict;
@@ -311,53 +302,74 @@ static void add_resources(struct pci_root_info *info)
311 "ignoring host bridge window %pR (conflicts with %s %pR)\n", 302 "ignoring host bridge window %pR (conflicts with %s %pR)\n",
312 res, conflict->name, conflict); 303 res, conflict->name, conflict);
313 else 304 else
314 pci_add_resource(info->resources, res); 305 pci_add_resource(resources, res);
315 } 306 }
316} 307}
317 308
309static void free_pci_root_info_res(struct pci_root_info *info)
310{
311 kfree(info->res);
312 info->res = NULL;
313 info->res_num = 0;
314}
315
316static void __release_pci_root_info(struct pci_root_info *info)
317{
318 int i;
319 struct resource *res;
320
321 for (i = 0; i < info->res_num; i++) {
322 res = &info->res[i];
323
324 if (!res->parent)
325 continue;
326
327 if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
328 continue;
329
330 release_resource(res);
331 }
332
333 free_pci_root_info_res(info);
334
335 kfree(info);
336}
337static void release_pci_root_info(struct pci_host_bridge *bridge)
338{
339 struct pci_root_info *info = bridge->release_data;
340
341 __release_pci_root_info(info);
342}
343
318static void 344static void
319get_current_resources(struct acpi_device *device, int busnum, 345probe_pci_root_info(struct pci_root_info *info, struct acpi_device *device,
320 int domain, struct list_head *resources) 346 int busnum, int domain)
321{ 347{
322 struct pci_root_info info;
323 size_t size; 348 size_t size;
324 349
325 info.bridge = device; 350 info->bridge = device;
326 info.res_num = 0; 351 info->res_num = 0;
327 info.resources = resources;
328 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, 352 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
329 &info); 353 info);
330 if (!info.res_num) 354 if (!info->res_num)
331 return; 355 return;
332 356
333 size = sizeof(*info.res) * info.res_num; 357 size = sizeof(*info->res) * info->res_num;
334 info.res = kmalloc(size, GFP_KERNEL); 358 info->res_num = 0;
335 if (!info.res) 359 info->res = kmalloc(size, GFP_KERNEL);
360 if (!info->res)
336 return; 361 return;
337 362
338 info.name = kasprintf(GFP_KERNEL, "PCI Bus %04x:%02x", domain, busnum); 363 sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
339 if (!info.name)
340 goto name_alloc_fail;
341 364
342 info.res_num = 0;
343 acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource, 365 acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
344 &info); 366 info);
345
346 if (pci_use_crs) {
347 add_resources(&info);
348
349 return;
350 }
351
352 kfree(info.name);
353
354name_alloc_fail:
355 kfree(info.res);
356} 367}
357 368
358struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) 369struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
359{ 370{
360 struct acpi_device *device = root->device; 371 struct acpi_device *device = root->device;
372 struct pci_root_info *info = NULL;
361 int domain = root->segment; 373 int domain = root->segment;
362 int busnum = root->secondary.start; 374 int busnum = root->secondary.start;
363 LIST_HEAD(resources); 375 LIST_HEAD(resources);
@@ -389,17 +401,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
389 if (node != -1 && !node_online(node)) 401 if (node != -1 && !node_online(node))
390 node = -1; 402 node = -1;
391 403
392 /* Allocate per-root-bus (not per bus) arch-specific data. 404 info = kzalloc(sizeof(*info), GFP_KERNEL);
393 * TODO: leak; this memory is never freed. 405 if (!info) {
394 * It's arguable whether it's worth the trouble to care.
395 */
396 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
397 if (!sd) {
398 printk(KERN_WARNING "pci_bus %04x:%02x: " 406 printk(KERN_WARNING "pci_bus %04x:%02x: "
399 "ignored (out of memory)\n", domain, busnum); 407 "ignored (out of memory)\n", domain, busnum);
400 return NULL; 408 return NULL;
401 } 409 }
402 410
411 sd = &info->sd;
403 sd->domain = domain; 412 sd->domain = domain;
404 sd->node = node; 413 sd->node = node;
405 /* 414 /*
@@ -413,22 +422,32 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
413 * be replaced by sd. 422 * be replaced by sd.
414 */ 423 */
415 memcpy(bus->sysdata, sd, sizeof(*sd)); 424 memcpy(bus->sysdata, sd, sizeof(*sd));
416 kfree(sd); 425 kfree(info);
417 } else { 426 } else {
418 get_current_resources(device, busnum, domain, &resources); 427 probe_pci_root_info(info, device, busnum, domain);
419 428
420 /* 429 /*
421 * _CRS with no apertures is normal, so only fall back to 430 * _CRS with no apertures is normal, so only fall back to
422 * defaults or native bridge info if we're ignoring _CRS. 431 * defaults or native bridge info if we're ignoring _CRS.
423 */ 432 */
424 if (!pci_use_crs) 433 if (pci_use_crs)
434 add_resources(info, &resources);
435 else {
436 free_pci_root_info_res(info);
425 x86_pci_root_bus_resources(busnum, &resources); 437 x86_pci_root_bus_resources(busnum, &resources);
438 }
439
426 bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, 440 bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd,
427 &resources); 441 &resources);
428 if (bus) 442 if (bus) {
429 bus->subordinate = pci_scan_child_bus(bus); 443 bus->subordinate = pci_scan_child_bus(bus);
430 else 444 pci_set_host_bridge_release(
445 to_pci_host_bridge(bus->bridge),
446 release_pci_root_info, info);
447 } else {
431 pci_free_resource_list(&resources); 448 pci_free_resource_list(&resources);
449 __release_pci_root_info(info);
450 }
432 } 451 }
433 452
434 /* After the PCI-E bus has been walked and all devices discovered, 453 /* After the PCI-E bus has been walked and all devices discovered,
@@ -445,9 +464,6 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
445 } 464 }
446 } 465 }
447 466
448 if (!bus)
449 kfree(sd);
450
451 if (bus && node != -1) { 467 if (bus && node != -1) {
452#ifdef CONFIG_ACPI_NUMA 468#ifdef CONFIG_ACPI_NUMA
453 if (pxm >= 0) 469 if (pxm >= 0)
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 0567df3890e1..5aed49bff058 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -32,6 +32,27 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
32 32
33#define RANGE_NUM 16 33#define RANGE_NUM 16
34 34
35static struct pci_root_info __init *find_pci_root_info(int node, int link)
36{
37 struct pci_root_info *info;
38
39 /* find the position */
40 list_for_each_entry(info, &pci_root_infos, list)
41 if (info->node == node && info->link == link)
42 return info;
43
44 return NULL;
45}
46
47static void __init set_mp_bus_range_to_node(int min_bus, int max_bus, int node)
48{
49#ifdef CONFIG_NUMA
50 int j;
51
52 for (j = min_bus; j <= max_bus; j++)
53 set_mp_bus_to_node(j, node);
54#endif
55}
35/** 56/**
36 * early_fill_mp_bus_to_node() 57 * early_fill_mp_bus_to_node()
37 * called before pcibios_scan_root and pci_scan_bus 58 * called before pcibios_scan_root and pci_scan_bus
@@ -41,7 +62,6 @@ static struct pci_hostbridge_probe pci_probes[] __initdata = {
41static int __init early_fill_mp_bus_info(void) 62static int __init early_fill_mp_bus_info(void)
42{ 63{
43 int i; 64 int i;
44 int j;
45 unsigned bus; 65 unsigned bus;
46 unsigned slot; 66 unsigned slot;
47 int node; 67 int node;
@@ -50,7 +70,6 @@ static int __init early_fill_mp_bus_info(void)
50 int def_link; 70 int def_link;
51 struct pci_root_info *info; 71 struct pci_root_info *info;
52 u32 reg; 72 u32 reg;
53 struct resource *res;
54 u64 start; 73 u64 start;
55 u64 end; 74 u64 end;
56 struct range range[RANGE_NUM]; 75 struct range range[RANGE_NUM];
@@ -86,7 +105,6 @@ static int __init early_fill_mp_bus_info(void)
86 if (!found) 105 if (!found)
87 return 0; 106 return 0;
88 107
89 pci_root_num = 0;
90 for (i = 0; i < 4; i++) { 108 for (i = 0; i < 4; i++) {
91 int min_bus; 109 int min_bus;
92 int max_bus; 110 int max_bus;
@@ -99,19 +117,11 @@ static int __init early_fill_mp_bus_info(void)
99 min_bus = (reg >> 16) & 0xff; 117 min_bus = (reg >> 16) & 0xff;
100 max_bus = (reg >> 24) & 0xff; 118 max_bus = (reg >> 24) & 0xff;
101 node = (reg >> 4) & 0x07; 119 node = (reg >> 4) & 0x07;
102#ifdef CONFIG_NUMA 120 set_mp_bus_range_to_node(min_bus, max_bus, node);
103 for (j = min_bus; j <= max_bus; j++)
104 set_mp_bus_to_node(j, node);
105#endif
106 link = (reg >> 8) & 0x03; 121 link = (reg >> 8) & 0x03;
107 122
108 info = &pci_root_info[pci_root_num]; 123 info = alloc_pci_root_info(min_bus, max_bus, node, link);
109 info->bus_min = min_bus;
110 info->bus_max = max_bus;
111 info->node = node;
112 info->link = link;
113 sprintf(info->name, "PCI Bus #%02x", min_bus); 124 sprintf(info->name, "PCI Bus #%02x", min_bus);
114 pci_root_num++;
115 } 125 }
116 126
117 /* get the default node and link for left over res */ 127 /* get the default node and link for left over res */
@@ -134,16 +144,10 @@ static int __init early_fill_mp_bus_info(void)
134 link = (reg >> 4) & 0x03; 144 link = (reg >> 4) & 0x03;
135 end = (reg & 0xfff000) | 0xfff; 145 end = (reg & 0xfff000) | 0xfff;
136 146
137 /* find the position */ 147 info = find_pci_root_info(node, link);
138 for (j = 0; j < pci_root_num; j++) { 148 if (!info)
139 info = &pci_root_info[j];
140 if (info->node == node && info->link == link)
141 break;
142 }
143 if (j == pci_root_num)
144 continue; /* not found */ 149 continue; /* not found */
145 150
146 info = &pci_root_info[j];
147 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", 151 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
148 node, link, start, end); 152 node, link, start, end);
149 153
@@ -155,13 +159,8 @@ static int __init early_fill_mp_bus_info(void)
155 } 159 }
156 /* add left over io port range to def node/link, [0, 0xffff] */ 160 /* add left over io port range to def node/link, [0, 0xffff] */
157 /* find the position */ 161 /* find the position */
158 for (j = 0; j < pci_root_num; j++) { 162 info = find_pci_root_info(def_node, def_link);
159 info = &pci_root_info[j]; 163 if (info) {
160 if (info->node == def_node && info->link == def_link)
161 break;
162 }
163 if (j < pci_root_num) {
164 info = &pci_root_info[j];
165 for (i = 0; i < RANGE_NUM; i++) { 164 for (i = 0; i < RANGE_NUM; i++) {
166 if (!range[i].end) 165 if (!range[i].end)
167 continue; 166 continue;
@@ -214,16 +213,10 @@ static int __init early_fill_mp_bus_info(void)
214 end <<= 8; 213 end <<= 8;
215 end |= 0xffff; 214 end |= 0xffff;
216 215
217 /* find the position */ 216 info = find_pci_root_info(node, link);
218 for (j = 0; j < pci_root_num; j++) {
219 info = &pci_root_info[j];
220 if (info->node == node && info->link == link)
221 break;
222 }
223 if (j == pci_root_num)
224 continue; /* not found */
225 217
226 info = &pci_root_info[j]; 218 if (!info)
219 continue;
227 220
228 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", 221 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
229 node, link, start, end); 222 node, link, start, end);
@@ -291,14 +284,8 @@ static int __init early_fill_mp_bus_info(void)
291 * add left over mmio range to def node/link ? 284 * add left over mmio range to def node/link ?
292 * that is tricky, just record range in from start_min to 4G 285 * that is tricky, just record range in from start_min to 4G
293 */ 286 */
294 for (j = 0; j < pci_root_num; j++) { 287 info = find_pci_root_info(def_node, def_link);
295 info = &pci_root_info[j]; 288 if (info) {
296 if (info->node == def_node && info->link == def_link)
297 break;
298 }
299 if (j < pci_root_num) {
300 info = &pci_root_info[j];
301
302 for (i = 0; i < RANGE_NUM; i++) { 289 for (i = 0; i < RANGE_NUM; i++) {
303 if (!range[i].end) 290 if (!range[i].end)
304 continue; 291 continue;
@@ -309,20 +296,16 @@ static int __init early_fill_mp_bus_info(void)
309 } 296 }
310 } 297 }
311 298
312 for (i = 0; i < pci_root_num; i++) { 299 list_for_each_entry(info, &pci_root_infos, list) {
313 int res_num;
314 int busnum; 300 int busnum;
301 struct pci_root_res *root_res;
315 302
316 info = &pci_root_info[i];
317 res_num = info->res_num;
318 busnum = info->bus_min; 303 busnum = info->bus_min;
319 printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", 304 printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
320 info->bus_min, info->bus_max, info->node, info->link); 305 info->bus_min, info->bus_max, info->node, info->link);
321 for (j = 0; j < res_num; j++) { 306 list_for_each_entry(root_res, &info->resources, list)
322 res = &info->res[j]; 307 printk(KERN_DEBUG "bus: %02x %pR\n",
323 printk(KERN_DEBUG "bus: %02x index %x %pR\n", 308 busnum, &root_res->res);
324 busnum, j, res);
325 }
326 } 309 }
327 310
328 return 0; 311 return 0;
diff --git a/arch/x86/pci/broadcom_bus.c b/arch/x86/pci/broadcom_bus.c
index f3a7c569a403..614392ced7d6 100644
--- a/arch/x86/pci/broadcom_bus.c
+++ b/arch/x86/pci/broadcom_bus.c
@@ -22,19 +22,15 @@
22static void __init cnb20le_res(u8 bus, u8 slot, u8 func) 22static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
23{ 23{
24 struct pci_root_info *info; 24 struct pci_root_info *info;
25 struct pci_root_res *root_res;
25 struct resource res; 26 struct resource res;
26 u16 word1, word2; 27 u16 word1, word2;
27 u8 fbus, lbus; 28 u8 fbus, lbus;
28 int i;
29
30 info = &pci_root_info[pci_root_num];
31 pci_root_num++;
32 29
33 /* read the PCI bus numbers */ 30 /* read the PCI bus numbers */
34 fbus = read_pci_config_byte(bus, slot, func, 0x44); 31 fbus = read_pci_config_byte(bus, slot, func, 0x44);
35 lbus = read_pci_config_byte(bus, slot, func, 0x45); 32 lbus = read_pci_config_byte(bus, slot, func, 0x45);
36 info->bus_min = fbus; 33 info = alloc_pci_root_info(fbus, lbus, 0, 0);
37 info->bus_max = lbus;
38 34
39 /* 35 /*
40 * Add the legacy IDE ports on bus 0 36 * Add the legacy IDE ports on bus 0
@@ -86,8 +82,8 @@ static void __init cnb20le_res(u8 bus, u8 slot, u8 func)
86 res.flags = IORESOURCE_BUS; 82 res.flags = IORESOURCE_BUS;
87 printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res); 83 printk(KERN_INFO "CNB20LE PCI Host Bridge (domain 0000 %pR)\n", &res);
88 84
89 for (i = 0; i < info->res_num; i++) 85 list_for_each_entry(root_res, &info->resources, list)
90 printk(KERN_INFO "host bridge window %pR\n", &info->res[i]); 86 printk(KERN_INFO "host bridge window %pR\n", &root_res->res);
91} 87}
92 88
93static int __init broadcom_postcore_init(void) 89static int __init broadcom_postcore_init(void)
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
index fd3f65510e9d..306579f7d0fd 100644
--- a/arch/x86/pci/bus_numa.c
+++ b/arch/x86/pci/bus_numa.c
@@ -4,35 +4,38 @@
4 4
5#include "bus_numa.h" 5#include "bus_numa.h"
6 6
7int pci_root_num; 7LIST_HEAD(pci_root_infos);
8struct pci_root_info pci_root_info[PCI_ROOT_NR];
9 8
10void x86_pci_root_bus_resources(int bus, struct list_head *resources) 9static struct pci_root_info *x86_find_pci_root_info(int bus)
11{ 10{
12 int i;
13 int j;
14 struct pci_root_info *info; 11 struct pci_root_info *info;
15 12
16 if (!pci_root_num) 13 if (list_empty(&pci_root_infos))
17 goto default_resources; 14 return NULL;
18 15
19 for (i = 0; i < pci_root_num; i++) { 16 list_for_each_entry(info, &pci_root_infos, list)
20 if (pci_root_info[i].bus_min == bus) 17 if (info->bus_min == bus)
21 break; 18 return info;
22 } 19
20 return NULL;
21}
23 22
24 if (i == pci_root_num) 23void x86_pci_root_bus_resources(int bus, struct list_head *resources)
24{
25 struct pci_root_info *info = x86_find_pci_root_info(bus);
26 struct pci_root_res *root_res;
27
28 if (!info)
25 goto default_resources; 29 goto default_resources;
26 30
27 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", 31 printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
28 bus); 32 bus);
29 33
30 info = &pci_root_info[i]; 34 list_for_each_entry(root_res, &info->resources, list) {
31 for (j = 0; j < info->res_num; j++) {
32 struct resource *res; 35 struct resource *res;
33 struct resource *root; 36 struct resource *root;
34 37
35 res = &info->res[j]; 38 res = &root_res->res;
36 pci_add_resource(resources, res); 39 pci_add_resource(resources, res);
37 if (res->flags & IORESOURCE_IO) 40 if (res->flags & IORESOURCE_IO)
38 root = &ioport_resource; 41 root = &ioport_resource;
@@ -53,11 +56,32 @@ default_resources:
53 pci_add_resource(resources, &iomem_resource); 56 pci_add_resource(resources, &iomem_resource);
54} 57}
55 58
59struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max,
60 int node, int link)
61{
62 struct pci_root_info *info;
63
64 info = kzalloc(sizeof(*info), GFP_KERNEL);
65
66 if (!info)
67 return info;
68
69 INIT_LIST_HEAD(&info->resources);
70 info->bus_min = bus_min;
71 info->bus_max = bus_max;
72 info->node = node;
73 info->link = link;
74
75 list_add_tail(&info->list, &pci_root_infos);
76
77 return info;
78}
79
56void __devinit update_res(struct pci_root_info *info, resource_size_t start, 80void __devinit update_res(struct pci_root_info *info, resource_size_t start,
57 resource_size_t end, unsigned long flags, int merge) 81 resource_size_t end, unsigned long flags, int merge)
58{ 82{
59 int i;
60 struct resource *res; 83 struct resource *res;
84 struct pci_root_res *root_res;
61 85
62 if (start > end) 86 if (start > end)
63 return; 87 return;
@@ -69,11 +93,11 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
69 goto addit; 93 goto addit;
70 94
71 /* try to merge it with old one */ 95 /* try to merge it with old one */
72 for (i = 0; i < info->res_num; i++) { 96 list_for_each_entry(root_res, &info->resources, list) {
73 resource_size_t final_start, final_end; 97 resource_size_t final_start, final_end;
74 resource_size_t common_start, common_end; 98 resource_size_t common_start, common_end;
75 99
76 res = &info->res[i]; 100 res = &root_res->res;
77 if (res->flags != flags) 101 if (res->flags != flags)
78 continue; 102 continue;
79 103
@@ -93,14 +117,15 @@ void __devinit update_res(struct pci_root_info *info, resource_size_t start,
93addit: 117addit:
94 118
95 /* need to add that */ 119 /* need to add that */
96 if (info->res_num >= RES_NUM) 120 root_res = kzalloc(sizeof(*root_res), GFP_KERNEL);
121 if (!root_res)
97 return; 122 return;
98 123
99 res = &info->res[info->res_num]; 124 res = &root_res->res;
100 res->name = info->name; 125 res->name = info->name;
101 res->flags = flags; 126 res->flags = flags;
102 res->start = start; 127 res->start = start;
103 res->end = end; 128 res->end = end;
104 res->child = NULL; 129
105 info->res_num++; 130 list_add_tail(&root_res->list, &info->resources);
106} 131}
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
index 804a4b40c31a..226a466b2b2b 100644
--- a/arch/x86/pci/bus_numa.h
+++ b/arch/x86/pci/bus_numa.h
@@ -4,22 +4,24 @@
4 * sub bus (transparent) will use entres from 3 to store extra from 4 * sub bus (transparent) will use entres from 3 to store extra from
5 * root, so need to make sure we have enough slot there. 5 * root, so need to make sure we have enough slot there.
6 */ 6 */
7#define RES_NUM 16 7struct pci_root_res {
8 struct list_head list;
9 struct resource res;
10};
11
8struct pci_root_info { 12struct pci_root_info {
13 struct list_head list;
9 char name[12]; 14 char name[12];
10 unsigned int res_num; 15 struct list_head resources;
11 struct resource res[RES_NUM];
12 int bus_min; 16 int bus_min;
13 int bus_max; 17 int bus_max;
14 int node; 18 int node;
15 int link; 19 int link;
16}; 20};
17 21
18/* 4 at this time, it may become to 32 */ 22extern struct list_head pci_root_infos;
19#define PCI_ROOT_NR 4 23struct pci_root_info *alloc_pci_root_info(int bus_min, int bus_max,
20extern int pci_root_num; 24 int node, int link);
21extern struct pci_root_info pci_root_info[PCI_ROOT_NR];
22
23extern void update_res(struct pci_root_info *info, resource_size_t start, 25extern void update_res(struct pci_root_info *info, resource_size_t start,
24 resource_size_t end, unsigned long flags, int merge); 26 resource_size_t end, unsigned long flags, int merge);
25#endif 27#endif
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 323481e06ef8..0ad990a20d4a 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -11,6 +11,7 @@
11#include <linux/dmi.h> 11#include <linux/dmi.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13 13
14#include <asm-generic/pci-bridge.h>
14#include <asm/acpi.h> 15#include <asm/acpi.h>
15#include <asm/segment.h> 16#include <asm/segment.h>
16#include <asm/io.h> 17#include <asm/io.h>
@@ -229,6 +230,14 @@ static int __devinit assign_all_busses(const struct dmi_system_id *d)
229} 230}
230#endif 231#endif
231 232
233static int __devinit set_scan_all(const struct dmi_system_id *d)
234{
235 printk(KERN_INFO "PCI: %s detected, enabling pci=pcie_scan_all\n",
236 d->ident);
237 pci_add_flags(PCI_SCAN_ALL_PCIE_DEVS);
238 return 0;
239}
240
232static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = { 241static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = {
233#ifdef __i386__ 242#ifdef __i386__
234/* 243/*
@@ -420,6 +429,13 @@ static const struct dmi_system_id __devinitconst pciprobe_dmi_table[] = {
420 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"), 429 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant DL585 G2"),
421 }, 430 },
422 }, 431 },
432 {
433 .callback = set_scan_all,
434 .ident = "Stratus/NEC ftServer",
435 .matches = {
436 DMI_MATCH(DMI_SYS_VENDOR, "ftServer"),
437 },
438 },
423 {} 439 {}
424}; 440};
425 441
@@ -430,9 +446,7 @@ void __init dmi_check_pciprobe(void)
430 446
431struct pci_bus * __devinit pcibios_scan_root(int busnum) 447struct pci_bus * __devinit pcibios_scan_root(int busnum)
432{ 448{
433 LIST_HEAD(resources);
434 struct pci_bus *bus = NULL; 449 struct pci_bus *bus = NULL;
435 struct pci_sysdata *sd;
436 450
437 while ((bus = pci_find_next_bus(bus)) != NULL) { 451 while ((bus = pci_find_next_bus(bus)) != NULL) {
438 if (bus->number == busnum) { 452 if (bus->number == busnum) {
@@ -441,28 +455,10 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
441 } 455 }
442 } 456 }
443 457
444 /* Allocate per-root-bus (not per bus) arch-specific data. 458 return pci_scan_bus_on_node(busnum, &pci_root_ops,
445 * TODO: leak; this memory is never freed. 459 get_mp_bus_to_node(busnum));
446 * It's arguable whether it's worth the trouble to care.
447 */
448 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
449 if (!sd) {
450 printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum);
451 return NULL;
452 }
453
454 sd->node = get_mp_bus_to_node(busnum);
455
456 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
457 x86_pci_root_bus_resources(busnum, &resources);
458 bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
459 if (!bus) {
460 pci_free_resource_list(&resources);
461 kfree(sd);
462 }
463
464 return bus;
465} 460}
461
466void __init pcibios_set_cache_line_size(void) 462void __init pcibios_set_cache_line_size(void)
467{ 463{
468 struct cpuinfo_x86 *c = &boot_cpu_data; 464 struct cpuinfo_x86 *c = &boot_cpu_data;
@@ -656,6 +652,7 @@ struct pci_bus * __devinit pci_scan_bus_on_node(int busno, struct pci_ops *ops,
656 } 652 }
657 sd->node = node; 653 sd->node = node;
658 x86_pci_root_bus_resources(busno, &resources); 654 x86_pci_root_bus_resources(busno, &resources);
655 printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busno);
659 bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources); 656 bus = pci_scan_root_bus(NULL, busno, ops, sd, &resources);
660 if (!bus) { 657 if (!bus) {
661 pci_free_resource_list(&resources); 658 pci_free_resource_list(&resources);
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 831971e731f7..dd8ca6f7223b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -57,7 +57,7 @@ static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev)
57{ 57{
58 struct pcibios_fwaddrmap *map; 58 struct pcibios_fwaddrmap *map;
59 59
60 WARN_ON(!spin_is_locked(&pcibios_fwaddrmap_lock)); 60 WARN_ON_SMP(!spin_is_locked(&pcibios_fwaddrmap_lock));
61 61
62 list_for_each_entry(map, &pcibios_fwaddrmappings, list) 62 list_for_each_entry(map, &pcibios_fwaddrmappings, list)
63 if (map->dev == dev) 63 if (map->dev == dev)