Blame view

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