Commit | Line | Data |
---|---|---|
67f241f4 YL |
1 | #include <linux/init.h> |
2 | #include <linux/pci.h> | |
9ad3f2c7 | 3 | #include <linux/range.h> |
67f241f4 YL |
4 | |
5 | #include "bus_numa.h" | |
6 | ||
7 | int pci_root_num; | |
8 | struct pci_root_info pci_root_info[PCI_ROOT_NR]; | |
67f241f4 | 9 | |
2cd6975a | 10 | void x86_pci_root_bus_resources(int bus, struct list_head *resources) |
67f241f4 YL |
11 | { |
12 | int i; | |
13 | int j; | |
14 | struct pci_root_info *info; | |
15 | ||
67f241f4 | 16 | if (!pci_root_num) |
2cd6975a | 17 | goto default_resources; |
67f241f4 | 18 | |
67f241f4 | 19 | for (i = 0; i < pci_root_num; i++) { |
2cd6975a | 20 | if (pci_root_info[i].bus_min == bus) |
67f241f4 YL |
21 | break; |
22 | } | |
23 | ||
24 | if (i == pci_root_num) | |
2cd6975a | 25 | goto default_resources; |
67f241f4 | 26 | |
2cd6975a BH |
27 | printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n", |
28 | bus); | |
67f241f4 YL |
29 | |
30 | info = &pci_root_info[i]; | |
31 | for (j = 0; j < info->res_num; j++) { | |
32 | struct resource *res; | |
33 | struct resource *root; | |
34 | ||
35 | res = &info->res[j]; | |
2cd6975a | 36 | pci_add_resource(resources, res); |
67f241f4 YL |
37 | if (res->flags & IORESOURCE_IO) |
38 | root = &ioport_resource; | |
39 | else | |
40 | root = &iomem_resource; | |
41 | insert_resource(root, res); | |
42 | } | |
2cd6975a BH |
43 | return; |
44 | ||
45 | default_resources: | |
46 | /* | |
47 | * We don't have any host bridge aperture information from the | |
48 | * "native host bridge drivers," e.g., amd_bus or broadcom_bus, | |
49 | * so fall back to the defaults historically used by pci_create_bus(). | |
50 | */ | |
51 | printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus); | |
52 | pci_add_resource(resources, &ioport_resource); | |
53 | pci_add_resource(resources, &iomem_resource); | |
67f241f4 YL |
54 | } |
55 | ||
b74fd238 YL |
56 | void __devinit update_res(struct pci_root_info *info, resource_size_t start, |
57 | resource_size_t end, unsigned long flags, int merge) | |
67f241f4 YL |
58 | { |
59 | int i; | |
60 | struct resource *res; | |
61 | ||
62 | if (start > end) | |
63 | return; | |
64 | ||
9ad3f2c7 YL |
65 | if (start == MAX_RESOURCE) |
66 | return; | |
67 | ||
67f241f4 YL |
68 | if (!merge) |
69 | goto addit; | |
70 | ||
71 | /* try to merge it with old one */ | |
72 | for (i = 0; i < info->res_num; i++) { | |
b74fd238 YL |
73 | resource_size_t final_start, final_end; |
74 | resource_size_t common_start, common_end; | |
67f241f4 YL |
75 | |
76 | res = &info->res[i]; | |
77 | if (res->flags != flags) | |
78 | continue; | |
79 | ||
b74fd238 YL |
80 | common_start = max(res->start, start); |
81 | common_end = min(res->end, end); | |
67f241f4 YL |
82 | if (common_start > common_end + 1) |
83 | continue; | |
84 | ||
b74fd238 YL |
85 | final_start = min(res->start, start); |
86 | final_end = max(res->end, end); | |
67f241f4 YL |
87 | |
88 | res->start = final_start; | |
89 | res->end = final_end; | |
90 | return; | |
91 | } | |
92 | ||
93 | addit: | |
94 | ||
95 | /* need to add that */ | |
96 | if (info->res_num >= RES_NUM) | |
97 | return; | |
98 | ||
99 | res = &info->res[info->res_num]; | |
100 | res->name = info->name; | |
101 | res->flags = flags; | |
102 | res->start = start; | |
103 | res->end = end; | |
104 | res->child = NULL; | |
105 | info->res_num++; | |
106 | } |