Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : #include <linux/init.h>
3 : : #include <linux/pci.h>
4 : : #include <linux/range.h>
5 : :
6 : : #include "bus_numa.h"
7 : :
8 : : LIST_HEAD(pci_root_infos);
9 : :
10 : 30 : static struct pci_root_info *x86_find_pci_root_info(int bus)
11 : : {
12 : 30 : struct pci_root_info *info;
13 : :
14 [ - - - + ]: 30 : list_for_each_entry(info, &pci_root_infos, list)
15 [ # # # # ]: 0 : if (info->busn.start == bus)
16 : : return info;
17 : :
18 : : return NULL;
19 : : }
20 : :
21 : 30 : int x86_pci_root_bus_node(int bus)
22 : : {
23 : 30 : struct pci_root_info *info = x86_find_pci_root_info(bus);
24 : :
25 [ - + ]: 30 : if (!info)
26 : : return NUMA_NO_NODE;
27 : :
28 : 0 : return info->node;
29 : : }
30 : :
31 : 0 : void x86_pci_root_bus_resources(int bus, struct list_head *resources)
32 : : {
33 : 0 : struct pci_root_info *info = x86_find_pci_root_info(bus);
34 : 0 : struct pci_root_res *root_res;
35 : 0 : struct resource_entry *window;
36 : 0 : bool found = false;
37 : :
38 [ # # ]: 0 : if (!info)
39 : 0 : goto default_resources;
40 : :
41 : 0 : printk(KERN_DEBUG "PCI: root bus %02x: hardware-probed resources\n",
42 : : bus);
43 : :
44 : : /* already added by acpi ? */
45 [ # # ]: 0 : resource_list_for_each_entry(window, resources)
46 [ # # ]: 0 : if (window->res->flags & IORESOURCE_BUS) {
47 : : found = true;
48 : : break;
49 : : }
50 : :
51 [ # # ]: 0 : if (!found)
52 : 0 : pci_add_resource(resources, &info->busn);
53 : :
54 [ # # ]: 0 : list_for_each_entry(root_res, &info->resources, list)
55 : 0 : pci_add_resource(resources, &root_res->res);
56 : :
57 : : return;
58 : :
59 : : default_resources:
60 : : /*
61 : : * We don't have any host bridge aperture information from the
62 : : * "native host bridge drivers," e.g., amd_bus or broadcom_bus,
63 : : * so fall back to the defaults historically used by pci_create_bus().
64 : : */
65 : 0 : printk(KERN_DEBUG "PCI: root bus %02x: using default resources\n", bus);
66 : 0 : pci_add_resource(resources, &ioport_resource);
67 : 0 : pci_add_resource(resources, &iomem_resource);
68 : : }
69 : :
70 : 0 : struct pci_root_info __init *alloc_pci_root_info(int bus_min, int bus_max,
71 : : int node, int link)
72 : : {
73 : 0 : struct pci_root_info *info;
74 : :
75 : 0 : info = kzalloc(sizeof(*info), GFP_KERNEL);
76 : :
77 [ # # ]: 0 : if (!info)
78 : : return info;
79 : :
80 : 0 : sprintf(info->name, "PCI Bus #%02x", bus_min);
81 : :
82 : 0 : INIT_LIST_HEAD(&info->resources);
83 : 0 : info->busn.name = info->name;
84 : 0 : info->busn.start = bus_min;
85 : 0 : info->busn.end = bus_max;
86 : 0 : info->busn.flags = IORESOURCE_BUS;
87 : 0 : info->node = node;
88 : 0 : info->link = link;
89 : :
90 : 0 : list_add_tail(&info->list, &pci_root_infos);
91 : :
92 : 0 : return info;
93 : : }
94 : :
95 : 0 : void update_res(struct pci_root_info *info, resource_size_t start,
96 : : resource_size_t end, unsigned long flags, int merge)
97 : : {
98 : 0 : struct resource *res;
99 : 0 : struct pci_root_res *root_res;
100 : :
101 [ # # ]: 0 : if (start > end)
102 : : return;
103 : :
104 [ # # ]: 0 : if (start == MAX_RESOURCE)
105 : : return;
106 : :
107 [ # # ]: 0 : if (!merge)
108 : 0 : goto addit;
109 : :
110 : : /* try to merge it with old one */
111 [ # # ]: 0 : list_for_each_entry(root_res, &info->resources, list) {
112 : 0 : resource_size_t final_start, final_end;
113 : 0 : resource_size_t common_start, common_end;
114 : :
115 : 0 : res = &root_res->res;
116 [ # # ]: 0 : if (res->flags != flags)
117 : 0 : continue;
118 : :
119 : 0 : common_start = max(res->start, start);
120 : 0 : common_end = min(res->end, end);
121 [ # # ]: 0 : if (common_start > common_end + 1)
122 : 0 : continue;
123 : :
124 : 0 : final_start = min(res->start, start);
125 : 0 : final_end = max(res->end, end);
126 : :
127 : 0 : res->start = final_start;
128 : 0 : res->end = final_end;
129 : 0 : return;
130 : : }
131 : :
132 : 0 : addit:
133 : :
134 : : /* need to add that */
135 : 0 : root_res = kzalloc(sizeof(*root_res), GFP_KERNEL);
136 [ # # ]: 0 : if (!root_res)
137 : : return;
138 : :
139 : 0 : res = &root_res->res;
140 : 0 : res->name = info->name;
141 : 0 : res->flags = flags;
142 : 0 : res->start = start;
143 : 0 : res->end = end;
144 : :
145 : 0 : list_add_tail(&root_res->list, &info->resources);
146 : : }
|