diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/pci/setup-bus.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/pci/setup-bus.c')
-rw-r--r-- | drivers/pci/setup-bus.c | 552 |
1 files changed, 552 insertions, 0 deletions
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c new file mode 100644 index 000000000000..1ba84be0b4c0 --- /dev/null +++ b/drivers/pci/setup-bus.c | |||
@@ -0,0 +1,552 @@ | |||
1 | /* | ||
2 | * drivers/pci/setup-bus.c | ||
3 | * | ||
4 | * Extruded from code written by | ||
5 | * Dave Rusling (david.rusling@reo.mts.dec.com) | ||
6 | * David Mosberger (davidm@cs.arizona.edu) | ||
7 | * David Miller (davem@redhat.com) | ||
8 | * | ||
9 | * Support routines for initializing a PCI subsystem. | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru> | ||
14 | * PCI-PCI bridges cleanup, sorted resource allocation. | ||
15 | * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru> | ||
16 | * Converted to allocation in 3 passes, which gives | ||
17 | * tighter packing. Prefetchable range support. | ||
18 | */ | ||
19 | |||
20 | #include <linux/init.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/errno.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/cache.h> | ||
27 | #include <linux/slab.h> | ||
28 | |||
29 | |||
30 | #define DEBUG_CONFIG 1 | ||
31 | #if DEBUG_CONFIG | ||
32 | #define DBG(x...) printk(x) | ||
33 | #else | ||
34 | #define DBG(x...) | ||
35 | #endif | ||
36 | |||
37 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) | ||
38 | |||
39 | /* | ||
40 | * FIXME: IO should be max 256 bytes. However, since we may | ||
41 | * have a P2P bridge below a cardbus bridge, we need 4K. | ||
42 | */ | ||
43 | #define CARDBUS_IO_SIZE (4096) | ||
44 | #define CARDBUS_MEM_SIZE (32*1024*1024) | ||
45 | |||
46 | static void __devinit | ||
47 | pbus_assign_resources_sorted(struct pci_bus *bus) | ||
48 | { | ||
49 | struct pci_dev *dev; | ||
50 | struct resource *res; | ||
51 | struct resource_list head, *list, *tmp; | ||
52 | int idx; | ||
53 | |||
54 | bus->bridge_ctl &= ~PCI_BRIDGE_CTL_VGA; | ||
55 | |||
56 | head.next = NULL; | ||
57 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
58 | u16 class = dev->class >> 8; | ||
59 | |||
60 | /* Don't touch classless devices and host bridges. */ | ||
61 | if (class == PCI_CLASS_NOT_DEFINED || | ||
62 | class == PCI_CLASS_BRIDGE_HOST) | ||
63 | continue; | ||
64 | |||
65 | if (class == PCI_CLASS_DISPLAY_VGA || | ||
66 | class == PCI_CLASS_NOT_DEFINED_VGA) | ||
67 | bus->bridge_ctl |= PCI_BRIDGE_CTL_VGA; | ||
68 | |||
69 | pdev_sort_resources(dev, &head); | ||
70 | } | ||
71 | |||
72 | for (list = head.next; list;) { | ||
73 | res = list->res; | ||
74 | idx = res - &list->dev->resource[0]; | ||
75 | pci_assign_resource(list->dev, idx); | ||
76 | tmp = list; | ||
77 | list = list->next; | ||
78 | kfree(tmp); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static void __devinit | ||
83 | pci_setup_cardbus(struct pci_bus *bus) | ||
84 | { | ||
85 | struct pci_dev *bridge = bus->self; | ||
86 | struct pci_bus_region region; | ||
87 | |||
88 | printk("PCI: Bus %d, cardbus bridge: %s\n", | ||
89 | bus->number, pci_name(bridge)); | ||
90 | |||
91 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | ||
92 | if (bus->resource[0]->flags & IORESOURCE_IO) { | ||
93 | /* | ||
94 | * The IO resource is allocated a range twice as large as it | ||
95 | * would normally need. This allows us to set both IO regs. | ||
96 | */ | ||
97 | printk(" IO window: %08lx-%08lx\n", | ||
98 | region.start, region.end); | ||
99 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_0, | ||
100 | region.start); | ||
101 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_0, | ||
102 | region.end); | ||
103 | } | ||
104 | |||
105 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | ||
106 | if (bus->resource[1]->flags & IORESOURCE_IO) { | ||
107 | printk(" IO window: %08lx-%08lx\n", | ||
108 | region.start, region.end); | ||
109 | pci_write_config_dword(bridge, PCI_CB_IO_BASE_1, | ||
110 | region.start); | ||
111 | pci_write_config_dword(bridge, PCI_CB_IO_LIMIT_1, | ||
112 | region.end); | ||
113 | } | ||
114 | |||
115 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | ||
116 | if (bus->resource[2]->flags & IORESOURCE_MEM) { | ||
117 | printk(" PREFETCH window: %08lx-%08lx\n", | ||
118 | region.start, region.end); | ||
119 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_0, | ||
120 | region.start); | ||
121 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_0, | ||
122 | region.end); | ||
123 | } | ||
124 | |||
125 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[3]); | ||
126 | if (bus->resource[3]->flags & IORESOURCE_MEM) { | ||
127 | printk(" MEM window: %08lx-%08lx\n", | ||
128 | region.start, region.end); | ||
129 | pci_write_config_dword(bridge, PCI_CB_MEMORY_BASE_1, | ||
130 | region.start); | ||
131 | pci_write_config_dword(bridge, PCI_CB_MEMORY_LIMIT_1, | ||
132 | region.end); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | /* Initialize bridges with base/limit values we have collected. | ||
137 | PCI-to-PCI Bridge Architecture Specification rev. 1.1 (1998) | ||
138 | requires that if there is no I/O ports or memory behind the | ||
139 | bridge, corresponding range must be turned off by writing base | ||
140 | value greater than limit to the bridge's base/limit registers. | ||
141 | |||
142 | Note: care must be taken when updating I/O base/limit registers | ||
143 | of bridges which support 32-bit I/O. This update requires two | ||
144 | config space writes, so it's quite possible that an I/O window of | ||
145 | the bridge will have some undesirable address (e.g. 0) after the | ||
146 | first write. Ditto 64-bit prefetchable MMIO. */ | ||
147 | static void __devinit | ||
148 | pci_setup_bridge(struct pci_bus *bus) | ||
149 | { | ||
150 | struct pci_dev *bridge = bus->self; | ||
151 | struct pci_bus_region region; | ||
152 | u32 l, io_upper16; | ||
153 | |||
154 | DBG(KERN_INFO "PCI: Bridge: %s\n", pci_name(bridge)); | ||
155 | |||
156 | /* Set up the top and bottom of the PCI I/O segment for this bus. */ | ||
157 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[0]); | ||
158 | if (bus->resource[0]->flags & IORESOURCE_IO) { | ||
159 | pci_read_config_dword(bridge, PCI_IO_BASE, &l); | ||
160 | l &= 0xffff0000; | ||
161 | l |= (region.start >> 8) & 0x00f0; | ||
162 | l |= region.end & 0xf000; | ||
163 | /* Set up upper 16 bits of I/O base/limit. */ | ||
164 | io_upper16 = (region.end & 0xffff0000) | (region.start >> 16); | ||
165 | DBG(KERN_INFO " IO window: %04lx-%04lx\n", | ||
166 | region.start, region.end); | ||
167 | } | ||
168 | else { | ||
169 | /* Clear upper 16 bits of I/O base/limit. */ | ||
170 | io_upper16 = 0; | ||
171 | l = 0x00f0; | ||
172 | DBG(KERN_INFO " IO window: disabled.\n"); | ||
173 | } | ||
174 | /* Temporarily disable the I/O range before updating PCI_IO_BASE. */ | ||
175 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, 0x0000ffff); | ||
176 | /* Update lower 16 bits of I/O base/limit. */ | ||
177 | pci_write_config_dword(bridge, PCI_IO_BASE, l); | ||
178 | /* Update upper 16 bits of I/O base/limit. */ | ||
179 | pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, io_upper16); | ||
180 | |||
181 | /* Set up the top and bottom of the PCI Memory segment | ||
182 | for this bus. */ | ||
183 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[1]); | ||
184 | if (bus->resource[1]->flags & IORESOURCE_MEM) { | ||
185 | l = (region.start >> 16) & 0xfff0; | ||
186 | l |= region.end & 0xfff00000; | ||
187 | DBG(KERN_INFO " MEM window: %08lx-%08lx\n", | ||
188 | region.start, region.end); | ||
189 | } | ||
190 | else { | ||
191 | l = 0x0000fff0; | ||
192 | DBG(KERN_INFO " MEM window: disabled.\n"); | ||
193 | } | ||
194 | pci_write_config_dword(bridge, PCI_MEMORY_BASE, l); | ||
195 | |||
196 | /* Clear out the upper 32 bits of PREF limit. | ||
197 | If PCI_PREF_BASE_UPPER32 was non-zero, this temporarily | ||
198 | disables PREF range, which is ok. */ | ||
199 | pci_write_config_dword(bridge, PCI_PREF_LIMIT_UPPER32, 0); | ||
200 | |||
201 | /* Set up PREF base/limit. */ | ||
202 | pcibios_resource_to_bus(bridge, ®ion, bus->resource[2]); | ||
203 | if (bus->resource[2]->flags & IORESOURCE_PREFETCH) { | ||
204 | l = (region.start >> 16) & 0xfff0; | ||
205 | l |= region.end & 0xfff00000; | ||
206 | DBG(KERN_INFO " PREFETCH window: %08lx-%08lx\n", | ||
207 | region.start, region.end); | ||
208 | } | ||
209 | else { | ||
210 | l = 0x0000fff0; | ||
211 | DBG(KERN_INFO " PREFETCH window: disabled.\n"); | ||
212 | } | ||
213 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l); | ||
214 | |||
215 | /* Clear out the upper 32 bits of PREF base. */ | ||
216 | pci_write_config_dword(bridge, PCI_PREF_BASE_UPPER32, 0); | ||
217 | |||
218 | pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, bus->bridge_ctl); | ||
219 | } | ||
220 | |||
221 | /* Check whether the bridge supports optional I/O and | ||
222 | prefetchable memory ranges. If not, the respective | ||
223 | base/limit registers must be read-only and read as 0. */ | ||
224 | static void __devinit | ||
225 | pci_bridge_check_ranges(struct pci_bus *bus) | ||
226 | { | ||
227 | u16 io; | ||
228 | u32 pmem; | ||
229 | struct pci_dev *bridge = bus->self; | ||
230 | struct resource *b_res; | ||
231 | |||
232 | b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | ||
233 | b_res[1].flags |= IORESOURCE_MEM; | ||
234 | |||
235 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | ||
236 | if (!io) { | ||
237 | pci_write_config_word(bridge, PCI_IO_BASE, 0xf0f0); | ||
238 | pci_read_config_word(bridge, PCI_IO_BASE, &io); | ||
239 | pci_write_config_word(bridge, PCI_IO_BASE, 0x0); | ||
240 | } | ||
241 | if (io) | ||
242 | b_res[0].flags |= IORESOURCE_IO; | ||
243 | /* DECchip 21050 pass 2 errata: the bridge may miss an address | ||
244 | disconnect boundary by one PCI data phase. | ||
245 | Workaround: do not use prefetching on this device. */ | ||
246 | if (bridge->vendor == PCI_VENDOR_ID_DEC && bridge->device == 0x0001) | ||
247 | return; | ||
248 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
249 | if (!pmem) { | ||
250 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, | ||
251 | 0xfff0fff0); | ||
252 | pci_read_config_dword(bridge, PCI_PREF_MEMORY_BASE, &pmem); | ||
253 | pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, 0x0); | ||
254 | } | ||
255 | if (pmem) | ||
256 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; | ||
257 | } | ||
258 | |||
259 | /* Helper function for sizing routines: find first available | ||
260 | bus resource of a given type. Note: we intentionally skip | ||
261 | the bus resources which have already been assigned (that is, | ||
262 | have non-NULL parent resource). */ | ||
263 | static struct resource * __devinit | ||
264 | find_free_bus_resource(struct pci_bus *bus, unsigned long type) | ||
265 | { | ||
266 | int i; | ||
267 | struct resource *r; | ||
268 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | ||
269 | IORESOURCE_PREFETCH; | ||
270 | |||
271 | for (i = 0; i < PCI_BUS_NUM_RESOURCES; i++) { | ||
272 | r = bus->resource[i]; | ||
273 | if (r && (r->flags & type_mask) == type && !r->parent) | ||
274 | return r; | ||
275 | } | ||
276 | return NULL; | ||
277 | } | ||
278 | |||
279 | /* Sizing the IO windows of the PCI-PCI bridge is trivial, | ||
280 | since these windows have 4K granularity and the IO ranges | ||
281 | of non-bridge PCI devices are limited to 256 bytes. | ||
282 | We must be careful with the ISA aliasing though. */ | ||
283 | static void __devinit | ||
284 | pbus_size_io(struct pci_bus *bus) | ||
285 | { | ||
286 | struct pci_dev *dev; | ||
287 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | ||
288 | unsigned long size = 0, size1 = 0; | ||
289 | |||
290 | if (!b_res) | ||
291 | return; | ||
292 | |||
293 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
297 | struct resource *r = &dev->resource[i]; | ||
298 | unsigned long r_size; | ||
299 | |||
300 | if (r->parent || !(r->flags & IORESOURCE_IO)) | ||
301 | continue; | ||
302 | r_size = r->end - r->start + 1; | ||
303 | |||
304 | if (r_size < 0x400) | ||
305 | /* Might be re-aligned for ISA */ | ||
306 | size += r_size; | ||
307 | else | ||
308 | size1 += r_size; | ||
309 | } | ||
310 | } | ||
311 | /* To be fixed in 2.5: we should have sort of HAVE_ISA | ||
312 | flag in the struct pci_bus. */ | ||
313 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | ||
314 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | ||
315 | #endif | ||
316 | size = ROUND_UP(size + size1, 4096); | ||
317 | if (!size) { | ||
318 | b_res->flags = 0; | ||
319 | return; | ||
320 | } | ||
321 | /* Alignment of the IO window is always 4K */ | ||
322 | b_res->start = 4096; | ||
323 | b_res->end = b_res->start + size - 1; | ||
324 | } | ||
325 | |||
326 | /* Calculate the size of the bus and minimal alignment which | ||
327 | guarantees that all child resources fit in this size. */ | ||
328 | static int __devinit | ||
329 | pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) | ||
330 | { | ||
331 | struct pci_dev *dev; | ||
332 | unsigned long min_align, align, size; | ||
333 | unsigned long aligns[12]; /* Alignments from 1Mb to 2Gb */ | ||
334 | int order, max_order; | ||
335 | struct resource *b_res = find_free_bus_resource(bus, type); | ||
336 | |||
337 | if (!b_res) | ||
338 | return 0; | ||
339 | |||
340 | memset(aligns, 0, sizeof(aligns)); | ||
341 | max_order = 0; | ||
342 | size = 0; | ||
343 | |||
344 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
345 | int i; | ||
346 | |||
347 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
348 | struct resource *r = &dev->resource[i]; | ||
349 | unsigned long r_size; | ||
350 | |||
351 | if (r->parent || (r->flags & mask) != type) | ||
352 | continue; | ||
353 | r_size = r->end - r->start + 1; | ||
354 | /* For bridges size != alignment */ | ||
355 | align = (i < PCI_BRIDGE_RESOURCES) ? r_size : r->start; | ||
356 | order = __ffs(align) - 20; | ||
357 | if (order > 11) { | ||
358 | printk(KERN_WARNING "PCI: region %s/%d " | ||
359 | "too large: %lx-%lx\n", | ||
360 | pci_name(dev), i, r->start, r->end); | ||
361 | r->flags = 0; | ||
362 | continue; | ||
363 | } | ||
364 | size += r_size; | ||
365 | if (order < 0) | ||
366 | order = 0; | ||
367 | /* Exclude ranges with size > align from | ||
368 | calculation of the alignment. */ | ||
369 | if (r_size == align) | ||
370 | aligns[order] += align; | ||
371 | if (order > max_order) | ||
372 | max_order = order; | ||
373 | } | ||
374 | } | ||
375 | |||
376 | align = 0; | ||
377 | min_align = 0; | ||
378 | for (order = 0; order <= max_order; order++) { | ||
379 | unsigned long align1 = 1UL << (order + 20); | ||
380 | |||
381 | if (!align) | ||
382 | min_align = align1; | ||
383 | else if (ROUND_UP(align + min_align, min_align) < align1) | ||
384 | min_align = align1 >> 1; | ||
385 | align += aligns[order]; | ||
386 | } | ||
387 | size = ROUND_UP(size, min_align); | ||
388 | if (!size) { | ||
389 | b_res->flags = 0; | ||
390 | return 1; | ||
391 | } | ||
392 | b_res->start = min_align; | ||
393 | b_res->end = size + min_align - 1; | ||
394 | return 1; | ||
395 | } | ||
396 | |||
397 | static void __devinit | ||
398 | pci_bus_size_cardbus(struct pci_bus *bus) | ||
399 | { | ||
400 | struct pci_dev *bridge = bus->self; | ||
401 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | ||
402 | u16 ctrl; | ||
403 | |||
404 | /* | ||
405 | * Reserve some resources for CardBus. We reserve | ||
406 | * a fixed amount of bus space for CardBus bridges. | ||
407 | */ | ||
408 | b_res[0].start = CARDBUS_IO_SIZE; | ||
409 | b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1; | ||
410 | b_res[0].flags |= IORESOURCE_IO; | ||
411 | |||
412 | b_res[1].start = CARDBUS_IO_SIZE; | ||
413 | b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1; | ||
414 | b_res[1].flags |= IORESOURCE_IO; | ||
415 | |||
416 | /* | ||
417 | * Check whether prefetchable memory is supported | ||
418 | * by this bridge. | ||
419 | */ | ||
420 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
421 | if (!(ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0)) { | ||
422 | ctrl |= PCI_CB_BRIDGE_CTL_PREFETCH_MEM0; | ||
423 | pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); | ||
424 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
425 | } | ||
426 | |||
427 | /* | ||
428 | * If we have prefetchable memory support, allocate | ||
429 | * two regions. Otherwise, allocate one region of | ||
430 | * twice the size. | ||
431 | */ | ||
432 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | ||
433 | b_res[2].start = CARDBUS_MEM_SIZE; | ||
434 | b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1; | ||
435 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; | ||
436 | |||
437 | b_res[3].start = CARDBUS_MEM_SIZE; | ||
438 | b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1; | ||
439 | b_res[3].flags |= IORESOURCE_MEM; | ||
440 | } else { | ||
441 | b_res[3].start = CARDBUS_MEM_SIZE * 2; | ||
442 | b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1; | ||
443 | b_res[3].flags |= IORESOURCE_MEM; | ||
444 | } | ||
445 | } | ||
446 | |||
447 | void __devinit | ||
448 | pci_bus_size_bridges(struct pci_bus *bus) | ||
449 | { | ||
450 | struct pci_dev *dev; | ||
451 | unsigned long mask, prefmask; | ||
452 | |||
453 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
454 | struct pci_bus *b = dev->subordinate; | ||
455 | if (!b) | ||
456 | continue; | ||
457 | |||
458 | switch (dev->class >> 8) { | ||
459 | case PCI_CLASS_BRIDGE_CARDBUS: | ||
460 | pci_bus_size_cardbus(b); | ||
461 | break; | ||
462 | |||
463 | case PCI_CLASS_BRIDGE_PCI: | ||
464 | default: | ||
465 | pci_bus_size_bridges(b); | ||
466 | break; | ||
467 | } | ||
468 | } | ||
469 | |||
470 | /* The root bus? */ | ||
471 | if (!bus->self) | ||
472 | return; | ||
473 | |||
474 | switch (bus->self->class >> 8) { | ||
475 | case PCI_CLASS_BRIDGE_CARDBUS: | ||
476 | /* don't size cardbuses yet. */ | ||
477 | break; | ||
478 | |||
479 | case PCI_CLASS_BRIDGE_PCI: | ||
480 | pci_bridge_check_ranges(bus); | ||
481 | default: | ||
482 | pbus_size_io(bus); | ||
483 | /* If the bridge supports prefetchable range, size it | ||
484 | separately. If it doesn't, or its prefetchable window | ||
485 | has already been allocated by arch code, try | ||
486 | non-prefetchable range for both types of PCI memory | ||
487 | resources. */ | ||
488 | mask = IORESOURCE_MEM; | ||
489 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; | ||
490 | if (pbus_size_mem(bus, prefmask, prefmask)) | ||
491 | mask = prefmask; /* Success, size non-prefetch only. */ | ||
492 | pbus_size_mem(bus, mask, IORESOURCE_MEM); | ||
493 | break; | ||
494 | } | ||
495 | } | ||
496 | EXPORT_SYMBOL(pci_bus_size_bridges); | ||
497 | |||
498 | void __devinit | ||
499 | pci_bus_assign_resources(struct pci_bus *bus) | ||
500 | { | ||
501 | struct pci_bus *b; | ||
502 | struct pci_dev *dev; | ||
503 | |||
504 | pbus_assign_resources_sorted(bus); | ||
505 | |||
506 | if (bus->bridge_ctl & PCI_BRIDGE_CTL_VGA) { | ||
507 | /* Propagate presence of the VGA to upstream bridges */ | ||
508 | for (b = bus; b->parent; b = b->parent) { | ||
509 | b->bridge_ctl |= PCI_BRIDGE_CTL_VGA; | ||
510 | } | ||
511 | } | ||
512 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
513 | b = dev->subordinate; | ||
514 | if (!b) | ||
515 | continue; | ||
516 | |||
517 | pci_bus_assign_resources(b); | ||
518 | |||
519 | switch (dev->class >> 8) { | ||
520 | case PCI_CLASS_BRIDGE_PCI: | ||
521 | pci_setup_bridge(b); | ||
522 | break; | ||
523 | |||
524 | case PCI_CLASS_BRIDGE_CARDBUS: | ||
525 | pci_setup_cardbus(b); | ||
526 | break; | ||
527 | |||
528 | default: | ||
529 | printk(KERN_INFO "PCI: not setting up bridge %s " | ||
530 | "for bus %d\n", pci_name(dev), b->number); | ||
531 | break; | ||
532 | } | ||
533 | } | ||
534 | } | ||
535 | EXPORT_SYMBOL(pci_bus_assign_resources); | ||
536 | |||
537 | void __init | ||
538 | pci_assign_unassigned_resources(void) | ||
539 | { | ||
540 | struct pci_bus *bus; | ||
541 | |||
542 | /* Depth first, calculate sizes and alignments of all | ||
543 | subordinate buses. */ | ||
544 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
545 | pci_bus_size_bridges(bus); | ||
546 | } | ||
547 | /* Depth last, allocate resources and update the hardware. */ | ||
548 | list_for_each_entry(bus, &pci_root_buses, node) { | ||
549 | pci_bus_assign_resources(bus); | ||
550 | pci_enable_bridges(bus); | ||
551 | } | ||
552 | } | ||