diff options
author | Yinghai Lu <yinghai@kernel.org> | 2009-10-05 00:54:24 -0400 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-11-04 11:47:09 -0500 |
commit | 99935a7a59eaca0292c1a5880e10bae03f4a5e3d (patch) | |
tree | 44d7265182ad7e1ee795a420088bc99d0096b62c /arch/x86/pci/amd_bus.c | |
parent | 91d3f9bacdb4950d2f79fe2ba296aa249f60d06c (diff) |
x86/PCI: read root resources from IOH on Intel
For intel systems with multi IOH, we should read peer root resources
directly from PCI config space, and don't trust _CRS.
Signed-off-by: Yinghai Lu <yinghai.lu@sun.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'arch/x86/pci/amd_bus.c')
-rw-r--r-- | arch/x86/pci/amd_bus.c | 45 |
1 files changed, 18 insertions, 27 deletions
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c index 572ee9782f2a..995f36096a42 100644 --- a/arch/x86/pci/amd_bus.c +++ b/arch/x86/pci/amd_bus.c | |||
@@ -10,6 +10,8 @@ | |||
10 | #include <linux/cpumask.h> | 10 | #include <linux/cpumask.h> |
11 | #endif | 11 | #endif |
12 | 12 | ||
13 | #include "bus_numa.h" | ||
14 | |||
13 | /* | 15 | /* |
14 | * This discovers the pcibus <-> node mapping on AMD K8. | 16 | * This discovers the pcibus <-> node mapping on AMD K8. |
15 | * also get peer root bus resource for io,mmio | 17 | * also get peer root bus resource for io,mmio |
@@ -17,25 +19,9 @@ | |||
17 | 19 | ||
18 | #ifdef CONFIG_X86_64 | 20 | #ifdef CONFIG_X86_64 |
19 | 21 | ||
20 | /* | 22 | int pci_root_num; |
21 | * sub bus (transparent) will use entres from 3 to store extra from root, | 23 | struct pci_root_info pci_root_info[PCI_ROOT_NR]; |
22 | * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES? | 24 | static int found_all_numa_early; |
23 | */ | ||
24 | #define RES_NUM 16 | ||
25 | struct pci_root_info { | ||
26 | char name[12]; | ||
27 | unsigned int res_num; | ||
28 | struct resource res[RES_NUM]; | ||
29 | int bus_min; | ||
30 | int bus_max; | ||
31 | int node; | ||
32 | int link; | ||
33 | }; | ||
34 | |||
35 | /* 4 at this time, it may become to 32 */ | ||
36 | #define PCI_ROOT_NR 4 | ||
37 | static int pci_root_num; | ||
38 | static struct pci_root_info pci_root_info[PCI_ROOT_NR]; | ||
39 | 25 | ||
40 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) | 26 | void x86_pci_root_bus_res_quirks(struct pci_bus *b) |
41 | { | 27 | { |
@@ -48,8 +34,11 @@ void x86_pci_root_bus_res_quirks(struct pci_bus *b) | |||
48 | b->resource[1] != &iomem_resource) | 34 | b->resource[1] != &iomem_resource) |
49 | return; | 35 | return; |
50 | 36 | ||
51 | /* if only one root bus, don't need to anything */ | 37 | if (!pci_root_num) |
52 | if (pci_root_num < 2) | 38 | return; |
39 | |||
40 | /* for amd, if only one root bus, don't need to do anything */ | ||
41 | if (pci_root_num < 2 && found_all_numa_early) | ||
53 | return; | 42 | return; |
54 | 43 | ||
55 | for (i = 0; i < pci_root_num; i++) { | 44 | for (i = 0; i < pci_root_num; i++) { |
@@ -130,12 +119,15 @@ static void __init update_range(struct res_range *range, size_t start, | |||
130 | } | 119 | } |
131 | } | 120 | } |
132 | 121 | ||
133 | static void __init update_res(struct pci_root_info *info, size_t start, | 122 | void __init update_res(struct pci_root_info *info, size_t start, |
134 | size_t end, unsigned long flags, int merge) | 123 | size_t end, unsigned long flags, int merge) |
135 | { | 124 | { |
136 | int i; | 125 | int i; |
137 | struct resource *res; | 126 | struct resource *res; |
138 | 127 | ||
128 | if (start > end) | ||
129 | return; | ||
130 | |||
139 | if (!merge) | 131 | if (!merge) |
140 | goto addit; | 132 | goto addit; |
141 | 133 | ||
@@ -230,7 +222,6 @@ static int __init early_fill_mp_bus_info(void) | |||
230 | int j; | 222 | int j; |
231 | unsigned bus; | 223 | unsigned bus; |
232 | unsigned slot; | 224 | unsigned slot; |
233 | int found; | ||
234 | int node; | 225 | int node; |
235 | int link; | 226 | int link; |
236 | int def_node; | 227 | int def_node; |
@@ -247,7 +238,7 @@ static int __init early_fill_mp_bus_info(void) | |||
247 | if (!early_pci_allowed()) | 238 | if (!early_pci_allowed()) |
248 | return -1; | 239 | return -1; |
249 | 240 | ||
250 | found = 0; | 241 | found_all_numa_early = 0; |
251 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { | 242 | for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { |
252 | u32 id; | 243 | u32 id; |
253 | u16 device; | 244 | u16 device; |
@@ -261,12 +252,12 @@ static int __init early_fill_mp_bus_info(void) | |||
261 | device = (id>>16) & 0xffff; | 252 | device = (id>>16) & 0xffff; |
262 | if (pci_probes[i].vendor == vendor && | 253 | if (pci_probes[i].vendor == vendor && |
263 | pci_probes[i].device == device) { | 254 | pci_probes[i].device == device) { |
264 | found = 1; | 255 | found_all_numa_early = 1; |
265 | break; | 256 | break; |
266 | } | 257 | } |
267 | } | 258 | } |
268 | 259 | ||
269 | if (!found) | 260 | if (!found_all_numa_early) |
270 | return 0; | 261 | return 0; |
271 | 262 | ||
272 | pci_root_num = 0; | 263 | pci_root_num = 0; |
@@ -488,7 +479,7 @@ static int __init early_fill_mp_bus_info(void) | |||
488 | info = &pci_root_info[i]; | 479 | info = &pci_root_info[i]; |
489 | res_num = info->res_num; | 480 | res_num = info->res_num; |
490 | busnum = info->bus_min; | 481 | busnum = info->bus_min; |
491 | printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n", | 482 | printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n", |
492 | info->bus_min, info->bus_max, info->node, info->link); | 483 | info->bus_min, info->bus_max, info->node, info->link); |
493 | for (j = 0; j < res_num; j++) { | 484 | for (j = 0; j < res_num; j++) { |
494 | res = &info->res[j]; | 485 | res = &info->res[j]; |