aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/pci
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /arch/x86/pci
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'arch/x86/pci')
-rw-r--r--arch/x86/pci/Makefile8
-rw-r--r--arch/x86/pci/acpi.c170
-rw-r--r--arch/x86/pci/amd_bus.c239
-rw-r--r--arch/x86/pci/bus_numa.c101
-rw-r--r--arch/x86/pci/bus_numa.h25
-rw-r--r--arch/x86/pci/common.c30
-rw-r--r--arch/x86/pci/early.c7
-rw-r--r--arch/x86/pci/i386.c58
-rw-r--r--arch/x86/pci/init.c8
-rw-r--r--arch/x86/pci/irq.c19
-rw-r--r--arch/x86/pci/legacy.c24
-rw-r--r--arch/x86/pci/mmconfig-shared.c356
-rw-r--r--arch/x86/pci/mmconfig_32.c16
-rw-r--r--arch/x86/pci/mmconfig_64.c88
-rw-r--r--arch/x86/pci/mrst.c266
-rw-r--r--arch/x86/pci/numaq_32.c12
-rw-r--r--arch/x86/pci/olpc.c3
-rw-r--r--arch/x86/pci/pcbios.c1
-rw-r--r--arch/x86/pci/visws.c6
19 files changed, 831 insertions, 606 deletions
diff --git a/arch/x86/pci/Makefile b/arch/x86/pci/Makefile
index d49202e740ea..b110d97fb925 100644
--- a/arch/x86/pci/Makefile
+++ b/arch/x86/pci/Makefile
@@ -13,5 +13,11 @@ obj-$(CONFIG_X86_VISWS) += visws.o
13 13
14obj-$(CONFIG_X86_NUMAQ) += numaq_32.o 14obj-$(CONFIG_X86_NUMAQ) += numaq_32.o
15 15
16obj-$(CONFIG_X86_MRST) += mrst.o
17
16obj-y += common.o early.o 18obj-y += common.o early.o
17obj-y += amd_bus.o 19obj-y += amd_bus.o bus_numa.o
20
21ifeq ($(CONFIG_PCI_DEBUG),y)
22EXTRA_CFLAGS += -DDEBUG
23endif
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 1014eb4bfc37..31930fd30ea9 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -3,10 +3,12 @@
3#include <linux/init.h> 3#include <linux/init.h>
4#include <linux/irq.h> 4#include <linux/irq.h>
5#include <linux/dmi.h> 5#include <linux/dmi.h>
6#include <linux/slab.h>
6#include <asm/numa.h> 7#include <asm/numa.h>
7#include <asm/pci_x86.h> 8#include <asm/pci_x86.h>
8 9
9struct pci_root_info { 10struct pci_root_info {
11 struct acpi_device *bridge;
10 char *name; 12 char *name;
11 unsigned int res_num; 13 unsigned int res_num;
12 struct resource *res; 14 struct resource *res;
@@ -14,19 +16,94 @@ struct pci_root_info {
14 int busnum; 16 int busnum;
15}; 17};
16 18
19static bool pci_use_crs = true;
20
21static int __init set_use_crs(const struct dmi_system_id *id)
22{
23 pci_use_crs = true;
24 return 0;
25}
26
27static const struct dmi_system_id pci_use_crs_table[] __initconst = {
28 /* http://bugzilla.kernel.org/show_bug.cgi?id=14183 */
29 {
30 .callback = set_use_crs,
31 .ident = "IBM System x3800",
32 .matches = {
33 DMI_MATCH(DMI_SYS_VENDOR, "IBM"),
34 DMI_MATCH(DMI_PRODUCT_NAME, "x3800"),
35 },
36 },
37 {}
38};
39
40void __init pci_acpi_crs_quirks(void)
41{
42 int year;
43
44 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008)
45 pci_use_crs = false;
46
47 dmi_check_system(pci_use_crs_table);
48
49 /*
50 * If the user specifies "pci=use_crs" or "pci=nocrs" explicitly, that
51 * takes precedence over anything we figured out above.
52 */
53 if (pci_probe & PCI_ROOT_NO_CRS)
54 pci_use_crs = false;
55 else if (pci_probe & PCI_USE__CRS)
56 pci_use_crs = true;
57
58 printk(KERN_INFO "PCI: %s host bridge windows from ACPI; "
59 "if necessary, use \"pci=%s\" and report a bug\n",
60 pci_use_crs ? "Using" : "Ignoring",
61 pci_use_crs ? "nocrs" : "use_crs");
62}
63
17static acpi_status 64static acpi_status
18resource_to_addr(struct acpi_resource *resource, 65resource_to_addr(struct acpi_resource *resource,
19 struct acpi_resource_address64 *addr) 66 struct acpi_resource_address64 *addr)
20{ 67{
21 acpi_status status; 68 acpi_status status;
22 69 struct acpi_resource_memory24 *memory24;
23 status = acpi_resource_to_address64(resource, addr); 70 struct acpi_resource_memory32 *memory32;
24 if (ACPI_SUCCESS(status) && 71 struct acpi_resource_fixed_memory32 *fixed_memory32;
25 (addr->resource_type == ACPI_MEMORY_RANGE || 72
26 addr->resource_type == ACPI_IO_RANGE) && 73 memset(addr, 0, sizeof(*addr));
27 addr->address_length > 0 && 74 switch (resource->type) {
28 addr->producer_consumer == ACPI_PRODUCER) { 75 case ACPI_RESOURCE_TYPE_MEMORY24:
76 memory24 = &resource->data.memory24;
77 addr->resource_type = ACPI_MEMORY_RANGE;
78 addr->minimum = memory24->minimum;
79 addr->address_length = memory24->address_length;
80 addr->maximum = addr->minimum + addr->address_length - 1;
81 return AE_OK;
82 case ACPI_RESOURCE_TYPE_MEMORY32:
83 memory32 = &resource->data.memory32;
84 addr->resource_type = ACPI_MEMORY_RANGE;
85 addr->minimum = memory32->minimum;
86 addr->address_length = memory32->address_length;
87 addr->maximum = addr->minimum + addr->address_length - 1;
29 return AE_OK; 88 return AE_OK;
89 case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
90 fixed_memory32 = &resource->data.fixed_memory32;
91 addr->resource_type = ACPI_MEMORY_RANGE;
92 addr->minimum = fixed_memory32->address;
93 addr->address_length = fixed_memory32->address_length;
94 addr->maximum = addr->minimum + addr->address_length - 1;
95 return AE_OK;
96 case ACPI_RESOURCE_TYPE_ADDRESS16:
97 case ACPI_RESOURCE_TYPE_ADDRESS32:
98 case ACPI_RESOURCE_TYPE_ADDRESS64:
99 status = acpi_resource_to_address64(resource, addr);
100 if (ACPI_SUCCESS(status) &&
101 (addr->resource_type == ACPI_MEMORY_RANGE ||
102 addr->resource_type == ACPI_IO_RANGE) &&
103 addr->address_length > 0) {
104 return AE_OK;
105 }
106 break;
30 } 107 }
31 return AE_ERROR; 108 return AE_ERROR;
32} 109}
@@ -44,20 +121,6 @@ count_resource(struct acpi_resource *acpi_res, void *data)
44 return AE_OK; 121 return AE_OK;
45} 122}
46 123
47static int
48bus_has_transparent_bridge(struct pci_bus *bus)
49{
50 struct pci_dev *dev;
51
52 list_for_each_entry(dev, &bus->devices, bus_list) {
53 u16 class = dev->class >> 8;
54
55 if (class == PCI_CLASS_BRIDGE_PCI && dev->transparent)
56 return true;
57 }
58 return false;
59}
60
61static acpi_status 124static acpi_status
62setup_resource(struct acpi_resource *acpi_res, void *data) 125setup_resource(struct acpi_resource *acpi_res, void *data)
63{ 126{
@@ -66,13 +129,9 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
66 struct acpi_resource_address64 addr; 129 struct acpi_resource_address64 addr;
67 acpi_status status; 130 acpi_status status;
68 unsigned long flags; 131 unsigned long flags;
69 struct resource *root; 132 struct resource *root, *conflict;
70 int max_root_bus_resources = PCI_BUS_NUM_RESOURCES;
71 u64 start, end; 133 u64 start, end;
72 134
73 if (bus_has_transparent_bridge(info->bus))
74 max_root_bus_resources -= 3;
75
76 status = resource_to_addr(acpi_res, &addr); 135 status = resource_to_addr(acpi_res, &addr);
77 if (!ACPI_SUCCESS(status)) 136 if (!ACPI_SUCCESS(status))
78 return AE_OK; 137 return AE_OK;
@@ -89,15 +148,7 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
89 return AE_OK; 148 return AE_OK;
90 149
91 start = addr.minimum + addr.translation_offset; 150 start = addr.minimum + addr.translation_offset;
92 end = start + addr.address_length - 1; 151 end = addr.maximum + addr.translation_offset;
93 if (info->res_num >= max_root_bus_resources) {
94 printk(KERN_WARNING "PCI: Failed to allocate 0x%lx-0x%lx "
95 "from %s for %s due to _CRS returning more than "
96 "%d resource descriptors\n", (unsigned long) start,
97 (unsigned long) end, root->name, info->name,
98 max_root_bus_resources);
99 return AE_OK;
100 }
101 152
102 res = &info->res[info->res_num]; 153 res = &info->res[info->res_num];
103 res->name = info->name; 154 res->name = info->name;
@@ -106,13 +157,29 @@ setup_resource(struct acpi_resource *acpi_res, void *data)
106 res->end = end; 157 res->end = end;
107 res->child = NULL; 158 res->child = NULL;
108 159
109 if (insert_resource(root, res)) { 160 if (!pci_use_crs) {
110 printk(KERN_ERR "PCI: Failed to allocate 0x%lx-0x%lx " 161 dev_printk(KERN_DEBUG, &info->bridge->dev,
111 "from %s for %s\n", (unsigned long) res->start, 162 "host bridge window %pR (ignored)\n", res);
112 (unsigned long) res->end, root->name, info->name); 163 return AE_OK;
164 }
165
166 conflict = insert_resource_conflict(root, res);
167 if (conflict) {
168 dev_err(&info->bridge->dev,
169 "address space collision: host bridge window %pR "
170 "conflicts with %s %pR\n",
171 res, conflict->name, conflict);
113 } else { 172 } else {
114 info->bus->resource[info->res_num] = res; 173 pci_bus_add_resource(info->bus, res, 0);
115 info->res_num++; 174 info->res_num++;
175 if (addr.translation_offset)
176 dev_info(&info->bridge->dev, "host bridge window %pR "
177 "(PCI address [%#llx-%#llx])\n",
178 res, res->start - addr.translation_offset,
179 res->end - addr.translation_offset);
180 else
181 dev_info(&info->bridge->dev,
182 "host bridge window %pR\n", res);
116 } 183 }
117 return AE_OK; 184 return AE_OK;
118} 185}
@@ -124,6 +191,10 @@ get_current_resources(struct acpi_device *device, int busnum,
124 struct pci_root_info info; 191 struct pci_root_info info;
125 size_t size; 192 size_t size;
126 193
194 if (pci_use_crs)
195 pci_bus_remove_resources(bus);
196
197 info.bridge = device;
127 info.bus = bus; 198 info.bus = bus;
128 info.res_num = 0; 199 info.res_num = 0;
129 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource, 200 acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
@@ -163,8 +234,9 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
163#endif 234#endif
164 235
165 if (domain && !pci_domains_supported) { 236 if (domain && !pci_domains_supported) {
166 printk(KERN_WARNING "PCI: Multiple domains not supported " 237 printk(KERN_WARNING "pci_bus %04x:%02x: "
167 "(dom %d, bus %d)\n", domain, busnum); 238 "ignored (multiple domains not supported)\n",
239 domain, busnum);
168 return NULL; 240 return NULL;
169 } 241 }
170 242
@@ -188,7 +260,8 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
188 */ 260 */
189 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 261 sd = kzalloc(sizeof(*sd), GFP_KERNEL);
190 if (!sd) { 262 if (!sd) {
191 printk(KERN_ERR "PCI: OOM, not probing PCI bus %02x\n", busnum); 263 printk(KERN_WARNING "pci_bus %04x:%02x: "
264 "ignored (out of memory)\n", domain, busnum);
192 return NULL; 265 return NULL;
193 } 266 }
194 267
@@ -209,9 +282,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
209 } else { 282 } else {
210 bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd); 283 bus = pci_create_bus(NULL, busnum, &pci_root_ops, sd);
211 if (bus) { 284 if (bus) {
212 if (pci_probe & PCI_USE__CRS) 285 get_current_resources(device, busnum, domain, bus);
213 get_current_resources(device, busnum, domain,
214 bus);
215 bus->subordinate = pci_scan_child_bus(bus); 286 bus->subordinate = pci_scan_child_bus(bus);
216 } 287 }
217 } 288 }
@@ -236,17 +307,14 @@ int __init pci_acpi_init(void)
236{ 307{
237 struct pci_dev *dev = NULL; 308 struct pci_dev *dev = NULL;
238 309
239 if (pcibios_scanned)
240 return 0;
241
242 if (acpi_noirq) 310 if (acpi_noirq)
243 return 0; 311 return -ENODEV;
244 312
245 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n"); 313 printk(KERN_INFO "PCI: Using ACPI for IRQ routing\n");
246 acpi_irq_penalty_init(); 314 acpi_irq_penalty_init();
247 pcibios_scanned++;
248 pcibios_enable_irq = acpi_pci_irq_enable; 315 pcibios_enable_irq = acpi_pci_irq_enable;
249 pcibios_disable_irq = acpi_pci_irq_disable; 316 pcibios_disable_irq = acpi_pci_irq_disable;
317 x86_init.pci.init_irq = x86_init_noop;
250 318
251 if (pci_routeirq) { 319 if (pci_routeirq) {
252 /* 320 /*
diff --git a/arch/x86/pci/amd_bus.c b/arch/x86/pci/amd_bus.c
index 572ee9782f2a..fc1e8fe07e5c 100644
--- a/arch/x86/pci/amd_bus.c
+++ b/arch/x86/pci/amd_bus.c
@@ -2,180 +2,19 @@
2#include <linux/pci.h> 2#include <linux/pci.h>
3#include <linux/topology.h> 3#include <linux/topology.h>
4#include <linux/cpu.h> 4#include <linux/cpu.h>
5#include <linux/range.h>
6
5#include <asm/pci_x86.h> 7#include <asm/pci_x86.h>
6 8
7#ifdef CONFIG_X86_64
8#include <asm/pci-direct.h> 9#include <asm/pci-direct.h>
9#include <asm/mpspec.h> 10
10#include <linux/cpumask.h> 11#include "bus_numa.h"
11#endif
12 12
13/* 13/*
14 * This discovers the pcibus <-> node mapping on AMD K8. 14 * This discovers the pcibus <-> node mapping on AMD K8.
15 * also get peer root bus resource for io,mmio 15 * also get peer root bus resource for io,mmio
16 */ 16 */
17 17
18#ifdef CONFIG_X86_64
19
20/*
21 * sub bus (transparent) will use entres from 3 to store extra from root,
22 * so need to make sure have enought slot there, increase PCI_BUS_NUM_RESOURCES?
23 */
24#define RES_NUM 16
25struct 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
37static int pci_root_num;
38static struct pci_root_info pci_root_info[PCI_ROOT_NR];
39
40void x86_pci_root_bus_res_quirks(struct pci_bus *b)
41{
42 int i;
43 int j;
44 struct pci_root_info *info;
45
46 /* don't go for it if _CRS is used already */
47 if (b->resource[0] != &ioport_resource ||
48 b->resource[1] != &iomem_resource)
49 return;
50
51 /* if only one root bus, don't need to anything */
52 if (pci_root_num < 2)
53 return;
54
55 for (i = 0; i < pci_root_num; i++) {
56 if (pci_root_info[i].bus_min == b->number)
57 break;
58 }
59
60 if (i == pci_root_num)
61 return;
62
63 printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
64 b->number);
65
66 info = &pci_root_info[i];
67 for (j = 0; j < info->res_num; j++) {
68 struct resource *res;
69 struct resource *root;
70
71 res = &info->res[j];
72 b->resource[j] = res;
73 if (res->flags & IORESOURCE_IO)
74 root = &ioport_resource;
75 else
76 root = &iomem_resource;
77 insert_resource(root, res);
78 }
79}
80
81#define RANGE_NUM 16
82
83struct res_range {
84 size_t start;
85 size_t end;
86};
87
88static void __init update_range(struct res_range *range, size_t start,
89 size_t end)
90{
91 int i;
92 int j;
93
94 for (j = 0; j < RANGE_NUM; j++) {
95 if (!range[j].end)
96 continue;
97
98 if (start <= range[j].start && end >= range[j].end) {
99 range[j].start = 0;
100 range[j].end = 0;
101 continue;
102 }
103
104 if (start <= range[j].start && end < range[j].end && range[j].start < end + 1) {
105 range[j].start = end + 1;
106 continue;
107 }
108
109
110 if (start > range[j].start && end >= range[j].end && range[j].end > start - 1) {
111 range[j].end = start - 1;
112 continue;
113 }
114
115 if (start > range[j].start && end < range[j].end) {
116 /* find the new spare */
117 for (i = 0; i < RANGE_NUM; i++) {
118 if (range[i].end == 0)
119 break;
120 }
121 if (i < RANGE_NUM) {
122 range[i].end = range[j].end;
123 range[i].start = end + 1;
124 } else {
125 printk(KERN_ERR "run of slot in ranges\n");
126 }
127 range[j].end = start - 1;
128 continue;
129 }
130 }
131}
132
133static void __init update_res(struct pci_root_info *info, size_t start,
134 size_t end, unsigned long flags, int merge)
135{
136 int i;
137 struct resource *res;
138
139 if (!merge)
140 goto addit;
141
142 /* try to merge it with old one */
143 for (i = 0; i < info->res_num; i++) {
144 size_t final_start, final_end;
145 size_t common_start, common_end;
146
147 res = &info->res[i];
148 if (res->flags != flags)
149 continue;
150
151 common_start = max((size_t)res->start, start);
152 common_end = min((size_t)res->end, end);
153 if (common_start > common_end + 1)
154 continue;
155
156 final_start = min((size_t)res->start, start);
157 final_end = max((size_t)res->end, end);
158
159 res->start = final_start;
160 res->end = final_end;
161 return;
162 }
163
164addit:
165
166 /* need to add that */
167 if (info->res_num >= RES_NUM)
168 return;
169
170 res = &info->res[info->res_num];
171 res->name = info->name;
172 res->flags = flags;
173 res->start = start;
174 res->end = end;
175 res->child = NULL;
176 info->res_num++;
177}
178
179struct pci_hostbridge_probe { 18struct pci_hostbridge_probe {
180 u32 bus; 19 u32 bus;
181 u32 slot; 20 u32 slot;
@@ -218,6 +57,8 @@ static void __init get_pci_mmcfg_amd_fam10h_range(void)
218 fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1; 57 fam10h_mmconf_end = base + (1ULL<<(segn_busn_bits + 20)) - 1;
219} 58}
220 59
60#define RANGE_NUM 16
61
221/** 62/**
222 * early_fill_mp_bus_to_node() 63 * early_fill_mp_bus_to_node()
223 * called before pcibios_scan_root and pci_scan_bus 64 * called before pcibios_scan_root and pci_scan_bus
@@ -230,7 +71,6 @@ static int __init early_fill_mp_bus_info(void)
230 int j; 71 int j;
231 unsigned bus; 72 unsigned bus;
232 unsigned slot; 73 unsigned slot;
233 int found;
234 int node; 74 int node;
235 int link; 75 int link;
236 int def_node; 76 int def_node;
@@ -238,16 +78,17 @@ static int __init early_fill_mp_bus_info(void)
238 struct pci_root_info *info; 78 struct pci_root_info *info;
239 u32 reg; 79 u32 reg;
240 struct resource *res; 80 struct resource *res;
241 size_t start; 81 u64 start;
242 size_t end; 82 u64 end;
243 struct res_range range[RANGE_NUM]; 83 struct range range[RANGE_NUM];
244 u64 val; 84 u64 val;
245 u32 address; 85 u32 address;
86 bool found;
246 87
247 if (!early_pci_allowed()) 88 if (!early_pci_allowed())
248 return -1; 89 return -1;
249 90
250 found = 0; 91 found = false;
251 for (i = 0; i < ARRAY_SIZE(pci_probes); i++) { 92 for (i = 0; i < ARRAY_SIZE(pci_probes); i++) {
252 u32 id; 93 u32 id;
253 u16 device; 94 u16 device;
@@ -261,7 +102,7 @@ static int __init early_fill_mp_bus_info(void)
261 device = (id>>16) & 0xffff; 102 device = (id>>16) & 0xffff;
262 if (pci_probes[i].vendor == vendor && 103 if (pci_probes[i].vendor == vendor &&
263 pci_probes[i].device == device) { 104 pci_probes[i].device == device) {
264 found = 1; 105 found = true;
265 break; 106 break;
266 } 107 }
267 } 108 }
@@ -304,7 +145,7 @@ static int __init early_fill_mp_bus_info(void)
304 def_link = (reg >> 8) & 0x03; 145 def_link = (reg >> 8) & 0x03;
305 146
306 memset(range, 0, sizeof(range)); 147 memset(range, 0, sizeof(range));
307 range[0].end = 0xffff; 148 add_range(range, RANGE_NUM, 0, 0, 0xffff + 1);
308 /* io port resource */ 149 /* io port resource */
309 for (i = 0; i < 4; i++) { 150 for (i = 0; i < 4; i++) {
310 reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3)); 151 reg = read_pci_config(bus, slot, 1, 0xc0 + (i << 3));
@@ -328,13 +169,13 @@ static int __init early_fill_mp_bus_info(void)
328 169
329 info = &pci_root_info[j]; 170 info = &pci_root_info[j];
330 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n", 171 printk(KERN_DEBUG "node %d link %d: io port [%llx, %llx]\n",
331 node, link, (u64)start, (u64)end); 172 node, link, start, end);
332 173
333 /* kernel only handle 16 bit only */ 174 /* kernel only handle 16 bit only */
334 if (end > 0xffff) 175 if (end > 0xffff)
335 end = 0xffff; 176 end = 0xffff;
336 update_res(info, start, end, IORESOURCE_IO, 1); 177 update_res(info, start, end, IORESOURCE_IO, 1);
337 update_range(range, start, end); 178 subtract_range(range, RANGE_NUM, start, end + 1);
338 } 179 }
339 /* add left over io port range to def node/link, [0, 0xffff] */ 180 /* add left over io port range to def node/link, [0, 0xffff] */
340 /* find the position */ 181 /* find the position */
@@ -349,29 +190,32 @@ static int __init early_fill_mp_bus_info(void)
349 if (!range[i].end) 190 if (!range[i].end)
350 continue; 191 continue;
351 192
352 update_res(info, range[i].start, range[i].end, 193 update_res(info, range[i].start, range[i].end - 1,
353 IORESOURCE_IO, 1); 194 IORESOURCE_IO, 1);
354 } 195 }
355 } 196 }
356 197
357 memset(range, 0, sizeof(range)); 198 memset(range, 0, sizeof(range));
358 /* 0xfd00000000-0xffffffffff for HT */ 199 /* 0xfd00000000-0xffffffffff for HT */
359 range[0].end = (0xfdULL<<32) - 1; 200 end = cap_resource((0xfdULL<<32) - 1);
201 end++;
202 add_range(range, RANGE_NUM, 0, 0, end);
360 203
361 /* need to take out [0, TOM) for RAM*/ 204 /* need to take out [0, TOM) for RAM*/
362 address = MSR_K8_TOP_MEM1; 205 address = MSR_K8_TOP_MEM1;
363 rdmsrl(address, val); 206 rdmsrl(address, val);
364 end = (val & 0xffffff800000ULL); 207 end = (val & 0xffffff800000ULL);
365 printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20); 208 printk(KERN_INFO "TOM: %016llx aka %lldM\n", end, end>>20);
366 if (end < (1ULL<<32)) 209 if (end < (1ULL<<32))
367 update_range(range, 0, end - 1); 210 subtract_range(range, RANGE_NUM, 0, end);
368 211
369 /* get mmconfig */ 212 /* get mmconfig */
370 get_pci_mmcfg_amd_fam10h_range(); 213 get_pci_mmcfg_amd_fam10h_range();
371 /* need to take out mmconf range */ 214 /* need to take out mmconf range */
372 if (fam10h_mmconf_end) { 215 if (fam10h_mmconf_end) {
373 printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end); 216 printk(KERN_DEBUG "Fam 10h mmconf [%llx, %llx]\n", fam10h_mmconf_start, fam10h_mmconf_end);
374 update_range(range, fam10h_mmconf_start, fam10h_mmconf_end); 217 subtract_range(range, RANGE_NUM, fam10h_mmconf_start,
218 fam10h_mmconf_end + 1);
375 } 219 }
376 220
377 /* mmio resource */ 221 /* mmio resource */
@@ -401,7 +245,7 @@ static int __init early_fill_mp_bus_info(void)
401 info = &pci_root_info[j]; 245 info = &pci_root_info[j];
402 246
403 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]", 247 printk(KERN_DEBUG "node %d link %d: mmio [%llx, %llx]",
404 node, link, (u64)start, (u64)end); 248 node, link, start, end);
405 /* 249 /*
406 * some sick allocation would have range overlap with fam10h 250 * some sick allocation would have range overlap with fam10h
407 * mmconf range, so need to update start and end. 251 * mmconf range, so need to update start and end.
@@ -426,14 +270,15 @@ static int __init early_fill_mp_bus_info(void)
426 /* we got a hole */ 270 /* we got a hole */
427 endx = fam10h_mmconf_start - 1; 271 endx = fam10h_mmconf_start - 1;
428 update_res(info, start, endx, IORESOURCE_MEM, 0); 272 update_res(info, start, endx, IORESOURCE_MEM, 0);
429 update_range(range, start, endx); 273 subtract_range(range, RANGE_NUM, start,
430 printk(KERN_CONT " ==> [%llx, %llx]", (u64)start, endx); 274 endx + 1);
275 printk(KERN_CONT " ==> [%llx, %llx]", start, endx);
431 start = fam10h_mmconf_end + 1; 276 start = fam10h_mmconf_end + 1;
432 changed = 1; 277 changed = 1;
433 } 278 }
434 if (changed) { 279 if (changed) {
435 if (start <= end) { 280 if (start <= end) {
436 printk(KERN_CONT " %s [%llx, %llx]", endx?"and":"==>", (u64)start, (u64)end); 281 printk(KERN_CONT " %s [%llx, %llx]", endx ? "and" : "==>", start, end);
437 } else { 282 } else {
438 printk(KERN_CONT "%s\n", endx?"":" ==> none"); 283 printk(KERN_CONT "%s\n", endx?"":" ==> none");
439 continue; 284 continue;
@@ -441,8 +286,9 @@ static int __init early_fill_mp_bus_info(void)
441 } 286 }
442 } 287 }
443 288
444 update_res(info, start, end, IORESOURCE_MEM, 1); 289 update_res(info, cap_resource(start), cap_resource(end),
445 update_range(range, start, end); 290 IORESOURCE_MEM, 1);
291 subtract_range(range, RANGE_NUM, start, end + 1);
446 printk(KERN_CONT "\n"); 292 printk(KERN_CONT "\n");
447 } 293 }
448 294
@@ -456,8 +302,8 @@ static int __init early_fill_mp_bus_info(void)
456 address = MSR_K8_TOP_MEM2; 302 address = MSR_K8_TOP_MEM2;
457 rdmsrl(address, val); 303 rdmsrl(address, val);
458 end = (val & 0xffffff800000ULL); 304 end = (val & 0xffffff800000ULL);
459 printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20); 305 printk(KERN_INFO "TOM2: %016llx aka %lldM\n", end, end>>20);
460 update_range(range, 1ULL<<32, end - 1); 306 subtract_range(range, RANGE_NUM, 1ULL<<32, end);
461 } 307 }
462 308
463 /* 309 /*
@@ -476,7 +322,8 @@ static int __init early_fill_mp_bus_info(void)
476 if (!range[i].end) 322 if (!range[i].end)
477 continue; 323 continue;
478 324
479 update_res(info, range[i].start, range[i].end, 325 update_res(info, cap_resource(range[i].start),
326 cap_resource(range[i].end - 1),
480 IORESOURCE_MEM, 1); 327 IORESOURCE_MEM, 1);
481 } 328 }
482 } 329 }
@@ -488,28 +335,18 @@ static int __init early_fill_mp_bus_info(void)
488 info = &pci_root_info[i]; 335 info = &pci_root_info[i];
489 res_num = info->res_num; 336 res_num = info->res_num;
490 busnum = info->bus_min; 337 busnum = info->bus_min;
491 printk(KERN_DEBUG "bus: [%02x,%02x] on node %x link %x\n", 338 printk(KERN_DEBUG "bus: [%02x, %02x] on node %x link %x\n",
492 info->bus_min, info->bus_max, info->node, info->link); 339 info->bus_min, info->bus_max, info->node, info->link);
493 for (j = 0; j < res_num; j++) { 340 for (j = 0; j < res_num; j++) {
494 res = &info->res[j]; 341 res = &info->res[j];
495 printk(KERN_DEBUG "bus: %02x index %x %s: [%llx, %llx]\n", 342 printk(KERN_DEBUG "bus: %02x index %x %pR\n",
496 busnum, j, 343 busnum, j, res);
497 (res->flags & IORESOURCE_IO)?"io port":"mmio",
498 res->start, res->end);
499 } 344 }
500 } 345 }
501 346
502 return 0; 347 return 0;
503} 348}
504 349
505#else /* !CONFIG_X86_64 */
506
507static int __init early_fill_mp_bus_info(void) { return 0; }
508
509#endif /* !CONFIG_X86_64 */
510
511/* common 32/64 bit code */
512
513#define ENABLE_CF8_EXT_CFG (1ULL << 46) 350#define ENABLE_CF8_EXT_CFG (1ULL << 46)
514 351
515static void enable_pci_io_ecs(void *unused) 352static void enable_pci_io_ecs(void *unused)
diff --git a/arch/x86/pci/bus_numa.c b/arch/x86/pci/bus_numa.c
new file mode 100644
index 000000000000..64a122883896
--- /dev/null
+++ b/arch/x86/pci/bus_numa.c
@@ -0,0 +1,101 @@
1#include <linux/init.h>
2#include <linux/pci.h>
3#include <linux/range.h>
4
5#include "bus_numa.h"
6
7int pci_root_num;
8struct pci_root_info pci_root_info[PCI_ROOT_NR];
9
10void x86_pci_root_bus_res_quirks(struct pci_bus *b)
11{
12 int i;
13 int j;
14 struct pci_root_info *info;
15
16 /* don't go for it if _CRS is used already */
17 if (b->resource[0] != &ioport_resource ||
18 b->resource[1] != &iomem_resource)
19 return;
20
21 if (!pci_root_num)
22 return;
23
24 for (i = 0; i < pci_root_num; i++) {
25 if (pci_root_info[i].bus_min == b->number)
26 break;
27 }
28
29 if (i == pci_root_num)
30 return;
31
32 printk(KERN_DEBUG "PCI: peer root bus %02x res updated from pci conf\n",
33 b->number);
34
35 pci_bus_remove_resources(b);
36 info = &pci_root_info[i];
37 for (j = 0; j < info->res_num; j++) {
38 struct resource *res;
39 struct resource *root;
40
41 res = &info->res[j];
42 pci_bus_add_resource(b, res, 0);
43 if (res->flags & IORESOURCE_IO)
44 root = &ioport_resource;
45 else
46 root = &iomem_resource;
47 insert_resource(root, res);
48 }
49}
50
51void __devinit update_res(struct pci_root_info *info, resource_size_t start,
52 resource_size_t end, unsigned long flags, int merge)
53{
54 int i;
55 struct resource *res;
56
57 if (start > end)
58 return;
59
60 if (start == MAX_RESOURCE)
61 return;
62
63 if (!merge)
64 goto addit;
65
66 /* try to merge it with old one */
67 for (i = 0; i < info->res_num; i++) {
68 resource_size_t final_start, final_end;
69 resource_size_t common_start, common_end;
70
71 res = &info->res[i];
72 if (res->flags != flags)
73 continue;
74
75 common_start = max(res->start, start);
76 common_end = min(res->end, end);
77 if (common_start > common_end + 1)
78 continue;
79
80 final_start = min(res->start, start);
81 final_end = max(res->end, end);
82
83 res->start = final_start;
84 res->end = final_end;
85 return;
86 }
87
88addit:
89
90 /* need to add that */
91 if (info->res_num >= RES_NUM)
92 return;
93
94 res = &info->res[info->res_num];
95 res->name = info->name;
96 res->flags = flags;
97 res->start = start;
98 res->end = end;
99 res->child = NULL;
100 info->res_num++;
101}
diff --git a/arch/x86/pci/bus_numa.h b/arch/x86/pci/bus_numa.h
new file mode 100644
index 000000000000..804a4b40c31a
--- /dev/null
+++ b/arch/x86/pci/bus_numa.h
@@ -0,0 +1,25 @@
1#ifndef __BUS_NUMA_H
2#define __BUS_NUMA_H
3/*
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.
6 */
7#define RES_NUM 16
8struct pci_root_info {
9 char name[12];
10 unsigned int res_num;
11 struct resource res[RES_NUM];
12 int bus_min;
13 int bus_max;
14 int node;
15 int link;
16};
17
18/* 4 at this time, it may become to 32 */
19#define PCI_ROOT_NR 4
20extern int pci_root_num;
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,
24 resource_size_t end, unsigned long flags, int merge);
25#endif
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 1331fcf26143..cf2e93869c48 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -9,6 +9,7 @@
9#include <linux/ioport.h> 9#include <linux/ioport.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/dmi.h> 11#include <linux/dmi.h>
12#include <linux/slab.h>
12 13
13#include <asm/acpi.h> 14#include <asm/acpi.h>
14#include <asm/segment.h> 15#include <asm/segment.h>
@@ -72,12 +73,6 @@ struct pci_ops pci_root_ops = {
72}; 73};
73 74
74/* 75/*
75 * legacy, numa, and acpi all want to call pcibios_scan_root
76 * from their initcalls. This flag prevents that.
77 */
78int pcibios_scanned;
79
80/*
81 * This interrupt-safe spinlock protects all accesses to PCI 76 * This interrupt-safe spinlock protects all accesses to PCI
82 * configuration space. 77 * configuration space.
83 */ 78 */
@@ -410,8 +405,6 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum)
410 return bus; 405 return bus;
411} 406}
412 407
413extern u8 pci_cache_line_size;
414
415int __init pcibios_init(void) 408int __init pcibios_init(void)
416{ 409{
417 struct cpuinfo_x86 *c = &boot_cpu_data; 410 struct cpuinfo_x86 *c = &boot_cpu_data;
@@ -422,15 +415,19 @@ int __init pcibios_init(void)
422 } 415 }
423 416
424 /* 417 /*
425 * Assume PCI cacheline size of 32 bytes for all x86s except K7/K8 418 * Set PCI cacheline size to that of the CPU if the CPU has reported it.
426 * and P4. It's also good for 386/486s (which actually have 16) 419 * (For older CPUs that don't support cpuid, we se it to 32 bytes
420 * It's also good for 386/486s (which actually have 16)
427 * as quite a few PCI devices do not support smaller values. 421 * as quite a few PCI devices do not support smaller values.
428 */ 422 */
429 pci_cache_line_size = 32 >> 2; 423 if (c->x86_clflush_size > 0) {
430 if (c->x86 >= 6 && c->x86_vendor == X86_VENDOR_AMD) 424 pci_dfl_cache_line_size = c->x86_clflush_size >> 2;
431 pci_cache_line_size = 64 >> 2; /* K7 & K8 */ 425 printk(KERN_DEBUG "PCI: pci_cache_line_size set to %d bytes\n",
432 else if (c->x86 > 6 && c->x86_vendor == X86_VENDOR_INTEL) 426 pci_dfl_cache_line_size << 2);
433 pci_cache_line_size = 128 >> 2; /* P4 */ 427 } else {
428 pci_dfl_cache_line_size = 32 >> 2;
429 printk(KERN_DEBUG "PCI: Unknown cacheline size. Setting to 32 bytes\n");
430 }
434 431
435 pcibios_resource_survey(); 432 pcibios_resource_survey();
436 433
@@ -518,6 +515,9 @@ char * __devinit pcibios_setup(char *str)
518 } else if (!strcmp(str, "use_crs")) { 515 } else if (!strcmp(str, "use_crs")) {
519 pci_probe |= PCI_USE__CRS; 516 pci_probe |= PCI_USE__CRS;
520 return NULL; 517 return NULL;
518 } else if (!strcmp(str, "nocrs")) {
519 pci_probe |= PCI_ROOT_NO_CRS;
520 return NULL;
521 } else if (!strcmp(str, "earlydump")) { 521 } else if (!strcmp(str, "earlydump")) {
522 pci_early_dump_regs = 1; 522 pci_early_dump_regs = 1;
523 return NULL; 523 return NULL;
diff --git a/arch/x86/pci/early.c b/arch/x86/pci/early.c
index aaf26ae58cd5..d1067d539bee 100644
--- a/arch/x86/pci/early.c
+++ b/arch/x86/pci/early.c
@@ -12,8 +12,6 @@ u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
12 u32 v; 12 u32 v;
13 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 13 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
14 v = inl(0xcfc); 14 v = inl(0xcfc);
15 if (v != 0xffffffff)
16 pr_debug("%x reading 4 from %x: %x\n", slot, offset, v);
17 return v; 15 return v;
18} 16}
19 17
@@ -22,7 +20,6 @@ u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
22 u8 v; 20 u8 v;
23 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 21 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
24 v = inb(0xcfc + (offset&3)); 22 v = inb(0xcfc + (offset&3));
25 pr_debug("%x reading 1 from %x: %x\n", slot, offset, v);
26 return v; 23 return v;
27} 24}
28 25
@@ -31,28 +28,24 @@ u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
31 u16 v; 28 u16 v;
32 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 29 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
33 v = inw(0xcfc + (offset&2)); 30 v = inw(0xcfc + (offset&2));
34 pr_debug("%x reading 2 from %x: %x\n", slot, offset, v);
35 return v; 31 return v;
36} 32}
37 33
38void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, 34void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset,
39 u32 val) 35 u32 val)
40{ 36{
41 pr_debug("%x writing to %x: %x\n", slot, offset, val);
42 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 37 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
43 outl(val, 0xcfc); 38 outl(val, 0xcfc);
44} 39}
45 40
46void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) 41void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val)
47{ 42{
48 pr_debug("%x writing to %x: %x\n", slot, offset, val);
49 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 43 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
50 outb(val, 0xcfc + (offset&3)); 44 outb(val, 0xcfc + (offset&3));
51} 45}
52 46
53void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val) 47void write_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset, u16 val)
54{ 48{
55 pr_debug("%x writing to %x: %x\n", slot, offset, val);
56 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); 49 outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
57 outw(val, 0xcfc + (offset&2)); 50 outw(val, 0xcfc + (offset&2));
58} 51}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index b22d13b0c71d..97da2ba9344b 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -60,22 +60,23 @@ skip_isa_ioresource_align(struct pci_dev *dev) {
60 * but we want to try to avoid allocating at 0x2900-0x2bff 60 * but we want to try to avoid allocating at 0x2900-0x2bff
61 * which might have be mirrored at 0x0100-0x03ff.. 61 * which might have be mirrored at 0x0100-0x03ff..
62 */ 62 */
63void 63resource_size_t
64pcibios_align_resource(void *data, struct resource *res, 64pcibios_align_resource(void *data, const struct resource *res,
65 resource_size_t size, resource_size_t align) 65 resource_size_t size, resource_size_t align)
66{ 66{
67 struct pci_dev *dev = data; 67 struct pci_dev *dev = data;
68 resource_size_t start = res->start;
68 69
69 if (res->flags & IORESOURCE_IO) { 70 if (res->flags & IORESOURCE_IO) {
70 resource_size_t start = res->start;
71
72 if (skip_isa_ioresource_align(dev)) 71 if (skip_isa_ioresource_align(dev))
73 return; 72 return start;
74 if (start & 0x300) { 73 if (start & 0x300)
75 start = (start + 0x3ff) & ~0x3ff; 74 start = (start + 0x3ff) & ~0x3ff;
76 res->start = start; 75 } else if (res->flags & IORESOURCE_MEM) {
77 } 76 if (start < BIOS_END)
77 start = BIOS_END;
78 } 78 }
79 return start;
79} 80}
80EXPORT_SYMBOL(pcibios_align_resource); 81EXPORT_SYMBOL(pcibios_align_resource);
81 82
@@ -129,7 +130,6 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
129 continue; 130 continue;
130 if (!r->start || 131 if (!r->start ||
131 pci_claim_resource(dev, idx) < 0) { 132 pci_claim_resource(dev, idx) < 0) {
132 dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
133 /* 133 /*
134 * Something is wrong with the region. 134 * Something is wrong with the region.
135 * Invalidate the resource to prevent 135 * Invalidate the resource to prevent
@@ -144,16 +144,29 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
144 } 144 }
145} 145}
146 146
147struct pci_check_idx_range {
148 int start;
149 int end;
150};
151
147static void __init pcibios_allocate_resources(int pass) 152static void __init pcibios_allocate_resources(int pass)
148{ 153{
149 struct pci_dev *dev = NULL; 154 struct pci_dev *dev = NULL;
150 int idx, disabled; 155 int idx, disabled, i;
151 u16 command; 156 u16 command;
152 struct resource *r; 157 struct resource *r;
153 158
159 struct pci_check_idx_range idx_range[] = {
160 { PCI_STD_RESOURCES, PCI_STD_RESOURCE_END },
161#ifdef CONFIG_PCI_IOV
162 { PCI_IOV_RESOURCES, PCI_IOV_RESOURCE_END },
163#endif
164 };
165
154 for_each_pci_dev(dev) { 166 for_each_pci_dev(dev) {
155 pci_read_config_word(dev, PCI_COMMAND, &command); 167 pci_read_config_word(dev, PCI_COMMAND, &command);
156 for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) { 168 for (i = 0; i < ARRAY_SIZE(idx_range); i++)
169 for (idx = idx_range[i].start; idx <= idx_range[i].end; idx++) {
157 r = &dev->resource[idx]; 170 r = &dev->resource[idx];
158 if (r->parent) /* Already allocated */ 171 if (r->parent) /* Already allocated */
159 continue; 172 continue;
@@ -164,12 +177,10 @@ static void __init pcibios_allocate_resources(int pass)
164 else 177 else
165 disabled = !(command & PCI_COMMAND_MEMORY); 178 disabled = !(command & PCI_COMMAND_MEMORY);
166 if (pass == disabled) { 179 if (pass == disabled) {
167 dev_dbg(&dev->dev, "resource %#08llx-%#08llx (f=%lx, d=%d, p=%d)\n", 180 dev_dbg(&dev->dev,
168 (unsigned long long) r->start, 181 "BAR %d: reserving %pr (d=%d, p=%d)\n",
169 (unsigned long long) r->end, 182 idx, r, disabled, pass);
170 r->flags, disabled, pass);
171 if (pci_claim_resource(dev, idx) < 0) { 183 if (pci_claim_resource(dev, idx) < 0) {
172 dev_info(&dev->dev, "BAR %d: can't allocate resource\n", idx);
173 /* We'll assign a new address later */ 184 /* We'll assign a new address later */
174 r->end -= r->start; 185 r->end -= r->start;
175 r->start = 0; 186 r->start = 0;
@@ -182,7 +193,7 @@ static void __init pcibios_allocate_resources(int pass)
182 /* Turn the ROM off, leave the resource region, 193 /* Turn the ROM off, leave the resource region,
183 * but keep it unregistered. */ 194 * but keep it unregistered. */
184 u32 reg; 195 u32 reg;
185 dev_dbg(&dev->dev, "disabling ROM\n"); 196 dev_dbg(&dev->dev, "disabling ROM %pR\n", r);
186 r->flags &= ~IORESOURCE_ROM_ENABLE; 197 r->flags &= ~IORESOURCE_ROM_ENABLE;
187 pci_read_config_dword(dev, 198 pci_read_config_dword(dev,
188 dev->rom_base_reg, &reg); 199 dev->rom_base_reg, &reg);
@@ -242,10 +253,6 @@ void __init pcibios_resource_survey(void)
242 */ 253 */
243fs_initcall(pcibios_assign_resources); 254fs_initcall(pcibios_assign_resources);
244 255
245void __weak x86_pci_root_bus_res_quirks(struct pci_bus *b)
246{
247}
248
249/* 256/*
250 * If we set up a device for bus mastering, we need to check the latency 257 * If we set up a device for bus mastering, we need to check the latency
251 * timer as certain crappy BIOSes forget to set it properly. 258 * timer as certain crappy BIOSes forget to set it properly.
@@ -282,6 +289,15 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
282 return -EINVAL; 289 return -EINVAL;
283 290
284 prot = pgprot_val(vma->vm_page_prot); 291 prot = pgprot_val(vma->vm_page_prot);
292
293 /*
294 * Return error if pat is not enabled and write_combine is requested.
295 * Caller can followup with UC MINUS request and add a WC mtrr if there
296 * is a free mtrr slot.
297 */
298 if (!pat_enabled && write_combine)
299 return -EINVAL;
300
285 if (pat_enabled && write_combine) 301 if (pat_enabled && write_combine)
286 prot |= _PAGE_CACHE_WC; 302 prot |= _PAGE_CACHE_WC;
287 else if (pat_enabled || boot_cpu_data.x86 > 3) 303 else if (pat_enabled || boot_cpu_data.x86 > 3)
diff --git a/arch/x86/pci/init.c b/arch/x86/pci/init.c
index 25a1f8efed4a..adb62aaa7ecd 100644
--- a/arch/x86/pci/init.c
+++ b/arch/x86/pci/init.c
@@ -1,6 +1,7 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <linux/init.h> 2#include <linux/init.h>
3#include <asm/pci_x86.h> 3#include <asm/pci_x86.h>
4#include <asm/x86_init.h>
4 5
5/* arch_initcall has too random ordering, so call the initializers 6/* arch_initcall has too random ordering, so call the initializers
6 in the right sequence from here. */ 7 in the right sequence from here. */
@@ -15,10 +16,9 @@ static __init int pci_arch_init(void)
15 if (!(pci_probe & PCI_PROBE_NOEARLY)) 16 if (!(pci_probe & PCI_PROBE_NOEARLY))
16 pci_mmcfg_early_init(); 17 pci_mmcfg_early_init();
17 18
18#ifdef CONFIG_PCI_OLPC 19 if (x86_init.pci.arch_init && !x86_init.pci.arch_init())
19 if (!pci_olpc_init()) 20 return 0;
20 return 0; /* skip additional checks if it's an XO */ 21
21#endif
22#ifdef CONFIG_PCI_BIOS 22#ifdef CONFIG_PCI_BIOS
23 pci_pcbios_init(); 23 pci_pcbios_init();
24#endif 24#endif
diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c
index 0696d506c4ad..5d362b5ba06f 100644
--- a/arch/x86/pci/irq.c
+++ b/arch/x86/pci/irq.c
@@ -8,7 +8,6 @@
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9#include <linux/pci.h> 9#include <linux/pci.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/slab.h>
12#include <linux/interrupt.h> 11#include <linux/interrupt.h>
13#include <linux/dmi.h> 12#include <linux/dmi.h>
14#include <linux/io.h> 13#include <linux/io.h>
@@ -53,7 +52,7 @@ struct irq_router_handler {
53 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device); 52 int (*probe)(struct irq_router *r, struct pci_dev *router, u16 device);
54}; 53};
55 54
56int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; 55int (*pcibios_enable_irq)(struct pci_dev *dev) = pirq_enable_irq;
57void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL; 56void (*pcibios_disable_irq)(struct pci_dev *dev) = NULL;
58 57
59/* 58/*
@@ -590,6 +589,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route
590 case PCI_DEVICE_ID_INTEL_ICH10_1: 589 case PCI_DEVICE_ID_INTEL_ICH10_1:
591 case PCI_DEVICE_ID_INTEL_ICH10_2: 590 case PCI_DEVICE_ID_INTEL_ICH10_2:
592 case PCI_DEVICE_ID_INTEL_ICH10_3: 591 case PCI_DEVICE_ID_INTEL_ICH10_3:
592 case PCI_DEVICE_ID_INTEL_CPT_LPC1:
593 case PCI_DEVICE_ID_INTEL_CPT_LPC2:
593 r->name = "PIIX/ICH"; 594 r->name = "PIIX/ICH";
594 r->get = pirq_piix_get; 595 r->get = pirq_piix_get;
595 r->set = pirq_piix_set; 596 r->set = pirq_piix_set;
@@ -1016,7 +1017,7 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
1016 return 1; 1017 return 1;
1017} 1018}
1018 1019
1019static void __init pcibios_fixup_irqs(void) 1020void __init pcibios_fixup_irqs(void)
1020{ 1021{
1021 struct pci_dev *dev = NULL; 1022 struct pci_dev *dev = NULL;
1022 u8 pin; 1023 u8 pin;
@@ -1110,12 +1111,12 @@ static struct dmi_system_id __initdata pciirq_dmi_table[] = {
1110 { } 1111 { }
1111}; 1112};
1112 1113
1113int __init pcibios_irq_init(void) 1114void __init pcibios_irq_init(void)
1114{ 1115{
1115 DBG(KERN_DEBUG "PCI: IRQ init\n"); 1116 DBG(KERN_DEBUG "PCI: IRQ init\n");
1116 1117
1117 if (pcibios_enable_irq || raw_pci_ops == NULL) 1118 if (raw_pci_ops == NULL)
1118 return 0; 1119 return;
1119 1120
1120 dmi_check_system(pciirq_dmi_table); 1121 dmi_check_system(pciirq_dmi_table);
1121 1122
@@ -1142,9 +1143,7 @@ int __init pcibios_irq_init(void)
1142 pirq_table = NULL; 1143 pirq_table = NULL;
1143 } 1144 }
1144 1145
1145 pcibios_enable_irq = pirq_enable_irq; 1146 x86_init.pci.fixup_irqs();
1146
1147 pcibios_fixup_irqs();
1148 1147
1149 if (io_apic_assign_pci_irqs && pci_routeirq) { 1148 if (io_apic_assign_pci_irqs && pci_routeirq) {
1150 struct pci_dev *dev = NULL; 1149 struct pci_dev *dev = NULL;
@@ -1157,8 +1156,6 @@ int __init pcibios_irq_init(void)
1157 for_each_pci_dev(dev) 1156 for_each_pci_dev(dev)
1158 pirq_enable_irq(dev); 1157 pirq_enable_irq(dev);
1159 } 1158 }
1160
1161 return 0;
1162} 1159}
1163 1160
1164static void pirq_penalize_isa_irq(int irq, int active) 1161static void pirq_penalize_isa_irq(int irq, int active)
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c
index 4061bb0f267d..0db5eaf54560 100644
--- a/arch/x86/pci/legacy.c
+++ b/arch/x86/pci/legacy.c
@@ -35,16 +35,13 @@ static void __devinit pcibios_fixup_peer_bridges(void)
35 } 35 }
36} 36}
37 37
38static int __init pci_legacy_init(void) 38int __init pci_legacy_init(void)
39{ 39{
40 if (!raw_pci_ops) { 40 if (!raw_pci_ops) {
41 printk("PCI: System does not support PCI\n"); 41 printk("PCI: System does not support PCI\n");
42 return 0; 42 return 0;
43 } 43 }
44 44
45 if (pcibios_scanned++)
46 return 0;
47
48 printk("PCI: Probing PCI hardware\n"); 45 printk("PCI: Probing PCI hardware\n");
49 pci_root_bus = pcibios_scan_root(0); 46 pci_root_bus = pcibios_scan_root(0);
50 if (pci_root_bus) 47 if (pci_root_bus)
@@ -55,18 +52,15 @@ static int __init pci_legacy_init(void)
55 52
56int __init pci_subsys_init(void) 53int __init pci_subsys_init(void)
57{ 54{
58#ifdef CONFIG_X86_NUMAQ 55 /*
59 pci_numaq_init(); 56 * The init function returns an non zero value when
60#endif 57 * pci_legacy_init should be invoked.
61#ifdef CONFIG_ACPI 58 */
62 pci_acpi_init(); 59 if (x86_init.pci.init())
63#endif 60 pci_legacy_init();
64#ifdef CONFIG_X86_VISWS 61
65 pci_visws_init();
66#endif
67 pci_legacy_init();
68 pcibios_fixup_peer_bridges(); 62 pcibios_fixup_peer_bridges();
69 pcibios_irq_init(); 63 x86_init.pci.init_irq();
70 pcibios_init(); 64 pcibios_init();
71 65
72 return 0; 66 return 0;
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 602c172d3bd5..39b9ebe8f886 100644
--- a/arch/x86/pci/mmconfig-shared.c
+++ b/arch/x86/pci/mmconfig-shared.c
@@ -15,48 +15,99 @@
15#include <linux/acpi.h> 15#include <linux/acpi.h>
16#include <linux/sfi_acpi.h> 16#include <linux/sfi_acpi.h>
17#include <linux/bitmap.h> 17#include <linux/bitmap.h>
18#include <linux/sort.h> 18#include <linux/dmi.h>
19#include <linux/slab.h>
19#include <asm/e820.h> 20#include <asm/e820.h>
20#include <asm/pci_x86.h> 21#include <asm/pci_x86.h>
21#include <asm/acpi.h> 22#include <asm/acpi.h>
22 23
23#define PREFIX "PCI: " 24#define PREFIX "PCI: "
24 25
25/* aperture is up to 256MB but BIOS may reserve less */
26#define MMCONFIG_APER_MIN (2 * 1024*1024)
27#define MMCONFIG_APER_MAX (256 * 1024*1024)
28
29/* Indicate if the mmcfg resources have been placed into the resource table. */ 26/* Indicate if the mmcfg resources have been placed into the resource table. */
30static int __initdata pci_mmcfg_resources_inserted; 27static int __initdata pci_mmcfg_resources_inserted;
31 28
32static __init int extend_mmcfg(int num) 29LIST_HEAD(pci_mmcfg_list);
30
31static __init void pci_mmconfig_remove(struct pci_mmcfg_region *cfg)
33{ 32{
34 struct acpi_mcfg_allocation *new; 33 if (cfg->res.parent)
35 int new_num = pci_mmcfg_config_num + num; 34 release_resource(&cfg->res);
35 list_del(&cfg->list);
36 kfree(cfg);
37}
36 38
37 new = kzalloc(sizeof(pci_mmcfg_config[0]) * new_num, GFP_KERNEL); 39static __init void free_all_mmcfg(void)
38 if (!new) 40{
39 return -1; 41 struct pci_mmcfg_region *cfg, *tmp;
42
43 pci_mmcfg_arch_free();
44 list_for_each_entry_safe(cfg, tmp, &pci_mmcfg_list, list)
45 pci_mmconfig_remove(cfg);
46}
40 47
41 if (pci_mmcfg_config) { 48static __init void list_add_sorted(struct pci_mmcfg_region *new)
42 memcpy(new, pci_mmcfg_config, 49{
43 sizeof(pci_mmcfg_config[0]) * new_num); 50 struct pci_mmcfg_region *cfg;
44 kfree(pci_mmcfg_config); 51
52 /* keep list sorted by segment and starting bus number */
53 list_for_each_entry(cfg, &pci_mmcfg_list, list) {
54 if (cfg->segment > new->segment ||
55 (cfg->segment == new->segment &&
56 cfg->start_bus >= new->start_bus)) {
57 list_add_tail(&new->list, &cfg->list);
58 return;
59 }
45 } 60 }
46 pci_mmcfg_config = new; 61 list_add_tail(&new->list, &pci_mmcfg_list);
62}
47 63
48 return 0; 64static __init struct pci_mmcfg_region *pci_mmconfig_add(int segment, int start,
65 int end, u64 addr)
66{
67 struct pci_mmcfg_region *new;
68 int num_buses;
69 struct resource *res;
70
71 if (addr == 0)
72 return NULL;
73
74 new = kzalloc(sizeof(*new), GFP_KERNEL);
75 if (!new)
76 return NULL;
77
78 new->address = addr;
79 new->segment = segment;
80 new->start_bus = start;
81 new->end_bus = end;
82
83 list_add_sorted(new);
84
85 num_buses = end - start + 1;
86 res = &new->res;
87 res->start = addr + PCI_MMCFG_BUS_OFFSET(start);
88 res->end = addr + PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
89 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
90 snprintf(new->name, PCI_MMCFG_RESOURCE_NAME_LEN,
91 "PCI MMCONFIG %04x [bus %02x-%02x]", segment, start, end);
92 res->name = new->name;
93
94 printk(KERN_INFO PREFIX "MMCONFIG for domain %04x [bus %02x-%02x] at "
95 "%pR (base %#lx)\n", segment, start, end, &new->res,
96 (unsigned long) addr);
97
98 return new;
49} 99}
50 100
51static __init void fill_one_mmcfg(u64 addr, int segment, int start, int end) 101struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus)
52{ 102{
53 int i = pci_mmcfg_config_num; 103 struct pci_mmcfg_region *cfg;
54 104
55 pci_mmcfg_config_num++; 105 list_for_each_entry(cfg, &pci_mmcfg_list, list)
56 pci_mmcfg_config[i].address = addr; 106 if (cfg->segment == segment &&
57 pci_mmcfg_config[i].pci_segment = segment; 107 cfg->start_bus <= bus && bus <= cfg->end_bus)
58 pci_mmcfg_config[i].start_bus_number = start; 108 return cfg;
59 pci_mmcfg_config[i].end_bus_number = end; 109
110 return NULL;
60} 111}
61 112
62static const char __init *pci_mmcfg_e7520(void) 113static const char __init *pci_mmcfg_e7520(void)
@@ -68,11 +119,9 @@ static const char __init *pci_mmcfg_e7520(void)
68 if (win == 0x0000 || win == 0xf000) 119 if (win == 0x0000 || win == 0xf000)
69 return NULL; 120 return NULL;
70 121
71 if (extend_mmcfg(1) == -1) 122 if (pci_mmconfig_add(0, 0, 255, win << 16) == NULL)
72 return NULL; 123 return NULL;
73 124
74 fill_one_mmcfg(win << 16, 0, 0, 255);
75
76 return "Intel Corporation E7520 Memory Controller Hub"; 125 return "Intel Corporation E7520 Memory Controller Hub";
77} 126}
78 127
@@ -114,11 +163,9 @@ static const char __init *pci_mmcfg_intel_945(void)
114 if ((pciexbar & mask) >= 0xf0000000U) 163 if ((pciexbar & mask) >= 0xf0000000U)
115 return NULL; 164 return NULL;
116 165
117 if (extend_mmcfg(1) == -1) 166 if (pci_mmconfig_add(0, 0, (len >> 20) - 1, pciexbar & mask) == NULL)
118 return NULL; 167 return NULL;
119 168
120 fill_one_mmcfg(pciexbar & mask, 0, 0, (len >> 20) - 1);
121
122 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub"; 169 return "Intel Corporation 945G/GZ/P/PL Express Memory Controller Hub";
123} 170}
124 171
@@ -127,7 +174,7 @@ static const char __init *pci_mmcfg_amd_fam10h(void)
127 u32 low, high, address; 174 u32 low, high, address;
128 u64 base, msr; 175 u64 base, msr;
129 int i; 176 int i;
130 unsigned segnbits = 0, busnbits; 177 unsigned segnbits = 0, busnbits, end_bus;
131 178
132 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF)) 179 if (!(pci_probe & PCI_CHECK_ENABLE_AMD_MMCONF))
133 return NULL; 180 return NULL;
@@ -161,11 +208,13 @@ static const char __init *pci_mmcfg_amd_fam10h(void)
161 busnbits = 8; 208 busnbits = 8;
162 } 209 }
163 210
164 if (extend_mmcfg(1 << segnbits) == -1) 211 end_bus = (1 << busnbits) - 1;
165 return NULL;
166
167 for (i = 0; i < (1 << segnbits); i++) 212 for (i = 0; i < (1 << segnbits); i++)
168 fill_one_mmcfg(base + (1<<28) * i, i, 0, (1 << busnbits) - 1); 213 if (pci_mmconfig_add(i, 0, end_bus,
214 base + (1<<28) * i) == NULL) {
215 free_all_mmcfg();
216 return NULL;
217 }
169 218
170 return "AMD Family 10h NB"; 219 return "AMD Family 10h NB";
171} 220}
@@ -190,7 +239,7 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
190 /* 239 /*
191 * do check if amd fam10h already took over 240 * do check if amd fam10h already took over
192 */ 241 */
193 if (!acpi_disabled || pci_mmcfg_config_num || mcp55_checked) 242 if (!acpi_disabled || !list_empty(&pci_mmcfg_list) || mcp55_checked)
194 return NULL; 243 return NULL;
195 244
196 mcp55_checked = true; 245 mcp55_checked = true;
@@ -213,16 +262,14 @@ static const char __init *pci_mmcfg_nvidia_mcp55(void)
213 if (!(extcfg & extcfg_enable_mask)) 262 if (!(extcfg & extcfg_enable_mask))
214 continue; 263 continue;
215 264
216 if (extend_mmcfg(1) == -1)
217 continue;
218
219 size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift; 265 size_index = (extcfg & extcfg_size_mask) >> extcfg_size_shift;
220 base = extcfg & extcfg_base_mask[size_index]; 266 base = extcfg & extcfg_base_mask[size_index];
221 /* base could > 4G */ 267 /* base could > 4G */
222 base <<= extcfg_base_lshift; 268 base <<= extcfg_base_lshift;
223 start = (extcfg & extcfg_start_mask) >> extcfg_start_shift; 269 start = (extcfg & extcfg_start_mask) >> extcfg_start_shift;
224 end = start + extcfg_sizebus[size_index] - 1; 270 end = start + extcfg_sizebus[size_index] - 1;
225 fill_one_mmcfg(base, 0, start, end); 271 if (pci_mmconfig_add(0, start, end, base) == NULL)
272 continue;
226 mcp55_mmconf_found++; 273 mcp55_mmconf_found++;
227 } 274 }
228 275
@@ -253,45 +300,22 @@ static struct pci_mmcfg_hostbridge_probe pci_mmcfg_probes[] __initdata = {
253 0x0369, pci_mmcfg_nvidia_mcp55 }, 300 0x0369, pci_mmcfg_nvidia_mcp55 },
254}; 301};
255 302
256static int __init cmp_mmcfg(const void *x1, const void *x2)
257{
258 const typeof(pci_mmcfg_config[0]) *m1 = x1;
259 const typeof(pci_mmcfg_config[0]) *m2 = x2;
260 int start1, start2;
261
262 start1 = m1->start_bus_number;
263 start2 = m2->start_bus_number;
264
265 return start1 - start2;
266}
267
268static void __init pci_mmcfg_check_end_bus_number(void) 303static void __init pci_mmcfg_check_end_bus_number(void)
269{ 304{
270 int i; 305 struct pci_mmcfg_region *cfg, *cfgx;
271 typeof(pci_mmcfg_config[0]) *cfg, *cfgx;
272
273 /* sort them at first */
274 sort(pci_mmcfg_config, pci_mmcfg_config_num,
275 sizeof(pci_mmcfg_config[0]), cmp_mmcfg, NULL);
276
277 /* last one*/
278 if (pci_mmcfg_config_num > 0) {
279 i = pci_mmcfg_config_num - 1;
280 cfg = &pci_mmcfg_config[i];
281 if (cfg->end_bus_number < cfg->start_bus_number)
282 cfg->end_bus_number = 255;
283 }
284 306
285 /* don't overlap please */ 307 /* Fixup overlaps */
286 for (i = 0; i < pci_mmcfg_config_num - 1; i++) { 308 list_for_each_entry(cfg, &pci_mmcfg_list, list) {
287 cfg = &pci_mmcfg_config[i]; 309 if (cfg->end_bus < cfg->start_bus)
288 cfgx = &pci_mmcfg_config[i+1]; 310 cfg->end_bus = 255;
289 311
290 if (cfg->end_bus_number < cfg->start_bus_number) 312 /* Don't access the list head ! */
291 cfg->end_bus_number = 255; 313 if (cfg->list.next == &pci_mmcfg_list)
314 break;
292 315
293 if (cfg->end_bus_number >= cfgx->start_bus_number) 316 cfgx = list_entry(cfg->list.next, typeof(*cfg), list);
294 cfg->end_bus_number = cfgx->start_bus_number - 1; 317 if (cfg->end_bus >= cfgx->start_bus)
318 cfg->end_bus = cfgx->start_bus - 1;
295 } 319 }
296} 320}
297 321
@@ -306,8 +330,7 @@ static int __init pci_mmcfg_check_hostbridge(void)
306 if (!raw_pci_ops) 330 if (!raw_pci_ops)
307 return 0; 331 return 0;
308 332
309 pci_mmcfg_config_num = 0; 333 free_all_mmcfg();
310 pci_mmcfg_config = NULL;
311 334
312 for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) { 335 for (i = 0; i < ARRAY_SIZE(pci_mmcfg_probes); i++) {
313 bus = pci_mmcfg_probes[i].bus; 336 bus = pci_mmcfg_probes[i].bus;
@@ -322,45 +345,22 @@ static int __init pci_mmcfg_check_hostbridge(void)
322 name = pci_mmcfg_probes[i].probe(); 345 name = pci_mmcfg_probes[i].probe();
323 346
324 if (name) 347 if (name)
325 printk(KERN_INFO "PCI: Found %s with MMCONFIG support.\n", 348 printk(KERN_INFO PREFIX "%s with MMCONFIG support\n",
326 name); 349 name);
327 } 350 }
328 351
329 /* some end_bus_number is crazy, fix it */ 352 /* some end_bus_number is crazy, fix it */
330 pci_mmcfg_check_end_bus_number(); 353 pci_mmcfg_check_end_bus_number();
331 354
332 return pci_mmcfg_config_num != 0; 355 return !list_empty(&pci_mmcfg_list);
333} 356}
334 357
335static void __init pci_mmcfg_insert_resources(void) 358static void __init pci_mmcfg_insert_resources(void)
336{ 359{
337#define PCI_MMCFG_RESOURCE_NAME_LEN 24 360 struct pci_mmcfg_region *cfg;
338 int i;
339 struct resource *res;
340 char *names;
341 unsigned num_buses;
342
343 res = kcalloc(PCI_MMCFG_RESOURCE_NAME_LEN + sizeof(*res),
344 pci_mmcfg_config_num, GFP_KERNEL);
345 if (!res) {
346 printk(KERN_ERR "PCI: Unable to allocate MMCONFIG resources\n");
347 return;
348 }
349 361
350 names = (void *)&res[pci_mmcfg_config_num]; 362 list_for_each_entry(cfg, &pci_mmcfg_list, list)
351 for (i = 0; i < pci_mmcfg_config_num; i++, res++) { 363 insert_resource(&iomem_resource, &cfg->res);
352 struct acpi_mcfg_allocation *cfg = &pci_mmcfg_config[i];
353 num_buses = cfg->end_bus_number - cfg->start_bus_number + 1;
354 res->name = names;
355 snprintf(names, PCI_MMCFG_RESOURCE_NAME_LEN,
356 "PCI MMCONFIG %u [%02x-%02x]", cfg->pci_segment,
357 cfg->start_bus_number, cfg->end_bus_number);
358 res->start = cfg->address + (cfg->start_bus_number << 20);
359 res->end = res->start + (num_buses << 20) - 1;
360 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
361 insert_resource(&iomem_resource, res);
362 names += PCI_MMCFG_RESOURCE_NAME_LEN;
363 }
364 364
365 /* Mark that the resources have been inserted. */ 365 /* Mark that the resources have been inserted. */
366 pci_mmcfg_resources_inserted = 1; 366 pci_mmcfg_resources_inserted = 1;
@@ -437,11 +437,12 @@ static int __init is_acpi_reserved(u64 start, u64 end, unsigned not_used)
437typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type); 437typedef int (*check_reserved_t)(u64 start, u64 end, unsigned type);
438 438
439static int __init is_mmconf_reserved(check_reserved_t is_reserved, 439static int __init is_mmconf_reserved(check_reserved_t is_reserved,
440 u64 addr, u64 size, int i, 440 struct pci_mmcfg_region *cfg, int with_e820)
441 typeof(pci_mmcfg_config[0]) *cfg, int with_e820)
442{ 441{
442 u64 addr = cfg->res.start;
443 u64 size = resource_size(&cfg->res);
443 u64 old_size = size; 444 u64 old_size = size;
444 int valid = 0; 445 int valid = 0, num_buses;
445 446
446 while (!is_reserved(addr, addr + size, E820_RESERVED)) { 447 while (!is_reserved(addr, addr + size, E820_RESERVED)) {
447 size >>= 1; 448 size >>= 1;
@@ -450,19 +451,25 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
450 } 451 }
451 452
452 if (size >= (16UL<<20) || size == old_size) { 453 if (size >= (16UL<<20) || size == old_size) {
453 printk(KERN_NOTICE 454 printk(KERN_INFO PREFIX "MMCONFIG at %pR reserved in %s\n",
454 "PCI: MCFG area at %Lx reserved in %s\n", 455 &cfg->res,
455 addr, with_e820?"E820":"ACPI motherboard resources"); 456 with_e820 ? "E820" : "ACPI motherboard resources");
456 valid = 1; 457 valid = 1;
457 458
458 if (old_size != size) { 459 if (old_size != size) {
459 /* update end_bus_number */ 460 /* update end_bus */
460 cfg->end_bus_number = cfg->start_bus_number + ((size>>20) - 1); 461 cfg->end_bus = cfg->start_bus + ((size>>20) - 1);
461 printk(KERN_NOTICE "PCI: updated MCFG configuration %d: base %lx " 462 num_buses = cfg->end_bus - cfg->start_bus + 1;
462 "segment %hu buses %u - %u\n", 463 cfg->res.end = cfg->res.start +
463 i, (unsigned long)cfg->address, cfg->pci_segment, 464 PCI_MMCFG_BUS_OFFSET(num_buses) - 1;
464 (unsigned int)cfg->start_bus_number, 465 snprintf(cfg->name, PCI_MMCFG_RESOURCE_NAME_LEN,
465 (unsigned int)cfg->end_bus_number); 466 "PCI MMCONFIG %04x [bus %02x-%02x]",
467 cfg->segment, cfg->start_bus, cfg->end_bus);
468 printk(KERN_INFO PREFIX
469 "MMCONFIG for %04x [bus%02x-%02x] "
470 "at %pR (base %#lx) (size reduced!)\n",
471 cfg->segment, cfg->start_bus, cfg->end_bus,
472 &cfg->res, (unsigned long) cfg->address);
466 } 473 }
467 } 474 }
468 475
@@ -471,45 +478,26 @@ static int __init is_mmconf_reserved(check_reserved_t is_reserved,
471 478
472static void __init pci_mmcfg_reject_broken(int early) 479static void __init pci_mmcfg_reject_broken(int early)
473{ 480{
474 typeof(pci_mmcfg_config[0]) *cfg; 481 struct pci_mmcfg_region *cfg;
475 int i;
476 482
477 if ((pci_mmcfg_config_num == 0) || 483 list_for_each_entry(cfg, &pci_mmcfg_list, list) {
478 (pci_mmcfg_config == NULL) ||
479 (pci_mmcfg_config[0].address == 0))
480 return;
481
482 for (i = 0; i < pci_mmcfg_config_num; i++) {
483 int valid = 0; 484 int valid = 0;
484 u64 addr, size;
485
486 cfg = &pci_mmcfg_config[i];
487 addr = cfg->start_bus_number;
488 addr <<= 20;
489 addr += cfg->address;
490 size = cfg->end_bus_number + 1 - cfg->start_bus_number;
491 size <<= 20;
492 printk(KERN_NOTICE "PCI: MCFG configuration %d: base %lx "
493 "segment %hu buses %u - %u\n",
494 i, (unsigned long)cfg->address, cfg->pci_segment,
495 (unsigned int)cfg->start_bus_number,
496 (unsigned int)cfg->end_bus_number);
497 485
498 if (!early && !acpi_disabled) 486 if (!early && !acpi_disabled)
499 valid = is_mmconf_reserved(is_acpi_reserved, addr, size, i, cfg, 0); 487 valid = is_mmconf_reserved(is_acpi_reserved, cfg, 0);
500 488
501 if (valid) 489 if (valid)
502 continue; 490 continue;
503 491
504 if (!early) 492 if (!early)
505 printk(KERN_ERR "PCI: BIOS Bug: MCFG area at %Lx is not" 493 printk(KERN_ERR FW_BUG PREFIX
506 " reserved in ACPI motherboard resources\n", 494 "MMCONFIG at %pR not reserved in "
507 cfg->address); 495 "ACPI motherboard resources\n", &cfg->res);
508 496
509 /* Don't try to do this check unless configuration 497 /* Don't try to do this check unless configuration
510 type 1 is available. how about type 2 ?*/ 498 type 1 is available. how about type 2 ?*/
511 if (raw_pci_ops) 499 if (raw_pci_ops)
512 valid = is_mmconf_reserved(e820_all_mapped, addr, size, i, cfg, 1); 500 valid = is_mmconf_reserved(e820_all_mapped, cfg, 1);
513 501
514 if (!valid) 502 if (!valid)
515 goto reject; 503 goto reject;
@@ -518,34 +506,41 @@ static void __init pci_mmcfg_reject_broken(int early)
518 return; 506 return;
519 507
520reject: 508reject:
521 printk(KERN_INFO "PCI: Not using MMCONFIG.\n"); 509 printk(KERN_INFO PREFIX "not using MMCONFIG\n");
522 pci_mmcfg_arch_free(); 510 free_all_mmcfg();
523 kfree(pci_mmcfg_config);
524 pci_mmcfg_config = NULL;
525 pci_mmcfg_config_num = 0;
526} 511}
527 512
528static int __initdata known_bridge; 513static int __initdata known_bridge;
529 514
530static int acpi_mcfg_64bit_base_addr __initdata = FALSE; 515static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
516 struct acpi_mcfg_allocation *cfg)
517{
518 int year;
531 519
532/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ 520 if (cfg->address < 0xFFFFFFFF)
533struct acpi_mcfg_allocation *pci_mmcfg_config; 521 return 0;
534int pci_mmcfg_config_num;
535 522
536static int __init acpi_mcfg_oem_check(struct acpi_table_mcfg *mcfg)
537{
538 if (!strcmp(mcfg->header.oem_id, "SGI")) 523 if (!strcmp(mcfg->header.oem_id, "SGI"))
539 acpi_mcfg_64bit_base_addr = TRUE; 524 return 0;
540 525
541 return 0; 526 if (mcfg->header.revision >= 1) {
527 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
528 year >= 2010)
529 return 0;
530 }
531
532 printk(KERN_ERR PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
533 "is above 4GB, ignored\n", cfg->pci_segment,
534 cfg->start_bus_number, cfg->end_bus_number, cfg->address);
535 return -EINVAL;
542} 536}
543 537
544static int __init pci_parse_mcfg(struct acpi_table_header *header) 538static int __init pci_parse_mcfg(struct acpi_table_header *header)
545{ 539{
546 struct acpi_table_mcfg *mcfg; 540 struct acpi_table_mcfg *mcfg;
541 struct acpi_mcfg_allocation *cfg_table, *cfg;
547 unsigned long i; 542 unsigned long i;
548 int config_size; 543 int entries;
549 544
550 if (!header) 545 if (!header)
551 return -EINVAL; 546 return -EINVAL;
@@ -553,38 +548,33 @@ static int __init pci_parse_mcfg(struct acpi_table_header *header)
553 mcfg = (struct acpi_table_mcfg *)header; 548 mcfg = (struct acpi_table_mcfg *)header;
554 549
555 /* how many config structures do we have */ 550 /* how many config structures do we have */
556 pci_mmcfg_config_num = 0; 551 free_all_mmcfg();
552 entries = 0;
557 i = header->length - sizeof(struct acpi_table_mcfg); 553 i = header->length - sizeof(struct acpi_table_mcfg);
558 while (i >= sizeof(struct acpi_mcfg_allocation)) { 554 while (i >= sizeof(struct acpi_mcfg_allocation)) {
559 ++pci_mmcfg_config_num; 555 entries++;
560 i -= sizeof(struct acpi_mcfg_allocation); 556 i -= sizeof(struct acpi_mcfg_allocation);
561 }; 557 };
562 if (pci_mmcfg_config_num == 0) { 558 if (entries == 0) {
563 printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); 559 printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
564 return -ENODEV; 560 return -ENODEV;
565 } 561 }
566 562
567 config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); 563 cfg_table = (struct acpi_mcfg_allocation *) &mcfg[1];
568 pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); 564 for (i = 0; i < entries; i++) {
569 if (!pci_mmcfg_config) { 565 cfg = &cfg_table[i];
570 printk(KERN_WARNING PREFIX 566 if (acpi_mcfg_check_entry(mcfg, cfg)) {
571 "No memory for MCFG config tables\n"); 567 free_all_mmcfg();
572 return -ENOMEM;
573 }
574
575 memcpy(pci_mmcfg_config, &mcfg[1], config_size);
576
577 acpi_mcfg_oem_check(mcfg);
578
579 for (i = 0; i < pci_mmcfg_config_num; ++i) {
580 if ((pci_mmcfg_config[i].address > 0xFFFFFFFF) &&
581 !acpi_mcfg_64bit_base_addr) {
582 printk(KERN_ERR PREFIX
583 "MMCONFIG not in low 4GB of memory\n");
584 kfree(pci_mmcfg_config);
585 pci_mmcfg_config_num = 0;
586 return -ENODEV; 568 return -ENODEV;
587 } 569 }
570
571 if (pci_mmconfig_add(cfg->pci_segment, cfg->start_bus_number,
572 cfg->end_bus_number, cfg->address) == NULL) {
573 printk(KERN_WARNING PREFIX
574 "no memory for MCFG entries\n");
575 free_all_mmcfg();
576 return -ENOMEM;
577 }
588 } 578 }
589 579
590 return 0; 580 return 0;
@@ -614,9 +604,7 @@ static void __init __pci_mmcfg_init(int early)
614 604
615 pci_mmcfg_reject_broken(early); 605 pci_mmcfg_reject_broken(early);
616 606
617 if ((pci_mmcfg_config_num == 0) || 607 if (list_empty(&pci_mmcfg_list))
618 (pci_mmcfg_config == NULL) ||
619 (pci_mmcfg_config[0].address == 0))
620 return; 608 return;
621 609
622 if (pci_mmcfg_arch_init()) 610 if (pci_mmcfg_arch_init())
@@ -648,9 +636,7 @@ static int __init pci_mmcfg_late_insert_resources(void)
648 */ 636 */
649 if ((pci_mmcfg_resources_inserted == 1) || 637 if ((pci_mmcfg_resources_inserted == 1) ||
650 (pci_probe & PCI_PROBE_MMCONF) == 0 || 638 (pci_probe & PCI_PROBE_MMCONF) == 0 ||
651 (pci_mmcfg_config_num == 0) || 639 list_empty(&pci_mmcfg_list))
652 (pci_mmcfg_config == NULL) ||
653 (pci_mmcfg_config[0].address == 0))
654 return 1; 640 return 1;
655 641
656 /* 642 /*
diff --git a/arch/x86/pci/mmconfig_32.c b/arch/x86/pci/mmconfig_32.c
index f10a7e94a84c..90d5fd476ed4 100644
--- a/arch/x86/pci/mmconfig_32.c
+++ b/arch/x86/pci/mmconfig_32.c
@@ -27,18 +27,10 @@ static int mmcfg_last_accessed_cpu;
27 */ 27 */
28static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn) 28static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
29{ 29{
30 struct acpi_mcfg_allocation *cfg; 30 struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
31 int cfg_num;
32
33 for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
34 cfg = &pci_mmcfg_config[cfg_num];
35 if (cfg->pci_segment == seg &&
36 (cfg->start_bus_number <= bus) &&
37 (cfg->end_bus_number >= bus))
38 return cfg->address;
39 }
40 31
41 /* Fall back to type 0 */ 32 if (cfg)
33 return cfg->address;
42 return 0; 34 return 0;
43} 35}
44 36
@@ -47,7 +39,7 @@ static u32 get_base_addr(unsigned int seg, int bus, unsigned devfn)
47 */ 39 */
48static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn) 40static void pci_exp_set_dev_base(unsigned int base, int bus, int devfn)
49{ 41{
50 u32 dev_base = base | (bus << 20) | (devfn << 12); 42 u32 dev_base = base | PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12);
51 int cpu = smp_processor_id(); 43 int cpu = smp_processor_id();
52 if (dev_base != mmcfg_last_accessed_device || 44 if (dev_base != mmcfg_last_accessed_device ||
53 cpu != mmcfg_last_accessed_cpu) { 45 cpu != mmcfg_last_accessed_cpu) {
diff --git a/arch/x86/pci/mmconfig_64.c b/arch/x86/pci/mmconfig_64.c
index 94349f8b2f96..e783841bd1d7 100644
--- a/arch/x86/pci/mmconfig_64.c
+++ b/arch/x86/pci/mmconfig_64.c
@@ -12,38 +12,15 @@
12#include <asm/e820.h> 12#include <asm/e820.h>
13#include <asm/pci_x86.h> 13#include <asm/pci_x86.h>
14 14
15/* Static virtual mapping of the MMCONFIG aperture */ 15#define PREFIX "PCI: "
16struct mmcfg_virt {
17 struct acpi_mcfg_allocation *cfg;
18 char __iomem *virt;
19};
20static struct mmcfg_virt *pci_mmcfg_virt;
21
22static char __iomem *get_virt(unsigned int seg, unsigned bus)
23{
24 struct acpi_mcfg_allocation *cfg;
25 int cfg_num;
26
27 for (cfg_num = 0; cfg_num < pci_mmcfg_config_num; cfg_num++) {
28 cfg = pci_mmcfg_virt[cfg_num].cfg;
29 if (cfg->pci_segment == seg &&
30 (cfg->start_bus_number <= bus) &&
31 (cfg->end_bus_number >= bus))
32 return pci_mmcfg_virt[cfg_num].virt;
33 }
34
35 /* Fall back to type 0 */
36 return NULL;
37}
38 16
39static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) 17static char __iomem *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn)
40{ 18{
41 char __iomem *addr; 19 struct pci_mmcfg_region *cfg = pci_mmconfig_lookup(seg, bus);
42 20
43 addr = get_virt(seg, bus); 21 if (cfg && cfg->virt)
44 if (!addr) 22 return cfg->virt + (PCI_MMCFG_BUS_OFFSET(bus) | (devfn << 12));
45 return NULL; 23 return NULL;
46 return addr + ((bus << 20) | (devfn << 12));
47} 24}
48 25
49static int pci_mmcfg_read(unsigned int seg, unsigned int bus, 26static int pci_mmcfg_read(unsigned int seg, unsigned int bus,
@@ -109,42 +86,30 @@ static struct pci_raw_ops pci_mmcfg = {
109 .write = pci_mmcfg_write, 86 .write = pci_mmcfg_write,
110}; 87};
111 88
112static void __iomem * __init mcfg_ioremap(struct acpi_mcfg_allocation *cfg) 89static void __iomem * __init mcfg_ioremap(struct pci_mmcfg_region *cfg)
113{ 90{
114 void __iomem *addr; 91 void __iomem *addr;
115 u64 start, size; 92 u64 start, size;
93 int num_buses;
116 94
117 start = cfg->start_bus_number; 95 start = cfg->address + PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
118 start <<= 20; 96 num_buses = cfg->end_bus - cfg->start_bus + 1;
119 start += cfg->address; 97 size = PCI_MMCFG_BUS_OFFSET(num_buses);
120 size = cfg->end_bus_number + 1 - cfg->start_bus_number;
121 size <<= 20;
122 addr = ioremap_nocache(start, size); 98 addr = ioremap_nocache(start, size);
123 if (addr) { 99 if (addr)
124 printk(KERN_INFO "PCI: Using MMCONFIG at %Lx - %Lx\n", 100 addr -= PCI_MMCFG_BUS_OFFSET(cfg->start_bus);
125 start, start + size - 1);
126 addr -= cfg->start_bus_number << 20;
127 }
128 return addr; 101 return addr;
129} 102}
130 103
131int __init pci_mmcfg_arch_init(void) 104int __init pci_mmcfg_arch_init(void)
132{ 105{
133 int i; 106 struct pci_mmcfg_region *cfg;
134 pci_mmcfg_virt = kzalloc(sizeof(*pci_mmcfg_virt) *
135 pci_mmcfg_config_num, GFP_KERNEL);
136 if (pci_mmcfg_virt == NULL) {
137 printk(KERN_ERR "PCI: Can not allocate memory for mmconfig structures\n");
138 return 0;
139 }
140 107
141 for (i = 0; i < pci_mmcfg_config_num; ++i) { 108 list_for_each_entry(cfg, &pci_mmcfg_list, list) {
142 pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; 109 cfg->virt = mcfg_ioremap(cfg);
143 pci_mmcfg_virt[i].virt = mcfg_ioremap(&pci_mmcfg_config[i]); 110 if (!cfg->virt) {
144 if (!pci_mmcfg_virt[i].virt) { 111 printk(KERN_ERR PREFIX "can't map MMCONFIG at %pR\n",
145 printk(KERN_ERR "PCI: Cannot map mmconfig aperture for " 112 &cfg->res);
146 "segment %d\n",
147 pci_mmcfg_config[i].pci_segment);
148 pci_mmcfg_arch_free(); 113 pci_mmcfg_arch_free();
149 return 0; 114 return 0;
150 } 115 }
@@ -155,19 +120,12 @@ int __init pci_mmcfg_arch_init(void)
155 120
156void __init pci_mmcfg_arch_free(void) 121void __init pci_mmcfg_arch_free(void)
157{ 122{
158 int i; 123 struct pci_mmcfg_region *cfg;
159
160 if (pci_mmcfg_virt == NULL)
161 return;
162 124
163 for (i = 0; i < pci_mmcfg_config_num; ++i) { 125 list_for_each_entry(cfg, &pci_mmcfg_list, list) {
164 if (pci_mmcfg_virt[i].virt) { 126 if (cfg->virt) {
165 iounmap(pci_mmcfg_virt[i].virt + (pci_mmcfg_virt[i].cfg->start_bus_number << 20)); 127 iounmap(cfg->virt + PCI_MMCFG_BUS_OFFSET(cfg->start_bus));
166 pci_mmcfg_virt[i].virt = NULL; 128 cfg->virt = NULL;
167 pci_mmcfg_virt[i].cfg = NULL;
168 } 129 }
169 } 130 }
170
171 kfree(pci_mmcfg_virt);
172 pci_mmcfg_virt = NULL;
173} 131}
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c
new file mode 100644
index 000000000000..1cdc02cf8fa4
--- /dev/null
+++ b/arch/x86/pci/mrst.c
@@ -0,0 +1,266 @@
1/*
2 * Moorestown PCI support
3 * Copyright (c) 2008 Intel Corporation
4 * Jesse Barnes <jesse.barnes@intel.com>
5 *
6 * Moorestown has an interesting PCI implementation:
7 * - configuration space is memory mapped (as defined by MCFG)
8 * - Lincroft devices also have a real, type 1 configuration space
9 * - Early Lincroft silicon has a type 1 access bug that will cause
10 * a hang if non-existent devices are accessed
11 * - some devices have the "fixed BAR" capability, which means
12 * they can't be relocated or modified; check for that during
13 * BAR sizing
14 *
15 * So, we use the MCFG space for all reads and writes, but also send
16 * Lincroft writes to type 1 space. But only read/write if the device
17 * actually exists, otherwise return all 1s for reads and bit bucket
18 * the writes.
19 */
20
21#include <linux/sched.h>
22#include <linux/pci.h>
23#include <linux/ioport.h>
24#include <linux/init.h>
25#include <linux/dmi.h>
26
27#include <asm/acpi.h>
28#include <asm/segment.h>
29#include <asm/io.h>
30#include <asm/smp.h>
31#include <asm/pci_x86.h>
32#include <asm/hw_irq.h>
33#include <asm/io_apic.h>
34
35#define PCIE_CAP_OFFSET 0x100
36
37/* Fixed BAR fields */
38#define PCIE_VNDR_CAP_ID_FIXED_BAR 0x00 /* Fixed BAR (TBD) */
39#define PCI_FIXED_BAR_0_SIZE 0x04
40#define PCI_FIXED_BAR_1_SIZE 0x08
41#define PCI_FIXED_BAR_2_SIZE 0x0c
42#define PCI_FIXED_BAR_3_SIZE 0x10
43#define PCI_FIXED_BAR_4_SIZE 0x14
44#define PCI_FIXED_BAR_5_SIZE 0x1c
45
46/**
47 * fixed_bar_cap - return the offset of the fixed BAR cap if found
48 * @bus: PCI bus
49 * @devfn: device in question
50 *
51 * Look for the fixed BAR cap on @bus and @devfn, returning its offset
52 * if found or 0 otherwise.
53 */
54static int fixed_bar_cap(struct pci_bus *bus, unsigned int devfn)
55{
56 int pos;
57 u32 pcie_cap = 0, cap_data;
58
59 pos = PCIE_CAP_OFFSET;
60
61 if (!raw_pci_ext_ops)
62 return 0;
63
64 while (pos) {
65 if (raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
66 devfn, pos, 4, &pcie_cap))
67 return 0;
68
69 if (pcie_cap == 0xffffffff)
70 return 0;
71
72 if (PCI_EXT_CAP_ID(pcie_cap) == PCI_EXT_CAP_ID_VNDR) {
73 raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
74 devfn, pos + 4, 4, &cap_data);
75 if ((cap_data & 0xffff) == PCIE_VNDR_CAP_ID_FIXED_BAR)
76 return pos;
77 }
78
79 pos = pcie_cap >> 20;
80 }
81
82 return 0;
83}
84
85static int pci_device_update_fixed(struct pci_bus *bus, unsigned int devfn,
86 int reg, int len, u32 val, int offset)
87{
88 u32 size;
89 unsigned int domain, busnum;
90 int bar = (reg - PCI_BASE_ADDRESS_0) >> 2;
91
92 domain = pci_domain_nr(bus);
93 busnum = bus->number;
94
95 if (val == ~0 && len == 4) {
96 unsigned long decode;
97
98 raw_pci_ext_ops->read(domain, busnum, devfn,
99 offset + 8 + (bar * 4), 4, &size);
100
101 /* Turn the size into a decode pattern for the sizing code */
102 if (size) {
103 decode = size - 1;
104 decode |= decode >> 1;
105 decode |= decode >> 2;
106 decode |= decode >> 4;
107 decode |= decode >> 8;
108 decode |= decode >> 16;
109 decode++;
110 decode = ~(decode - 1);
111 } else {
112 decode = ~0;
113 }
114
115 /*
116 * If val is all ones, the core code is trying to size the reg,
117 * so update the mmconfig space with the real size.
118 *
119 * Note: this assumes the fixed size we got is a power of two.
120 */
121 return raw_pci_ext_ops->write(domain, busnum, devfn, reg, 4,
122 decode);
123 }
124
125 /* This is some other kind of BAR write, so just do it. */
126 return raw_pci_ext_ops->write(domain, busnum, devfn, reg, len, val);
127}
128
129/**
130 * type1_access_ok - check whether to use type 1
131 * @bus: bus number
132 * @devfn: device & function in question
133 *
134 * If the bus is on a Lincroft chip and it exists, or is not on a Lincroft at
135 * all, the we can go ahead with any reads & writes. If it's on a Lincroft,
136 * but doesn't exist, avoid the access altogether to keep the chip from
137 * hanging.
138 */
139static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg)
140{
141 /* This is a workaround for A0 LNC bug where PCI status register does
142 * not have new CAP bit set. can not be written by SW either.
143 *
144 * PCI header type in real LNC indicates a single function device, this
145 * will prevent probing other devices under the same function in PCI
146 * shim. Therefore, use the header type in shim instead.
147 */
148 if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE)
149 return 0;
150 if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0)))
151 return 1;
152 return 0; /* langwell on others */
153}
154
155static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
156 int size, u32 *value)
157{
158 if (type1_access_ok(bus->number, devfn, where))
159 return pci_direct_conf1.read(pci_domain_nr(bus), bus->number,
160 devfn, where, size, value);
161 return raw_pci_ext_ops->read(pci_domain_nr(bus), bus->number,
162 devfn, where, size, value);
163}
164
165static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
166 int size, u32 value)
167{
168 int offset;
169
170 /* On MRST, there is no PCI ROM BAR, this will cause a subsequent read
171 * to ROM BAR return 0 then being ignored.
172 */
173 if (where == PCI_ROM_ADDRESS)
174 return 0;
175
176 /*
177 * Devices with fixed BARs need special handling:
178 * - BAR sizing code will save, write ~0, read size, restore
179 * - so writes to fixed BARs need special handling
180 * - other writes to fixed BAR devices should go through mmconfig
181 */
182 offset = fixed_bar_cap(bus, devfn);
183 if (offset &&
184 (where >= PCI_BASE_ADDRESS_0 && where <= PCI_BASE_ADDRESS_5)) {
185 return pci_device_update_fixed(bus, devfn, where, size, value,
186 offset);
187 }
188
189 /*
190 * On Moorestown update both real & mmconfig space
191 * Note: early Lincroft silicon can't handle type 1 accesses to
192 * non-existent devices, so just eat the write in that case.
193 */
194 if (type1_access_ok(bus->number, devfn, where))
195 return pci_direct_conf1.write(pci_domain_nr(bus), bus->number,
196 devfn, where, size, value);
197 return raw_pci_ext_ops->write(pci_domain_nr(bus), bus->number, devfn,
198 where, size, value);
199}
200
201static int mrst_pci_irq_enable(struct pci_dev *dev)
202{
203 u8 pin;
204 struct io_apic_irq_attr irq_attr;
205
206 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
207
208 /* MRST only have IOAPIC, the PCI irq lines are 1:1 mapped to
209 * IOAPIC RTE entries, so we just enable RTE for the device.
210 */
211 irq_attr.ioapic = mp_find_ioapic(dev->irq);
212 irq_attr.ioapic_pin = dev->irq;
213 irq_attr.trigger = 1; /* level */
214 irq_attr.polarity = 1; /* active low */
215 io_apic_set_pci_routing(&dev->dev, dev->irq, &irq_attr);
216
217 return 0;
218}
219
220struct pci_ops pci_mrst_ops = {
221 .read = pci_read,
222 .write = pci_write,
223};
224
225/**
226 * pci_mrst_init - installs pci_mrst_ops
227 *
228 * Moorestown has an interesting PCI implementation (see above).
229 * Called when the early platform detection installs it.
230 */
231int __init pci_mrst_init(void)
232{
233 printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n");
234 pci_mmcfg_late_init();
235 pcibios_enable_irq = mrst_pci_irq_enable;
236 pci_root_ops = pci_mrst_ops;
237 /* Continue with standard init */
238 return 1;
239}
240
241/*
242 * Langwell devices reside at fixed offsets, don't try to move them.
243 */
244static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev)
245{
246 unsigned long offset;
247 u32 size;
248 int i;
249
250 /* Must have extended configuration space */
251 if (dev->cfg_size < PCIE_CAP_OFFSET + 4)
252 return;
253
254 /* Fixup the BAR sizes for fixed BAR devices and make them unmoveable */
255 offset = fixed_bar_cap(dev->bus, dev->devfn);
256 if (!offset || PCI_DEVFN(2, 0) == dev->devfn ||
257 PCI_DEVFN(2, 2) == dev->devfn)
258 return;
259
260 for (i = 0; i < PCI_ROM_RESOURCE; i++) {
261 pci_read_config_dword(dev, offset + 8 + (i * 4), &size);
262 dev->resource[i].end = dev->resource[i].start + size - 1;
263 dev->resource[i].flags |= IORESOURCE_PCI_FIXED;
264 }
265}
266DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixed_bar_fixup);
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c
index 8eb295e116f6..8223738ad806 100644
--- a/arch/x86/pci/numaq_32.c
+++ b/arch/x86/pci/numaq_32.c
@@ -8,9 +8,7 @@
8#include <asm/apic.h> 8#include <asm/apic.h>
9#include <asm/mpspec.h> 9#include <asm/mpspec.h>
10#include <asm/pci_x86.h> 10#include <asm/pci_x86.h>
11 11#include <asm/numaq.h>
12#define XQUAD_PORTIO_BASE 0xfe400000
13#define XQUAD_PORTIO_QUAD 0x40000 /* 256k per quad. */
14 12
15#define BUS2QUAD(global) (mp_bus_id_to_node[global]) 13#define BUS2QUAD(global) (mp_bus_id_to_node[global])
16 14
@@ -18,8 +16,6 @@
18 16
19#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local]) 17#define QUADLOCAL2BUS(quad,local) (quad_local_to_mp_bus_id[quad][local])
20 18
21#define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
22
23#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \ 19#define PCI_CONF1_MQ_ADDRESS(bus, devfn, reg) \
24 (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3)) 20 (0x80000000 | (BUS2LOCAL(bus) << 16) | (devfn << 8) | (reg & ~3))
25 21
@@ -152,14 +148,8 @@ int __init pci_numaq_init(void)
152{ 148{
153 int quad; 149 int quad;
154 150
155 if (!found_numaq)
156 return 0;
157
158 raw_pci_ops = &pci_direct_conf1_mq; 151 raw_pci_ops = &pci_direct_conf1_mq;
159 152
160 if (pcibios_scanned++)
161 return 0;
162
163 pci_root_bus = pcibios_scan_root(0); 153 pci_root_bus = pcibios_scan_root(0);
164 if (pci_root_bus) 154 if (pci_root_bus)
165 pci_bus_add_devices(pci_root_bus); 155 pci_bus_add_devices(pci_root_bus);
diff --git a/arch/x86/pci/olpc.c b/arch/x86/pci/olpc.c
index b889d824f7c6..b34815408f58 100644
--- a/arch/x86/pci/olpc.c
+++ b/arch/x86/pci/olpc.c
@@ -304,9 +304,6 @@ static struct pci_raw_ops pci_olpc_conf = {
304 304
305int __init pci_olpc_init(void) 305int __init pci_olpc_init(void)
306{ 306{
307 if (!machine_is_olpc() || olpc_has_vsa())
308 return -ENODEV;
309
310 printk(KERN_INFO "PCI: Using configuration type OLPC\n"); 307 printk(KERN_INFO "PCI: Using configuration type OLPC\n");
311 raw_pci_ops = &pci_olpc_conf; 308 raw_pci_ops = &pci_olpc_conf;
312 is_lx = is_geode_lx(); 309 is_lx = is_geode_lx();
diff --git a/arch/x86/pci/pcbios.c b/arch/x86/pci/pcbios.c
index 1c975cc9839e..59a225c17b84 100644
--- a/arch/x86/pci/pcbios.c
+++ b/arch/x86/pci/pcbios.c
@@ -4,6 +4,7 @@
4 4
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/init.h> 6#include <linux/init.h>
7#include <linux/slab.h>
7#include <linux/module.h> 8#include <linux/module.h>
8#include <linux/uaccess.h> 9#include <linux/uaccess.h>
9#include <asm/pci_x86.h> 10#include <asm/pci_x86.h>
diff --git a/arch/x86/pci/visws.c b/arch/x86/pci/visws.c
index bcead7a46871..03008f72eb04 100644
--- a/arch/x86/pci/visws.c
+++ b/arch/x86/pci/visws.c
@@ -69,9 +69,6 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
69 69
70int __init pci_visws_init(void) 70int __init pci_visws_init(void)
71{ 71{
72 if (!is_visws_box())
73 return -1;
74
75 pcibios_enable_irq = &pci_visws_enable_irq; 72 pcibios_enable_irq = &pci_visws_enable_irq;
76 pcibios_disable_irq = &pci_visws_disable_irq; 73 pcibios_disable_irq = &pci_visws_disable_irq;
77 74
@@ -90,5 +87,6 @@ int __init pci_visws_init(void)
90 pci_scan_bus_with_sysdata(pci_bus1); 87 pci_scan_bus_with_sysdata(pci_bus1);
91 pci_fixup_irqs(pci_common_swizzle, visws_map_irq); 88 pci_fixup_irqs(pci_common_swizzle, visws_map_irq);
92 pcibios_resource_survey(); 89 pcibios_resource_survey();
93 return 0; 90 /* Request bus scan */
91 return 1;
94} 92}