diff options
119 files changed, 1649 insertions, 1701 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 7c33ef8a1ba9..1c9a348548dc 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2147,8 +2147,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2147 | the default. | 2147 | the default. |
2148 | off: Turn ECRC off | 2148 | off: Turn ECRC off |
2149 | on: Turn ECRC on. | 2149 | on: Turn ECRC on. |
2150 | realloc reallocate PCI resources if allocations done by BIOS | 2150 | realloc= Enable/disable reallocating PCI bridge resources |
2151 | are erroneous. | 2151 | if allocations done by BIOS are too small to |
2152 | accommodate resources required by all child | ||
2153 | devices. | ||
2154 | off: Turn realloc off | ||
2155 | on: Turn realloc on | ||
2156 | realloc same as realloc=on | ||
2157 | noari do not use PCIe ARI. | ||
2152 | 2158 | ||
2153 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power | 2159 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power |
2154 | Management. | 2160 | Management. |
@@ -2156,6 +2162,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2156 | force Enable ASPM even on devices that claim not to support it. | 2162 | force Enable ASPM even on devices that claim not to support it. |
2157 | WARNING: Forcing ASPM on may cause system lockups. | 2163 | WARNING: Forcing ASPM on may cause system lockups. |
2158 | 2164 | ||
2165 | pcie_hp= [PCIE] PCI Express Hotplug driver options: | ||
2166 | nomsi Do not use MSI for PCI Express Native Hotplug (this | ||
2167 | makes all PCIe ports use INTx for hotplug services). | ||
2168 | |||
2159 | pcie_ports= [PCIE] PCIe ports handling: | 2169 | pcie_ports= [PCIE] PCIe ports handling: |
2160 | auto Ask the BIOS whether or not to use native PCIe services | 2170 | auto Ask the BIOS whether or not to use native PCIe services |
2161 | associated with PCIe ports (PME, hot-plug, AER). Use | 2171 | associated with PCIe ports (PME, hot-plug, AER). Use |
diff --git a/MAINTAINERS b/MAINTAINERS index 95eba3135018..3b733fafb055 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5120,7 +5120,7 @@ F: Documentation/PCI/pci-error-recovery.txt | |||
5120 | F: Documentation/powerpc/eeh-pci-error-recovery.txt | 5120 | F: Documentation/powerpc/eeh-pci-error-recovery.txt |
5121 | 5121 | ||
5122 | PCI SUBSYSTEM | 5122 | PCI SUBSYSTEM |
5123 | M: Jesse Barnes <jbarnes@virtuousgeek.org> | 5123 | M: Bjorn Helgaas <bhelgaas@google.com> |
5124 | L: linux-pci@vger.kernel.org | 5124 | L: linux-pci@vger.kernel.org |
5125 | Q: http://patchwork.kernel.org/project/linux-pci/list/ | 5125 | Q: http://patchwork.kernel.org/project/linux-pci/list/ |
5126 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git | 5126 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git |
@@ -5130,7 +5130,7 @@ F: drivers/pci/ | |||
5130 | F: include/linux/pci* | 5130 | F: include/linux/pci* |
5131 | 5131 | ||
5132 | PCI HOTPLUG | 5132 | PCI HOTPLUG |
5133 | M: Jesse Barnes <jbarnes@virtuousgeek.org> | 5133 | M: Bjorn Helgaas <bhelgaas@google.com> |
5134 | L: linux-pci@vger.kernel.org | 5134 | L: linux-pci@vger.kernel.org |
5135 | S: Supported | 5135 | S: Supported |
5136 | F: drivers/pci/hotplug | 5136 | F: drivers/pci/hotplug |
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h index 28d0497fd3c7..d01afb78919c 100644 --- a/arch/alpha/include/asm/pci.h +++ b/arch/alpha/include/asm/pci.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/dma-mapping.h> | 7 | #include <linux/dma-mapping.h> |
8 | #include <asm/scatterlist.h> | 8 | #include <asm/scatterlist.h> |
9 | #include <asm/machvec.h> | 9 | #include <asm/machvec.h> |
10 | #include <asm-generic/pci-bridge.h> | ||
10 | 11 | ||
11 | /* | 12 | /* |
12 | * The following structure is used to manage multiple PCI busses. | 13 | * The following structure is used to manage multiple PCI busses. |
@@ -99,12 +100,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
99 | return channel ? 15 : 14; | 100 | return channel ? 15 : 14; |
100 | } | 101 | } |
101 | 102 | ||
102 | extern void pcibios_resource_to_bus(struct pci_dev *, struct pci_bus_region *, | ||
103 | struct resource *); | ||
104 | |||
105 | extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
106 | struct pci_bus_region *region); | ||
107 | |||
108 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index | 103 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index |
109 | 104 | ||
110 | static inline int pci_proc_domain(struct pci_bus *bus) | 105 | static inline int pci_proc_domain(struct pci_bus *bus) |
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c index 8c723c1b086a..1a629636cc16 100644 --- a/arch/alpha/kernel/pci.c +++ b/arch/alpha/kernel/pci.c | |||
@@ -43,12 +43,10 @@ const char *const pci_mem_names[] = { | |||
43 | 43 | ||
44 | const char pci_hae0_name[] = "HAE0"; | 44 | const char pci_hae0_name[] = "HAE0"; |
45 | 45 | ||
46 | /* Indicate whether we respect the PCI setup left by console. */ | ||
47 | /* | 46 | /* |
48 | * Make this long-lived so that we know when shutting down | 47 | * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource |
49 | * whether we probed only or not. | 48 | * assignments. |
50 | */ | 49 | */ |
51 | int pci_probe_only; | ||
52 | 50 | ||
53 | /* | 51 | /* |
54 | * The PCI controller list. | 52 | * The PCI controller list. |
@@ -215,7 +213,7 @@ pdev_save_srm_config(struct pci_dev *dev) | |||
215 | struct pdev_srm_saved_conf *tmp; | 213 | struct pdev_srm_saved_conf *tmp; |
216 | static int printed = 0; | 214 | static int printed = 0; |
217 | 215 | ||
218 | if (!alpha_using_srm || pci_probe_only) | 216 | if (!alpha_using_srm || pci_has_flag(PCI_PROBE_ONLY)) |
219 | return; | 217 | return; |
220 | 218 | ||
221 | if (!printed) { | 219 | if (!printed) { |
@@ -242,7 +240,7 @@ pci_restore_srm_config(void) | |||
242 | struct pdev_srm_saved_conf *tmp; | 240 | struct pdev_srm_saved_conf *tmp; |
243 | 241 | ||
244 | /* No need to restore if probed only. */ | 242 | /* No need to restore if probed only. */ |
245 | if (pci_probe_only) | 243 | if (pci_has_flag(PCI_PROBE_ONLY)) |
246 | return; | 244 | return; |
247 | 245 | ||
248 | /* Restore SRM config. */ | 246 | /* Restore SRM config. */ |
@@ -253,46 +251,17 @@ pci_restore_srm_config(void) | |||
253 | #endif | 251 | #endif |
254 | 252 | ||
255 | void __devinit | 253 | void __devinit |
256 | pcibios_fixup_resource(struct resource *res, struct resource *root) | ||
257 | { | ||
258 | res->start += root->start; | ||
259 | res->end += root->start; | ||
260 | } | ||
261 | |||
262 | void __devinit | ||
263 | pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus) | ||
264 | { | ||
265 | /* Update device resources. */ | ||
266 | struct pci_controller *hose = (struct pci_controller *)bus->sysdata; | ||
267 | int i; | ||
268 | |||
269 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
270 | if (!dev->resource[i].start) | ||
271 | continue; | ||
272 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
273 | pcibios_fixup_resource(&dev->resource[i], | ||
274 | hose->io_space); | ||
275 | else if (dev->resource[i].flags & IORESOURCE_MEM) | ||
276 | pcibios_fixup_resource(&dev->resource[i], | ||
277 | hose->mem_space); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | void __devinit | ||
282 | pcibios_fixup_bus(struct pci_bus *bus) | 254 | pcibios_fixup_bus(struct pci_bus *bus) |
283 | { | 255 | { |
284 | struct pci_dev *dev = bus->self; | 256 | struct pci_dev *dev = bus->self; |
285 | 257 | ||
286 | if (pci_probe_only && dev && | 258 | if (pci_has_flag(PCI_PROBE_ONLY) && dev && |
287 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | 259 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
288 | pci_read_bridge_bases(bus); | 260 | pci_read_bridge_bases(bus); |
289 | pcibios_fixup_device_resources(dev, bus); | ||
290 | } | 261 | } |
291 | 262 | ||
292 | list_for_each_entry(dev, &bus->devices, bus_list) { | 263 | list_for_each_entry(dev, &bus->devices, bus_list) { |
293 | pdev_save_srm_config(dev); | 264 | pdev_save_srm_config(dev); |
294 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
295 | pcibios_fixup_device_resources(dev, bus); | ||
296 | } | 265 | } |
297 | } | 266 | } |
298 | 267 | ||
@@ -302,42 +271,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq) | |||
302 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 271 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
303 | } | 272 | } |
304 | 273 | ||
305 | void | ||
306 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
307 | struct resource *res) | ||
308 | { | ||
309 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
310 | unsigned long offset = 0; | ||
311 | |||
312 | if (res->flags & IORESOURCE_IO) | ||
313 | offset = hose->io_space->start; | ||
314 | else if (res->flags & IORESOURCE_MEM) | ||
315 | offset = hose->mem_space->start; | ||
316 | |||
317 | region->start = res->start - offset; | ||
318 | region->end = res->end - offset; | ||
319 | } | ||
320 | |||
321 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
322 | struct pci_bus_region *region) | ||
323 | { | ||
324 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
325 | unsigned long offset = 0; | ||
326 | |||
327 | if (res->flags & IORESOURCE_IO) | ||
328 | offset = hose->io_space->start; | ||
329 | else if (res->flags & IORESOURCE_MEM) | ||
330 | offset = hose->mem_space->start; | ||
331 | |||
332 | res->start = region->start + offset; | ||
333 | res->end = region->end + offset; | ||
334 | } | ||
335 | |||
336 | #ifdef CONFIG_HOTPLUG | ||
337 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
338 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
339 | #endif | ||
340 | |||
341 | int | 274 | int |
342 | pcibios_enable_device(struct pci_dev *dev, int mask) | 275 | pcibios_enable_device(struct pci_dev *dev, int mask) |
343 | { | 276 | { |
@@ -374,7 +307,8 @@ pcibios_claim_one_bus(struct pci_bus *b) | |||
374 | 307 | ||
375 | if (r->parent || !r->start || !r->flags) | 308 | if (r->parent || !r->start || !r->flags) |
376 | continue; | 309 | continue; |
377 | if (pci_probe_only || (r->flags & IORESOURCE_PCI_FIXED)) | 310 | if (pci_has_flag(PCI_PROBE_ONLY) || |
311 | (r->flags & IORESOURCE_PCI_FIXED)) | ||
378 | pci_claim_resource(dev, i); | 312 | pci_claim_resource(dev, i); |
379 | } | 313 | } |
380 | } | 314 | } |
@@ -416,8 +350,10 @@ common_init_pci(void) | |||
416 | hose->mem_space->end = end; | 350 | hose->mem_space->end = end; |
417 | 351 | ||
418 | INIT_LIST_HEAD(&resources); | 352 | INIT_LIST_HEAD(&resources); |
419 | pci_add_resource(&resources, hose->io_space); | 353 | pci_add_resource_offset(&resources, hose->io_space, |
420 | pci_add_resource(&resources, hose->mem_space); | 354 | hose->io_space->start); |
355 | pci_add_resource_offset(&resources, hose->mem_space, | ||
356 | hose->mem_space->start); | ||
421 | 357 | ||
422 | bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, | 358 | bus = pci_scan_root_bus(NULL, next_busno, alpha_mv.pci_ops, |
423 | hose, &resources); | 359 | hose, &resources); |
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h index 85457b2d4516..2b0ac429f5eb 100644 --- a/arch/alpha/kernel/pci_impl.h +++ b/arch/alpha/kernel/pci_impl.h | |||
@@ -173,9 +173,6 @@ extern void pci_restore_srm_config(void); | |||
173 | extern struct pci_controller *hose_head, **hose_tail; | 173 | extern struct pci_controller *hose_head, **hose_tail; |
174 | extern struct pci_controller *pci_isa_hose; | 174 | extern struct pci_controller *pci_isa_hose; |
175 | 175 | ||
176 | /* Indicate that we trust the console to configure things properly. */ | ||
177 | extern int pci_probe_only; | ||
178 | |||
179 | extern unsigned long alpha_agpgart_size; | 176 | extern unsigned long alpha_agpgart_size; |
180 | 177 | ||
181 | extern void common_init_pci(void); | 178 | extern void common_init_pci(void); |
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c index 95cfc83ece8f..fc8b12508611 100644 --- a/arch/alpha/kernel/sys_marvel.c +++ b/arch/alpha/kernel/sys_marvel.c | |||
@@ -384,7 +384,8 @@ marvel_init_pci(void) | |||
384 | 384 | ||
385 | marvel_register_error_handlers(); | 385 | marvel_register_error_handlers(); |
386 | 386 | ||
387 | pci_probe_only = 1; | 387 | /* Indicate that we trust the console to configure things properly */ |
388 | pci_set_flags(PCI_PROBE_ONLY); | ||
388 | common_init_pci(); | 389 | common_init_pci(); |
389 | locate_and_init_vga(NULL); | 390 | locate_and_init_vga(NULL); |
390 | 391 | ||
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index f47b30a2a117..b8eafa053539 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c | |||
@@ -331,7 +331,8 @@ titan_init_pci(void) | |||
331 | */ | 331 | */ |
332 | titan_late_init(); | 332 | titan_late_init(); |
333 | 333 | ||
334 | pci_probe_only = 1; | 334 | /* Indicate that we trust the console to configure things properly */ |
335 | pci_set_flags(PCI_PROBE_ONLY); | ||
335 | common_init_pci(); | 336 | common_init_pci(); |
336 | SMC669_Init(0); | 337 | SMC669_Init(0); |
337 | locate_and_init_vga(NULL); | 338 | locate_and_init_vga(NULL); |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index fb1f1cfce60c..dcb13494ca0d 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -299,8 +299,8 @@ int __init it8152_pci_setup(int nr, struct pci_sys_data *sys) | |||
299 | goto err1; | 299 | goto err1; |
300 | } | 300 | } |
301 | 301 | ||
302 | pci_add_resource(&sys->resources, &it8152_io); | 302 | pci_add_resource_offset(&sys->resources, &it8152_io, sys->io_offset); |
303 | pci_add_resource(&sys->resources, &it8152_mem); | 303 | pci_add_resource_offset(&sys->resources, &it8152_mem, sys->mem_offset); |
304 | 304 | ||
305 | if (platform_notify || platform_notify_remove) { | 305 | if (platform_notify || platform_notify_remove) { |
306 | printk(KERN_ERR "PCI: Can't use platform_notify\n"); | 306 | printk(KERN_ERR "PCI: Can't use platform_notify\n"); |
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h index da337ba57ffd..a98a2e112fae 100644 --- a/arch/arm/include/asm/pci.h +++ b/arch/arm/include/asm/pci.h | |||
@@ -57,14 +57,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
57 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | 57 | extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, |
58 | enum pci_mmap_state mmap_state, int write_combine); | 58 | enum pci_mmap_state mmap_state, int write_combine); |
59 | 59 | ||
60 | extern void | ||
61 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
62 | struct resource *res); | ||
63 | |||
64 | extern void | ||
65 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
66 | struct pci_bus_region *region); | ||
67 | |||
68 | /* | 60 | /* |
69 | * Dummy implementation; always return 0. | 61 | * Dummy implementation; always return 0. |
70 | */ | 62 | */ |
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index f58ba3589908..632df9a66f8c 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <asm/mach/pci.h> | 16 | #include <asm/mach/pci.h> |
17 | 17 | ||
18 | static int debug_pci; | 18 | static int debug_pci; |
19 | static int use_firmware; | ||
20 | 19 | ||
21 | /* | 20 | /* |
22 | * We can't use pci_find_device() here since we are | 21 | * We can't use pci_find_device() here since we are |
@@ -295,28 +294,6 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) | |||
295 | } | 294 | } |
296 | 295 | ||
297 | /* | 296 | /* |
298 | * Adjust the device resources from bus-centric to Linux-centric. | ||
299 | */ | ||
300 | static void __devinit | ||
301 | pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) | ||
302 | { | ||
303 | resource_size_t offset; | ||
304 | int i; | ||
305 | |||
306 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
307 | if (dev->resource[i].start == 0) | ||
308 | continue; | ||
309 | if (dev->resource[i].flags & IORESOURCE_MEM) | ||
310 | offset = root->mem_offset; | ||
311 | else | ||
312 | offset = root->io_offset; | ||
313 | |||
314 | dev->resource[i].start += offset; | ||
315 | dev->resource[i].end += offset; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | /* | ||
320 | * pcibios_fixup_bus - Called after each bus is probed, | 297 | * pcibios_fixup_bus - Called after each bus is probed, |
321 | * but before its children are examined. | 298 | * but before its children are examined. |
322 | */ | 299 | */ |
@@ -333,8 +310,6 @@ void pcibios_fixup_bus(struct pci_bus *bus) | |||
333 | list_for_each_entry(dev, &bus->devices, bus_list) { | 310 | list_for_each_entry(dev, &bus->devices, bus_list) { |
334 | u16 status; | 311 | u16 status; |
335 | 312 | ||
336 | pdev_fixup_device_resources(root, dev); | ||
337 | |||
338 | pci_read_config_word(dev, PCI_STATUS, &status); | 313 | pci_read_config_word(dev, PCI_STATUS, &status); |
339 | 314 | ||
340 | /* | 315 | /* |
@@ -400,43 +375,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); | |||
400 | #endif | 375 | #endif |
401 | 376 | ||
402 | /* | 377 | /* |
403 | * Convert from Linux-centric to bus-centric addresses for bridge devices. | ||
404 | */ | ||
405 | void | ||
406 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
407 | struct resource *res) | ||
408 | { | ||
409 | struct pci_sys_data *root = dev->sysdata; | ||
410 | unsigned long offset = 0; | ||
411 | |||
412 | if (res->flags & IORESOURCE_IO) | ||
413 | offset = root->io_offset; | ||
414 | if (res->flags & IORESOURCE_MEM) | ||
415 | offset = root->mem_offset; | ||
416 | |||
417 | region->start = res->start - offset; | ||
418 | region->end = res->end - offset; | ||
419 | } | ||
420 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
421 | |||
422 | void __devinit | ||
423 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
424 | struct pci_bus_region *region) | ||
425 | { | ||
426 | struct pci_sys_data *root = dev->sysdata; | ||
427 | unsigned long offset = 0; | ||
428 | |||
429 | if (res->flags & IORESOURCE_IO) | ||
430 | offset = root->io_offset; | ||
431 | if (res->flags & IORESOURCE_MEM) | ||
432 | offset = root->mem_offset; | ||
433 | |||
434 | res->start = region->start + offset; | ||
435 | res->end = region->end + offset; | ||
436 | } | ||
437 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
438 | |||
439 | /* | ||
440 | * Swizzle the device pin each time we cross a bridge. | 378 | * Swizzle the device pin each time we cross a bridge. |
441 | * This might update pin and returns the slot number. | 379 | * This might update pin and returns the slot number. |
442 | */ | 380 | */ |
@@ -497,10 +435,10 @@ static void __init pcibios_init_hw(struct hw_pci *hw) | |||
497 | 435 | ||
498 | if (ret > 0) { | 436 | if (ret > 0) { |
499 | if (list_empty(&sys->resources)) { | 437 | if (list_empty(&sys->resources)) { |
500 | pci_add_resource(&sys->resources, | 438 | pci_add_resource_offset(&sys->resources, |
501 | &ioport_resource); | 439 | &ioport_resource, sys->io_offset); |
502 | pci_add_resource(&sys->resources, | 440 | pci_add_resource_offset(&sys->resources, |
503 | &iomem_resource); | 441 | &iomem_resource, sys->mem_offset); |
504 | } | 442 | } |
505 | 443 | ||
506 | sys->bus = hw->scan(nr, sys); | 444 | sys->bus = hw->scan(nr, sys); |
@@ -525,6 +463,7 @@ void __init pci_common_init(struct hw_pci *hw) | |||
525 | 463 | ||
526 | INIT_LIST_HEAD(&hw->buses); | 464 | INIT_LIST_HEAD(&hw->buses); |
527 | 465 | ||
466 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | ||
528 | if (hw->preinit) | 467 | if (hw->preinit) |
529 | hw->preinit(); | 468 | hw->preinit(); |
530 | pcibios_init_hw(hw); | 469 | pcibios_init_hw(hw); |
@@ -536,7 +475,7 @@ void __init pci_common_init(struct hw_pci *hw) | |||
536 | list_for_each_entry(sys, &hw->buses, node) { | 475 | list_for_each_entry(sys, &hw->buses, node) { |
537 | struct pci_bus *bus = sys->bus; | 476 | struct pci_bus *bus = sys->bus; |
538 | 477 | ||
539 | if (!use_firmware) { | 478 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
540 | /* | 479 | /* |
541 | * Size the bridge windows. | 480 | * Size the bridge windows. |
542 | */ | 481 | */ |
@@ -573,7 +512,7 @@ char * __init pcibios_setup(char *str) | |||
573 | debug_pci = 1; | 512 | debug_pci = 1; |
574 | return NULL; | 513 | return NULL; |
575 | } else if (!strcmp(str, "firmware")) { | 514 | } else if (!strcmp(str, "firmware")) { |
576 | use_firmware = 1; | 515 | pci_add_flags(PCI_PROBE_ONLY); |
577 | return NULL; | 516 | return NULL; |
578 | } | 517 | } |
579 | return str; | 518 | return str; |
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c index e159d69967c9..79d001f831e0 100644 --- a/arch/arm/mach-cns3xxx/pcie.c +++ b/arch/arm/mach-cns3xxx/pcie.c | |||
@@ -155,8 +155,8 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys) | |||
155 | BUG_ON(request_resource(&iomem_resource, res_io) || | 155 | BUG_ON(request_resource(&iomem_resource, res_io) || |
156 | request_resource(&iomem_resource, res_mem)); | 156 | request_resource(&iomem_resource, res_mem)); |
157 | 157 | ||
158 | pci_add_resource(&sys->resources, res_io); | 158 | pci_add_resource_offset(&sys->resources, res_io, sys->io_offset); |
159 | pci_add_resource(&sys->resources, res_mem); | 159 | pci_add_resource_offset(&sys->resources, res_mem, sys->mem_offset); |
160 | 160 | ||
161 | return 1; | 161 | return 1; |
162 | } | 162 | } |
diff --git a/arch/arm/mach-dove/pcie.c b/arch/arm/mach-dove/pcie.c index 52e96d397ba8..48a032005ea3 100644 --- a/arch/arm/mach-dove/pcie.c +++ b/arch/arm/mach-dove/pcie.c | |||
@@ -69,7 +69,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) | |||
69 | pp->res[0].flags = IORESOURCE_IO; | 69 | pp->res[0].flags = IORESOURCE_IO; |
70 | if (request_resource(&ioport_resource, &pp->res[0])) | 70 | if (request_resource(&ioport_resource, &pp->res[0])) |
71 | panic("Request PCIe IO resource failed\n"); | 71 | panic("Request PCIe IO resource failed\n"); |
72 | pci_add_resource(&sys->resources, &pp->res[0]); | 72 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * IORESOURCE_MEM | 75 | * IORESOURCE_MEM |
@@ -88,7 +88,7 @@ static int __init dove_pcie_setup(int nr, struct pci_sys_data *sys) | |||
88 | pp->res[1].flags = IORESOURCE_MEM; | 88 | pp->res[1].flags = IORESOURCE_MEM; |
89 | if (request_resource(&iomem_resource, &pp->res[1])) | 89 | if (request_resource(&iomem_resource, &pp->res[1])) |
90 | panic("Request PCIe Memory resource failed\n"); | 90 | panic("Request PCIe Memory resource failed\n"); |
91 | pci_add_resource(&sys->resources, &pp->res[1]); | 91 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); |
92 | 92 | ||
93 | return 1; | 93 | return 1; |
94 | } | 94 | } |
diff --git a/arch/arm/mach-footbridge/dc21285.c b/arch/arm/mach-footbridge/dc21285.c index f685650c25d7..3194d3f73503 100644 --- a/arch/arm/mach-footbridge/dc21285.c +++ b/arch/arm/mach-footbridge/dc21285.c | |||
@@ -275,11 +275,13 @@ int __init dc21285_setup(int nr, struct pci_sys_data *sys) | |||
275 | allocate_resource(&iomem_resource, &res[0], 0x40000000, | 275 | allocate_resource(&iomem_resource, &res[0], 0x40000000, |
276 | 0x80000000, 0xffffffff, 0x40000000, NULL, NULL); | 276 | 0x80000000, 0xffffffff, 0x40000000, NULL, NULL); |
277 | 277 | ||
278 | pci_add_resource(&sys->resources, &ioport_resource); | ||
279 | pci_add_resource(&sys->resources, &res[0]); | ||
280 | pci_add_resource(&sys->resources, &res[1]); | ||
281 | sys->mem_offset = DC21285_PCI_MEM; | 278 | sys->mem_offset = DC21285_PCI_MEM; |
282 | 279 | ||
280 | pci_add_resource_offset(&sys->resources, | ||
281 | &ioport_resource, sys->io_offset); | ||
282 | pci_add_resource_offset(&sys->resources, &res[0], sys->mem_offset); | ||
283 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); | ||
284 | |||
283 | return 1; | 285 | return 1; |
284 | } | 286 | } |
285 | 287 | ||
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c index 3c82566acece..015be770c1d8 100644 --- a/arch/arm/mach-integrator/pci_v3.c +++ b/arch/arm/mach-integrator/pci_v3.c | |||
@@ -378,9 +378,10 @@ static int __init pci_v3_setup_resources(struct pci_sys_data *sys) | |||
378 | * the mem resource for this bus | 378 | * the mem resource for this bus |
379 | * the prefetch mem resource for this bus | 379 | * the prefetch mem resource for this bus |
380 | */ | 380 | */ |
381 | pci_add_resource(&sys->resources, &ioport_resource); | 381 | pci_add_resource_offset(&sys->resources, |
382 | pci_add_resource(&sys->resources, &non_mem); | 382 | &ioport_resource, sys->io_offset); |
383 | pci_add_resource(&sys->resources, &pre_mem); | 383 | pci_add_resource_offset(&sys->resources, &non_mem, sys->mem_offset); |
384 | pci_add_resource_offset(&sys->resources, &pre_mem, sys->mem_offset); | ||
384 | 385 | ||
385 | return 1; | 386 | return 1; |
386 | } | 387 | } |
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c index b8f5a8736511..861cb12ef436 100644 --- a/arch/arm/mach-iop13xx/pci.c +++ b/arch/arm/mach-iop13xx/pci.c | |||
@@ -1084,8 +1084,8 @@ int iop13xx_pci_setup(int nr, struct pci_sys_data *sys) | |||
1084 | request_resource(&ioport_resource, &res[0]); | 1084 | request_resource(&ioport_resource, &res[0]); |
1085 | request_resource(&iomem_resource, &res[1]); | 1085 | request_resource(&iomem_resource, &res[1]); |
1086 | 1086 | ||
1087 | pci_add_resource(&sys->resources, &res[0]); | 1087 | pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); |
1088 | pci_add_resource(&sys->resources, &res[1]); | 1088 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); |
1089 | 1089 | ||
1090 | return 1; | 1090 | return 1; |
1091 | } | 1091 | } |
diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index f53e911ec94a..d519944653ad 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c | |||
@@ -134,11 +134,11 @@ static void ixdp2400_pci_postinit(void) | |||
134 | 134 | ||
135 | if (ixdp2x00_master_npu()) { | 135 | if (ixdp2x00_master_npu()) { |
136 | dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); | 136 | dev = pci_get_bus_and_slot(1, IXDP2400_SLAVE_ENET_DEVFN); |
137 | pci_remove_bus_device(dev); | 137 | pci_stop_and_remove_bus_device(dev); |
138 | pci_dev_put(dev); | 138 | pci_dev_put(dev); |
139 | } else { | 139 | } else { |
140 | dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); | 140 | dev = pci_get_bus_and_slot(1, IXDP2400_MASTER_ENET_DEVFN); |
141 | pci_remove_bus_device(dev); | 141 | pci_stop_and_remove_bus_device(dev); |
142 | pci_dev_put(dev); | 142 | pci_dev_put(dev); |
143 | 143 | ||
144 | ixdp2x00_slave_pci_postinit(); | 144 | ixdp2x00_slave_pci_postinit(); |
diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index a2e7c393e74f..b415febd2025 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c | |||
@@ -262,14 +262,14 @@ int __init ixdp2800_pci_init(void) | |||
262 | pci_common_init(&ixdp2800_pci); | 262 | pci_common_init(&ixdp2800_pci); |
263 | if (ixdp2x00_master_npu()) { | 263 | if (ixdp2x00_master_npu()) { |
264 | dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); | 264 | dev = pci_get_bus_and_slot(1, IXDP2800_SLAVE_ENET_DEVFN); |
265 | pci_remove_bus_device(dev); | 265 | pci_stop_and_remove_bus_device(dev); |
266 | pci_dev_put(dev); | 266 | pci_dev_put(dev); |
267 | 267 | ||
268 | ixdp2800_master_enable_slave(); | 268 | ixdp2800_master_enable_slave(); |
269 | ixdp2800_master_wait_for_slave_bus_scan(); | 269 | ixdp2800_master_wait_for_slave_bus_scan(); |
270 | } else { | 270 | } else { |
271 | dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); | 271 | dev = pci_get_bus_and_slot(1, IXDP2800_MASTER_ENET_DEVFN); |
272 | pci_remove_bus_device(dev); | 272 | pci_stop_and_remove_bus_device(dev); |
273 | pci_dev_put(dev); | 273 | pci_dev_put(dev); |
274 | } | 274 | } |
275 | } | 275 | } |
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c index 634b6c852f68..dd9838299068 100644 --- a/arch/arm/mach-ixp2000/ixdp2x00.c +++ b/arch/arm/mach-ixp2000/ixdp2x00.c | |||
@@ -239,12 +239,12 @@ void ixdp2x00_slave_pci_postinit(void) | |||
239 | * Remove PMC device is there is one | 239 | * Remove PMC device is there is one |
240 | */ | 240 | */ |
241 | if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { | 241 | if((dev = pci_get_bus_and_slot(1, IXDP2X00_PMC_DEVFN))) { |
242 | pci_remove_bus_device(dev); | 242 | pci_stop_and_remove_bus_device(dev); |
243 | pci_dev_put(dev); | 243 | pci_dev_put(dev); |
244 | } | 244 | } |
245 | 245 | ||
246 | dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); | 246 | dev = pci_get_bus_and_slot(0, IXDP2X00_21555_DEVFN); |
247 | pci_remove_bus_device(dev); | 247 | pci_stop_and_remove_bus_device(dev); |
248 | pci_dev_put(dev); | 248 | pci_dev_put(dev); |
249 | } | 249 | } |
250 | 250 | ||
diff --git a/arch/arm/mach-ixp2000/pci.c b/arch/arm/mach-ixp2000/pci.c index 626fda435aa9..49c36f3cd602 100644 --- a/arch/arm/mach-ixp2000/pci.c +++ b/arch/arm/mach-ixp2000/pci.c | |||
@@ -243,8 +243,10 @@ int ixp2000_pci_setup(int nr, struct pci_sys_data *sys) | |||
243 | if (nr >= 1) | 243 | if (nr >= 1) |
244 | return 0; | 244 | return 0; |
245 | 245 | ||
246 | pci_add_resource(&sys->resources, &ixp2000_pci_io_space); | 246 | pci_add_resource_offset(&sys->resources, |
247 | pci_add_resource(&sys->resources, &ixp2000_pci_mem_space); | 247 | &ixp2000_pci_io_space, sys->io_offset); |
248 | pci_add_resource_offset(&sys->resources, | ||
249 | &ixp2000_pci_mem_space, sys->mem_offset); | ||
248 | 250 | ||
249 | return 1; | 251 | return 1; |
250 | } | 252 | } |
diff --git a/arch/arm/mach-ixp23xx/pci.c b/arch/arm/mach-ixp23xx/pci.c index 25b5c462cea2..3cbbd3208fa8 100644 --- a/arch/arm/mach-ixp23xx/pci.c +++ b/arch/arm/mach-ixp23xx/pci.c | |||
@@ -281,8 +281,10 @@ int ixp23xx_pci_setup(int nr, struct pci_sys_data *sys) | |||
281 | if (nr >= 1) | 281 | if (nr >= 1) |
282 | return 0; | 282 | return 0; |
283 | 283 | ||
284 | pci_add_resource(&sys->resources, &ixp23xx_pci_io_space); | 284 | pci_add_resource_offset(&sys->resources, |
285 | pci_add_resource(&sys->resources, &ixp23xx_pci_mem_space); | 285 | &ixp23xx_pci_io_space, sys->io_offset); |
286 | pci_add_resource_offset(&sys->resources, | ||
287 | &ixp23xx_pci_mem_space, sys->mem_offset); | ||
286 | 288 | ||
287 | return 1; | 289 | return 1; |
288 | } | 290 | } |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 5eff15f24bc2..8508882b13f0 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -472,8 +472,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) | |||
472 | request_resource(&ioport_resource, &res[0]); | 472 | request_resource(&ioport_resource, &res[0]); |
473 | request_resource(&iomem_resource, &res[1]); | 473 | request_resource(&iomem_resource, &res[1]); |
474 | 474 | ||
475 | pci_add_resource(&sys->resources, &res[0]); | 475 | pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); |
476 | pci_add_resource(&sys->resources, &res[1]); | 476 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); |
477 | 477 | ||
478 | platform_notify = ixp4xx_pci_platform_notify; | 478 | platform_notify = ixp4xx_pci_platform_notify; |
479 | platform_notify_remove = ixp4xx_pci_platform_notify_remove; | 479 | platform_notify_remove = ixp4xx_pci_platform_notify_remove; |
diff --git a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c index a066a6d8d9d2..f56a0118c1bb 100644 --- a/arch/arm/mach-kirkwood/pcie.c +++ b/arch/arm/mach-kirkwood/pcie.c | |||
@@ -198,9 +198,9 @@ static int __init kirkwood_pcie_setup(int nr, struct pci_sys_data *sys) | |||
198 | if (request_resource(&iomem_resource, &pp->res[1])) | 198 | if (request_resource(&iomem_resource, &pp->res[1])) |
199 | panic("Request PCIe%d Memory resource failed\n", index); | 199 | panic("Request PCIe%d Memory resource failed\n", index); |
200 | 200 | ||
201 | pci_add_resource(&sys->resources, &pp->res[0]); | ||
202 | pci_add_resource(&sys->resources, &pp->res[1]); | ||
203 | sys->io_offset = 0; | 201 | sys->io_offset = 0; |
202 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); | ||
203 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); | ||
204 | 204 | ||
205 | /* | 205 | /* |
206 | * Generic PCIe unit setup. | 206 | * Generic PCIe unit setup. |
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c index b26f992071df..acc701435817 100644 --- a/arch/arm/mach-ks8695/pci.c +++ b/arch/arm/mach-ks8695/pci.c | |||
@@ -169,8 +169,8 @@ static int __init ks8695_pci_setup(int nr, struct pci_sys_data *sys) | |||
169 | request_resource(&iomem_resource, &pci_mem); | 169 | request_resource(&iomem_resource, &pci_mem); |
170 | request_resource(&ioport_resource, &pci_io); | 170 | request_resource(&ioport_resource, &pci_io); |
171 | 171 | ||
172 | pci_add_resource(&sys->resources, &pci_io); | 172 | pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset); |
173 | pci_add_resource(&sys->resources, &pci_mem); | 173 | pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset); |
174 | 174 | ||
175 | /* Assign and enable processor bridge */ | 175 | /* Assign and enable processor bridge */ |
176 | ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA); | 176 | ks8695_local_writeconfig(PCI_BASE_ADDRESS_0, KS8695_PCIMEM_PA); |
diff --git a/arch/arm/mach-mv78xx0/pcie.c b/arch/arm/mach-mv78xx0/pcie.c index 8459f6d7d8ca..df3e38055a24 100644 --- a/arch/arm/mach-mv78xx0/pcie.c +++ b/arch/arm/mach-mv78xx0/pcie.c | |||
@@ -155,8 +155,8 @@ static int __init mv78xx0_pcie_setup(int nr, struct pci_sys_data *sys) | |||
155 | orion_pcie_set_local_bus_nr(pp->base, sys->busnr); | 155 | orion_pcie_set_local_bus_nr(pp->base, sys->busnr); |
156 | orion_pcie_setup(pp->base); | 156 | orion_pcie_setup(pp->base); |
157 | 157 | ||
158 | pci_add_resource(&sys->resources, &pp->res[0]); | 158 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); |
159 | pci_add_resource(&sys->resources, &pp->res[1]); | 159 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); |
160 | 160 | ||
161 | return 1; | 161 | return 1; |
162 | } | 162 | } |
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c index 09a045f0c406..d6a91948e4dc 100644 --- a/arch/arm/mach-orion5x/pci.c +++ b/arch/arm/mach-orion5x/pci.c | |||
@@ -171,13 +171,14 @@ static int __init pcie_setup(struct pci_sys_data *sys) | |||
171 | /* | 171 | /* |
172 | * IORESOURCE_IO | 172 | * IORESOURCE_IO |
173 | */ | 173 | */ |
174 | sys->io_offset = 0; | ||
174 | res[0].name = "PCIe I/O Space"; | 175 | res[0].name = "PCIe I/O Space"; |
175 | res[0].flags = IORESOURCE_IO; | 176 | res[0].flags = IORESOURCE_IO; |
176 | res[0].start = ORION5X_PCIE_IO_BUS_BASE; | 177 | res[0].start = ORION5X_PCIE_IO_BUS_BASE; |
177 | res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1; | 178 | res[0].end = res[0].start + ORION5X_PCIE_IO_SIZE - 1; |
178 | if (request_resource(&ioport_resource, &res[0])) | 179 | if (request_resource(&ioport_resource, &res[0])) |
179 | panic("Request PCIe IO resource failed\n"); | 180 | panic("Request PCIe IO resource failed\n"); |
180 | pci_add_resource(&sys->resources, &res[0]); | 181 | pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); |
181 | 182 | ||
182 | /* | 183 | /* |
183 | * IORESOURCE_MEM | 184 | * IORESOURCE_MEM |
@@ -188,9 +189,7 @@ static int __init pcie_setup(struct pci_sys_data *sys) | |||
188 | res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1; | 189 | res[1].end = res[1].start + ORION5X_PCIE_MEM_SIZE - 1; |
189 | if (request_resource(&iomem_resource, &res[1])) | 190 | if (request_resource(&iomem_resource, &res[1])) |
190 | panic("Request PCIe Memory resource failed\n"); | 191 | panic("Request PCIe Memory resource failed\n"); |
191 | pci_add_resource(&sys->resources, &res[1]); | 192 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); |
192 | |||
193 | sys->io_offset = 0; | ||
194 | 193 | ||
195 | return 1; | 194 | return 1; |
196 | } | 195 | } |
@@ -499,13 +498,14 @@ static int __init pci_setup(struct pci_sys_data *sys) | |||
499 | /* | 498 | /* |
500 | * IORESOURCE_IO | 499 | * IORESOURCE_IO |
501 | */ | 500 | */ |
501 | sys->io_offset = 0; | ||
502 | res[0].name = "PCI I/O Space"; | 502 | res[0].name = "PCI I/O Space"; |
503 | res[0].flags = IORESOURCE_IO; | 503 | res[0].flags = IORESOURCE_IO; |
504 | res[0].start = ORION5X_PCI_IO_BUS_BASE; | 504 | res[0].start = ORION5X_PCI_IO_BUS_BASE; |
505 | res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1; | 505 | res[0].end = res[0].start + ORION5X_PCI_IO_SIZE - 1; |
506 | if (request_resource(&ioport_resource, &res[0])) | 506 | if (request_resource(&ioport_resource, &res[0])) |
507 | panic("Request PCI IO resource failed\n"); | 507 | panic("Request PCI IO resource failed\n"); |
508 | pci_add_resource(&sys->resources, &res[0]); | 508 | pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); |
509 | 509 | ||
510 | /* | 510 | /* |
511 | * IORESOURCE_MEM | 511 | * IORESOURCE_MEM |
@@ -516,9 +516,7 @@ static int __init pci_setup(struct pci_sys_data *sys) | |||
516 | res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1; | 516 | res[1].end = res[1].start + ORION5X_PCI_MEM_SIZE - 1; |
517 | if (request_resource(&iomem_resource, &res[1])) | 517 | if (request_resource(&iomem_resource, &res[1])) |
518 | panic("Request PCI Memory resource failed\n"); | 518 | panic("Request PCI Memory resource failed\n"); |
519 | pci_add_resource(&sys->resources, &res[1]); | 519 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); |
520 | |||
521 | sys->io_offset = 0; | ||
522 | 520 | ||
523 | return 1; | 521 | return 1; |
524 | } | 522 | } |
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c index 0d01ca788922..b466bca9c651 100644 --- a/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/arch/arm/mach-sa1100/pci-nanoengine.c | |||
@@ -244,9 +244,11 @@ static int __init pci_nanoengine_setup_resources(struct pci_sys_data *sys) | |||
244 | printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); | 244 | printk(KERN_ERR "PCI: unable to allocate prefetchable\n"); |
245 | return -EBUSY; | 245 | return -EBUSY; |
246 | } | 246 | } |
247 | pci_add_resource(&sys->resources, &pci_io_ports); | 247 | pci_add_resource_offset(&sys->resources, &pci_io_ports, sys->io_offset); |
248 | pci_add_resource(&sys->resources, &pci_non_prefetchable_memory); | 248 | pci_add_resource_offset(&sys->resources, |
249 | pci_add_resource(&sys->resources, &pci_prefetchable_memory); | 249 | &pci_non_prefetchable_memory, sys->mem_offset); |
250 | pci_add_resource_offset(&sys->resources, | ||
251 | &pci_prefetchable_memory, sys->mem_offset); | ||
250 | 252 | ||
251 | return 1; | 253 | return 1; |
252 | } | 254 | } |
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index af8b63435727..14b29ab5d8f0 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c | |||
@@ -408,7 +408,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
408 | pp->res[0].flags = IORESOURCE_IO; | 408 | pp->res[0].flags = IORESOURCE_IO; |
409 | if (request_resource(&ioport_resource, &pp->res[0])) | 409 | if (request_resource(&ioport_resource, &pp->res[0])) |
410 | panic("Request PCIe IO resource failed\n"); | 410 | panic("Request PCIe IO resource failed\n"); |
411 | pci_add_resource(&sys->resources, &pp->res[0]); | 411 | pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset); |
412 | 412 | ||
413 | /* | 413 | /* |
414 | * IORESOURCE_MEM | 414 | * IORESOURCE_MEM |
@@ -427,7 +427,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
427 | pp->res[1].flags = IORESOURCE_MEM; | 427 | pp->res[1].flags = IORESOURCE_MEM; |
428 | if (request_resource(&iomem_resource, &pp->res[1])) | 428 | if (request_resource(&iomem_resource, &pp->res[1])) |
429 | panic("Request PCIe Memory resource failed\n"); | 429 | panic("Request PCIe Memory resource failed\n"); |
430 | pci_add_resource(&sys->resources, &pp->res[1]); | 430 | pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset); |
431 | 431 | ||
432 | /* | 432 | /* |
433 | * IORESOURCE_MEM | IORESOURCE_PREFETCH | 433 | * IORESOURCE_MEM | IORESOURCE_PREFETCH |
@@ -446,7 +446,7 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) | |||
446 | pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 446 | pp->res[2].flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
447 | if (request_resource(&iomem_resource, &pp->res[2])) | 447 | if (request_resource(&iomem_resource, &pp->res[2])) |
448 | panic("Request PCIe Prefetch Memory resource failed\n"); | 448 | panic("Request PCIe Prefetch Memory resource failed\n"); |
449 | pci_add_resource(&sys->resources, &pp->res[2]); | 449 | pci_add_resource_offset(&sys->resources, &pp->res[2], sys->mem_offset); |
450 | 450 | ||
451 | return 1; | 451 | return 1; |
452 | } | 452 | } |
diff --git a/arch/arm/mach-versatile/pci.c b/arch/arm/mach-versatile/pci.c index 90069bce23bc..51733b022d04 100644 --- a/arch/arm/mach-versatile/pci.c +++ b/arch/arm/mach-versatile/pci.c | |||
@@ -219,9 +219,9 @@ static int __init pci_versatile_setup_resources(struct list_head *resources) | |||
219 | * the mem resource for this bus | 219 | * the mem resource for this bus |
220 | * the prefetch mem resource for this bus | 220 | * the prefetch mem resource for this bus |
221 | */ | 221 | */ |
222 | pci_add_resource(resources, &io_mem); | 222 | pci_add_resource_offset(resources, &io_mem, sys->io_offset); |
223 | pci_add_resource(resources, &non_mem); | 223 | pci_add_resource_offset(resources, &non_mem, sys->mem_offset); |
224 | pci_add_resource(resources, &pre_mem); | 224 | pci_add_resource_offset(resources, &pre_mem, sys->mem_offset); |
225 | 225 | ||
226 | goto out; | 226 | goto out; |
227 | 227 | ||
diff --git a/arch/arm/mm/iomap.c b/arch/arm/mm/iomap.c index e62956e12030..4614208369f1 100644 --- a/arch/arm/mm/iomap.c +++ b/arch/arm/mm/iomap.c | |||
@@ -32,9 +32,6 @@ EXPORT_SYMBOL(pcibios_min_io); | |||
32 | unsigned long pcibios_min_mem = 0x01000000; | 32 | unsigned long pcibios_min_mem = 0x01000000; |
33 | EXPORT_SYMBOL(pcibios_min_mem); | 33 | EXPORT_SYMBOL(pcibios_min_mem); |
34 | 34 | ||
35 | unsigned int pci_flags = PCI_REASSIGN_ALL_RSRC; | ||
36 | EXPORT_SYMBOL(pci_flags); | ||
37 | |||
38 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) | 35 | void pci_iounmap(struct pci_dev *dev, void __iomem *addr) |
39 | { | 36 | { |
40 | if ((unsigned long)addr >= VMALLOC_START && | 37 | if ((unsigned long)addr >= VMALLOC_START && |
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c index f4d40a27111e..72768356447a 100644 --- a/arch/arm/plat-iop/pci.c +++ b/arch/arm/plat-iop/pci.c | |||
@@ -215,8 +215,8 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys) | |||
215 | sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0; | 215 | sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - *IOP3XX_OMWTVR0; |
216 | sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR; | 216 | sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - *IOP3XX_OIOWTVR; |
217 | 217 | ||
218 | pci_add_resource(&sys->resources, &res[0]); | 218 | pci_add_resource_offset(&sys->resources, &res[0], sys->io_offset); |
219 | pci_add_resource(&sys->resources, &res[1]); | 219 | pci_add_resource_offset(&sys->resources, &res[1], sys->mem_offset); |
220 | 220 | ||
221 | return 1; | 221 | return 1; |
222 | } | 222 | } |
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h index 279b38ae74aa..b22e5f5fa593 100644 --- a/arch/ia64/include/asm/pci.h +++ b/arch/ia64/include/asm/pci.h | |||
@@ -108,12 +108,6 @@ static inline int pci_proc_domain(struct pci_bus *bus) | |||
108 | return (pci_domain_nr(bus) != 0); | 108 | return (pci_domain_nr(bus) != 0); |
109 | } | 109 | } |
110 | 110 | ||
111 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
112 | struct pci_bus_region *region, struct resource *res); | ||
113 | |||
114 | extern void pcibios_bus_to_resource(struct pci_dev *dev, | ||
115 | struct resource *res, struct pci_bus_region *region); | ||
116 | |||
117 | static inline struct resource * | 111 | static inline struct resource * |
118 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) | 112 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) |
119 | { | 113 | { |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index f82f5d4b65fd..d1ce3200147c 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -320,7 +320,8 @@ static __devinit acpi_status add_window(struct acpi_resource *res, void *data) | |||
320 | * Ignore these tiny memory ranges */ | 320 | * Ignore these tiny memory ranges */ |
321 | if (!((window->resource.flags & IORESOURCE_MEM) && | 321 | if (!((window->resource.flags & IORESOURCE_MEM) && |
322 | (window->resource.end - window->resource.start < 16))) | 322 | (window->resource.end - window->resource.start < 16))) |
323 | pci_add_resource(&info->resources, &window->resource); | 323 | pci_add_resource_offset(&info->resources, &window->resource, |
324 | window->offset); | ||
324 | 325 | ||
325 | return AE_OK; | 326 | return AE_OK; |
326 | } | 327 | } |
@@ -395,54 +396,6 @@ out1: | |||
395 | return NULL; | 396 | return NULL; |
396 | } | 397 | } |
397 | 398 | ||
398 | void pcibios_resource_to_bus(struct pci_dev *dev, | ||
399 | struct pci_bus_region *region, struct resource *res) | ||
400 | { | ||
401 | struct pci_controller *controller = PCI_CONTROLLER(dev); | ||
402 | unsigned long offset = 0; | ||
403 | int i; | ||
404 | |||
405 | for (i = 0; i < controller->windows; i++) { | ||
406 | struct pci_window *window = &controller->window[i]; | ||
407 | if (!(window->resource.flags & res->flags)) | ||
408 | continue; | ||
409 | if (window->resource.start > res->start) | ||
410 | continue; | ||
411 | if (window->resource.end < res->end) | ||
412 | continue; | ||
413 | offset = window->offset; | ||
414 | break; | ||
415 | } | ||
416 | |||
417 | region->start = res->start - offset; | ||
418 | region->end = res->end - offset; | ||
419 | } | ||
420 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
421 | |||
422 | void pcibios_bus_to_resource(struct pci_dev *dev, | ||
423 | struct resource *res, struct pci_bus_region *region) | ||
424 | { | ||
425 | struct pci_controller *controller = PCI_CONTROLLER(dev); | ||
426 | unsigned long offset = 0; | ||
427 | int i; | ||
428 | |||
429 | for (i = 0; i < controller->windows; i++) { | ||
430 | struct pci_window *window = &controller->window[i]; | ||
431 | if (!(window->resource.flags & res->flags)) | ||
432 | continue; | ||
433 | if (window->resource.start - window->offset > region->start) | ||
434 | continue; | ||
435 | if (window->resource.end - window->offset < region->end) | ||
436 | continue; | ||
437 | offset = window->offset; | ||
438 | break; | ||
439 | } | ||
440 | |||
441 | res->start = region->start + offset; | ||
442 | res->end = region->end + offset; | ||
443 | } | ||
444 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
445 | |||
446 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | 399 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) |
447 | { | 400 | { |
448 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 401 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
@@ -464,15 +417,11 @@ static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | |||
464 | static void __devinit | 417 | static void __devinit |
465 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) | 418 | pcibios_fixup_resources(struct pci_dev *dev, int start, int limit) |
466 | { | 419 | { |
467 | struct pci_bus_region region; | ||
468 | int i; | 420 | int i; |
469 | 421 | ||
470 | for (i = start; i < limit; i++) { | 422 | for (i = start; i < limit; i++) { |
471 | if (!dev->resource[i].flags) | 423 | if (!dev->resource[i].flags) |
472 | continue; | 424 | continue; |
473 | region.start = dev->resource[i].start; | ||
474 | region.end = dev->resource[i].end; | ||
475 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | ||
476 | if ((is_valid_resource(dev, i))) | 425 | if ((is_valid_resource(dev, i))) |
477 | pci_claim_resource(dev, i); | 426 | pci_claim_resource(dev, i); |
478 | } | 427 | } |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 0a36f082eaf1..238e2c511d94 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -297,7 +297,8 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
297 | s64 status = 0; | 297 | s64 status = 0; |
298 | struct pci_controller *controller; | 298 | struct pci_controller *controller; |
299 | struct pcibus_bussoft *prom_bussoft_ptr; | 299 | struct pcibus_bussoft *prom_bussoft_ptr; |
300 | 300 | LIST_HEAD(resources); | |
301 | int i; | ||
301 | 302 | ||
302 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, | 303 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, |
303 | (u64) ia64_tpa(&prom_bussoft_ptr)); | 304 | (u64) ia64_tpa(&prom_bussoft_ptr)); |
@@ -315,7 +316,15 @@ sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
315 | */ | 316 | */ |
316 | controller->platform_data = prom_bussoft_ptr; | 317 | controller->platform_data = prom_bussoft_ptr; |
317 | 318 | ||
318 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); | 319 | sn_legacy_pci_window_fixup(controller, |
320 | prom_bussoft_ptr->bs_legacy_io, | ||
321 | prom_bussoft_ptr->bs_legacy_mem); | ||
322 | for (i = 0; i < controller->windows; i++) | ||
323 | pci_add_resource_offset(&resources, | ||
324 | &controller->window[i].resource, | ||
325 | controller->window[i].offset); | ||
326 | bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, controller, | ||
327 | &resources); | ||
319 | if (bus == NULL) | 328 | if (bus == NULL) |
320 | goto error_return; /* error, or bus already scanned */ | 329 | goto error_return; /* error, or bus already scanned */ |
321 | 330 | ||
@@ -348,9 +357,6 @@ sn_bus_fixup(struct pci_bus *bus) | |||
348 | return; | 357 | return; |
349 | } | 358 | } |
350 | sn_common_bus_fixup(bus, prom_bussoft_ptr); | 359 | sn_common_bus_fixup(bus, prom_bussoft_ptr); |
351 | sn_legacy_pci_window_fixup(PCI_CONTROLLER(bus), | ||
352 | prom_bussoft_ptr->bs_legacy_io, | ||
353 | prom_bussoft_ptr->bs_legacy_mem); | ||
354 | } | 360 | } |
355 | list_for_each_entry(pci_dev, &bus->devices, bus_list) { | 361 | list_for_each_entry(pci_dev, &bus->devices, bus_list) { |
356 | sn_io_slot_fixup(pci_dev); | 362 | sn_io_slot_fixup(pci_dev); |
diff --git a/arch/microblaze/include/asm/pci-bridge.h b/arch/microblaze/include/asm/pci-bridge.h index e9834b2991d0..cb5d39794800 100644 --- a/arch/microblaze/include/asm/pci-bridge.h +++ b/arch/microblaze/include/asm/pci-bridge.h | |||
@@ -10,7 +10,6 @@ | |||
10 | #include <linux/pci.h> | 10 | #include <linux/pci.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/ioport.h> | 12 | #include <linux/ioport.h> |
13 | #include <asm-generic/pci-bridge.h> | ||
14 | 13 | ||
15 | struct device_node; | 14 | struct device_node; |
16 | 15 | ||
diff --git a/arch/microblaze/include/asm/pci.h b/arch/microblaze/include/asm/pci.h index 033137628e8a..a0da88bf70c5 100644 --- a/arch/microblaze/include/asm/pci.h +++ b/arch/microblaze/include/asm/pci.h | |||
@@ -94,14 +94,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
94 | */ | 94 | */ |
95 | #define PCI_DMA_BUS_IS_PHYS (1) | 95 | #define PCI_DMA_BUS_IS_PHYS (1) |
96 | 96 | ||
97 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
98 | struct pci_bus_region *region, | ||
99 | struct resource *res); | ||
100 | |||
101 | extern void pcibios_bus_to_resource(struct pci_dev *dev, | ||
102 | struct resource *res, | ||
103 | struct pci_bus_region *region); | ||
104 | |||
105 | static inline struct resource *pcibios_select_root(struct pci_dev *pdev, | 97 | static inline struct resource *pcibios_select_root(struct pci_dev *pdev, |
106 | struct resource *res) | 98 | struct resource *res) |
107 | { | 99 | { |
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c index 85f2ac1230a8..d10403dadd2b 100644 --- a/arch/microblaze/pci/pci-common.c +++ b/arch/microblaze/pci/pci-common.c | |||
@@ -46,9 +46,6 @@ static int global_phb_number; /* Global phb counter */ | |||
46 | /* ISA Memory physical address */ | 46 | /* ISA Memory physical address */ |
47 | resource_size_t isa_mem_base; | 47 | resource_size_t isa_mem_base; |
48 | 48 | ||
49 | /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ | ||
50 | unsigned int pci_flags; | ||
51 | |||
52 | static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; | 49 | static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; |
53 | 50 | ||
54 | unsigned long isa_io_base; | 51 | unsigned long isa_io_base; |
@@ -833,64 +830,7 @@ int pci_proc_domain(struct pci_bus *bus) | |||
833 | { | 830 | { |
834 | struct pci_controller *hose = pci_bus_to_host(bus); | 831 | struct pci_controller *hose = pci_bus_to_host(bus); |
835 | 832 | ||
836 | if (!(pci_flags & PCI_ENABLE_PROC_DOMAINS)) | 833 | return 0; |
837 | return 0; | ||
838 | if (pci_flags & PCI_COMPAT_DOMAIN_0) | ||
839 | return hose->global_number != 0; | ||
840 | return 1; | ||
841 | } | ||
842 | |||
843 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
844 | struct resource *res) | ||
845 | { | ||
846 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
847 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
848 | |||
849 | if (!hose) | ||
850 | return; | ||
851 | if (res->flags & IORESOURCE_IO) { | ||
852 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
853 | mask = 0xffffffffu; | ||
854 | } else if (res->flags & IORESOURCE_MEM) | ||
855 | offset = hose->pci_mem_offset; | ||
856 | |||
857 | region->start = (res->start - offset) & mask; | ||
858 | region->end = (res->end - offset) & mask; | ||
859 | } | ||
860 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
861 | |||
862 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
863 | struct pci_bus_region *region) | ||
864 | { | ||
865 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
866 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
867 | |||
868 | if (!hose) | ||
869 | return; | ||
870 | if (res->flags & IORESOURCE_IO) { | ||
871 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
872 | mask = 0xffffffffu; | ||
873 | } else if (res->flags & IORESOURCE_MEM) | ||
874 | offset = hose->pci_mem_offset; | ||
875 | res->start = (region->start + offset) & mask; | ||
876 | res->end = (region->end + offset) & mask; | ||
877 | } | ||
878 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
879 | |||
880 | /* Fixup a bus resource into a linux resource */ | ||
881 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | ||
882 | { | ||
883 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
884 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
885 | |||
886 | if (res->flags & IORESOURCE_IO) { | ||
887 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
888 | mask = 0xffffffffu; | ||
889 | } else if (res->flags & IORESOURCE_MEM) | ||
890 | offset = hose->pci_mem_offset; | ||
891 | |||
892 | res->start = (res->start + offset) & mask; | ||
893 | res->end = (res->end + offset) & mask; | ||
894 | } | 834 | } |
895 | 835 | ||
896 | /* This header fixup will do the resource fixup for all devices as they are | 836 | /* This header fixup will do the resource fixup for all devices as they are |
@@ -910,13 +850,7 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) | |||
910 | struct resource *res = dev->resource + i; | 850 | struct resource *res = dev->resource + i; |
911 | if (!res->flags) | 851 | if (!res->flags) |
912 | continue; | 852 | continue; |
913 | /* On platforms that have PCI_PROBE_ONLY set, we don't | 853 | if (res->start == 0) { |
914 | * consider 0 as an unassigned BAR value. It's technically | ||
915 | * a valid value, but linux doesn't like it... so when we can | ||
916 | * re-assign things, we do so, but if we can't, we keep it | ||
917 | * around and hope for the best... | ||
918 | */ | ||
919 | if (res->start == 0 && !(pci_flags & PCI_PROBE_ONLY)) { | ||
920 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \ | 854 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]" \ |
921 | "is unassigned\n", | 855 | "is unassigned\n", |
922 | pci_name(dev), i, | 856 | pci_name(dev), i, |
@@ -929,18 +863,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) | |||
929 | continue; | 863 | continue; |
930 | } | 864 | } |
931 | 865 | ||
932 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", | 866 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", |
933 | pci_name(dev), i, | 867 | pci_name(dev), i, |
934 | (unsigned long long)res->start,\ | 868 | (unsigned long long)res->start,\ |
935 | (unsigned long long)res->end, | 869 | (unsigned long long)res->end, |
936 | (unsigned int)res->flags); | 870 | (unsigned int)res->flags); |
937 | |||
938 | fixup_resource(res, dev); | ||
939 | |||
940 | pr_debug("PCI:%s %016llx-%016llx\n", | ||
941 | pci_name(dev), | ||
942 | (unsigned long long)res->start, | ||
943 | (unsigned long long)res->end); | ||
944 | } | 871 | } |
945 | } | 872 | } |
946 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); | 873 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources); |
@@ -959,10 +886,6 @@ static int __devinit pcibios_uninitialized_bridge_resource(struct pci_bus *bus, | |||
959 | u16 command; | 886 | u16 command; |
960 | int i; | 887 | int i; |
961 | 888 | ||
962 | /* We don't do anything if PCI_PROBE_ONLY is set */ | ||
963 | if (pci_flags & PCI_PROBE_ONLY) | ||
964 | return 0; | ||
965 | |||
966 | /* Job is a bit different between memory and IO */ | 889 | /* Job is a bit different between memory and IO */ |
967 | if (res->flags & IORESOURCE_MEM) { | 890 | if (res->flags & IORESOURCE_MEM) { |
968 | /* If the BAR is non-0 (res != pci_mem_offset) then it's | 891 | /* If the BAR is non-0 (res != pci_mem_offset) then it's |
@@ -1037,9 +960,6 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1037 | (unsigned long long)res->end, | 960 | (unsigned long long)res->end, |
1038 | (unsigned int)res->flags); | 961 | (unsigned int)res->flags); |
1039 | 962 | ||
1040 | /* Perform fixup */ | ||
1041 | fixup_resource(res, dev); | ||
1042 | |||
1043 | /* Try to detect uninitialized P2P bridge resources, | 963 | /* Try to detect uninitialized P2P bridge resources, |
1044 | * and clear them out so they get re-assigned later | 964 | * and clear them out so they get re-assigned later |
1045 | */ | 965 | */ |
@@ -1107,9 +1027,6 @@ EXPORT_SYMBOL(pcibios_fixup_bus); | |||
1107 | 1027 | ||
1108 | static int skip_isa_ioresource_align(struct pci_dev *dev) | 1028 | static int skip_isa_ioresource_align(struct pci_dev *dev) |
1109 | { | 1029 | { |
1110 | if ((pci_flags & PCI_CAN_SKIP_ISA_ALIGN) && | ||
1111 | !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA)) | ||
1112 | return 1; | ||
1113 | return 0; | 1030 | return 0; |
1114 | } | 1031 | } |
1115 | 1032 | ||
@@ -1236,8 +1153,6 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) | |||
1236 | * and as such ensure proper re-allocation | 1153 | * and as such ensure proper re-allocation |
1237 | * later. | 1154 | * later. |
1238 | */ | 1155 | */ |
1239 | if (pci_flags & PCI_REASSIGN_ALL_RSRC) | ||
1240 | goto clear_resource; | ||
1241 | pr = pci_find_parent_resource(bus->self, res); | 1156 | pr = pci_find_parent_resource(bus->self, res); |
1242 | if (pr == res) { | 1157 | if (pr == res) { |
1243 | /* this happens when the generic PCI | 1158 | /* this happens when the generic PCI |
@@ -1422,27 +1337,19 @@ void __init pcibios_resource_survey(void) | |||
1422 | list_for_each_entry(b, &pci_root_buses, node) | 1337 | list_for_each_entry(b, &pci_root_buses, node) |
1423 | pcibios_allocate_bus_resources(b); | 1338 | pcibios_allocate_bus_resources(b); |
1424 | 1339 | ||
1425 | if (!(pci_flags & PCI_REASSIGN_ALL_RSRC)) { | 1340 | pcibios_allocate_resources(0); |
1426 | pcibios_allocate_resources(0); | 1341 | pcibios_allocate_resources(1); |
1427 | pcibios_allocate_resources(1); | ||
1428 | } | ||
1429 | 1342 | ||
1430 | /* Before we start assigning unassigned resource, we try to reserve | 1343 | /* Before we start assigning unassigned resource, we try to reserve |
1431 | * the low IO area and the VGA memory area if they intersect the | 1344 | * the low IO area and the VGA memory area if they intersect the |
1432 | * bus available resources to avoid allocating things on top of them | 1345 | * bus available resources to avoid allocating things on top of them |
1433 | */ | 1346 | */ |
1434 | if (!(pci_flags & PCI_PROBE_ONLY)) { | 1347 | list_for_each_entry(b, &pci_root_buses, node) |
1435 | list_for_each_entry(b, &pci_root_buses, node) | 1348 | pcibios_reserve_legacy_regions(b); |
1436 | pcibios_reserve_legacy_regions(b); | ||
1437 | } | ||
1438 | 1349 | ||
1439 | /* Now, if the platform didn't decide to blindly trust the firmware, | 1350 | /* Now proceed to assigning things that were left unassigned */ |
1440 | * we proceed to assigning things that were left unassigned | 1351 | pr_debug("PCI: Assigning unassigned resources...\n"); |
1441 | */ | 1352 | pci_assign_unassigned_resources(); |
1442 | if (!(pci_flags & PCI_PROBE_ONLY)) { | ||
1443 | pr_debug("PCI: Assigning unassigned resources...\n"); | ||
1444 | pci_assign_unassigned_resources(); | ||
1445 | } | ||
1446 | } | 1353 | } |
1447 | 1354 | ||
1448 | #ifdef CONFIG_HOTPLUG | 1355 | #ifdef CONFIG_HOTPLUG |
@@ -1535,7 +1442,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s | |||
1535 | res->end = res->start + IO_SPACE_LIMIT; | 1442 | res->end = res->start + IO_SPACE_LIMIT; |
1536 | res->flags = IORESOURCE_IO; | 1443 | res->flags = IORESOURCE_IO; |
1537 | } | 1444 | } |
1538 | pci_add_resource(resources, res); | 1445 | pci_add_resource_offset(resources, res, hose->io_base_virt - _IO_BASE); |
1539 | 1446 | ||
1540 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", | 1447 | pr_debug("PCI: PHB IO resource = %016llx-%016llx [%lx]\n", |
1541 | (unsigned long long)res->start, | 1448 | (unsigned long long)res->start, |
@@ -1558,7 +1465,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s | |||
1558 | res->flags = IORESOURCE_MEM; | 1465 | res->flags = IORESOURCE_MEM; |
1559 | 1466 | ||
1560 | } | 1467 | } |
1561 | pci_add_resource(resources, res); | 1468 | pci_add_resource_offset(resources, res, hose->pci_mem_offset); |
1562 | 1469 | ||
1563 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", | 1470 | pr_debug("PCI: PHB MEM resource %d = %016llx-%016llx [%lx]\n", |
1564 | i, (unsigned long long)res->start, | 1471 | i, (unsigned long long)res->start, |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index 576397c69920..fcd4060f6421 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -92,6 +92,7 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
92 | #include <asm/scatterlist.h> | 92 | #include <asm/scatterlist.h> |
93 | #include <linux/string.h> | 93 | #include <linux/string.h> |
94 | #include <asm/io.h> | 94 | #include <asm/io.h> |
95 | #include <asm-generic/pci-bridge.h> | ||
95 | 96 | ||
96 | struct pci_dev; | 97 | struct pci_dev; |
97 | 98 | ||
@@ -112,12 +113,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
112 | } | 113 | } |
113 | #endif | 114 | #endif |
114 | 115 | ||
115 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
116 | struct pci_bus_region *region, struct resource *res); | ||
117 | |||
118 | extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
119 | struct pci_bus_region *region); | ||
120 | |||
121 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index | 116 | #define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index |
122 | 117 | ||
123 | static inline int pci_proc_domain(struct pci_bus *bus) | 118 | static inline int pci_proc_domain(struct pci_bus *bus) |
@@ -145,8 +140,6 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
145 | #define arch_setup_msi_irqs arch_setup_msi_irqs | 140 | #define arch_setup_msi_irqs arch_setup_msi_irqs |
146 | #endif | 141 | #endif |
147 | 142 | ||
148 | extern int pci_probe_only; | ||
149 | |||
150 | extern char * (*pcibios_plat_setup)(char *str); | 143 | extern char * (*pcibios_plat_setup)(char *str); |
151 | 144 | ||
152 | #endif /* _ASM_PCI_H */ | 145 | #endif /* _ASM_PCI_H */ |
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c index acacd1407c63..9553b14002dd 100644 --- a/arch/mips/pci/fixup-cobalt.c +++ b/arch/mips/pci/fixup-cobalt.c | |||
@@ -51,67 +51,6 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev) | |||
51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, | 51 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111, |
52 | qube_raq_galileo_early_fixup); | 52 | qube_raq_galileo_early_fixup); |
53 | 53 | ||
54 | static void __devinit cobalt_legacy_ide_resource_fixup(struct pci_dev *dev, | ||
55 | struct resource *res) | ||
56 | { | ||
57 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
58 | unsigned long offset = hose->io_offset; | ||
59 | struct resource orig = *res; | ||
60 | |||
61 | if (!(res->flags & IORESOURCE_IO) || | ||
62 | !(res->flags & IORESOURCE_PCI_FIXED)) | ||
63 | return; | ||
64 | |||
65 | res->start -= offset; | ||
66 | res->end -= offset; | ||
67 | dev_printk(KERN_DEBUG, &dev->dev, "converted legacy %pR to bus %pR\n", | ||
68 | &orig, res); | ||
69 | } | ||
70 | |||
71 | static void __devinit cobalt_legacy_ide_fixup(struct pci_dev *dev) | ||
72 | { | ||
73 | u32 class; | ||
74 | u8 progif; | ||
75 | |||
76 | /* | ||
77 | * If the IDE controller is in legacy mode, pci_setup_device() fills in | ||
78 | * the resources with the legacy addresses that normally appear on the | ||
79 | * PCI bus, just as if we had read them from a BAR. | ||
80 | * | ||
81 | * However, with the GT-64111, those legacy addresses, e.g., 0x1f0, | ||
82 | * will never appear on the PCI bus because it converts memory accesses | ||
83 | * in the PCI I/O region (which is never at address zero) into I/O port | ||
84 | * accesses with no address translation. | ||
85 | * | ||
86 | * For example, if GT_DEF_PCI0_IO_BASE is 0x10000000, a load or store | ||
87 | * to physical address 0x100001f0 will become a PCI access to I/O port | ||
88 | * 0x100001f0. There's no way to generate an access to I/O port 0x1f0, | ||
89 | * but the VT82C586 IDE controller does respond at 0x100001f0 because | ||
90 | * it only decodes the low 24 bits of the address. | ||
91 | * | ||
92 | * When this quirk runs, the pci_dev resources should contain bus | ||
93 | * addresses, not Linux I/O port numbers, so convert legacy addresses | ||
94 | * like 0x1f0 to bus addresses like 0x100001f0. Later, we'll convert | ||
95 | * them back with pcibios_fixup_bus() or pcibios_bus_to_resource(). | ||
96 | */ | ||
97 | class = dev->class >> 8; | ||
98 | if (class != PCI_CLASS_STORAGE_IDE) | ||
99 | return; | ||
100 | |||
101 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | ||
102 | if ((progif & 1) == 0) { | ||
103 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[0]); | ||
104 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[1]); | ||
105 | } | ||
106 | if ((progif & 4) == 0) { | ||
107 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[2]); | ||
108 | cobalt_legacy_ide_resource_fixup(dev, &dev->resource[3]); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, | ||
113 | cobalt_legacy_ide_fixup); | ||
114 | |||
115 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) | 54 | static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev) |
116 | { | 55 | { |
117 | unsigned short cfgword; | 56 | unsigned short cfgword; |
diff --git a/arch/mips/pci/pci-bcm1480.c b/arch/mips/pci/pci-bcm1480.c index af8c31996965..37b52dc3d27e 100644 --- a/arch/mips/pci/pci-bcm1480.c +++ b/arch/mips/pci/pci-bcm1480.c | |||
@@ -204,7 +204,7 @@ static int __init bcm1480_pcibios_init(void) | |||
204 | uint64_t reg; | 204 | uint64_t reg; |
205 | 205 | ||
206 | /* CFE will assign PCI resources */ | 206 | /* CFE will assign PCI resources */ |
207 | pci_probe_only = 1; | 207 | pci_set_flags(PCI_PROBE_ONLY); |
208 | 208 | ||
209 | /* Avoid ISA compat ranges. */ | 209 | /* Avoid ISA compat ranges. */ |
210 | PCIBIOS_MIN_IO = 0x00008000UL; | 210 | PCIBIOS_MIN_IO = 0x00008000UL; |
diff --git a/arch/mips/pci/pci-ip27.c b/arch/mips/pci/pci-ip27.c index 193e9494f98e..0fbe4c0c170a 100644 --- a/arch/mips/pci/pci-ip27.c +++ b/arch/mips/pci/pci-ip27.c | |||
@@ -50,7 +50,7 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid) | |||
50 | bridge_t *bridge; | 50 | bridge_t *bridge; |
51 | int slot; | 51 | int slot; |
52 | 52 | ||
53 | pci_probe_only = 1; | 53 | pci_set_flags(PCI_PROBE_ONLY); |
54 | 54 | ||
55 | printk("a bridge\n"); | 55 | printk("a bridge\n"); |
56 | 56 | ||
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index be1e1afe12c3..030c77e7926e 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c | |||
@@ -270,7 +270,8 @@ static int __devinit ltq_pci_probe(struct platform_device *pdev) | |||
270 | { | 270 | { |
271 | struct ltq_pci_data *ltq_pci_data = | 271 | struct ltq_pci_data *ltq_pci_data = |
272 | (struct ltq_pci_data *) pdev->dev.platform_data; | 272 | (struct ltq_pci_data *) pdev->dev.platform_data; |
273 | pci_probe_only = 0; | 273 | |
274 | pci_clear_flags(PCI_PROBE_ONLY); | ||
274 | ltq_pci_irq_map = ltq_pci_data->irq; | 275 | ltq_pci_irq_map = ltq_pci_data->irq; |
275 | ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE); | 276 | ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE); |
276 | ltq_pci_mapped_cfg = | 277 | ltq_pci_mapped_cfg = |
diff --git a/arch/mips/pci/pci-sb1250.c b/arch/mips/pci/pci-sb1250.c index 1711e8e101bc..dd97f3a83baa 100644 --- a/arch/mips/pci/pci-sb1250.c +++ b/arch/mips/pci/pci-sb1250.c | |||
@@ -213,7 +213,7 @@ static int __init sb1250_pcibios_init(void) | |||
213 | uint64_t reg; | 213 | uint64_t reg; |
214 | 214 | ||
215 | /* CFE will assign PCI resources */ | 215 | /* CFE will assign PCI resources */ |
216 | pci_probe_only = 1; | 216 | pci_set_flags(PCI_PROBE_ONLY); |
217 | 217 | ||
218 | /* Avoid ISA compat ranges. */ | 218 | /* Avoid ISA compat ranges. */ |
219 | PCIBIOS_MIN_IO = 0x00008000UL; | 219 | PCIBIOS_MIN_IO = 0x00008000UL; |
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c index 3d701a962ef4..1644805a6730 100644 --- a/arch/mips/pci/pci-xlr.c +++ b/arch/mips/pci/pci-xlr.c | |||
@@ -292,7 +292,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev) | |||
292 | static int __init pcibios_init(void) | 292 | static int __init pcibios_init(void) |
293 | { | 293 | { |
294 | /* PSB assigns PCI resources */ | 294 | /* PSB assigns PCI resources */ |
295 | pci_probe_only = 1; | 295 | pci_set_flags(PCI_PROBE_ONLY); |
296 | pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); | 296 | pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20); |
297 | 297 | ||
298 | /* Extend IO port for memory mapped io */ | 298 | /* Extend IO port for memory mapped io */ |
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 15521505ebe8..0514866fa925 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -20,16 +20,9 @@ | |||
20 | #include <asm/cpu-info.h> | 20 | #include <asm/cpu-info.h> |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * Indicate whether we respect the PCI setup left by the firmware. | 23 | * If PCI_PROBE_ONLY in pci_flags is set, we don't change any PCI resource |
24 | * | 24 | * assignments. |
25 | * Make this long-lived so that we know when shutting down | ||
26 | * whether we probed only or not. | ||
27 | */ | 25 | */ |
28 | int pci_probe_only; | ||
29 | |||
30 | #define PCI_ASSIGN_ALL_BUSSES 1 | ||
31 | |||
32 | unsigned int pci_probe = PCI_ASSIGN_ALL_BUSSES; | ||
33 | 26 | ||
34 | /* | 27 | /* |
35 | * The PCI controller list. | 28 | * The PCI controller list. |
@@ -92,11 +85,12 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) | |||
92 | if (!hose->iommu) | 85 | if (!hose->iommu) |
93 | PCI_DMA_BUS_IS_PHYS = 1; | 86 | PCI_DMA_BUS_IS_PHYS = 1; |
94 | 87 | ||
95 | if (hose->get_busno && pci_probe_only) | 88 | if (hose->get_busno && pci_has_flag(PCI_PROBE_ONLY)) |
96 | next_busno = (*hose->get_busno)(); | 89 | next_busno = (*hose->get_busno)(); |
97 | 90 | ||
98 | pci_add_resource(&resources, hose->mem_resource); | 91 | pci_add_resource_offset(&resources, |
99 | pci_add_resource(&resources, hose->io_resource); | 92 | hose->mem_resource, hose->mem_offset); |
93 | pci_add_resource_offset(&resources, hose->io_resource, hose->io_offset); | ||
100 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | 94 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, |
101 | &resources); | 95 | &resources); |
102 | if (!bus) | 96 | if (!bus) |
@@ -115,7 +109,7 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) | |||
115 | need_domain_info = 1; | 109 | need_domain_info = 1; |
116 | } | 110 | } |
117 | 111 | ||
118 | if (!pci_probe_only) { | 112 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
119 | pci_bus_size_bridges(bus); | 113 | pci_bus_size_bridges(bus); |
120 | pci_bus_assign_resources(bus); | 114 | pci_bus_assign_resources(bus); |
121 | pci_enable_bridges(bus); | 115 | pci_enable_bridges(bus); |
@@ -241,7 +235,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask) | |||
241 | 235 | ||
242 | unsigned int pcibios_assign_all_busses(void) | 236 | unsigned int pcibios_assign_all_busses(void) |
243 | { | 237 | { |
244 | return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0; | 238 | return 1; |
245 | } | 239 | } |
246 | 240 | ||
247 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 241 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
@@ -254,42 +248,13 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
254 | return pcibios_plat_dev_init(dev); | 248 | return pcibios_plat_dev_init(dev); |
255 | } | 249 | } |
256 | 250 | ||
257 | static void pcibios_fixup_device_resources(struct pci_dev *dev, | ||
258 | struct pci_bus *bus) | ||
259 | { | ||
260 | /* Update device resources. */ | ||
261 | struct pci_controller *hose = (struct pci_controller *)bus->sysdata; | ||
262 | unsigned long offset = 0; | ||
263 | int i; | ||
264 | |||
265 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
266 | if (!dev->resource[i].start) | ||
267 | continue; | ||
268 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
269 | offset = hose->io_offset; | ||
270 | else if (dev->resource[i].flags & IORESOURCE_MEM) | ||
271 | offset = hose->mem_offset; | ||
272 | |||
273 | dev->resource[i].start += offset; | ||
274 | dev->resource[i].end += offset; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 251 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
279 | { | 252 | { |
280 | /* Propagate hose info into the subordinate devices. */ | ||
281 | |||
282 | struct pci_dev *dev = bus->self; | 253 | struct pci_dev *dev = bus->self; |
283 | 254 | ||
284 | if (pci_probe_only && dev && | 255 | if (pci_has_flag(PCI_PROBE_ONLY) && dev && |
285 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | 256 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { |
286 | pci_read_bridge_bases(bus); | 257 | pci_read_bridge_bases(bus); |
287 | pcibios_fixup_device_resources(dev, bus); | ||
288 | } | ||
289 | |||
290 | list_for_each_entry(dev, &bus->devices, bus_list) { | ||
291 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
292 | pcibios_fixup_device_resources(dev, bus); | ||
293 | } | 258 | } |
294 | } | 259 | } |
295 | 260 | ||
@@ -299,40 +264,7 @@ pcibios_update_irq(struct pci_dev *dev, int irq) | |||
299 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); | 264 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); |
300 | } | 265 | } |
301 | 266 | ||
302 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
303 | struct resource *res) | ||
304 | { | ||
305 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
306 | unsigned long offset = 0; | ||
307 | |||
308 | if (res->flags & IORESOURCE_IO) | ||
309 | offset = hose->io_offset; | ||
310 | else if (res->flags & IORESOURCE_MEM) | ||
311 | offset = hose->mem_offset; | ||
312 | |||
313 | region->start = res->start - offset; | ||
314 | region->end = res->end - offset; | ||
315 | } | ||
316 | |||
317 | void __devinit | ||
318 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
319 | struct pci_bus_region *region) | ||
320 | { | ||
321 | struct pci_controller *hose = (struct pci_controller *)dev->sysdata; | ||
322 | unsigned long offset = 0; | ||
323 | |||
324 | if (res->flags & IORESOURCE_IO) | ||
325 | offset = hose->io_offset; | ||
326 | else if (res->flags & IORESOURCE_MEM) | ||
327 | offset = hose->mem_offset; | ||
328 | |||
329 | res->start = region->start + offset; | ||
330 | res->end = region->end + offset; | ||
331 | } | ||
332 | |||
333 | #ifdef CONFIG_HOTPLUG | 267 | #ifdef CONFIG_HOTPLUG |
334 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
335 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
336 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | 268 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
337 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | 269 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); |
338 | #endif | 270 | #endif |
diff --git a/arch/mn10300/include/asm/pci.h b/arch/mn10300/include/asm/pci.h index 6095a28561dd..8137c25c4e15 100644 --- a/arch/mn10300/include/asm/pci.h +++ b/arch/mn10300/include/asm/pci.h | |||
@@ -85,22 +85,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
85 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ | 85 | /* implement the pci_ DMA API in terms of the generic device dma_ one */ |
86 | #include <asm-generic/pci-dma-compat.h> | 86 | #include <asm-generic/pci-dma-compat.h> |
87 | 87 | ||
88 | /** | ||
89 | * pcibios_resource_to_bus - convert resource to PCI bus address | ||
90 | * @dev: device which owns this resource | ||
91 | * @region: converted bus-centric region (start,end) | ||
92 | * @res: resource to convert | ||
93 | * | ||
94 | * Convert a resource to a PCI device bus address or bus window. | ||
95 | */ | ||
96 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
97 | struct pci_bus_region *region, | ||
98 | struct resource *res); | ||
99 | |||
100 | extern void pcibios_bus_to_resource(struct pci_dev *dev, | ||
101 | struct resource *res, | ||
102 | struct pci_bus_region *region); | ||
103 | |||
104 | static inline struct resource * | 88 | static inline struct resource * |
105 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) | 89 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) |
106 | { | 90 | { |
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index a7c5f08ca9f5..6dce9fc2cf3c 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c | |||
@@ -32,8 +32,7 @@ struct pci_ops *pci_root_ops; | |||
32 | * insert specific PCI bus resources instead of using the platform-level bus | 32 | * insert specific PCI bus resources instead of using the platform-level bus |
33 | * resources directly for the PCI root bus. | 33 | * resources directly for the PCI root bus. |
34 | * | 34 | * |
35 | * These are configured and inserted by pcibios_init() and are attached to the | 35 | * These are configured and inserted by pcibios_init(). |
36 | * root bus by pcibios_fixup_bus(). | ||
37 | */ | 36 | */ |
38 | static struct resource pci_ioport_resource = { | 37 | static struct resource pci_ioport_resource = { |
39 | .name = "PCI IO", | 38 | .name = "PCI IO", |
@@ -78,52 +77,6 @@ static inline int __query(const struct pci_bus *bus, unsigned int devfn) | |||
78 | } | 77 | } |
79 | 78 | ||
80 | /* | 79 | /* |
81 | * translate Linuxcentric addresses to PCI bus addresses | ||
82 | */ | ||
83 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
84 | struct resource *res) | ||
85 | { | ||
86 | if (res->flags & IORESOURCE_IO) { | ||
87 | region->start = (res->start & 0x00ffffff); | ||
88 | region->end = (res->end & 0x00ffffff); | ||
89 | } | ||
90 | |||
91 | if (res->flags & IORESOURCE_MEM) { | ||
92 | region->start = (res->start & 0x03ffffff) | MEM_PAGING_REG; | ||
93 | region->end = (res->end & 0x03ffffff) | MEM_PAGING_REG; | ||
94 | } | ||
95 | |||
96 | #if 0 | ||
97 | printk(KERN_DEBUG "RES->BUS: %lx-%lx => %lx-%lx\n", | ||
98 | res->start, res->end, region->start, region->end); | ||
99 | #endif | ||
100 | } | ||
101 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
102 | |||
103 | /* | ||
104 | * translate PCI bus addresses to Linuxcentric addresses | ||
105 | */ | ||
106 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
107 | struct pci_bus_region *region) | ||
108 | { | ||
109 | if (res->flags & IORESOURCE_IO) { | ||
110 | res->start = (region->start & 0x00ffffff) | 0xbe000000; | ||
111 | res->end = (region->end & 0x00ffffff) | 0xbe000000; | ||
112 | } | ||
113 | |||
114 | if (res->flags & IORESOURCE_MEM) { | ||
115 | res->start = (region->start & 0x03ffffff) | 0xb8000000; | ||
116 | res->end = (region->end & 0x03ffffff) | 0xb8000000; | ||
117 | } | ||
118 | |||
119 | #if 0 | ||
120 | printk(KERN_INFO "BUS->RES: %lx-%lx => %lx-%lx\n", | ||
121 | region->start, region->end, res->start, res->end); | ||
122 | #endif | ||
123 | } | ||
124 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
125 | |||
126 | /* | ||
127 | * | 80 | * |
128 | */ | 81 | */ |
129 | static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn, | 82 | static int pci_ampci_read_config_byte(struct pci_bus *bus, unsigned int devfn, |
@@ -364,9 +317,6 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) | |||
364 | if (!dev->resource[i].flags) | 317 | if (!dev->resource[i].flags) |
365 | continue; | 318 | continue; |
366 | 319 | ||
367 | region.start = dev->resource[i].start; | ||
368 | region.end = dev->resource[i].end; | ||
369 | pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); | ||
370 | if (is_valid_resource(dev, i)) | 320 | if (is_valid_resource(dev, i)) |
371 | pci_claim_resource(dev, i); | 321 | pci_claim_resource(dev, i); |
372 | } | 322 | } |
@@ -397,6 +347,7 @@ void __devinit pcibios_fixup_bus(struct pci_bus *bus) | |||
397 | */ | 347 | */ |
398 | static int __init pcibios_init(void) | 348 | static int __init pcibios_init(void) |
399 | { | 349 | { |
350 | resource_size_t io_offset, mem_offset; | ||
400 | LIST_HEAD(resources); | 351 | LIST_HEAD(resources); |
401 | 352 | ||
402 | ioport_resource.start = 0xA0000000; | 353 | ioport_resource.start = 0xA0000000; |
@@ -420,8 +371,13 @@ static int __init pcibios_init(void) | |||
420 | printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n", | 371 | printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n", |
421 | MEM_PAGING_REG); | 372 | MEM_PAGING_REG); |
422 | 373 | ||
423 | pci_add_resource(&resources, &pci_ioport_resource); | 374 | io_offset = pci_ioport_resource.start - |
424 | pci_add_resource(&resources, &pci_iomem_resource); | 375 | (pci_ioport_resource.start & 0x00ffffff); |
376 | mem_offset = pci_iomem_resource.start - | ||
377 | ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG); | ||
378 | |||
379 | pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset); | ||
380 | pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset); | ||
425 | pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, | 381 | pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, |
426 | &resources); | 382 | &resources); |
427 | 383 | ||
diff --git a/arch/parisc/include/asm/pci.h b/arch/parisc/include/asm/pci.h index 2242a5c636c2..3234f492d575 100644 --- a/arch/parisc/include/asm/pci.h +++ b/arch/parisc/include/asm/pci.h | |||
@@ -82,38 +82,8 @@ struct pci_hba_data { | |||
82 | 82 | ||
83 | #ifdef CONFIG_64BIT | 83 | #ifdef CONFIG_64BIT |
84 | #define PCI_F_EXTEND 0xffffffff00000000UL | 84 | #define PCI_F_EXTEND 0xffffffff00000000UL |
85 | #define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) | ||
86 | |||
87 | /* We need to know if an address is LMMMIO or GMMIO. | ||
88 | * LMMIO requires mangling and GMMIO we must use as-is. | ||
89 | */ | ||
90 | static __inline__ int pci_is_lmmio(struct pci_hba_data *hba, unsigned long a) | ||
91 | { | ||
92 | return(((a) & PCI_F_EXTEND) == PCI_F_EXTEND); | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | ** Convert between PCI (IO_VIEW) addresses and processor (PA_VIEW) addresses. | ||
97 | ** See pci.c for more conversions used by Generic PCI code. | ||
98 | ** | ||
99 | ** Platform characteristics/firmware guarantee that | ||
100 | ** (1) PA_VIEW - IO_VIEW = lmmio_offset for both LMMIO and ELMMIO | ||
101 | ** (2) PA_VIEW == IO_VIEW for GMMIO | ||
102 | */ | ||
103 | #define PCI_BUS_ADDR(hba,a) (PCI_IS_LMMIO(hba,a) \ | ||
104 | ? ((a) - hba->lmmio_space_offset) /* mangle LMMIO */ \ | ||
105 | : (a)) /* GMMIO */ | ||
106 | #define PCI_HOST_ADDR(hba,a) (((a) & PCI_F_EXTEND) == 0 \ | ||
107 | ? (a) + hba->lmmio_space_offset \ | ||
108 | : (a)) | ||
109 | |||
110 | #else /* !CONFIG_64BIT */ | 85 | #else /* !CONFIG_64BIT */ |
111 | |||
112 | #define PCI_BUS_ADDR(hba,a) (a) | ||
113 | #define PCI_HOST_ADDR(hba,a) (a) | ||
114 | #define PCI_F_EXTEND 0UL | 86 | #define PCI_F_EXTEND 0UL |
115 | #define PCI_IS_LMMIO(hba,a) (1) /* 32-bit doesn't support GMMIO */ | ||
116 | |||
117 | #endif /* !CONFIG_64BIT */ | 87 | #endif /* !CONFIG_64BIT */ |
118 | 88 | ||
119 | /* | 89 | /* |
@@ -245,14 +215,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
245 | } | 215 | } |
246 | #endif | 216 | #endif |
247 | 217 | ||
248 | extern void | ||
249 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
250 | struct resource *res); | ||
251 | |||
252 | extern void | ||
253 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
254 | struct pci_bus_region *region); | ||
255 | |||
256 | static inline void pcibios_penalize_isa_irq(int irq, int active) | 218 | static inline void pcibios_penalize_isa_irq(int irq, int active) |
257 | { | 219 | { |
258 | /* We don't need to penalize isa irq's */ | 220 | /* We don't need to penalize isa irq's */ |
diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index 9efd97405317..74d544b1cd22 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c | |||
@@ -195,58 +195,6 @@ void __init pcibios_init_bus(struct pci_bus *bus) | |||
195 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); | 195 | pci_write_config_word(dev, PCI_BRIDGE_CONTROL, bridge_ctl); |
196 | } | 196 | } |
197 | 197 | ||
198 | /* called by drivers/pci/setup-bus.c:pci_setup_bridge(). */ | ||
199 | void __devinit pcibios_resource_to_bus(struct pci_dev *dev, | ||
200 | struct pci_bus_region *region, struct resource *res) | ||
201 | { | ||
202 | #ifdef CONFIG_64BIT | ||
203 | struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); | ||
204 | #endif | ||
205 | |||
206 | if (res->flags & IORESOURCE_IO) { | ||
207 | /* | ||
208 | ** I/O space may see busnumbers here. Something | ||
209 | ** in the form of 0xbbxxxx where bb is the bus num | ||
210 | ** and xxxx is the I/O port space address. | ||
211 | ** Remaining address translation are done in the | ||
212 | ** PCI Host adapter specific code - ie dino_out8. | ||
213 | */ | ||
214 | region->start = PCI_PORT_ADDR(res->start); | ||
215 | region->end = PCI_PORT_ADDR(res->end); | ||
216 | } else if (res->flags & IORESOURCE_MEM) { | ||
217 | /* Convert MMIO addr to PCI addr (undo global virtualization) */ | ||
218 | region->start = PCI_BUS_ADDR(hba, res->start); | ||
219 | region->end = PCI_BUS_ADDR(hba, res->end); | ||
220 | } | ||
221 | |||
222 | DBG_RES("pcibios_resource_to_bus(%02x %s [%lx,%lx])\n", | ||
223 | dev->bus->number, res->flags & IORESOURCE_IO ? "IO" : "MEM", | ||
224 | region->start, region->end); | ||
225 | } | ||
226 | |||
227 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
228 | struct pci_bus_region *region) | ||
229 | { | ||
230 | #ifdef CONFIG_64BIT | ||
231 | struct pci_hba_data *hba = HBA_DATA(dev->bus->bridge->platform_data); | ||
232 | #endif | ||
233 | |||
234 | if (res->flags & IORESOURCE_MEM) { | ||
235 | res->start = PCI_HOST_ADDR(hba, region->start); | ||
236 | res->end = PCI_HOST_ADDR(hba, region->end); | ||
237 | } | ||
238 | |||
239 | if (res->flags & IORESOURCE_IO) { | ||
240 | res->start = region->start; | ||
241 | res->end = region->end; | ||
242 | } | ||
243 | } | ||
244 | |||
245 | #ifdef CONFIG_HOTPLUG | ||
246 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
247 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
248 | #endif | ||
249 | |||
250 | /* | 198 | /* |
251 | * pcibios align resources() is called every time generic PCI code | 199 | * pcibios align resources() is called every time generic PCI code |
252 | * wants to generate a new address. The process of looking for | 200 | * wants to generate a new address. The process of looking for |
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h index f54b3d26ce9d..6653f2743c4e 100644 --- a/arch/powerpc/include/asm/pci.h +++ b/arch/powerpc/include/asm/pci.h | |||
@@ -154,14 +154,6 @@ extern int pci_mmap_legacy_page_range(struct pci_bus *bus, | |||
154 | 154 | ||
155 | #endif /* CONFIG_PPC64 */ | 155 | #endif /* CONFIG_PPC64 */ |
156 | 156 | ||
157 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
158 | struct pci_bus_region *region, | ||
159 | struct resource *res); | ||
160 | |||
161 | extern void pcibios_bus_to_resource(struct pci_dev *dev, | ||
162 | struct resource *res, | ||
163 | struct pci_bus_region *region); | ||
164 | |||
165 | extern void pcibios_claim_one_bus(struct pci_bus *b); | 157 | extern void pcibios_claim_one_bus(struct pci_bus *b); |
166 | 158 | ||
167 | extern void pcibios_finish_adding_to_bus(struct pci_bus *bus); | 159 | extern void pcibios_finish_adding_to_bus(struct pci_bus *bus); |
@@ -190,6 +182,7 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
190 | const struct resource *rsrc, | 182 | const struct resource *rsrc, |
191 | resource_size_t *start, resource_size_t *end); | 183 | resource_size_t *start, resource_size_t *end); |
192 | 184 | ||
185 | extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose); | ||
193 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); | 186 | extern void pcibios_setup_bus_devices(struct pci_bus *bus); |
194 | extern void pcibios_setup_bus_self(struct pci_bus *bus); | 187 | extern void pcibios_setup_bus_self(struct pci_bus *bus); |
195 | extern void pcibios_setup_phb_io_space(struct pci_controller *hose); | 188 | extern void pcibios_setup_phb_io_space(struct pci_controller *hose); |
diff --git a/arch/powerpc/include/asm/ppc-pci.h b/arch/powerpc/include/asm/ppc-pci.h index e660b37aa7d0..80fa704d410f 100644 --- a/arch/powerpc/include/asm/ppc-pci.h +++ b/arch/powerpc/include/asm/ppc-pci.h | |||
@@ -45,8 +45,6 @@ extern void init_pci_config_tokens (void); | |||
45 | extern unsigned long get_phb_buid (struct device_node *); | 45 | extern unsigned long get_phb_buid (struct device_node *); |
46 | extern int rtas_setup_phb(struct pci_controller *phb); | 46 | extern int rtas_setup_phb(struct pci_controller *phb); |
47 | 47 | ||
48 | extern unsigned long pci_probe_only; | ||
49 | |||
50 | #ifdef CONFIG_EEH | 48 | #ifdef CONFIG_EEH |
51 | 49 | ||
52 | void pci_addr_cache_build(void); | 50 | void pci_addr_cache_build(void); |
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index d0373bcb7c9d..8e78e93c8185 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c | |||
@@ -49,9 +49,6 @@ static int global_phb_number; /* Global phb counter */ | |||
49 | /* ISA Memory physical address */ | 49 | /* ISA Memory physical address */ |
50 | resource_size_t isa_mem_base; | 50 | resource_size_t isa_mem_base; |
51 | 51 | ||
52 | /* Default PCI flags is 0 on ppc32, modified at boot on ppc64 */ | ||
53 | unsigned int pci_flags = 0; | ||
54 | |||
55 | 52 | ||
56 | static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; | 53 | static struct dma_map_ops *pci_dma_ops = &dma_direct_ops; |
57 | 54 | ||
@@ -834,60 +831,6 @@ int pci_proc_domain(struct pci_bus *bus) | |||
834 | return 1; | 831 | return 1; |
835 | } | 832 | } |
836 | 833 | ||
837 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
838 | struct resource *res) | ||
839 | { | ||
840 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
841 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
842 | |||
843 | if (!hose) | ||
844 | return; | ||
845 | if (res->flags & IORESOURCE_IO) { | ||
846 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
847 | mask = 0xffffffffu; | ||
848 | } else if (res->flags & IORESOURCE_MEM) | ||
849 | offset = hose->pci_mem_offset; | ||
850 | |||
851 | region->start = (res->start - offset) & mask; | ||
852 | region->end = (res->end - offset) & mask; | ||
853 | } | ||
854 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
855 | |||
856 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
857 | struct pci_bus_region *region) | ||
858 | { | ||
859 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
860 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
861 | |||
862 | if (!hose) | ||
863 | return; | ||
864 | if (res->flags & IORESOURCE_IO) { | ||
865 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
866 | mask = 0xffffffffu; | ||
867 | } else if (res->flags & IORESOURCE_MEM) | ||
868 | offset = hose->pci_mem_offset; | ||
869 | res->start = (region->start + offset) & mask; | ||
870 | res->end = (region->end + offset) & mask; | ||
871 | } | ||
872 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
873 | |||
874 | /* Fixup a bus resource into a linux resource */ | ||
875 | static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev) | ||
876 | { | ||
877 | struct pci_controller *hose = pci_bus_to_host(dev->bus); | ||
878 | resource_size_t offset = 0, mask = (resource_size_t)-1; | ||
879 | |||
880 | if (res->flags & IORESOURCE_IO) { | ||
881 | offset = (unsigned long)hose->io_base_virt - _IO_BASE; | ||
882 | mask = 0xffffffffu; | ||
883 | } else if (res->flags & IORESOURCE_MEM) | ||
884 | offset = hose->pci_mem_offset; | ||
885 | |||
886 | res->start = (res->start + offset) & mask; | ||
887 | res->end = (res->end + offset) & mask; | ||
888 | } | ||
889 | |||
890 | |||
891 | /* This header fixup will do the resource fixup for all devices as they are | 834 | /* This header fixup will do the resource fixup for all devices as they are |
892 | * probed, but not for bridge ranges | 835 | * probed, but not for bridge ranges |
893 | */ | 836 | */ |
@@ -927,18 +870,11 @@ static void __devinit pcibios_fixup_resources(struct pci_dev *dev) | |||
927 | continue; | 870 | continue; |
928 | } | 871 | } |
929 | 872 | ||
930 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n", | 873 | pr_debug("PCI:%s Resource %d %016llx-%016llx [%x]\n", |
931 | pci_name(dev), i, | 874 | pci_name(dev), i, |
932 | (unsigned long long)res->start,\ | 875 | (unsigned long long)res->start,\ |
933 | (unsigned long long)res->end, | 876 | (unsigned long long)res->end, |
934 | (unsigned int)res->flags); | 877 | (unsigned int)res->flags); |
935 | |||
936 | fixup_resource(res, dev); | ||
937 | |||
938 | pr_debug("PCI:%s %016llx-%016llx\n", | ||
939 | pci_name(dev), | ||
940 | (unsigned long long)res->start, | ||
941 | (unsigned long long)res->end); | ||
942 | } | 878 | } |
943 | 879 | ||
944 | /* Call machine specific resource fixup */ | 880 | /* Call machine specific resource fixup */ |
@@ -1040,27 +976,18 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) | |||
1040 | continue; | 976 | continue; |
1041 | } | 977 | } |
1042 | 978 | ||
1043 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n", | 979 | pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x]\n", |
1044 | pci_name(dev), i, | 980 | pci_name(dev), i, |
1045 | (unsigned long long)res->start,\ | 981 | (unsigned long long)res->start,\ |
1046 | (unsigned long long)res->end, | 982 | (unsigned long long)res->end, |
1047 | (unsigned int)res->flags); | 983 | (unsigned int)res->flags); |
1048 | 984 | ||
1049 | /* Perform fixup */ | ||
1050 | fixup_resource(res, dev); | ||
1051 | |||
1052 | /* Try to detect uninitialized P2P bridge resources, | 985 | /* Try to detect uninitialized P2P bridge resources, |
1053 | * and clear them out so they get re-assigned later | 986 | * and clear them out so they get re-assigned later |
1054 | */ | 987 | */ |
1055 | if (pcibios_uninitialized_bridge_resource(bus, res)) { | 988 | if (pcibios_uninitialized_bridge_resource(bus, res)) { |
1056 | res->flags = 0; | 989 | res->flags = 0; |
1057 | pr_debug("PCI:%s (unassigned)\n", pci_name(dev)); | 990 | pr_debug("PCI:%s (unassigned)\n", pci_name(dev)); |
1058 | } else { | ||
1059 | |||
1060 | pr_debug("PCI:%s %016llx-%016llx\n", | ||
1061 | pci_name(dev), | ||
1062 | (unsigned long long)res->start, | ||
1063 | (unsigned long long)res->end); | ||
1064 | } | 991 | } |
1065 | } | 992 | } |
1066 | } | 993 | } |
@@ -1550,6 +1477,11 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
1550 | return pci_enable_resources(dev, mask); | 1477 | return pci_enable_resources(dev, mask); |
1551 | } | 1478 | } |
1552 | 1479 | ||
1480 | resource_size_t pcibios_io_space_offset(struct pci_controller *hose) | ||
1481 | { | ||
1482 | return (unsigned long) hose->io_base_virt - _IO_BASE; | ||
1483 | } | ||
1484 | |||
1553 | static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources) | 1485 | static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, struct list_head *resources) |
1554 | { | 1486 | { |
1555 | struct resource *res; | 1487 | struct resource *res; |
@@ -1574,7 +1506,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s | |||
1574 | (unsigned long long)res->start, | 1506 | (unsigned long long)res->start, |
1575 | (unsigned long long)res->end, | 1507 | (unsigned long long)res->end, |
1576 | (unsigned long)res->flags); | 1508 | (unsigned long)res->flags); |
1577 | pci_add_resource(resources, res); | 1509 | pci_add_resource_offset(resources, res, pcibios_io_space_offset(hose)); |
1578 | 1510 | ||
1579 | /* Hookup PHB Memory resources */ | 1511 | /* Hookup PHB Memory resources */ |
1580 | for (i = 0; i < 3; ++i) { | 1512 | for (i = 0; i < 3; ++i) { |
@@ -1597,7 +1529,7 @@ static void __devinit pcibios_setup_phb_resources(struct pci_controller *hose, s | |||
1597 | (unsigned long long)res->start, | 1529 | (unsigned long long)res->start, |
1598 | (unsigned long long)res->end, | 1530 | (unsigned long long)res->end, |
1599 | (unsigned long)res->flags); | 1531 | (unsigned long)res->flags); |
1600 | pci_add_resource(resources, res); | 1532 | pci_add_resource_offset(resources, res, hose->pci_mem_offset); |
1601 | } | 1533 | } |
1602 | 1534 | ||
1603 | pr_debug("PCI: PHB MEM offset = %016llx\n", | 1535 | pr_debug("PCI: PHB MEM offset = %016llx\n", |
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c index fdd1a3d951dc..4b06ec5a502e 100644 --- a/arch/powerpc/kernel/pci_32.c +++ b/arch/powerpc/kernel/pci_32.c | |||
@@ -219,9 +219,9 @@ void __devinit pcibios_setup_phb_io_space(struct pci_controller *hose) | |||
219 | struct resource *res = &hose->io_resource; | 219 | struct resource *res = &hose->io_resource; |
220 | 220 | ||
221 | /* Fixup IO space offset */ | 221 | /* Fixup IO space offset */ |
222 | io_offset = (unsigned long)hose->io_base_virt - isa_io_base; | 222 | io_offset = pcibios_io_space_offset(hose); |
223 | res->start = (res->start + io_offset) & 0xffffffffu; | 223 | res->start += io_offset; |
224 | res->end = (res->end + io_offset) & 0xffffffffu; | 224 | res->end += io_offset; |
225 | } | 225 | } |
226 | 226 | ||
227 | static int __init pcibios_init(void) | 227 | static int __init pcibios_init(void) |
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 3318d39b7d4c..94a54f61d341 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include <asm/machdep.h> | 33 | #include <asm/machdep.h> |
34 | #include <asm/ppc-pci.h> | 34 | #include <asm/ppc-pci.h> |
35 | 35 | ||
36 | unsigned long pci_probe_only = 1; | ||
37 | |||
38 | /* pci_io_base -- the base address from which io bars are offsets. | 36 | /* pci_io_base -- the base address from which io bars are offsets. |
39 | * This is the lowest I/O base address (so bar values are always positive), | 37 | * This is the lowest I/O base address (so bar values are always positive), |
40 | * and it *must* be the start of ISA space if an ISA bus exists because | 38 | * and it *must* be the start of ISA space if an ISA bus exists because |
@@ -55,9 +53,6 @@ static int __init pcibios_init(void) | |||
55 | */ | 53 | */ |
56 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | 54 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; |
57 | 55 | ||
58 | if (pci_probe_only) | ||
59 | pci_add_flags(PCI_PROBE_ONLY); | ||
60 | |||
61 | /* On ppc64, we always enable PCI domains and we keep domain 0 | 56 | /* On ppc64, we always enable PCI domains and we keep domain 0 |
62 | * backward compatible in /proc for video cards | 57 | * backward compatible in /proc for video cards |
63 | */ | 58 | */ |
@@ -173,7 +168,7 @@ static int __devinit pcibios_map_phb_io_space(struct pci_controller *hose) | |||
173 | return -ENOMEM; | 168 | return -ENOMEM; |
174 | 169 | ||
175 | /* Fixup hose IO resource */ | 170 | /* Fixup hose IO resource */ |
176 | io_virt_offset = (unsigned long)hose->io_base_virt - _IO_BASE; | 171 | io_virt_offset = pcibios_io_space_offset(hose); |
177 | hose->io_resource.start += io_virt_offset; | 172 | hose->io_resource.start += io_virt_offset; |
178 | hose->io_resource.end += io_virt_offset; | 173 | hose->io_resource.end += io_virt_offset; |
179 | 174 | ||
diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index b37d0b5a796e..89dde171a6fa 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c | |||
@@ -75,6 +75,7 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) | |||
75 | { | 75 | { |
76 | u64 base, size; | 76 | u64 base, size; |
77 | unsigned int flags; | 77 | unsigned int flags; |
78 | struct pci_bus_region region; | ||
78 | struct resource *res; | 79 | struct resource *res; |
79 | const u32 *addrs; | 80 | const u32 *addrs; |
80 | u32 i; | 81 | u32 i; |
@@ -106,10 +107,11 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) | |||
106 | printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); | 107 | printk(KERN_ERR "PCI: bad cfg reg num 0x%x\n", i); |
107 | continue; | 108 | continue; |
108 | } | 109 | } |
109 | res->start = base; | ||
110 | res->end = base + size - 1; | ||
111 | res->flags = flags; | 110 | res->flags = flags; |
112 | res->name = pci_name(dev); | 111 | res->name = pci_name(dev); |
112 | region.start = base; | ||
113 | region.end = base + size - 1; | ||
114 | pcibios_bus_to_resource(dev, res, ®ion); | ||
113 | } | 115 | } |
114 | } | 116 | } |
115 | 117 | ||
@@ -209,6 +211,7 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) | |||
209 | struct pci_bus *bus; | 211 | struct pci_bus *bus; |
210 | const u32 *busrange, *ranges; | 212 | const u32 *busrange, *ranges; |
211 | int len, i, mode; | 213 | int len, i, mode; |
214 | struct pci_bus_region region; | ||
212 | struct resource *res; | 215 | struct resource *res; |
213 | unsigned int flags; | 216 | unsigned int flags; |
214 | u64 size; | 217 | u64 size; |
@@ -270,9 +273,10 @@ void __devinit of_scan_pci_bridge(struct pci_dev *dev) | |||
270 | res = bus->resource[i]; | 273 | res = bus->resource[i]; |
271 | ++i; | 274 | ++i; |
272 | } | 275 | } |
273 | res->start = of_read_number(&ranges[1], 2); | ||
274 | res->end = res->start + size - 1; | ||
275 | res->flags = flags; | 276 | res->flags = flags; |
277 | region.start = of_read_number(&ranges[1], 2); | ||
278 | region.end = region.start + size - 1; | ||
279 | pcibios_bus_to_resource(dev, res, ®ion); | ||
276 | } | 280 | } |
277 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 281 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
278 | bus->number); | 282 | bus->number); |
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index 517bd86bc3f0..179af906dcda 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c | |||
@@ -279,7 +279,7 @@ void __init find_and_init_phbs(void) | |||
279 | eeh_dev_phb_init(); | 279 | eeh_dev_phb_init(); |
280 | 280 | ||
281 | /* | 281 | /* |
282 | * pci_probe_only and pci_assign_all_buses can be set via properties | 282 | * PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties |
283 | * in chosen. | 283 | * in chosen. |
284 | */ | 284 | */ |
285 | if (of_chosen) { | 285 | if (of_chosen) { |
@@ -287,8 +287,12 @@ void __init find_and_init_phbs(void) | |||
287 | 287 | ||
288 | prop = of_get_property(of_chosen, | 288 | prop = of_get_property(of_chosen, |
289 | "linux,pci-probe-only", NULL); | 289 | "linux,pci-probe-only", NULL); |
290 | if (prop) | 290 | if (prop) { |
291 | pci_probe_only = *prop; | 291 | if (*prop) |
292 | pci_add_flags(PCI_PROBE_ONLY); | ||
293 | else | ||
294 | pci_clear_flags(PCI_PROBE_ONLY); | ||
295 | } | ||
292 | 296 | ||
293 | #ifdef CONFIG_PPC32 /* Will be made generic soon */ | 297 | #ifdef CONFIG_PPC32 /* Will be made generic soon */ |
294 | prop = of_get_property(of_chosen, | 298 | prop = of_get_property(of_chosen, |
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 401e3f3f74c8..465ee8f5c086 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -620,7 +620,7 @@ void __init maple_pci_init(void) | |||
620 | } | 620 | } |
621 | 621 | ||
622 | /* Tell pci.c to not change any resource allocations. */ | 622 | /* Tell pci.c to not change any resource allocations. */ |
623 | pci_probe_only = 1; | 623 | pci_add_flags(PCI_PROBE_ONLY); |
624 | } | 624 | } |
625 | 625 | ||
626 | int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) | 626 | int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) |
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c index b6a0ec45c695..aa862713258c 100644 --- a/arch/powerpc/platforms/pasemi/pci.c +++ b/arch/powerpc/platforms/pasemi/pci.c | |||
@@ -229,9 +229,6 @@ void __init pas_pci_init(void) | |||
229 | 229 | ||
230 | /* Setup the linkage between OF nodes and PHBs */ | 230 | /* Setup the linkage between OF nodes and PHBs */ |
231 | pci_devs_phb_init(); | 231 | pci_devs_phb_init(); |
232 | |||
233 | /* Use the common resource allocation mechanism */ | ||
234 | pci_probe_only = 1; | ||
235 | } | 232 | } |
236 | 233 | ||
237 | void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset) | 234 | void __iomem *pasemi_pci_getcfgaddr(struct pci_dev *dev, int offset) |
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index 31a7d3a7ce25..43bbe1bda939 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1059,9 +1059,6 @@ void __init pmac_pci_init(void) | |||
1059 | } | 1059 | } |
1060 | /* pmac_check_ht_link(); */ | 1060 | /* pmac_check_ht_link(); */ |
1061 | 1061 | ||
1062 | /* We can allocate missing resources if any */ | ||
1063 | pci_probe_only = 0; | ||
1064 | |||
1065 | #else /* CONFIG_PPC64 */ | 1062 | #else /* CONFIG_PPC64 */ |
1066 | init_p2pbridge(); | 1063 | init_p2pbridge(); |
1067 | init_second_ohare(); | 1064 | init_second_ohare(); |
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 5e155dfc4320..fbdd74dac3ac 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c | |||
@@ -1299,15 +1299,14 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) | |||
1299 | /* Setup MSI support */ | 1299 | /* Setup MSI support */ |
1300 | pnv_pci_init_ioda_msis(phb); | 1300 | pnv_pci_init_ioda_msis(phb); |
1301 | 1301 | ||
1302 | /* We set both probe_only and PCI_REASSIGN_ALL_RSRC. This is an | 1302 | /* We set both PCI_PROBE_ONLY and PCI_REASSIGN_ALL_RSRC. This is an |
1303 | * odd combination which essentially means that we skip all resource | 1303 | * odd combination which essentially means that we skip all resource |
1304 | * fixups and assignments in the generic code, and do it all | 1304 | * fixups and assignments in the generic code, and do it all |
1305 | * ourselves here | 1305 | * ourselves here |
1306 | */ | 1306 | */ |
1307 | pci_probe_only = 1; | ||
1308 | ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; | 1307 | ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; |
1309 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; | 1308 | ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; |
1310 | pci_add_flags(PCI_REASSIGN_ALL_RSRC); | 1309 | pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC); |
1311 | 1310 | ||
1312 | /* Reset IODA tables to a clean state */ | 1311 | /* Reset IODA tables to a clean state */ |
1313 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); | 1312 | rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); |
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 214478d781ae..be3cfc5ceabb 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c | |||
@@ -562,10 +562,7 @@ void __init pnv_pci_init(void) | |||
562 | { | 562 | { |
563 | struct device_node *np; | 563 | struct device_node *np; |
564 | 564 | ||
565 | pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN); | 565 | pci_add_flags(PCI_CAN_SKIP_ISA_ALIGN); |
566 | |||
567 | /* We do not want to just probe */ | ||
568 | pci_probe_only = 0; | ||
569 | 566 | ||
570 | /* OPAL absent, try POPAL first then RTAS detection of PHBs */ | 567 | /* OPAL absent, try POPAL first then RTAS detection of PHBs */ |
571 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { | 568 | if (!firmware_has_feature(FW_FEATURE_OPAL)) { |
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c index fbb21fc3080b..8b7bafa489c2 100644 --- a/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/arch/powerpc/platforms/pseries/pci_dlpar.c | |||
@@ -84,7 +84,7 @@ void pcibios_remove_pci_devices(struct pci_bus *bus) | |||
84 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { | 84 | list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { |
85 | pr_debug(" * Removing %s...\n", pci_name(dev)); | 85 | pr_debug(" * Removing %s...\n", pci_name(dev)); |
86 | eeh_remove_bus_device(dev); | 86 | eeh_remove_bus_device(dev); |
87 | pci_remove_bus_device(dev); | 87 | pci_stop_and_remove_bus_device(dev); |
88 | } | 88 | } |
89 | } | 89 | } |
90 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); | 90 | EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 8f137af616af..51ecac920dd8 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -383,6 +383,9 @@ static void __init pSeries_setup_arch(void) | |||
383 | 383 | ||
384 | fwnmi_init(); | 384 | fwnmi_init(); |
385 | 385 | ||
386 | /* By default, only probe PCI (can be overriden by rtas_pci) */ | ||
387 | pci_add_flags(PCI_PROBE_ONLY); | ||
388 | |||
386 | /* Find and initialize PCI host bridges */ | 389 | /* Find and initialize PCI host bridges */ |
387 | init_pci_config_tokens(); | 390 | init_pci_config_tokens(); |
388 | eeh_pseries_init(); | 391 | eeh_pseries_init(); |
diff --git a/arch/powerpc/platforms/wsp/wsp_pci.c b/arch/powerpc/platforms/wsp/wsp_pci.c index d24b3acf858e..763014cd1e62 100644 --- a/arch/powerpc/platforms/wsp/wsp_pci.c +++ b/arch/powerpc/platforms/wsp/wsp_pci.c | |||
@@ -682,7 +682,6 @@ static int __init wsp_setup_one_phb(struct device_node *np) | |||
682 | /* XXX Force re-assigning of everything for now */ | 682 | /* XXX Force re-assigning of everything for now */ |
683 | pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC | | 683 | pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC | |
684 | PCI_ENABLE_PROC_DOMAINS); | 684 | PCI_ENABLE_PROC_DOMAINS); |
685 | pci_probe_only = 0; | ||
686 | 685 | ||
687 | /* Calculate how the TCE space is divided */ | 686 | /* Calculate how the TCE space is divided */ |
688 | phb->dma32_base = 0; | 687 | phb->dma32_base = 0; |
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 1e7b0e2e764d..9d10a3cb8797 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c | |||
@@ -37,11 +37,20 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose) | |||
37 | static int next_busno; | 37 | static int next_busno; |
38 | static int need_domain_info; | 38 | static int need_domain_info; |
39 | LIST_HEAD(resources); | 39 | LIST_HEAD(resources); |
40 | struct resource *res; | ||
41 | resource_size_t offset; | ||
40 | int i; | 42 | int i; |
41 | struct pci_bus *bus; | 43 | struct pci_bus *bus; |
42 | 44 | ||
43 | for (i = 0; i < hose->nr_resources; i++) | 45 | for (i = 0; i < hose->nr_resources; i++) { |
44 | pci_add_resource(&resources, hose->resources + i); | 46 | res = hose->resources + i; |
47 | offset = 0; | ||
48 | if (res->flags & IORESOURCE_IO) | ||
49 | offset = hose->io_offset; | ||
50 | else if (res->flags & IORESOURCE_MEM) | ||
51 | offset = hose->mem_offset; | ||
52 | pci_add_resource_offset(&resources, res, offset); | ||
53 | } | ||
45 | 54 | ||
46 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, | 55 | bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, |
47 | &resources); | 56 | &resources); |
@@ -143,42 +152,12 @@ static int __init pcibios_init(void) | |||
143 | } | 152 | } |
144 | subsys_initcall(pcibios_init); | 153 | subsys_initcall(pcibios_init); |
145 | 154 | ||
146 | static void pcibios_fixup_device_resources(struct pci_dev *dev, | ||
147 | struct pci_bus *bus) | ||
148 | { | ||
149 | /* Update device resources. */ | ||
150 | struct pci_channel *hose = bus->sysdata; | ||
151 | unsigned long offset = 0; | ||
152 | int i; | ||
153 | |||
154 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
155 | if (!dev->resource[i].start) | ||
156 | continue; | ||
157 | if (dev->resource[i].flags & IORESOURCE_IO) | ||
158 | offset = hose->io_offset; | ||
159 | else if (dev->resource[i].flags & IORESOURCE_MEM) | ||
160 | offset = hose->mem_offset; | ||
161 | |||
162 | dev->resource[i].start += offset; | ||
163 | dev->resource[i].end += offset; | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /* | 155 | /* |
168 | * Called after each bus is probed, but before its children | 156 | * Called after each bus is probed, but before its children |
169 | * are examined. | 157 | * are examined. |
170 | */ | 158 | */ |
171 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) | 159 | void __devinit pcibios_fixup_bus(struct pci_bus *bus) |
172 | { | 160 | { |
173 | struct pci_dev *dev; | ||
174 | struct list_head *ln; | ||
175 | |||
176 | for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { | ||
177 | dev = pci_dev_b(ln); | ||
178 | |||
179 | if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) | ||
180 | pcibios_fixup_device_resources(dev, bus); | ||
181 | } | ||
182 | } | 161 | } |
183 | 162 | ||
184 | /* | 163 | /* |
@@ -208,36 +187,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res, | |||
208 | return start; | 187 | return start; |
209 | } | 188 | } |
210 | 189 | ||
211 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
212 | struct resource *res) | ||
213 | { | ||
214 | struct pci_channel *hose = dev->sysdata; | ||
215 | unsigned long offset = 0; | ||
216 | |||
217 | if (res->flags & IORESOURCE_IO) | ||
218 | offset = hose->io_offset; | ||
219 | else if (res->flags & IORESOURCE_MEM) | ||
220 | offset = hose->mem_offset; | ||
221 | |||
222 | region->start = res->start - offset; | ||
223 | region->end = res->end - offset; | ||
224 | } | ||
225 | |||
226 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
227 | struct pci_bus_region *region) | ||
228 | { | ||
229 | struct pci_channel *hose = dev->sysdata; | ||
230 | unsigned long offset = 0; | ||
231 | |||
232 | if (res->flags & IORESOURCE_IO) | ||
233 | offset = hose->io_offset; | ||
234 | else if (res->flags & IORESOURCE_MEM) | ||
235 | offset = hose->mem_offset; | ||
236 | |||
237 | res->start = region->start + offset; | ||
238 | res->end = region->end + offset; | ||
239 | } | ||
240 | |||
241 | int pcibios_enable_device(struct pci_dev *dev, int mask) | 190 | int pcibios_enable_device(struct pci_dev *dev, int mask) |
242 | { | 191 | { |
243 | return pci_enable_resources(dev, mask); | 192 | return pci_enable_resources(dev, mask); |
@@ -381,8 +330,6 @@ EXPORT_SYMBOL(pci_iounmap); | |||
381 | #endif /* CONFIG_GENERIC_IOMAP */ | 330 | #endif /* CONFIG_GENERIC_IOMAP */ |
382 | 331 | ||
383 | #ifdef CONFIG_HOTPLUG | 332 | #ifdef CONFIG_HOTPLUG |
384 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
385 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
386 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); | 333 | EXPORT_SYMBOL(PCIBIOS_MIN_IO); |
387 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); | 334 | EXPORT_SYMBOL(PCIBIOS_MIN_MEM); |
388 | #endif | 335 | #endif |
diff --git a/arch/sh/include/asm/pci.h b/arch/sh/include/asm/pci.h index cb21e2399dc1..bff96c2e7d25 100644 --- a/arch/sh/include/asm/pci.h +++ b/arch/sh/include/asm/pci.h | |||
@@ -114,12 +114,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
114 | /* Board-specific fixup routines. */ | 114 | /* Board-specific fixup routines. */ |
115 | int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin); | 115 | int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin); |
116 | 116 | ||
117 | extern void pcibios_resource_to_bus(struct pci_dev *dev, | ||
118 | struct pci_bus_region *region, struct resource *res); | ||
119 | |||
120 | extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
121 | struct pci_bus_region *region); | ||
122 | |||
123 | #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index | 117 | #define pci_domain_nr(bus) ((struct pci_channel *)(bus)->sysdata)->index |
124 | 118 | ||
125 | static inline int pci_proc_domain(struct pci_bus *bus) | 119 | static inline int pci_proc_domain(struct pci_bus *bus) |
diff --git a/arch/sparc/include/asm/pci_32.h b/arch/sparc/include/asm/pci_32.h index 6de7f7bf956a..dc503297481f 100644 --- a/arch/sparc/include/asm/pci_32.h +++ b/arch/sparc/include/asm/pci_32.h | |||
@@ -52,14 +52,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, | |||
52 | * 64Kbytes by the Host controller. | 52 | * 64Kbytes by the Host controller. |
53 | */ | 53 | */ |
54 | 54 | ||
55 | extern void | ||
56 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
57 | struct resource *res); | ||
58 | |||
59 | extern void | ||
60 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
61 | struct pci_bus_region *region); | ||
62 | |||
63 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | 55 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
64 | { | 56 | { |
65 | return PCI_IRQ_NONE; | 57 | return PCI_IRQ_NONE; |
diff --git a/arch/sparc/include/asm/pci_64.h b/arch/sparc/include/asm/pci_64.h index 755a4bb6bcd3..1633b718d3bc 100644 --- a/arch/sparc/include/asm/pci_64.h +++ b/arch/sparc/include/asm/pci_64.h | |||
@@ -73,14 +73,6 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, | |||
73 | enum pci_mmap_state mmap_state, | 73 | enum pci_mmap_state mmap_state, |
74 | int write_combine); | 74 | int write_combine); |
75 | 75 | ||
76 | extern void | ||
77 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
78 | struct resource *res); | ||
79 | |||
80 | extern void | ||
81 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
82 | struct pci_bus_region *region); | ||
83 | |||
84 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | 76 | static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) |
85 | { | 77 | { |
86 | return PCI_IRQ_NONE; | 78 | return PCI_IRQ_NONE; |
diff --git a/arch/sparc/kernel/leon_pci.c b/arch/sparc/kernel/leon_pci.c index c7bec25fdb1c..aba6b958b2a5 100644 --- a/arch/sparc/kernel/leon_pci.c +++ b/arch/sparc/kernel/leon_pci.c | |||
@@ -15,14 +15,19 @@ | |||
15 | 15 | ||
16 | /* The LEON architecture does not rely on a BIOS or bootloader to setup | 16 | /* The LEON architecture does not rely on a BIOS or bootloader to setup |
17 | * PCI for us. The Linux generic routines are used to setup resources, | 17 | * PCI for us. The Linux generic routines are used to setup resources, |
18 | * reset values of confuration-space registers settings ae preseved. | 18 | * reset values of configuration-space register settings are preserved. |
19 | * | ||
20 | * PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is | ||
21 | * accessed through a Window which is translated to low 64KB in PCI space, the | ||
22 | * first 4KB is not used so 60KB is available. | ||
19 | */ | 23 | */ |
20 | void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) | 24 | void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) |
21 | { | 25 | { |
22 | LIST_HEAD(resources); | 26 | LIST_HEAD(resources); |
23 | struct pci_bus *root_bus; | 27 | struct pci_bus *root_bus; |
24 | 28 | ||
25 | pci_add_resource(&resources, &info->io_space); | 29 | pci_add_resource_offset(&resources, &info->io_space, |
30 | info->io_space.start - 0x1000); | ||
26 | pci_add_resource(&resources, &info->mem_space); | 31 | pci_add_resource(&resources, &info->mem_space); |
27 | 32 | ||
28 | root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, | 33 | root_bus = pci_scan_root_bus(&ofdev->dev, 0, info->ops, info, |
@@ -38,44 +43,6 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info) | |||
38 | } | 43 | } |
39 | } | 44 | } |
40 | 45 | ||
41 | /* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is | ||
42 | * accessed through a Window which is translated to low 64KB in PCI space, the | ||
43 | * first 4KB is not used so 60KB is available. | ||
44 | * | ||
45 | * This function is used by generic code to translate resource addresses into | ||
46 | * PCI addresses. | ||
47 | */ | ||
48 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
49 | struct resource *res) | ||
50 | { | ||
51 | struct leon_pci_info *info = dev->bus->sysdata; | ||
52 | |||
53 | region->start = res->start; | ||
54 | region->end = res->end; | ||
55 | |||
56 | if (res->flags & IORESOURCE_IO) { | ||
57 | region->start -= (info->io_space.start - 0x1000); | ||
58 | region->end -= (info->io_space.start - 0x1000); | ||
59 | } | ||
60 | } | ||
61 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
62 | |||
63 | /* see pcibios_resource_to_bus() comment */ | ||
64 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
65 | struct pci_bus_region *region) | ||
66 | { | ||
67 | struct leon_pci_info *info = dev->bus->sysdata; | ||
68 | |||
69 | res->start = region->start; | ||
70 | res->end = region->end; | ||
71 | |||
72 | if (res->flags & IORESOURCE_IO) { | ||
73 | res->start += (info->io_space.start - 0x1000); | ||
74 | res->end += (info->io_space.start - 0x1000); | ||
75 | } | ||
76 | } | ||
77 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
78 | |||
79 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) | 46 | void __devinit pcibios_fixup_bus(struct pci_bus *pbus) |
80 | { | 47 | { |
81 | struct leon_pci_info *info = pbus->sysdata; | 48 | struct leon_pci_info *info = pbus->sysdata; |
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c index bb8bc2e519ac..fdaf21811670 100644 --- a/arch/sparc/kernel/pci.c +++ b/arch/sparc/kernel/pci.c | |||
@@ -375,13 +375,6 @@ static void __devinit apb_calc_first_last(u8 map, u32 *first_p, u32 *last_p) | |||
375 | *last_p = last; | 375 | *last_p = last; |
376 | } | 376 | } |
377 | 377 | ||
378 | static void pci_resource_adjust(struct resource *res, | ||
379 | struct resource *root) | ||
380 | { | ||
381 | res->start += root->start; | ||
382 | res->end += root->start; | ||
383 | } | ||
384 | |||
385 | /* For PCI bus devices which lack a 'ranges' property we interrogate | 378 | /* For PCI bus devices which lack a 'ranges' property we interrogate |
386 | * the config space values to set the resources, just like the generic | 379 | * the config space values to set the resources, just like the generic |
387 | * Linux PCI probing code does. | 380 | * Linux PCI probing code does. |
@@ -390,7 +383,8 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | |||
390 | struct pci_bus *bus, | 383 | struct pci_bus *bus, |
391 | struct pci_pbm_info *pbm) | 384 | struct pci_pbm_info *pbm) |
392 | { | 385 | { |
393 | struct resource *res; | 386 | struct pci_bus_region region; |
387 | struct resource *res, res2; | ||
394 | u8 io_base_lo, io_limit_lo; | 388 | u8 io_base_lo, io_limit_lo; |
395 | u16 mem_base_lo, mem_limit_lo; | 389 | u16 mem_base_lo, mem_limit_lo; |
396 | unsigned long base, limit; | 390 | unsigned long base, limit; |
@@ -412,11 +406,14 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | |||
412 | res = bus->resource[0]; | 406 | res = bus->resource[0]; |
413 | if (base <= limit) { | 407 | if (base <= limit) { |
414 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 408 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
409 | res2.flags = res->flags; | ||
410 | region.start = base; | ||
411 | region.end = limit + 0xfff; | ||
412 | pcibios_bus_to_resource(dev, &res2, ®ion); | ||
415 | if (!res->start) | 413 | if (!res->start) |
416 | res->start = base; | 414 | res->start = res2.start; |
417 | if (!res->end) | 415 | if (!res->end) |
418 | res->end = limit + 0xfff; | 416 | res->end = res2.end; |
419 | pci_resource_adjust(res, &pbm->io_space); | ||
420 | } | 417 | } |
421 | 418 | ||
422 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); | 419 | pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo); |
@@ -428,9 +425,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | |||
428 | if (base <= limit) { | 425 | if (base <= limit) { |
429 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | 426 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | |
430 | IORESOURCE_MEM); | 427 | IORESOURCE_MEM); |
431 | res->start = base; | 428 | region.start = base; |
432 | res->end = limit + 0xfffff; | 429 | region.end = limit + 0xfffff; |
433 | pci_resource_adjust(res, &pbm->mem_space); | 430 | pcibios_bus_to_resource(dev, res, ®ion); |
434 | } | 431 | } |
435 | 432 | ||
436 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); | 433 | pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo); |
@@ -459,9 +456,9 @@ static void __devinit pci_cfg_fake_ranges(struct pci_dev *dev, | |||
459 | if (base <= limit) { | 456 | if (base <= limit) { |
460 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | | 457 | res->flags = ((mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | |
461 | IORESOURCE_MEM | IORESOURCE_PREFETCH); | 458 | IORESOURCE_MEM | IORESOURCE_PREFETCH); |
462 | res->start = base; | 459 | region.start = base; |
463 | res->end = limit + 0xfffff; | 460 | region.end = limit + 0xfffff; |
464 | pci_resource_adjust(res, &pbm->mem_space); | 461 | pcibios_bus_to_resource(dev, res, ®ion); |
465 | } | 462 | } |
466 | } | 463 | } |
467 | 464 | ||
@@ -472,6 +469,7 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, | |||
472 | struct pci_bus *bus, | 469 | struct pci_bus *bus, |
473 | struct pci_pbm_info *pbm) | 470 | struct pci_pbm_info *pbm) |
474 | { | 471 | { |
472 | struct pci_bus_region region; | ||
475 | struct resource *res; | 473 | struct resource *res; |
476 | u32 first, last; | 474 | u32 first, last; |
477 | u8 map; | 475 | u8 map; |
@@ -479,18 +477,18 @@ static void __devinit apb_fake_ranges(struct pci_dev *dev, | |||
479 | pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map); | 477 | pci_read_config_byte(dev, APB_IO_ADDRESS_MAP, &map); |
480 | apb_calc_first_last(map, &first, &last); | 478 | apb_calc_first_last(map, &first, &last); |
481 | res = bus->resource[0]; | 479 | res = bus->resource[0]; |
482 | res->start = (first << 21); | ||
483 | res->end = (last << 21) + ((1 << 21) - 1); | ||
484 | res->flags = IORESOURCE_IO; | 480 | res->flags = IORESOURCE_IO; |
485 | pci_resource_adjust(res, &pbm->io_space); | 481 | region.start = (first << 21); |
482 | region.end = (last << 21) + ((1 << 21) - 1); | ||
483 | pcibios_bus_to_resource(dev, res, ®ion); | ||
486 | 484 | ||
487 | pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); | 485 | pci_read_config_byte(dev, APB_MEM_ADDRESS_MAP, &map); |
488 | apb_calc_first_last(map, &first, &last); | 486 | apb_calc_first_last(map, &first, &last); |
489 | res = bus->resource[1]; | 487 | res = bus->resource[1]; |
490 | res->start = (first << 21); | ||
491 | res->end = (last << 21) + ((1 << 21) - 1); | ||
492 | res->flags = IORESOURCE_MEM; | 488 | res->flags = IORESOURCE_MEM; |
493 | pci_resource_adjust(res, &pbm->mem_space); | 489 | region.start = (first << 21); |
490 | region.end = (last << 21) + ((1 << 21) - 1); | ||
491 | pcibios_bus_to_resource(dev, res, ®ion); | ||
494 | } | 492 | } |
495 | 493 | ||
496 | static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, | 494 | static void __devinit pci_of_scan_bus(struct pci_pbm_info *pbm, |
@@ -506,6 +504,7 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
506 | struct pci_bus *bus; | 504 | struct pci_bus *bus; |
507 | const u32 *busrange, *ranges; | 505 | const u32 *busrange, *ranges; |
508 | int len, i, simba; | 506 | int len, i, simba; |
507 | struct pci_bus_region region; | ||
509 | struct resource *res; | 508 | struct resource *res; |
510 | unsigned int flags; | 509 | unsigned int flags; |
511 | u64 size; | 510 | u64 size; |
@@ -556,8 +555,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
556 | } | 555 | } |
557 | i = 1; | 556 | i = 1; |
558 | for (; len >= 32; len -= 32, ranges += 8) { | 557 | for (; len >= 32; len -= 32, ranges += 8) { |
559 | struct resource *root; | ||
560 | |||
561 | flags = pci_parse_of_flags(ranges[0]); | 558 | flags = pci_parse_of_flags(ranges[0]); |
562 | size = GET_64BIT(ranges, 6); | 559 | size = GET_64BIT(ranges, 6); |
563 | if (flags == 0 || size == 0) | 560 | if (flags == 0 || size == 0) |
@@ -569,7 +566,6 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
569 | " for bridge %s\n", node->full_name); | 566 | " for bridge %s\n", node->full_name); |
570 | continue; | 567 | continue; |
571 | } | 568 | } |
572 | root = &pbm->io_space; | ||
573 | } else { | 569 | } else { |
574 | if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { | 570 | if (i >= PCI_NUM_RESOURCES - PCI_BRIDGE_RESOURCES) { |
575 | printk(KERN_ERR "PCI: too many memory ranges" | 571 | printk(KERN_ERR "PCI: too many memory ranges" |
@@ -578,18 +574,12 @@ static void __devinit of_scan_pci_bridge(struct pci_pbm_info *pbm, | |||
578 | } | 574 | } |
579 | res = bus->resource[i]; | 575 | res = bus->resource[i]; |
580 | ++i; | 576 | ++i; |
581 | root = &pbm->mem_space; | ||
582 | } | 577 | } |
583 | 578 | ||
584 | res->start = GET_64BIT(ranges, 1); | ||
585 | res->end = res->start + size - 1; | ||
586 | res->flags = flags; | 579 | res->flags = flags; |
587 | 580 | region.start = GET_64BIT(ranges, 1); | |
588 | /* Another way to implement this would be to add an of_device | 581 | region.end = region.start + size - 1; |
589 | * layer routine that can calculate a resource for a given | 582 | pcibios_bus_to_resource(dev, res, ®ion); |
590 | * range property value in a PCI device. | ||
591 | */ | ||
592 | pci_resource_adjust(res, root); | ||
593 | } | 583 | } |
594 | after_ranges: | 584 | after_ranges: |
595 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), | 585 | sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), |
@@ -691,8 +681,10 @@ struct pci_bus * __devinit pci_scan_one_pbm(struct pci_pbm_info *pbm, | |||
691 | 681 | ||
692 | printk("PCI: Scanning PBM %s\n", node->full_name); | 682 | printk("PCI: Scanning PBM %s\n", node->full_name); |
693 | 683 | ||
694 | pci_add_resource(&resources, &pbm->io_space); | 684 | pci_add_resource_offset(&resources, &pbm->io_space, |
695 | pci_add_resource(&resources, &pbm->mem_space); | 685 | pbm->io_space.start); |
686 | pci_add_resource_offset(&resources, &pbm->mem_space, | ||
687 | pbm->mem_space.start); | ||
696 | bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, | 688 | bus = pci_create_root_bus(parent, pbm->pci_first_busno, pbm->pci_ops, |
697 | pbm, &resources); | 689 | pbm, &resources); |
698 | if (!bus) { | 690 | if (!bus) { |
@@ -755,46 +747,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) | |||
755 | return 0; | 747 | return 0; |
756 | } | 748 | } |
757 | 749 | ||
758 | void pcibios_resource_to_bus(struct pci_dev *pdev, struct pci_bus_region *region, | ||
759 | struct resource *res) | ||
760 | { | ||
761 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | ||
762 | struct resource zero_res, *root; | ||
763 | |||
764 | zero_res.start = 0; | ||
765 | zero_res.end = 0; | ||
766 | zero_res.flags = res->flags; | ||
767 | |||
768 | if (res->flags & IORESOURCE_IO) | ||
769 | root = &pbm->io_space; | ||
770 | else | ||
771 | root = &pbm->mem_space; | ||
772 | |||
773 | pci_resource_adjust(&zero_res, root); | ||
774 | |||
775 | region->start = res->start - zero_res.start; | ||
776 | region->end = res->end - zero_res.start; | ||
777 | } | ||
778 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
779 | |||
780 | void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, | ||
781 | struct pci_bus_region *region) | ||
782 | { | ||
783 | struct pci_pbm_info *pbm = pdev->bus->sysdata; | ||
784 | struct resource *root; | ||
785 | |||
786 | res->start = region->start; | ||
787 | res->end = region->end; | ||
788 | |||
789 | if (res->flags & IORESOURCE_IO) | ||
790 | root = &pbm->io_space; | ||
791 | else | ||
792 | root = &pbm->mem_space; | ||
793 | |||
794 | pci_resource_adjust(res, root); | ||
795 | } | ||
796 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
797 | |||
798 | char * __devinit pcibios_setup(char *str) | 750 | char * __devinit pcibios_setup(char *str) |
799 | { | 751 | { |
800 | return str; | 752 | return str; |
diff --git a/arch/unicore32/include/asm/pci.h b/arch/unicore32/include/asm/pci.h index dd3867727c35..f5e108f4a151 100644 --- a/arch/unicore32/include/asm/pci.h +++ b/arch/unicore32/include/asm/pci.h | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #ifdef __KERNEL__ | 15 | #ifdef __KERNEL__ |
16 | #include <asm-generic/pci-dma-compat.h> | 16 | #include <asm-generic/pci-dma-compat.h> |
17 | #include <asm-generic/pci-bridge.h> | ||
17 | #include <asm-generic/pci.h> | 18 | #include <asm-generic/pci.h> |
18 | #include <mach/hardware.h> /* for PCIBIOS_MIN_* */ | 19 | #include <mach/hardware.h> /* for PCIBIOS_MIN_* */ |
19 | 20 | ||
diff --git a/arch/unicore32/kernel/pci.c b/arch/unicore32/kernel/pci.c index a8f07fe10cad..2fc2b1ba825e 100644 --- a/arch/unicore32/kernel/pci.c +++ b/arch/unicore32/kernel/pci.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/io.h> | 21 | #include <linux/io.h> |
22 | 22 | ||
23 | static int debug_pci; | 23 | static int debug_pci; |
24 | static int use_firmware; | ||
25 | 24 | ||
26 | #define CONFIG_CMD(bus, devfn, where) \ | 25 | #define CONFIG_CMD(bus, devfn, where) \ |
27 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) | 26 | (0x80000000 | (bus->number << 16) | (devfn << 8) | (where & ~3)) |
@@ -276,7 +275,7 @@ static int __init pci_common_init(void) | |||
276 | 275 | ||
277 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); | 276 | pci_fixup_irqs(pci_common_swizzle, pci_puv3_map_irq); |
278 | 277 | ||
279 | if (!use_firmware) { | 278 | if (!pci_has_flag(PCI_PROBE_ONLY)) { |
280 | /* | 279 | /* |
281 | * Size the bridge windows. | 280 | * Size the bridge windows. |
282 | */ | 281 | */ |
@@ -303,7 +302,7 @@ char * __devinit pcibios_setup(char *str) | |||
303 | debug_pci = 1; | 302 | debug_pci = 1; |
304 | return NULL; | 303 | return NULL; |
305 | } else if (!strcmp(str, "firmware")) { | 304 | } else if (!strcmp(str, "firmware")) { |
306 | use_firmware = 1; | 305 | pci_add_flags(PCI_PROBE_ONLY); |
307 | return NULL; | 306 | return NULL; |
308 | } | 307 | } |
309 | return str; | 308 | return str; |
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c index 1c4d769e21ea..28e5e06fcba4 100644 --- a/arch/x86/kernel/pci-dma.c +++ b/arch/x86/kernel/pci-dma.c | |||
@@ -262,10 +262,11 @@ rootfs_initcall(pci_iommu_init); | |||
262 | 262 | ||
263 | static __devinit void via_no_dac(struct pci_dev *dev) | 263 | static __devinit void via_no_dac(struct pci_dev *dev) |
264 | { | 264 | { |
265 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) { | 265 | if (forbid_dac == 0) { |
266 | dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); | 266 | dev_info(&dev->dev, "disabling DAC on VIA PCI bridge\n"); |
267 | forbid_dac = 1; | 267 | forbid_dac = 1; |
268 | } | 268 | } |
269 | } | 269 | } |
270 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, via_no_dac); | 270 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_VIA, PCI_ANY_ID, |
271 | PCI_CLASS_BRIDGE_PCI, 8, via_no_dac); | ||
271 | #endif | 272 | #endif |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 49a5cb55429b..ed2835e148b5 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -416,7 +416,12 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
416 | kfree(sd); | 416 | kfree(sd); |
417 | } else { | 417 | } else { |
418 | get_current_resources(device, busnum, domain, &resources); | 418 | get_current_resources(device, busnum, domain, &resources); |
419 | if (list_empty(&resources)) | 419 | |
420 | /* | ||
421 | * _CRS with no apertures is normal, so only fall back to | ||
422 | * defaults or native bridge info if we're ignoring _CRS. | ||
423 | */ | ||
424 | if (!pci_use_crs) | ||
420 | x86_pci_root_bus_resources(busnum, &resources); | 425 | x86_pci_root_bus_resources(busnum, &resources); |
421 | bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, | 426 | bus = pci_create_root_bus(NULL, busnum, &pci_root_ops, sd, |
422 | &resources); | 427 | &resources); |
diff --git a/arch/x86/pci/fixup.c b/arch/x86/pci/fixup.c index 6dd89555fbfa..d0e6e403b4f6 100644 --- a/arch/x86/pci/fixup.c +++ b/arch/x86/pci/fixup.c | |||
@@ -164,11 +164,11 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_ | |||
164 | */ | 164 | */ |
165 | static void __devinit pci_fixup_transparent_bridge(struct pci_dev *dev) | 165 | static void __devinit pci_fixup_transparent_bridge(struct pci_dev *dev) |
166 | { | 166 | { |
167 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && | 167 | if ((dev->device & 0xff00) == 0x2400) |
168 | (dev->device & 0xff00) == 0x2400) | ||
169 | dev->transparent = 1; | 168 | dev->transparent = 1; |
170 | } | 169 | } |
171 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_bridge); | 170 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
171 | PCI_CLASS_BRIDGE_PCI, 8, pci_fixup_transparent_bridge); | ||
172 | 172 | ||
173 | /* | 173 | /* |
174 | * Fixup for C1 Halt Disconnect problem on nForce2 systems. | 174 | * Fixup for C1 Halt Disconnect problem on nForce2 systems. |
@@ -322,9 +322,6 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) | |||
322 | struct pci_bus *bus; | 322 | struct pci_bus *bus; |
323 | u16 config; | 323 | u16 config; |
324 | 324 | ||
325 | if ((pdev->class >> 8) != PCI_CLASS_DISPLAY_VGA) | ||
326 | return; | ||
327 | |||
328 | /* Is VGA routed to us? */ | 325 | /* Is VGA routed to us? */ |
329 | bus = pdev->bus; | 326 | bus = pdev->bus; |
330 | while (bus) { | 327 | while (bus) { |
@@ -353,7 +350,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) | |||
353 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); | 350 | dev_printk(KERN_DEBUG, &pdev->dev, "Boot video device\n"); |
354 | } | 351 | } |
355 | } | 352 | } |
356 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); | 353 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
354 | PCI_CLASS_DISPLAY_VGA, 8, pci_fixup_video); | ||
357 | 355 | ||
358 | 356 | ||
359 | static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = { | 357 | static const struct dmi_system_id __devinitconst msi_k8t_dmi_table[] = { |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index 91821a1a0c3a..831971e731f7 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -39,6 +39,87 @@ | |||
39 | #include <asm/io_apic.h> | 39 | #include <asm/io_apic.h> |
40 | 40 | ||
41 | 41 | ||
42 | /* | ||
43 | * This list of dynamic mappings is for temporarily maintaining | ||
44 | * original BIOS BAR addresses for possible reinstatement. | ||
45 | */ | ||
46 | struct pcibios_fwaddrmap { | ||
47 | struct list_head list; | ||
48 | struct pci_dev *dev; | ||
49 | resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; | ||
50 | }; | ||
51 | |||
52 | static LIST_HEAD(pcibios_fwaddrmappings); | ||
53 | static DEFINE_SPINLOCK(pcibios_fwaddrmap_lock); | ||
54 | |||
55 | /* Must be called with 'pcibios_fwaddrmap_lock' lock held. */ | ||
56 | static struct pcibios_fwaddrmap *pcibios_fwaddrmap_lookup(struct pci_dev *dev) | ||
57 | { | ||
58 | struct pcibios_fwaddrmap *map; | ||
59 | |||
60 | WARN_ON(!spin_is_locked(&pcibios_fwaddrmap_lock)); | ||
61 | |||
62 | list_for_each_entry(map, &pcibios_fwaddrmappings, list) | ||
63 | if (map->dev == dev) | ||
64 | return map; | ||
65 | |||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | static void | ||
70 | pcibios_save_fw_addr(struct pci_dev *dev, int idx, resource_size_t fw_addr) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | struct pcibios_fwaddrmap *map; | ||
74 | |||
75 | spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); | ||
76 | map = pcibios_fwaddrmap_lookup(dev); | ||
77 | if (!map) { | ||
78 | spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); | ||
79 | map = kzalloc(sizeof(*map), GFP_KERNEL); | ||
80 | if (!map) | ||
81 | return; | ||
82 | |||
83 | map->dev = pci_dev_get(dev); | ||
84 | map->fw_addr[idx] = fw_addr; | ||
85 | INIT_LIST_HEAD(&map->list); | ||
86 | |||
87 | spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); | ||
88 | list_add_tail(&map->list, &pcibios_fwaddrmappings); | ||
89 | } else | ||
90 | map->fw_addr[idx] = fw_addr; | ||
91 | spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); | ||
92 | } | ||
93 | |||
94 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) | ||
95 | { | ||
96 | unsigned long flags; | ||
97 | struct pcibios_fwaddrmap *map; | ||
98 | resource_size_t fw_addr = 0; | ||
99 | |||
100 | spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); | ||
101 | map = pcibios_fwaddrmap_lookup(dev); | ||
102 | if (map) | ||
103 | fw_addr = map->fw_addr[idx]; | ||
104 | spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); | ||
105 | |||
106 | return fw_addr; | ||
107 | } | ||
108 | |||
109 | static void pcibios_fw_addr_list_del(void) | ||
110 | { | ||
111 | unsigned long flags; | ||
112 | struct pcibios_fwaddrmap *entry, *next; | ||
113 | |||
114 | spin_lock_irqsave(&pcibios_fwaddrmap_lock, flags); | ||
115 | list_for_each_entry_safe(entry, next, &pcibios_fwaddrmappings, list) { | ||
116 | list_del(&entry->list); | ||
117 | pci_dev_put(entry->dev); | ||
118 | kfree(entry); | ||
119 | } | ||
120 | spin_unlock_irqrestore(&pcibios_fwaddrmap_lock, flags); | ||
121 | } | ||
122 | |||
42 | static int | 123 | static int |
43 | skip_isa_ioresource_align(struct pci_dev *dev) { | 124 | skip_isa_ioresource_align(struct pci_dev *dev) { |
44 | 125 | ||
@@ -182,7 +263,8 @@ static void __init pcibios_allocate_resources(int pass) | |||
182 | idx, r, disabled, pass); | 263 | idx, r, disabled, pass); |
183 | if (pci_claim_resource(dev, idx) < 0) { | 264 | if (pci_claim_resource(dev, idx) < 0) { |
184 | /* We'll assign a new address later */ | 265 | /* We'll assign a new address later */ |
185 | dev->fw_addr[idx] = r->start; | 266 | pcibios_save_fw_addr(dev, |
267 | idx, r->start); | ||
186 | r->end -= r->start; | 268 | r->end -= r->start; |
187 | r->start = 0; | 269 | r->start = 0; |
188 | } | 270 | } |
@@ -228,6 +310,7 @@ static int __init pcibios_assign_resources(void) | |||
228 | } | 310 | } |
229 | 311 | ||
230 | pci_assign_unassigned_resources(); | 312 | pci_assign_unassigned_resources(); |
313 | pcibios_fw_addr_list_del(); | ||
231 | 314 | ||
232 | return 0; | 315 | return 0; |
233 | } | 316 | } |
diff --git a/arch/x86/pci/mrst.c b/arch/x86/pci/mrst.c index cb29191cee58..140942f66b31 100644 --- a/arch/x86/pci/mrst.c +++ b/arch/x86/pci/mrst.c | |||
@@ -43,6 +43,8 @@ | |||
43 | #define PCI_FIXED_BAR_4_SIZE 0x14 | 43 | #define PCI_FIXED_BAR_4_SIZE 0x14 |
44 | #define PCI_FIXED_BAR_5_SIZE 0x1c | 44 | #define PCI_FIXED_BAR_5_SIZE 0x1c |
45 | 45 | ||
46 | static int pci_soc_mode = 0; | ||
47 | |||
46 | /** | 48 | /** |
47 | * fixed_bar_cap - return the offset of the fixed BAR cap if found | 49 | * fixed_bar_cap - return the offset of the fixed BAR cap if found |
48 | * @bus: PCI bus | 50 | * @bus: PCI bus |
@@ -148,7 +150,9 @@ static bool type1_access_ok(unsigned int bus, unsigned int devfn, int reg) | |||
148 | */ | 150 | */ |
149 | if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) | 151 | if (reg >= 0x100 || reg == PCI_STATUS || reg == PCI_HEADER_TYPE) |
150 | return 0; | 152 | return 0; |
151 | if (bus == 0 && (devfn == PCI_DEVFN(2, 0) || devfn == PCI_DEVFN(0, 0))) | 153 | if (bus == 0 && (devfn == PCI_DEVFN(2, 0) |
154 | || devfn == PCI_DEVFN(0, 0) | ||
155 | || devfn == PCI_DEVFN(3, 0))) | ||
152 | return 1; | 156 | return 1; |
153 | return 0; /* langwell on others */ | 157 | return 0; /* langwell on others */ |
154 | } | 158 | } |
@@ -231,14 +235,43 @@ struct pci_ops pci_mrst_ops = { | |||
231 | */ | 235 | */ |
232 | int __init pci_mrst_init(void) | 236 | int __init pci_mrst_init(void) |
233 | { | 237 | { |
234 | printk(KERN_INFO "Moorestown platform detected, using MRST PCI ops\n"); | 238 | printk(KERN_INFO "Intel MID platform detected, using MID PCI ops\n"); |
235 | pci_mmcfg_late_init(); | 239 | pci_mmcfg_late_init(); |
236 | pcibios_enable_irq = mrst_pci_irq_enable; | 240 | pcibios_enable_irq = mrst_pci_irq_enable; |
237 | pci_root_ops = pci_mrst_ops; | 241 | pci_root_ops = pci_mrst_ops; |
242 | pci_soc_mode = 1; | ||
238 | /* Continue with standard init */ | 243 | /* Continue with standard init */ |
239 | return 1; | 244 | return 1; |
240 | } | 245 | } |
241 | 246 | ||
247 | /* Langwell devices are not true pci devices, they are not subject to 10 ms | ||
248 | * d3 to d0 delay required by pci spec. | ||
249 | */ | ||
250 | static void __devinit pci_d3delay_fixup(struct pci_dev *dev) | ||
251 | { | ||
252 | /* PCI fixups are effectively decided compile time. If we have a dual | ||
253 | SoC/non-SoC kernel we don't want to mangle d3 on non SoC devices */ | ||
254 | if (!pci_soc_mode) | ||
255 | return; | ||
256 | /* true pci devices in lincroft should allow type 1 access, the rest | ||
257 | * are langwell fake pci devices. | ||
258 | */ | ||
259 | if (type1_access_ok(dev->bus->number, dev->devfn, PCI_DEVICE_ID)) | ||
260 | return; | ||
261 | dev->d3_delay = 0; | ||
262 | } | ||
263 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_d3delay_fixup); | ||
264 | |||
265 | static void __devinit mrst_power_off_unused_dev(struct pci_dev *dev) | ||
266 | { | ||
267 | pci_set_power_state(dev, PCI_D3cold); | ||
268 | } | ||
269 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0801, mrst_power_off_unused_dev); | ||
270 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0809, mrst_power_off_unused_dev); | ||
271 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x080C, mrst_power_off_unused_dev); | ||
272 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0812, mrst_power_off_unused_dev); | ||
273 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0815, mrst_power_off_unused_dev); | ||
274 | |||
242 | /* | 275 | /* |
243 | * Langwell devices reside at fixed offsets, don't try to move them. | 276 | * Langwell devices reside at fixed offsets, don't try to move them. |
244 | */ | 277 | */ |
@@ -248,6 +281,9 @@ static void __devinit pci_fixed_bar_fixup(struct pci_dev *dev) | |||
248 | u32 size; | 281 | u32 size; |
249 | int i; | 282 | int i; |
250 | 283 | ||
284 | if (!pci_soc_mode) | ||
285 | return; | ||
286 | |||
251 | /* Must have extended configuration space */ | 287 | /* Must have extended configuration space */ |
252 | if (dev->cfg_size < PCIE_CAP_OFFSET + 4) | 288 | if (dev->cfg_size < PCIE_CAP_OFFSET + 4) |
253 | return; | 289 | return; |
diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index 61045c192e88..eb30e356f5be 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c | |||
@@ -153,7 +153,7 @@ static void __init pci_controller_apertures(struct pci_controller *pci_ctrl, | |||
153 | } | 153 | } |
154 | res->start += io_offset; | 154 | res->start += io_offset; |
155 | res->end += io_offset; | 155 | res->end += io_offset; |
156 | pci_add_resource(resources, res); | 156 | pci_add_resource_offset(resources, res, io_offset); |
157 | 157 | ||
158 | for (i = 0; i < 3; i++) { | 158 | for (i = 0; i < 3; i++) { |
159 | res = &pci_ctrl->mem_resources[i]; | 159 | res = &pci_ctrl->mem_resources[i]; |
@@ -200,24 +200,9 @@ subsys_initcall(pcibios_init); | |||
200 | 200 | ||
201 | void __init pcibios_fixup_bus(struct pci_bus *bus) | 201 | void __init pcibios_fixup_bus(struct pci_bus *bus) |
202 | { | 202 | { |
203 | struct pci_controller *pci_ctrl = bus->sysdata; | ||
204 | struct resource *res; | ||
205 | unsigned long io_offset; | ||
206 | int i; | ||
207 | |||
208 | io_offset = (unsigned long)pci_ctrl->io_space.base; | ||
209 | if (bus->parent) { | 203 | if (bus->parent) { |
210 | /* This is a subordinate bridge */ | 204 | /* This is a subordinate bridge */ |
211 | pci_read_bridge_bases(bus); | 205 | pci_read_bridge_bases(bus); |
212 | |||
213 | for (i = 0; i < 4; i++) { | ||
214 | if ((res = bus->resource[i]) == NULL || !res->flags) | ||
215 | continue; | ||
216 | if (io_offset && (res->flags & IORESOURCE_IO)) { | ||
217 | res->start += io_offset; | ||
218 | res->end += io_offset; | ||
219 | } | ||
220 | } | ||
221 | } | 206 | } |
222 | } | 207 | } |
223 | 208 | ||
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index a7dc4672d996..a5c591ffe395 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -346,7 +346,7 @@ static int mpt_remove_dead_ioc_func(void *arg) | |||
346 | if ((pdev == NULL)) | 346 | if ((pdev == NULL)) |
347 | return -1; | 347 | return -1; |
348 | 348 | ||
349 | pci_remove_bus_device(pdev); | 349 | pci_stop_and_remove_bus_device(pdev); |
350 | return 0; | 350 | return 0; |
351 | } | 351 | } |
352 | 352 | ||
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index 7ff10c1e8664..0610e91bceb2 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c | |||
@@ -553,7 +553,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
553 | struct list_head *ln; | 553 | struct list_head *ln; |
554 | struct pci_dev *dev; | 554 | struct pci_dev *dev; |
555 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); | 555 | struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge)); |
556 | int port_base = HBA_PORT_BASE(dino_dev->hba.hba_num); | ||
557 | 556 | ||
558 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", | 557 | DBG(KERN_WARNING "%s(0x%p) bus %d platform_data 0x%p\n", |
559 | __func__, bus, bus->secondary, | 558 | __func__, bus, bus->secondary, |
@@ -599,8 +598,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
599 | 598 | ||
600 | 599 | ||
601 | list_for_each(ln, &bus->devices) { | 600 | list_for_each(ln, &bus->devices) { |
602 | int i; | ||
603 | |||
604 | dev = pci_dev_b(ln); | 601 | dev = pci_dev_b(ln); |
605 | if (is_card_dino(&dino_dev->hba.dev->id)) | 602 | if (is_card_dino(&dino_dev->hba.dev->id)) |
606 | dino_card_fixup(dev); | 603 | dino_card_fixup(dev); |
@@ -612,21 +609,6 @@ dino_fixup_bus(struct pci_bus *bus) | |||
612 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) | 609 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) |
613 | continue; | 610 | continue; |
614 | 611 | ||
615 | /* Adjust the I/O Port space addresses */ | ||
616 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
617 | struct resource *res = &dev->resource[i]; | ||
618 | if (res->flags & IORESOURCE_IO) { | ||
619 | res->start |= port_base; | ||
620 | res->end |= port_base; | ||
621 | } | ||
622 | #ifdef __LP64__ | ||
623 | /* Sign Extend MMIO addresses */ | ||
624 | else if (res->flags & IORESOURCE_MEM) { | ||
625 | res->start |= F_EXTEND(0UL); | ||
626 | res->end |= F_EXTEND(0UL); | ||
627 | } | ||
628 | #endif | ||
629 | } | ||
630 | /* null out the ROM resource if there is one (we don't | 612 | /* null out the ROM resource if there is one (we don't |
631 | * care about an expansion rom on parisc, since it | 613 | * care about an expansion rom on parisc, since it |
632 | * usually contains (x86) bios code) */ | 614 | * usually contains (x86) bios code) */ |
@@ -991,11 +973,14 @@ static int __init dino_probe(struct parisc_device *dev) | |||
991 | 973 | ||
992 | dev->dev.platform_data = dino_dev; | 974 | dev->dev.platform_data = dino_dev; |
993 | 975 | ||
994 | pci_add_resource(&resources, &dino_dev->hba.io_space); | 976 | pci_add_resource_offset(&resources, &dino_dev->hba.io_space, |
977 | HBA_PORT_BASE(dino_dev->hba.hba_num)); | ||
995 | if (dino_dev->hba.lmmio_space.flags) | 978 | if (dino_dev->hba.lmmio_space.flags) |
996 | pci_add_resource(&resources, &dino_dev->hba.lmmio_space); | 979 | pci_add_resource_offset(&resources, &dino_dev->hba.lmmio_space, |
980 | dino_dev->hba.lmmio_space_offset); | ||
997 | if (dino_dev->hba.elmmio_space.flags) | 981 | if (dino_dev->hba.elmmio_space.flags) |
998 | pci_add_resource(&resources, &dino_dev->hba.elmmio_space); | 982 | pci_add_resource_offset(&resources, &dino_dev->hba.elmmio_space, |
983 | dino_dev->hba.lmmio_space_offset); | ||
999 | if (dino_dev->hba.gmmio_space.flags) | 984 | if (dino_dev->hba.gmmio_space.flags) |
1000 | pci_add_resource(&resources, &dino_dev->hba.gmmio_space); | 985 | pci_add_resource(&resources, &dino_dev->hba.gmmio_space); |
1001 | 986 | ||
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index d5f3d753a108..e8857647e210 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c | |||
@@ -635,7 +635,6 @@ lba_fixup_bus(struct pci_bus *bus) | |||
635 | u16 status; | 635 | u16 status; |
636 | #endif | 636 | #endif |
637 | struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); | 637 | struct lba_device *ldev = LBA_DEV(parisc_walk_tree(bus->bridge)); |
638 | int lba_portbase = HBA_PORT_BASE(ldev->hba.hba_num); | ||
639 | 638 | ||
640 | DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", | 639 | DBG("lba_fixup_bus(0x%p) bus %d platform_data 0x%p\n", |
641 | bus, bus->secondary, bus->bridge->platform_data); | 640 | bus, bus->secondary, bus->bridge->platform_data); |
@@ -726,27 +725,6 @@ lba_fixup_bus(struct pci_bus *bus) | |||
726 | if (!res->start) | 725 | if (!res->start) |
727 | continue; | 726 | continue; |
728 | 727 | ||
729 | if (res->flags & IORESOURCE_IO) { | ||
730 | DBG("lba_fixup_bus() I/O Ports [%lx/%lx] -> ", | ||
731 | res->start, res->end); | ||
732 | res->start |= lba_portbase; | ||
733 | res->end |= lba_portbase; | ||
734 | DBG("[%lx/%lx]\n", res->start, res->end); | ||
735 | } else if (res->flags & IORESOURCE_MEM) { | ||
736 | /* | ||
737 | ** Convert PCI (IO_VIEW) addresses to | ||
738 | ** processor (PA_VIEW) addresses | ||
739 | */ | ||
740 | DBG("lba_fixup_bus() MMIO [%lx/%lx] -> ", | ||
741 | res->start, res->end); | ||
742 | res->start = PCI_HOST_ADDR(HBA_DATA(ldev), res->start); | ||
743 | res->end = PCI_HOST_ADDR(HBA_DATA(ldev), res->end); | ||
744 | DBG("[%lx/%lx]\n", res->start, res->end); | ||
745 | } else { | ||
746 | DBG("lba_fixup_bus() WTF? 0x%lx [%lx/%lx] XXX", | ||
747 | res->flags, res->start, res->end); | ||
748 | } | ||
749 | |||
750 | /* | 728 | /* |
751 | ** FIXME: this will result in whinging for devices | 729 | ** FIXME: this will result in whinging for devices |
752 | ** that share expansion ROMs (think quad tulip), but | 730 | ** that share expansion ROMs (think quad tulip), but |
@@ -1514,11 +1492,14 @@ lba_driver_probe(struct parisc_device *dev) | |||
1514 | lba_dev->hba.lmmio_space.flags = 0; | 1492 | lba_dev->hba.lmmio_space.flags = 0; |
1515 | } | 1493 | } |
1516 | 1494 | ||
1517 | pci_add_resource(&resources, &lba_dev->hba.io_space); | 1495 | pci_add_resource_offset(&resources, &lba_dev->hba.io_space, |
1496 | HBA_PORT_BASE(lba_dev->hba.hba_num)); | ||
1518 | if (lba_dev->hba.elmmio_space.start) | 1497 | if (lba_dev->hba.elmmio_space.start) |
1519 | pci_add_resource(&resources, &lba_dev->hba.elmmio_space); | 1498 | pci_add_resource_offset(&resources, &lba_dev->hba.elmmio_space, |
1499 | lba_dev->hba.lmmio_space_offset); | ||
1520 | if (lba_dev->hba.lmmio_space.flags) | 1500 | if (lba_dev->hba.lmmio_space.flags) |
1521 | pci_add_resource(&resources, &lba_dev->hba.lmmio_space); | 1501 | pci_add_resource_offset(&resources, &lba_dev->hba.lmmio_space, |
1502 | lba_dev->hba.lmmio_space_offset); | ||
1522 | if (lba_dev->hba.gmmio_space.flags) | 1503 | if (lba_dev->hba.gmmio_space.flags) |
1523 | pci_add_resource(&resources, &lba_dev->hba.gmmio_space); | 1504 | pci_add_resource(&resources, &lba_dev->hba.gmmio_space); |
1524 | 1505 | ||
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 37856f7c7781..848bfb84c04c 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig | |||
@@ -31,6 +31,19 @@ config PCI_DEBUG | |||
31 | 31 | ||
32 | When in doubt, say N. | 32 | When in doubt, say N. |
33 | 33 | ||
34 | config PCI_REALLOC_ENABLE_AUTO | ||
35 | bool "Enable PCI resource re-allocation detection" | ||
36 | depends on PCI | ||
37 | help | ||
38 | Say Y here if you want the PCI core to detect if PCI resource | ||
39 | re-allocation needs to be enabled. You can always use pci=realloc=on | ||
40 | or pci=realloc=off to override it. Note this feature is a no-op | ||
41 | unless PCI_IOV support is also enabled; in that case it will | ||
42 | automatically re-allocate PCI resources if SR-IOV BARs have not | ||
43 | been allocated by the BIOS. | ||
44 | |||
45 | When in doubt, say N. | ||
46 | |||
34 | config PCI_STUB | 47 | config PCI_STUB |
35 | tristate "PCI Stub driver" | 48 | tristate "PCI Stub driver" |
36 | depends on PCI | 49 | depends on PCI |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 398f5d859791..4ce5ef2f2826 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -18,28 +18,36 @@ | |||
18 | 18 | ||
19 | #include "pci.h" | 19 | #include "pci.h" |
20 | 20 | ||
21 | void pci_add_resource(struct list_head *resources, struct resource *res) | 21 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, |
22 | resource_size_t offset) | ||
22 | { | 23 | { |
23 | struct pci_bus_resource *bus_res; | 24 | struct pci_host_bridge_window *window; |
24 | 25 | ||
25 | bus_res = kzalloc(sizeof(struct pci_bus_resource), GFP_KERNEL); | 26 | window = kzalloc(sizeof(struct pci_host_bridge_window), GFP_KERNEL); |
26 | if (!bus_res) { | 27 | if (!window) { |
27 | printk(KERN_ERR "PCI: can't add bus resource %pR\n", res); | 28 | printk(KERN_ERR "PCI: can't add host bridge window %pR\n", res); |
28 | return; | 29 | return; |
29 | } | 30 | } |
30 | 31 | ||
31 | bus_res->res = res; | 32 | window->res = res; |
32 | list_add_tail(&bus_res->list, resources); | 33 | window->offset = offset; |
34 | list_add_tail(&window->list, resources); | ||
35 | } | ||
36 | EXPORT_SYMBOL(pci_add_resource_offset); | ||
37 | |||
38 | void pci_add_resource(struct list_head *resources, struct resource *res) | ||
39 | { | ||
40 | pci_add_resource_offset(resources, res, 0); | ||
33 | } | 41 | } |
34 | EXPORT_SYMBOL(pci_add_resource); | 42 | EXPORT_SYMBOL(pci_add_resource); |
35 | 43 | ||
36 | void pci_free_resource_list(struct list_head *resources) | 44 | void pci_free_resource_list(struct list_head *resources) |
37 | { | 45 | { |
38 | struct pci_bus_resource *bus_res, *tmp; | 46 | struct pci_host_bridge_window *window, *tmp; |
39 | 47 | ||
40 | list_for_each_entry_safe(bus_res, tmp, resources, list) { | 48 | list_for_each_entry_safe(window, tmp, resources, list) { |
41 | list_del(&bus_res->list); | 49 | list_del(&window->list); |
42 | kfree(bus_res); | 50 | kfree(window); |
43 | } | 51 | } |
44 | } | 52 | } |
45 | EXPORT_SYMBOL(pci_free_resource_list); | 53 | EXPORT_SYMBOL(pci_free_resource_list); |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 9ddf69e3bbef..806c44fa645a 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -800,20 +800,10 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
800 | if (slot->flags & SLOT_ENABLED) | 800 | if (slot->flags & SLOT_ENABLED) |
801 | goto err_exit; | 801 | goto err_exit; |
802 | 802 | ||
803 | /* sanity check: dev should be NULL when hot-plugged in */ | ||
804 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
805 | if (dev) { | ||
806 | /* This case shouldn't happen */ | ||
807 | err("pci_dev structure already exists.\n"); | ||
808 | pci_dev_put(dev); | ||
809 | retval = -1; | ||
810 | goto err_exit; | ||
811 | } | ||
812 | |||
813 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); | 803 | num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); |
814 | if (num == 0) { | 804 | if (num == 0) { |
815 | err("No new device found\n"); | 805 | /* Maybe only part of funcs are added. */ |
816 | retval = -1; | 806 | dbg("No new device found\n"); |
817 | goto err_exit; | 807 | goto err_exit; |
818 | } | 808 | } |
819 | 809 | ||
@@ -848,11 +838,16 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
848 | 838 | ||
849 | pci_bus_add_devices(bus); | 839 | pci_bus_add_devices(bus); |
850 | 840 | ||
841 | slot->flags |= SLOT_ENABLED; | ||
851 | list_for_each_entry(func, &slot->funcs, sibling) { | 842 | list_for_each_entry(func, &slot->funcs, sibling) { |
852 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, | 843 | dev = pci_get_slot(bus, PCI_DEVFN(slot->device, |
853 | func->function)); | 844 | func->function)); |
854 | if (!dev) | 845 | if (!dev) { |
846 | /* Do not set SLOT_ENABLED flag if some funcs | ||
847 | are not added. */ | ||
848 | slot->flags &= (~SLOT_ENABLED); | ||
855 | continue; | 849 | continue; |
850 | } | ||
856 | 851 | ||
857 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && | 852 | if (dev->hdr_type != PCI_HEADER_TYPE_BRIDGE && |
858 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { | 853 | dev->hdr_type != PCI_HEADER_TYPE_CARDBUS) { |
@@ -867,7 +862,6 @@ static int __ref enable_device(struct acpiphp_slot *slot) | |||
867 | pci_dev_put(dev); | 862 | pci_dev_put(dev); |
868 | } | 863 | } |
869 | 864 | ||
870 | slot->flags |= SLOT_ENABLED; | ||
871 | 865 | ||
872 | err_exit: | 866 | err_exit: |
873 | return retval; | 867 | return retval; |
@@ -892,9 +886,12 @@ static int disable_device(struct acpiphp_slot *slot) | |||
892 | { | 886 | { |
893 | struct acpiphp_func *func; | 887 | struct acpiphp_func *func; |
894 | struct pci_dev *pdev; | 888 | struct pci_dev *pdev; |
889 | struct pci_bus *bus = slot->bridge->pci_bus; | ||
895 | 890 | ||
896 | /* is this slot already disabled? */ | 891 | /* The slot will be enabled when func 0 is added, so check |
897 | if (!(slot->flags & SLOT_ENABLED)) | 892 | func 0 before disable the slot. */ |
893 | pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); | ||
894 | if (!pdev) | ||
898 | goto err_exit; | 895 | goto err_exit; |
899 | 896 | ||
900 | list_for_each_entry(func, &slot->funcs, sibling) { | 897 | list_for_each_entry(func, &slot->funcs, sibling) { |
@@ -913,7 +910,7 @@ static int disable_device(struct acpiphp_slot *slot) | |||
913 | disable_bridges(pdev->subordinate); | 910 | disable_bridges(pdev->subordinate); |
914 | pci_disable_device(pdev); | 911 | pci_disable_device(pdev); |
915 | } | 912 | } |
916 | pci_remove_bus_device(pdev); | 913 | __pci_remove_bus_device(pdev); |
917 | pci_dev_put(pdev); | 914 | pci_dev_put(pdev); |
918 | } | 915 | } |
919 | } | 916 | } |
@@ -1070,7 +1067,7 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
1070 | res->end) { | 1067 | res->end) { |
1071 | /* Could not assign a required resources | 1068 | /* Could not assign a required resources |
1072 | * for this device, remove it */ | 1069 | * for this device, remove it */ |
1073 | pci_remove_bus_device(dev); | 1070 | pci_stop_and_remove_bus_device(dev); |
1074 | break; | 1071 | break; |
1075 | } | 1072 | } |
1076 | } | 1073 | } |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 829c327cfb5e..ae853ccd0cd5 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -341,7 +341,7 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
341 | dev = pci_get_slot(slot->bus, | 341 | dev = pci_get_slot(slot->bus, |
342 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 342 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
343 | if (dev) { | 343 | if (dev) { |
344 | pci_remove_bus_device(dev); | 344 | pci_stop_and_remove_bus_device(dev); |
345 | pci_dev_put(dev); | 345 | pci_dev_put(dev); |
346 | } | 346 | } |
347 | } | 347 | } |
diff --git a/drivers/pci/hotplug/cpcihp_generic.c b/drivers/pci/hotplug/cpcihp_generic.c index fb3f84661bdc..81af764c629b 100644 --- a/drivers/pci/hotplug/cpcihp_generic.c +++ b/drivers/pci/hotplug/cpcihp_generic.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 62 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
63 | 63 | ||
64 | /* local variables */ | 64 | /* local variables */ |
65 | static int debug; | 65 | static bool debug; |
66 | static char *bridge; | 66 | static char *bridge; |
67 | static u8 bridge_busnr; | 67 | static u8 bridge_busnr; |
68 | static u8 bridge_slot; | 68 | static u8 bridge_slot; |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 6173b9a4544e..1c8494021a42 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -127,7 +127,7 @@ int cpqhp_unconfigure_device(struct pci_func* func) | |||
127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); | 127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); |
128 | if (temp) { | 128 | if (temp) { |
129 | pci_dev_put(temp); | 129 | pci_dev_put(temp); |
130 | pci_remove_bus_device(temp); | 130 | pci_stop_and_remove_bus_device(temp); |
131 | } | 131 | } |
132 | } | 132 | } |
133 | return 0; | 133 | return 0; |
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 17d10e2e8fb6..a019c9a712be 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c | |||
@@ -40,7 +40,7 @@ static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr, | |||
40 | 40 | ||
41 | static void remove_callback(void *data) | 41 | static void remove_callback(void *data) |
42 | { | 42 | { |
43 | pci_remove_bus_device((struct pci_dev *)data); | 43 | pci_stop_and_remove_bus_device((struct pci_dev *)data); |
44 | } | 44 | } |
45 | 45 | ||
46 | static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, | 46 | static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr, |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index 5506e0e8fbc0..4fda7e6a86a7 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -721,7 +721,7 @@ static void ibm_unconfigure_device(struct pci_func *func) | |||
721 | for (j = 0; j < 0x08; j++) { | 721 | for (j = 0; j < 0x08; j++) { |
722 | temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); | 722 | temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j); |
723 | if (temp) { | 723 | if (temp) { |
724 | pci_remove_bus_device(temp); | 724 | pci_stop_and_remove_bus_device(temp); |
725 | pci_dev_put(temp); | 725 | pci_dev_put(temp); |
726 | } | 726 | } |
727 | } | 727 | } |
diff --git a/drivers/pci/hotplug/ibmphp_ebda.c b/drivers/pci/hotplug/ibmphp_ebda.c index 2850e64dedae..714ca5c4ed50 100644 --- a/drivers/pci/hotplug/ibmphp_ebda.c +++ b/drivers/pci/hotplug/ibmphp_ebda.c | |||
@@ -368,8 +368,10 @@ int __init ibmphp_access_ebda (void) | |||
368 | debug ("rio blk id: %x\n", blk_id); | 368 | debug ("rio blk id: %x\n", blk_id); |
369 | 369 | ||
370 | rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); | 370 | rio_table_ptr = kzalloc(sizeof(struct rio_table_hdr), GFP_KERNEL); |
371 | if (!rio_table_ptr) | 371 | if (!rio_table_ptr) { |
372 | return -ENOMEM; | 372 | rc = -ENOMEM; |
373 | goto out; | ||
374 | } | ||
373 | rio_table_ptr->ver_num = readb (io_mem + offset); | 375 | rio_table_ptr->ver_num = readb (io_mem + offset); |
374 | rio_table_ptr->scal_count = readb (io_mem + offset + 1); | 376 | rio_table_ptr->scal_count = readb (io_mem + offset + 1); |
375 | rio_table_ptr->riodev_count = readb (io_mem + offset + 2); | 377 | rio_table_ptr->riodev_count = readb (io_mem + offset + 2); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index bcdbb1643621..a960faec1021 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -241,34 +241,79 @@ static int pcie_write_cmd(struct controller *ctrl, u16 cmd, u16 mask) | |||
241 | return retval; | 241 | return retval; |
242 | } | 242 | } |
243 | 243 | ||
244 | static inline int check_link_active(struct controller *ctrl) | 244 | static bool check_link_active(struct controller *ctrl) |
245 | { | 245 | { |
246 | u16 link_status; | 246 | bool ret = false; |
247 | u16 lnk_status; | ||
247 | 248 | ||
248 | if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &link_status)) | 249 | if (pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status)) |
249 | return 0; | 250 | return ret; |
250 | return !!(link_status & PCI_EXP_LNKSTA_DLLLA); | 251 | |
252 | ret = !!(lnk_status & PCI_EXP_LNKSTA_DLLLA); | ||
253 | |||
254 | if (ret) | ||
255 | ctrl_dbg(ctrl, "%s: lnk_status = %x\n", __func__, lnk_status); | ||
256 | |||
257 | return ret; | ||
251 | } | 258 | } |
252 | 259 | ||
253 | static void pcie_wait_link_active(struct controller *ctrl) | 260 | static void __pcie_wait_link_active(struct controller *ctrl, bool active) |
254 | { | 261 | { |
255 | int timeout = 1000; | 262 | int timeout = 1000; |
256 | 263 | ||
257 | if (check_link_active(ctrl)) | 264 | if (check_link_active(ctrl) == active) |
258 | return; | 265 | return; |
259 | while (timeout > 0) { | 266 | while (timeout > 0) { |
260 | msleep(10); | 267 | msleep(10); |
261 | timeout -= 10; | 268 | timeout -= 10; |
262 | if (check_link_active(ctrl)) | 269 | if (check_link_active(ctrl) == active) |
263 | return; | 270 | return; |
264 | } | 271 | } |
265 | ctrl_dbg(ctrl, "Data Link Layer Link Active not set in 1000 msec\n"); | 272 | ctrl_dbg(ctrl, "Data Link Layer Link Active not %s in 1000 msec\n", |
273 | active ? "set" : "cleared"); | ||
274 | } | ||
275 | |||
276 | static void pcie_wait_link_active(struct controller *ctrl) | ||
277 | { | ||
278 | __pcie_wait_link_active(ctrl, true); | ||
279 | } | ||
280 | |||
281 | static void pcie_wait_link_not_active(struct controller *ctrl) | ||
282 | { | ||
283 | __pcie_wait_link_active(ctrl, false); | ||
284 | } | ||
285 | |||
286 | static bool pci_bus_check_dev(struct pci_bus *bus, int devfn) | ||
287 | { | ||
288 | u32 l; | ||
289 | int count = 0; | ||
290 | int delay = 1000, step = 20; | ||
291 | bool found = false; | ||
292 | |||
293 | do { | ||
294 | found = pci_bus_read_dev_vendor_id(bus, devfn, &l, 0); | ||
295 | count++; | ||
296 | |||
297 | if (found) | ||
298 | break; | ||
299 | |||
300 | msleep(step); | ||
301 | delay -= step; | ||
302 | } while (delay > 0); | ||
303 | |||
304 | if (count > 1 && pciehp_debug) | ||
305 | printk(KERN_DEBUG "pci %04x:%02x:%02x.%d id reading try %d times with interval %d ms to get %08x\n", | ||
306 | pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), | ||
307 | PCI_FUNC(devfn), count, step, l); | ||
308 | |||
309 | return found; | ||
266 | } | 310 | } |
267 | 311 | ||
268 | int pciehp_check_link_status(struct controller *ctrl) | 312 | int pciehp_check_link_status(struct controller *ctrl) |
269 | { | 313 | { |
270 | u16 lnk_status; | 314 | u16 lnk_status; |
271 | int retval = 0; | 315 | int retval = 0; |
316 | bool found = false; | ||
272 | 317 | ||
273 | /* | 318 | /* |
274 | * Data Link Layer Link Active Reporting must be capable for | 319 | * Data Link Layer Link Active Reporting must be capable for |
@@ -280,13 +325,10 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
280 | else | 325 | else |
281 | msleep(1000); | 326 | msleep(1000); |
282 | 327 | ||
283 | /* | 328 | /* wait 100ms before read pci conf, and try in 1s */ |
284 | * Need to wait for 1000 ms after Data Link Layer Link Active | 329 | msleep(100); |
285 | * (DLLLA) bit reads 1b before sending configuration request. | 330 | found = pci_bus_check_dev(ctrl->pcie->port->subordinate, |
286 | * We need it before checking Link Training (LT) bit becuase | 331 | PCI_DEVFN(0, 0)); |
287 | * LT is still set even after DLLLA bit is set on some platform. | ||
288 | */ | ||
289 | msleep(1000); | ||
290 | 332 | ||
291 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); | 333 | retval = pciehp_readw(ctrl, PCI_EXP_LNKSTA, &lnk_status); |
292 | if (retval) { | 334 | if (retval) { |
@@ -302,19 +344,50 @@ int pciehp_check_link_status(struct controller *ctrl) | |||
302 | return retval; | 344 | return retval; |
303 | } | 345 | } |
304 | 346 | ||
305 | /* | ||
306 | * If the port supports Link speeds greater than 5.0 GT/s, we | ||
307 | * must wait for 100 ms after Link training completes before | ||
308 | * sending configuration request. | ||
309 | */ | ||
310 | if (ctrl->pcie->port->subordinate->max_bus_speed > PCIE_SPEED_5_0GT) | ||
311 | msleep(100); | ||
312 | |||
313 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); | 347 | pcie_update_link_speed(ctrl->pcie->port->subordinate, lnk_status); |
314 | 348 | ||
349 | if (!found && !retval) | ||
350 | retval = -1; | ||
351 | |||
315 | return retval; | 352 | return retval; |
316 | } | 353 | } |
317 | 354 | ||
355 | static int __pciehp_link_set(struct controller *ctrl, bool enable) | ||
356 | { | ||
357 | u16 lnk_ctrl; | ||
358 | int retval = 0; | ||
359 | |||
360 | retval = pciehp_readw(ctrl, PCI_EXP_LNKCTL, &lnk_ctrl); | ||
361 | if (retval) { | ||
362 | ctrl_err(ctrl, "Cannot read LNKCTRL register\n"); | ||
363 | return retval; | ||
364 | } | ||
365 | |||
366 | if (enable) | ||
367 | lnk_ctrl &= ~PCI_EXP_LNKCTL_LD; | ||
368 | else | ||
369 | lnk_ctrl |= PCI_EXP_LNKCTL_LD; | ||
370 | |||
371 | retval = pciehp_writew(ctrl, PCI_EXP_LNKCTL, lnk_ctrl); | ||
372 | if (retval) { | ||
373 | ctrl_err(ctrl, "Cannot write LNKCTRL register\n"); | ||
374 | return retval; | ||
375 | } | ||
376 | ctrl_dbg(ctrl, "%s: lnk_ctrl = %x\n", __func__, lnk_ctrl); | ||
377 | |||
378 | return retval; | ||
379 | } | ||
380 | |||
381 | static int pciehp_link_enable(struct controller *ctrl) | ||
382 | { | ||
383 | return __pciehp_link_set(ctrl, true); | ||
384 | } | ||
385 | |||
386 | static int pciehp_link_disable(struct controller *ctrl) | ||
387 | { | ||
388 | return __pciehp_link_set(ctrl, false); | ||
389 | } | ||
390 | |||
318 | int pciehp_get_attention_status(struct slot *slot, u8 *status) | 391 | int pciehp_get_attention_status(struct slot *slot, u8 *status) |
319 | { | 392 | { |
320 | struct controller *ctrl = slot->ctrl; | 393 | struct controller *ctrl = slot->ctrl; |
@@ -533,6 +606,10 @@ int pciehp_power_on_slot(struct slot * slot) | |||
533 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, | 606 | ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n", __func__, |
534 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); | 607 | pci_pcie_cap(ctrl->pcie->port) + PCI_EXP_SLTCTL, slot_cmd); |
535 | 608 | ||
609 | retval = pciehp_link_enable(ctrl); | ||
610 | if (retval) | ||
611 | ctrl_err(ctrl, "%s: Can not enable the link!\n", __func__); | ||
612 | |||
536 | return retval; | 613 | return retval; |
537 | } | 614 | } |
538 | 615 | ||
@@ -543,6 +620,14 @@ int pciehp_power_off_slot(struct slot * slot) | |||
543 | u16 cmd_mask; | 620 | u16 cmd_mask; |
544 | int retval; | 621 | int retval; |
545 | 622 | ||
623 | /* Disable the link at first */ | ||
624 | pciehp_link_disable(ctrl); | ||
625 | /* wait the link is down */ | ||
626 | if (ctrl->link_active_reporting) | ||
627 | pcie_wait_link_not_active(ctrl); | ||
628 | else | ||
629 | msleep(1000); | ||
630 | |||
546 | slot_cmd = POWER_OFF; | 631 | slot_cmd = POWER_OFF; |
547 | cmd_mask = PCI_EXP_SLTCTL_PCC; | 632 | cmd_mask = PCI_EXP_SLTCTL_PCC; |
548 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); | 633 | retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask); |
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index a4031dfe938e..47d9dc06b109 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -141,7 +141,7 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | } | 143 | } |
144 | pci_remove_bus_device(temp); | 144 | pci_stop_and_remove_bus_device(temp); |
145 | /* | 145 | /* |
146 | * Ensure that no new Requests will be generated from | 146 | * Ensure that no new Requests will be generated from |
147 | * the device. | 147 | * the device. |
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index c56a9413e1af..1e117c2a3cad 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c | |||
@@ -389,7 +389,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) | |||
389 | BUG_ON(!bus->self); | 389 | BUG_ON(!bus->self); |
390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); | 390 | pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); |
391 | eeh_remove_bus_device(bus->self); | 391 | eeh_remove_bus_device(bus->self); |
392 | pci_remove_bus_device(bus->self); | 392 | pci_stop_and_remove_bus_device(bus->self); |
393 | 393 | ||
394 | return 0; | 394 | return 0; |
395 | } | 395 | } |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 72d507b6a2aa..de573113c102 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -554,7 +554,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
554 | PCI_FUNC(func))); | 554 | PCI_FUNC(func))); |
555 | if (dev) { | 555 | if (dev) { |
556 | sn_bus_free_data(dev); | 556 | sn_bus_free_data(dev); |
557 | pci_remove_bus_device(dev); | 557 | pci_stop_and_remove_bus_device(dev); |
558 | pci_dev_put(dev); | 558 | pci_dev_put(dev); |
559 | } | 559 | } |
560 | } | 560 | } |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index a2ccfcd3c298..df7e4bfadae3 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -124,7 +124,7 @@ int shpchp_unconfigure_device(struct slot *p_slot) | |||
124 | break; | 124 | break; |
125 | } | 125 | } |
126 | } | 126 | } |
127 | pci_remove_bus_device(temp); | 127 | pci_stop_and_remove_bus_device(temp); |
128 | pci_dev_put(temp); | 128 | pci_dev_put(temp); |
129 | } | 129 | } |
130 | return rc; | 130 | return rc; |
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 0dab5ecf61bb..6554e1a0f634 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c | |||
@@ -142,7 +142,7 @@ failed2: | |||
142 | failed1: | 142 | failed1: |
143 | pci_dev_put(dev); | 143 | pci_dev_put(dev); |
144 | mutex_lock(&iov->dev->sriov->lock); | 144 | mutex_lock(&iov->dev->sriov->lock); |
145 | pci_remove_bus_device(virtfn); | 145 | pci_stop_and_remove_bus_device(virtfn); |
146 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); | 146 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); |
147 | mutex_unlock(&iov->dev->sriov->lock); | 147 | mutex_unlock(&iov->dev->sriov->lock); |
148 | 148 | ||
@@ -173,10 +173,16 @@ static void virtfn_remove(struct pci_dev *dev, int id, int reset) | |||
173 | 173 | ||
174 | sprintf(buf, "virtfn%u", id); | 174 | sprintf(buf, "virtfn%u", id); |
175 | sysfs_remove_link(&dev->dev.kobj, buf); | 175 | sysfs_remove_link(&dev->dev.kobj, buf); |
176 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); | 176 | /* |
177 | * pci_stop_dev() could have been called for this virtfn already, | ||
178 | * so the directory for the virtfn may have been removed before. | ||
179 | * Double check to avoid spurious sysfs warnings. | ||
180 | */ | ||
181 | if (virtfn->dev.kobj.sd) | ||
182 | sysfs_remove_link(&virtfn->dev.kobj, "physfn"); | ||
177 | 183 | ||
178 | mutex_lock(&iov->dev->sriov->lock); | 184 | mutex_lock(&iov->dev->sriov->lock); |
179 | pci_remove_bus_device(virtfn); | 185 | pci_stop_and_remove_bus_device(virtfn); |
180 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); | 186 | virtfn_remove_bus(dev->bus, virtfn_bus(dev, id)); |
181 | mutex_unlock(&iov->dev->sriov->lock); | 187 | mutex_unlock(&iov->dev->sriov->lock); |
182 | 188 | ||
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8d9616b821ca..6b54b23b990b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -419,6 +419,16 @@ static void pci_device_shutdown(struct device *dev) | |||
419 | drv->shutdown(pci_dev); | 419 | drv->shutdown(pci_dev); |
420 | pci_msi_shutdown(pci_dev); | 420 | pci_msi_shutdown(pci_dev); |
421 | pci_msix_shutdown(pci_dev); | 421 | pci_msix_shutdown(pci_dev); |
422 | |||
423 | /* | ||
424 | * Devices may be enabled to wake up by runtime PM, but they need not | ||
425 | * be supposed to wake up the system from its "power off" state (e.g. | ||
426 | * ACPI S5). Therefore disable wakeup for all devices that aren't | ||
427 | * supposed to wake up the system at this point. The state argument | ||
428 | * will be ignored by pci_enable_wake(). | ||
429 | */ | ||
430 | if (!device_may_wakeup(dev)) | ||
431 | pci_enable_wake(pci_dev, PCI_UNKNOWN, false); | ||
422 | } | 432 | } |
423 | 433 | ||
424 | #ifdef CONFIG_PM | 434 | #ifdef CONFIG_PM |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a3cd8cad532a..a55e248618cd 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -330,7 +330,7 @@ static void remove_callback(struct device *dev) | |||
330 | struct pci_dev *pdev = to_pci_dev(dev); | 330 | struct pci_dev *pdev = to_pci_dev(dev); |
331 | 331 | ||
332 | mutex_lock(&pci_remove_rescan_mutex); | 332 | mutex_lock(&pci_remove_rescan_mutex); |
333 | pci_remove_bus_device(pdev); | 333 | pci_stop_and_remove_bus_device(pdev); |
334 | mutex_unlock(&pci_remove_rescan_mutex); | 334 | mutex_unlock(&pci_remove_rescan_mutex); |
335 | } | 335 | } |
336 | 336 | ||
@@ -366,7 +366,10 @@ dev_bus_rescan_store(struct device *dev, struct device_attribute *attr, | |||
366 | 366 | ||
367 | if (val) { | 367 | if (val) { |
368 | mutex_lock(&pci_remove_rescan_mutex); | 368 | mutex_lock(&pci_remove_rescan_mutex); |
369 | pci_rescan_bus(bus); | 369 | if (!pci_is_root_bus(bus) && list_empty(&bus->devices)) |
370 | pci_rescan_bus_bridge_resize(bus->self); | ||
371 | else | ||
372 | pci_rescan_bus(bus); | ||
370 | mutex_unlock(&pci_remove_rescan_mutex); | 373 | mutex_unlock(&pci_remove_rescan_mutex); |
371 | } | 374 | } |
372 | return count; | 375 | return count; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 053670e09e2b..815674415267 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -94,6 +94,9 @@ u8 pci_cache_line_size; | |||
94 | */ | 94 | */ |
95 | unsigned int pcibios_max_latency = 255; | 95 | unsigned int pcibios_max_latency = 255; |
96 | 96 | ||
97 | /* If set, the PCIe ARI capability will not be used. */ | ||
98 | static bool pcie_ari_disabled; | ||
99 | |||
97 | /** | 100 | /** |
98 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children | 101 | * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children |
99 | * @bus: pointer to PCI bus structure to search | 102 | * @bus: pointer to PCI bus structure to search |
@@ -825,6 +828,19 @@ EXPORT_SYMBOL(pci_choose_state); | |||
825 | #define pcie_cap_has_sltctl2(type, flags) \ | 828 | #define pcie_cap_has_sltctl2(type, flags) \ |
826 | ((flags & PCI_EXP_FLAGS_VERS) > 1) | 829 | ((flags & PCI_EXP_FLAGS_VERS) > 1) |
827 | 830 | ||
831 | static struct pci_cap_saved_state *pci_find_saved_cap( | ||
832 | struct pci_dev *pci_dev, char cap) | ||
833 | { | ||
834 | struct pci_cap_saved_state *tmp; | ||
835 | struct hlist_node *pos; | ||
836 | |||
837 | hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { | ||
838 | if (tmp->cap.cap_nr == cap) | ||
839 | return tmp; | ||
840 | } | ||
841 | return NULL; | ||
842 | } | ||
843 | |||
828 | static int pci_save_pcie_state(struct pci_dev *dev) | 844 | static int pci_save_pcie_state(struct pci_dev *dev) |
829 | { | 845 | { |
830 | int pos, i = 0; | 846 | int pos, i = 0; |
@@ -959,6 +975,7 @@ void pci_restore_state(struct pci_dev *dev) | |||
959 | { | 975 | { |
960 | int i; | 976 | int i; |
961 | u32 val; | 977 | u32 val; |
978 | int tries; | ||
962 | 979 | ||
963 | if (!dev->state_saved) | 980 | if (!dev->state_saved) |
964 | return; | 981 | return; |
@@ -973,12 +990,16 @@ void pci_restore_state(struct pci_dev *dev) | |||
973 | */ | 990 | */ |
974 | for (i = 15; i >= 0; i--) { | 991 | for (i = 15; i >= 0; i--) { |
975 | pci_read_config_dword(dev, i * 4, &val); | 992 | pci_read_config_dword(dev, i * 4, &val); |
976 | if (val != dev->saved_config_space[i]) { | 993 | tries = 10; |
994 | while (tries && val != dev->saved_config_space[i]) { | ||
977 | dev_dbg(&dev->dev, "restoring config " | 995 | dev_dbg(&dev->dev, "restoring config " |
978 | "space at offset %#x (was %#x, writing %#x)\n", | 996 | "space at offset %#x (was %#x, writing %#x)\n", |
979 | i, val, (int)dev->saved_config_space[i]); | 997 | i, val, (int)dev->saved_config_space[i]); |
980 | pci_write_config_dword(dev,i * 4, | 998 | pci_write_config_dword(dev,i * 4, |
981 | dev->saved_config_space[i]); | 999 | dev->saved_config_space[i]); |
1000 | pci_read_config_dword(dev, i * 4, &val); | ||
1001 | mdelay(10); | ||
1002 | tries--; | ||
982 | } | 1003 | } |
983 | } | 1004 | } |
984 | pci_restore_pcix_state(dev); | 1005 | pci_restore_pcix_state(dev); |
@@ -1864,6 +1885,12 @@ void platform_pci_wakeup_init(struct pci_dev *dev) | |||
1864 | platform_pci_sleep_wake(dev, false); | 1885 | platform_pci_sleep_wake(dev, false); |
1865 | } | 1886 | } |
1866 | 1887 | ||
1888 | static void pci_add_saved_cap(struct pci_dev *pci_dev, | ||
1889 | struct pci_cap_saved_state *new_cap) | ||
1890 | { | ||
1891 | hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); | ||
1892 | } | ||
1893 | |||
1867 | /** | 1894 | /** |
1868 | * pci_add_save_buffer - allocate buffer for saving given capability registers | 1895 | * pci_add_save_buffer - allocate buffer for saving given capability registers |
1869 | * @dev: the PCI device | 1896 | * @dev: the PCI device |
@@ -1911,6 +1938,15 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev) | |||
1911 | "unable to preallocate PCI-X save buffer\n"); | 1938 | "unable to preallocate PCI-X save buffer\n"); |
1912 | } | 1939 | } |
1913 | 1940 | ||
1941 | void pci_free_cap_save_buffers(struct pci_dev *dev) | ||
1942 | { | ||
1943 | struct pci_cap_saved_state *tmp; | ||
1944 | struct hlist_node *pos, *n; | ||
1945 | |||
1946 | hlist_for_each_entry_safe(tmp, pos, n, &dev->saved_cap_space, next) | ||
1947 | kfree(tmp); | ||
1948 | } | ||
1949 | |||
1914 | /** | 1950 | /** |
1915 | * pci_enable_ari - enable ARI forwarding if hardware support it | 1951 | * pci_enable_ari - enable ARI forwarding if hardware support it |
1916 | * @dev: the PCI device | 1952 | * @dev: the PCI device |
@@ -1922,7 +1958,7 @@ void pci_enable_ari(struct pci_dev *dev) | |||
1922 | u16 flags, ctrl; | 1958 | u16 flags, ctrl; |
1923 | struct pci_dev *bridge; | 1959 | struct pci_dev *bridge; |
1924 | 1960 | ||
1925 | if (!pci_is_pcie(dev) || dev->devfn) | 1961 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) |
1926 | return; | 1962 | return; |
1927 | 1963 | ||
1928 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1964 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); |
@@ -3661,6 +3697,68 @@ int pci_is_reassigndev(struct pci_dev *dev) | |||
3661 | return (pci_specified_resource_alignment(dev) != 0); | 3697 | return (pci_specified_resource_alignment(dev) != 0); |
3662 | } | 3698 | } |
3663 | 3699 | ||
3700 | /* | ||
3701 | * This function disables memory decoding and releases memory resources | ||
3702 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
3703 | * It also rounds up size to specified alignment. | ||
3704 | * Later on, the kernel will assign page-aligned memory resource back | ||
3705 | * to the device. | ||
3706 | */ | ||
3707 | void pci_reassigndev_resource_alignment(struct pci_dev *dev) | ||
3708 | { | ||
3709 | int i; | ||
3710 | struct resource *r; | ||
3711 | resource_size_t align, size; | ||
3712 | u16 command; | ||
3713 | |||
3714 | if (!pci_is_reassigndev(dev)) | ||
3715 | return; | ||
3716 | |||
3717 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
3718 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
3719 | dev_warn(&dev->dev, | ||
3720 | "Can't reassign resources to host bridge.\n"); | ||
3721 | return; | ||
3722 | } | ||
3723 | |||
3724 | dev_info(&dev->dev, | ||
3725 | "Disabling memory decoding and releasing memory resources.\n"); | ||
3726 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
3727 | command &= ~PCI_COMMAND_MEMORY; | ||
3728 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
3729 | |||
3730 | align = pci_specified_resource_alignment(dev); | ||
3731 | for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
3732 | r = &dev->resource[i]; | ||
3733 | if (!(r->flags & IORESOURCE_MEM)) | ||
3734 | continue; | ||
3735 | size = resource_size(r); | ||
3736 | if (size < align) { | ||
3737 | size = align; | ||
3738 | dev_info(&dev->dev, | ||
3739 | "Rounding up size of resource #%d to %#llx.\n", | ||
3740 | i, (unsigned long long)size); | ||
3741 | } | ||
3742 | r->end = size - 1; | ||
3743 | r->start = 0; | ||
3744 | } | ||
3745 | /* Need to disable bridge's resource window, | ||
3746 | * to enable the kernel to reassign new resource | ||
3747 | * window later on. | ||
3748 | */ | ||
3749 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
3750 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
3751 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
3752 | r = &dev->resource[i]; | ||
3753 | if (!(r->flags & IORESOURCE_MEM)) | ||
3754 | continue; | ||
3755 | r->end = resource_size(r) - 1; | ||
3756 | r->start = 0; | ||
3757 | } | ||
3758 | pci_disable_bridge_window(dev); | ||
3759 | } | ||
3760 | } | ||
3761 | |||
3664 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) | 3762 | ssize_t pci_set_resource_alignment_param(const char *buf, size_t count) |
3665 | { | 3763 | { |
3666 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) | 3764 | if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1) |
@@ -3739,10 +3837,14 @@ static int __init pci_setup(char *str) | |||
3739 | pci_no_msi(); | 3837 | pci_no_msi(); |
3740 | } else if (!strcmp(str, "noaer")) { | 3838 | } else if (!strcmp(str, "noaer")) { |
3741 | pci_no_aer(); | 3839 | pci_no_aer(); |
3840 | } else if (!strncmp(str, "realloc=", 8)) { | ||
3841 | pci_realloc_get_opt(str + 8); | ||
3742 | } else if (!strncmp(str, "realloc", 7)) { | 3842 | } else if (!strncmp(str, "realloc", 7)) { |
3743 | pci_realloc(); | 3843 | pci_realloc_get_opt("on"); |
3744 | } else if (!strcmp(str, "nodomains")) { | 3844 | } else if (!strcmp(str, "nodomains")) { |
3745 | pci_no_domains(); | 3845 | pci_no_domains(); |
3846 | } else if (!strncmp(str, "noari", 5)) { | ||
3847 | pcie_ari_disabled = true; | ||
3746 | } else if (!strncmp(str, "cbiosize=", 9)) { | 3848 | } else if (!strncmp(str, "cbiosize=", 9)) { |
3747 | pci_cardbus_io_size = memparse(str + 9, &str); | 3849 | pci_cardbus_io_size = memparse(str + 9, &str); |
3748 | } else if (!strncmp(str, "cbmemsize=", 10)) { | 3850 | } else if (!strncmp(str, "cbmemsize=", 10)) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 1009a5e88e53..e4943479b234 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -73,6 +73,7 @@ extern int __pci_pme_wakeup(struct pci_dev *dev, void *ign); | |||
73 | extern void pci_pm_init(struct pci_dev *dev); | 73 | extern void pci_pm_init(struct pci_dev *dev); |
74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); | 74 | extern void platform_pci_wakeup_init(struct pci_dev *dev); |
75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); | 75 | extern void pci_allocate_cap_save_buffers(struct pci_dev *dev); |
76 | void pci_free_cap_save_buffers(struct pci_dev *dev); | ||
76 | 77 | ||
77 | static inline void pci_wakeup_event(struct pci_dev *dev) | 78 | static inline void pci_wakeup_event(struct pci_dev *dev) |
78 | { | 79 | { |
@@ -148,7 +149,7 @@ static inline void pci_no_msi(void) { } | |||
148 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 149 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
149 | #endif | 150 | #endif |
150 | 151 | ||
151 | extern void pci_realloc(void); | 152 | void pci_realloc_get_opt(char *); |
152 | 153 | ||
153 | static inline int pci_no_d1d2(struct pci_dev *dev) | 154 | static inline int pci_no_d1d2(struct pci_dev *dev) |
154 | { | 155 | { |
@@ -207,6 +208,8 @@ enum pci_bar_type { | |||
207 | pci_bar_mem64, /* A 64-bit memory BAR */ | 208 | pci_bar_mem64, /* A 64-bit memory BAR */ |
208 | }; | 209 | }; |
209 | 210 | ||
211 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *pl, | ||
212 | int crs_timeout); | ||
210 | extern int pci_setup_device(struct pci_dev *dev); | 213 | extern int pci_setup_device(struct pci_dev *dev); |
211 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | 214 | extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, |
212 | struct resource *res, unsigned int reg); | 215 | struct resource *res, unsigned int reg); |
@@ -225,11 +228,8 @@ static inline int pci_ari_enabled(struct pci_bus *bus) | |||
225 | return bus->self && bus->self->ari_enabled; | 228 | return bus->self && bus->self->ari_enabled; |
226 | } | 229 | } |
227 | 230 | ||
228 | #ifdef CONFIG_PCI_QUIRKS | 231 | void pci_reassigndev_resource_alignment(struct pci_dev *dev); |
229 | extern int pci_is_reassigndev(struct pci_dev *dev); | ||
230 | resource_size_t pci_specified_resource_alignment(struct pci_dev *dev); | ||
231 | extern void pci_disable_bridge_window(struct pci_dev *dev); | 232 | extern void pci_disable_bridge_window(struct pci_dev *dev); |
232 | #endif | ||
233 | 233 | ||
234 | /* Single Root I/O Virtualization */ | 234 | /* Single Root I/O Virtualization */ |
235 | struct pci_sriov { | 235 | struct pci_sriov { |
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig index 72962cc92e0a..6c8bc5809787 100644 --- a/drivers/pci/pcie/Kconfig +++ b/drivers/pci/pcie/Kconfig | |||
@@ -55,6 +55,31 @@ config PCIEASPM_DEBUG | |||
55 | This enables PCI Express ASPM debug support. It will add per-device | 55 | This enables PCI Express ASPM debug support. It will add per-device |
56 | interface to control ASPM. | 56 | interface to control ASPM. |
57 | 57 | ||
58 | choice | ||
59 | prompt "Default ASPM policy" | ||
60 | default PCIEASPM_DEFAULT | ||
61 | depends on PCIEASPM | ||
62 | |||
63 | config PCIEASPM_DEFAULT | ||
64 | bool "BIOS default" | ||
65 | depends on PCIEASPM | ||
66 | help | ||
67 | Use the BIOS defaults for PCI Express ASPM. | ||
68 | |||
69 | config PCIEASPM_POWERSAVE | ||
70 | bool "Powersave" | ||
71 | depends on PCIEASPM | ||
72 | help | ||
73 | Enable PCI Express ASPM L0s and L1 where possible, even if the | ||
74 | BIOS did not. | ||
75 | |||
76 | config PCIEASPM_PERFORMANCE | ||
77 | bool "Performance" | ||
78 | depends on PCIEASPM | ||
79 | help | ||
80 | Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them. | ||
81 | endchoice | ||
82 | |||
58 | config PCIE_PME | 83 | config PCIE_PME |
59 | def_bool y | 84 | def_bool y |
60 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI | 85 | depends on PCIEPORTBUS && PM_RUNTIME && EXPERIMENTAL && ACPI |
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 24f049e73952..4bdef24cd412 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c | |||
@@ -76,7 +76,15 @@ static LIST_HEAD(link_list); | |||
76 | #define POLICY_DEFAULT 0 /* BIOS default setting */ | 76 | #define POLICY_DEFAULT 0 /* BIOS default setting */ |
77 | #define POLICY_PERFORMANCE 1 /* high performance */ | 77 | #define POLICY_PERFORMANCE 1 /* high performance */ |
78 | #define POLICY_POWERSAVE 2 /* high power saving */ | 78 | #define POLICY_POWERSAVE 2 /* high power saving */ |
79 | |||
80 | #ifdef CONFIG_PCIEASPM_PERFORMANCE | ||
81 | static int aspm_policy = POLICY_PERFORMANCE; | ||
82 | #elif defined CONFIG_PCIEASPM_POWERSAVE | ||
83 | static int aspm_policy = POLICY_POWERSAVE; | ||
84 | #else | ||
79 | static int aspm_policy; | 85 | static int aspm_policy; |
86 | #endif | ||
87 | |||
80 | static const char *policy_str[] = { | 88 | static const char *policy_str[] = { |
81 | [POLICY_DEFAULT] = "default", | 89 | [POLICY_DEFAULT] = "default", |
82 | [POLICY_PERFORMANCE] = "performance", | 90 | [POLICY_PERFORMANCE] = "performance", |
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index bd00a01aef14..eea2ca2375e6 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h | |||
@@ -34,6 +34,18 @@ struct pci_dev; | |||
34 | 34 | ||
35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); | 35 | extern void pcie_clear_root_pme_status(struct pci_dev *dev); |
36 | 36 | ||
37 | #ifdef CONFIG_HOTPLUG_PCI_PCIE | ||
38 | extern bool pciehp_msi_disabled; | ||
39 | |||
40 | static inline bool pciehp_no_msi(void) | ||
41 | { | ||
42 | return pciehp_msi_disabled; | ||
43 | } | ||
44 | |||
45 | #else /* !CONFIG_HOTPLUG_PCI_PCIE */ | ||
46 | static inline bool pciehp_no_msi(void) { return false; } | ||
47 | #endif /* !CONFIG_HOTPLUG_PCI_PCIE */ | ||
48 | |||
37 | #ifdef CONFIG_PCIE_PME | 49 | #ifdef CONFIG_PCIE_PME |
38 | extern bool pcie_pme_msi_disabled; | 50 | extern bool pcie_pme_msi_disabled; |
39 | 51 | ||
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index 595654a1a6a6..2f589a54f9bd 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c | |||
@@ -19,6 +19,17 @@ | |||
19 | #include "../pci.h" | 19 | #include "../pci.h" |
20 | #include "portdrv.h" | 20 | #include "portdrv.h" |
21 | 21 | ||
22 | bool pciehp_msi_disabled; | ||
23 | |||
24 | static int __init pciehp_setup(char *str) | ||
25 | { | ||
26 | if (!strncmp(str, "nomsi", 5)) | ||
27 | pciehp_msi_disabled = true; | ||
28 | |||
29 | return 1; | ||
30 | } | ||
31 | __setup("pcie_hp=", pciehp_setup); | ||
32 | |||
22 | /** | 33 | /** |
23 | * release_pcie_device - free PCI Express port service device structure | 34 | * release_pcie_device - free PCI Express port service device structure |
24 | * @dev: Port service device to release | 35 | * @dev: Port service device to release |
@@ -189,8 +200,9 @@ static int init_service_irqs(struct pci_dev *dev, int *irqs, int mask) | |||
189 | { | 200 | { |
190 | int i, irq = -1; | 201 | int i, irq = -1; |
191 | 202 | ||
192 | /* We have to use INTx if MSI cannot be used for PCIe PME. */ | 203 | /* We have to use INTx if MSI cannot be used for PCIe PME or pciehp. */ |
193 | if ((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) { | 204 | if (((mask & PCIE_PORT_SERVICE_PME) && pcie_pme_no_msi()) || |
205 | ((mask & PCIE_PORT_SERVICE_HP) && pciehp_no_msi())) { | ||
194 | if (dev->pin) | 206 | if (dev->pin) |
195 | irq = dev->irq; | 207 | irq = dev->irq; |
196 | goto no_msi; | 208 | goto no_msi; |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 71eac9cd724d..5e1ca3c58a7d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | 15 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ |
16 | #define CARDBUS_RESERVE_BUSNR 3 | 16 | #define CARDBUS_RESERVE_BUSNR 3 |
17 | 17 | ||
18 | static LIST_HEAD(pci_host_bridges); | ||
19 | |||
18 | /* Ugh. Need to stop exporting this to modules. */ | 20 | /* Ugh. Need to stop exporting this to modules. */ |
19 | LIST_HEAD(pci_root_buses); | 21 | LIST_HEAD(pci_root_buses); |
20 | EXPORT_SYMBOL(pci_root_buses); | 22 | EXPORT_SYMBOL(pci_root_buses); |
@@ -42,6 +44,82 @@ int no_pci_devices(void) | |||
42 | } | 44 | } |
43 | EXPORT_SYMBOL(no_pci_devices); | 45 | EXPORT_SYMBOL(no_pci_devices); |
44 | 46 | ||
47 | static struct pci_host_bridge *pci_host_bridge(struct pci_dev *dev) | ||
48 | { | ||
49 | struct pci_bus *bus; | ||
50 | struct pci_host_bridge *bridge; | ||
51 | |||
52 | bus = dev->bus; | ||
53 | while (bus->parent) | ||
54 | bus = bus->parent; | ||
55 | |||
56 | list_for_each_entry(bridge, &pci_host_bridges, list) { | ||
57 | if (bridge->bus == bus) | ||
58 | return bridge; | ||
59 | } | ||
60 | |||
61 | return NULL; | ||
62 | } | ||
63 | |||
64 | static bool resource_contains(struct resource *res1, struct resource *res2) | ||
65 | { | ||
66 | return res1->start <= res2->start && res1->end >= res2->end; | ||
67 | } | ||
68 | |||
69 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
70 | struct resource *res) | ||
71 | { | ||
72 | struct pci_host_bridge *bridge = pci_host_bridge(dev); | ||
73 | struct pci_host_bridge_window *window; | ||
74 | resource_size_t offset = 0; | ||
75 | |||
76 | list_for_each_entry(window, &bridge->windows, list) { | ||
77 | if (resource_type(res) != resource_type(window->res)) | ||
78 | continue; | ||
79 | |||
80 | if (resource_contains(window->res, res)) { | ||
81 | offset = window->offset; | ||
82 | break; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | region->start = res->start - offset; | ||
87 | region->end = res->end - offset; | ||
88 | } | ||
89 | EXPORT_SYMBOL(pcibios_resource_to_bus); | ||
90 | |||
91 | static bool region_contains(struct pci_bus_region *region1, | ||
92 | struct pci_bus_region *region2) | ||
93 | { | ||
94 | return region1->start <= region2->start && region1->end >= region2->end; | ||
95 | } | ||
96 | |||
97 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
98 | struct pci_bus_region *region) | ||
99 | { | ||
100 | struct pci_host_bridge *bridge = pci_host_bridge(dev); | ||
101 | struct pci_host_bridge_window *window; | ||
102 | struct pci_bus_region bus_region; | ||
103 | resource_size_t offset = 0; | ||
104 | |||
105 | list_for_each_entry(window, &bridge->windows, list) { | ||
106 | if (resource_type(res) != resource_type(window->res)) | ||
107 | continue; | ||
108 | |||
109 | bus_region.start = window->res->start - window->offset; | ||
110 | bus_region.end = window->res->end - window->offset; | ||
111 | |||
112 | if (region_contains(&bus_region, region)) { | ||
113 | offset = window->offset; | ||
114 | break; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | res->start = region->start + offset; | ||
119 | res->end = region->end + offset; | ||
120 | } | ||
121 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
122 | |||
45 | /* | 123 | /* |
46 | * PCI Bus Class | 124 | * PCI Bus Class |
47 | */ | 125 | */ |
@@ -135,6 +213,7 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
135 | { | 213 | { |
136 | u32 l, sz, mask; | 214 | u32 l, sz, mask; |
137 | u16 orig_cmd; | 215 | u16 orig_cmd; |
216 | struct pci_bus_region region; | ||
138 | 217 | ||
139 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; | 218 | mask = type ? PCI_ROM_ADDRESS_MASK : ~0; |
140 | 219 | ||
@@ -214,11 +293,13 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
214 | /* Address above 32-bit boundary; disable the BAR */ | 293 | /* Address above 32-bit boundary; disable the BAR */ |
215 | pci_write_config_dword(dev, pos, 0); | 294 | pci_write_config_dword(dev, pos, 0); |
216 | pci_write_config_dword(dev, pos + 4, 0); | 295 | pci_write_config_dword(dev, pos + 4, 0); |
217 | res->start = 0; | 296 | region.start = 0; |
218 | res->end = sz64; | 297 | region.end = sz64; |
298 | pcibios_bus_to_resource(dev, res, ®ion); | ||
219 | } else { | 299 | } else { |
220 | res->start = l64; | 300 | region.start = l64; |
221 | res->end = l64 + sz64; | 301 | region.end = l64 + sz64; |
302 | pcibios_bus_to_resource(dev, res, ®ion); | ||
222 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", | 303 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", |
223 | pos, res); | 304 | pos, res); |
224 | } | 305 | } |
@@ -228,8 +309,9 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
228 | if (!sz) | 309 | if (!sz) |
229 | goto fail; | 310 | goto fail; |
230 | 311 | ||
231 | res->start = l; | 312 | region.start = l; |
232 | res->end = l + sz; | 313 | region.end = l + sz; |
314 | pcibios_bus_to_resource(dev, res, ®ion); | ||
233 | 315 | ||
234 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); | 316 | dev_printk(KERN_DEBUG, &dev->dev, "reg %x: %pR\n", pos, res); |
235 | } | 317 | } |
@@ -266,7 +348,8 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
266 | struct pci_dev *dev = child->self; | 348 | struct pci_dev *dev = child->self; |
267 | u8 io_base_lo, io_limit_lo; | 349 | u8 io_base_lo, io_limit_lo; |
268 | unsigned long base, limit; | 350 | unsigned long base, limit; |
269 | struct resource *res; | 351 | struct pci_bus_region region; |
352 | struct resource *res, res2; | ||
270 | 353 | ||
271 | res = child->resource[0]; | 354 | res = child->resource[0]; |
272 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); | 355 | pci_read_config_byte(dev, PCI_IO_BASE, &io_base_lo); |
@@ -284,10 +367,14 @@ static void __devinit pci_read_bridge_io(struct pci_bus *child) | |||
284 | 367 | ||
285 | if (base && base <= limit) { | 368 | if (base && base <= limit) { |
286 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; | 369 | res->flags = (io_base_lo & PCI_IO_RANGE_TYPE_MASK) | IORESOURCE_IO; |
370 | res2.flags = res->flags; | ||
371 | region.start = base; | ||
372 | region.end = limit + 0xfff; | ||
373 | pcibios_bus_to_resource(dev, &res2, ®ion); | ||
287 | if (!res->start) | 374 | if (!res->start) |
288 | res->start = base; | 375 | res->start = res2.start; |
289 | if (!res->end) | 376 | if (!res->end) |
290 | res->end = limit + 0xfff; | 377 | res->end = res2.end; |
291 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 378 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
292 | } | 379 | } |
293 | } | 380 | } |
@@ -297,6 +384,7 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
297 | struct pci_dev *dev = child->self; | 384 | struct pci_dev *dev = child->self; |
298 | u16 mem_base_lo, mem_limit_lo; | 385 | u16 mem_base_lo, mem_limit_lo; |
299 | unsigned long base, limit; | 386 | unsigned long base, limit; |
387 | struct pci_bus_region region; | ||
300 | struct resource *res; | 388 | struct resource *res; |
301 | 389 | ||
302 | res = child->resource[1]; | 390 | res = child->resource[1]; |
@@ -306,8 +394,9 @@ static void __devinit pci_read_bridge_mmio(struct pci_bus *child) | |||
306 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; | 394 | limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16; |
307 | if (base && base <= limit) { | 395 | if (base && base <= limit) { |
308 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; | 396 | res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; |
309 | res->start = base; | 397 | region.start = base; |
310 | res->end = limit + 0xfffff; | 398 | region.end = limit + 0xfffff; |
399 | pcibios_bus_to_resource(dev, res, ®ion); | ||
311 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 400 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
312 | } | 401 | } |
313 | } | 402 | } |
@@ -317,6 +406,7 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
317 | struct pci_dev *dev = child->self; | 406 | struct pci_dev *dev = child->self; |
318 | u16 mem_base_lo, mem_limit_lo; | 407 | u16 mem_base_lo, mem_limit_lo; |
319 | unsigned long base, limit; | 408 | unsigned long base, limit; |
409 | struct pci_bus_region region; | ||
320 | struct resource *res; | 410 | struct resource *res; |
321 | 411 | ||
322 | res = child->resource[2]; | 412 | res = child->resource[2]; |
@@ -353,8 +443,9 @@ static void __devinit pci_read_bridge_mmio_pref(struct pci_bus *child) | |||
353 | IORESOURCE_MEM | IORESOURCE_PREFETCH; | 443 | IORESOURCE_MEM | IORESOURCE_PREFETCH; |
354 | if (res->flags & PCI_PREF_RANGE_TYPE_64) | 444 | if (res->flags & PCI_PREF_RANGE_TYPE_64) |
355 | res->flags |= IORESOURCE_MEM_64; | 445 | res->flags |= IORESOURCE_MEM_64; |
356 | res->start = base; | 446 | region.start = base; |
357 | res->end = limit + 0xfffff; | 447 | region.end = limit + 0xfffff; |
448 | pcibios_bus_to_resource(dev, res, ®ion); | ||
358 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); | 449 | dev_printk(KERN_DEBUG, &dev->dev, " bridge window %pR\n", res); |
359 | } | 450 | } |
360 | } | 451 | } |
@@ -900,6 +991,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
900 | u8 hdr_type; | 991 | u8 hdr_type; |
901 | struct pci_slot *slot; | 992 | struct pci_slot *slot; |
902 | int pos = 0; | 993 | int pos = 0; |
994 | struct pci_bus_region region; | ||
995 | struct resource *res; | ||
903 | 996 | ||
904 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) | 997 | if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type)) |
905 | return -EIO; | 998 | return -EIO; |
@@ -926,12 +1019,10 @@ int pci_setup_device(struct pci_dev *dev) | |||
926 | 1019 | ||
927 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); | 1020 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); |
928 | dev->revision = class & 0xff; | 1021 | dev->revision = class & 0xff; |
929 | class >>= 8; /* upper 3 bytes */ | 1022 | dev->class = class >> 8; /* upper 3 bytes */ |
930 | dev->class = class; | ||
931 | class >>= 8; | ||
932 | 1023 | ||
933 | dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %d class %#08x\n", | 1024 | dev_printk(KERN_DEBUG, &dev->dev, "[%04x:%04x] type %02x class %#08x\n", |
934 | dev->vendor, dev->device, dev->hdr_type, class); | 1025 | dev->vendor, dev->device, dev->hdr_type, dev->class); |
935 | 1026 | ||
936 | /* need to have dev->class ready */ | 1027 | /* need to have dev->class ready */ |
937 | dev->cfg_size = pci_cfg_space_size(dev); | 1028 | dev->cfg_size = pci_cfg_space_size(dev); |
@@ -963,20 +1054,28 @@ int pci_setup_device(struct pci_dev *dev) | |||
963 | u8 progif; | 1054 | u8 progif; |
964 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); | 1055 | pci_read_config_byte(dev, PCI_CLASS_PROG, &progif); |
965 | if ((progif & 1) == 0) { | 1056 | if ((progif & 1) == 0) { |
966 | dev->resource[0].start = 0x1F0; | 1057 | region.start = 0x1F0; |
967 | dev->resource[0].end = 0x1F7; | 1058 | region.end = 0x1F7; |
968 | dev->resource[0].flags = LEGACY_IO_RESOURCE; | 1059 | res = &dev->resource[0]; |
969 | dev->resource[1].start = 0x3F6; | 1060 | res->flags = LEGACY_IO_RESOURCE; |
970 | dev->resource[1].end = 0x3F6; | 1061 | pcibios_bus_to_resource(dev, res, ®ion); |
971 | dev->resource[1].flags = LEGACY_IO_RESOURCE; | 1062 | region.start = 0x3F6; |
1063 | region.end = 0x3F6; | ||
1064 | res = &dev->resource[1]; | ||
1065 | res->flags = LEGACY_IO_RESOURCE; | ||
1066 | pcibios_bus_to_resource(dev, res, ®ion); | ||
972 | } | 1067 | } |
973 | if ((progif & 4) == 0) { | 1068 | if ((progif & 4) == 0) { |
974 | dev->resource[2].start = 0x170; | 1069 | region.start = 0x170; |
975 | dev->resource[2].end = 0x177; | 1070 | region.end = 0x177; |
976 | dev->resource[2].flags = LEGACY_IO_RESOURCE; | 1071 | res = &dev->resource[2]; |
977 | dev->resource[3].start = 0x376; | 1072 | res->flags = LEGACY_IO_RESOURCE; |
978 | dev->resource[3].end = 0x376; | 1073 | pcibios_bus_to_resource(dev, res, ®ion); |
979 | dev->resource[3].flags = LEGACY_IO_RESOURCE; | 1074 | region.start = 0x376; |
1075 | region.end = 0x376; | ||
1076 | res = &dev->resource[3]; | ||
1077 | res->flags = LEGACY_IO_RESOURCE; | ||
1078 | pcibios_bus_to_resource(dev, res, ®ion); | ||
980 | } | 1079 | } |
981 | } | 1080 | } |
982 | break; | 1081 | break; |
@@ -1013,8 +1112,8 @@ int pci_setup_device(struct pci_dev *dev) | |||
1013 | return -EIO; | 1112 | return -EIO; |
1014 | 1113 | ||
1015 | bad: | 1114 | bad: |
1016 | dev_err(&dev->dev, "ignoring class %02x (doesn't match header " | 1115 | dev_err(&dev->dev, "ignoring class %#08x (doesn't match header " |
1017 | "type %02x)\n", class, dev->hdr_type); | 1116 | "type %02x)\n", dev->class, dev->hdr_type); |
1018 | dev->class = PCI_CLASS_NOT_DEFINED; | 1117 | dev->class = PCI_CLASS_NOT_DEFINED; |
1019 | } | 1118 | } |
1020 | 1119 | ||
@@ -1026,6 +1125,7 @@ static void pci_release_capabilities(struct pci_dev *dev) | |||
1026 | { | 1125 | { |
1027 | pci_vpd_release(dev); | 1126 | pci_vpd_release(dev); |
1028 | pci_iov_release(dev); | 1127 | pci_iov_release(dev); |
1128 | pci_free_cap_save_buffers(dev); | ||
1029 | } | 1129 | } |
1030 | 1130 | ||
1031 | /** | 1131 | /** |
@@ -1118,40 +1218,54 @@ struct pci_dev *alloc_pci_dev(void) | |||
1118 | } | 1218 | } |
1119 | EXPORT_SYMBOL(alloc_pci_dev); | 1219 | EXPORT_SYMBOL(alloc_pci_dev); |
1120 | 1220 | ||
1121 | /* | 1221 | bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, |
1122 | * Read the config data for a PCI device, sanity-check it | 1222 | int crs_timeout) |
1123 | * and fill in the dev structure... | ||
1124 | */ | ||
1125 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | ||
1126 | { | 1223 | { |
1127 | struct pci_dev *dev; | ||
1128 | u32 l; | ||
1129 | int delay = 1; | 1224 | int delay = 1; |
1130 | 1225 | ||
1131 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) | 1226 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) |
1132 | return NULL; | 1227 | return false; |
1133 | 1228 | ||
1134 | /* some broken boards return 0 or ~0 if a slot is empty: */ | 1229 | /* some broken boards return 0 or ~0 if a slot is empty: */ |
1135 | if (l == 0xffffffff || l == 0x00000000 || | 1230 | if (*l == 0xffffffff || *l == 0x00000000 || |
1136 | l == 0x0000ffff || l == 0xffff0000) | 1231 | *l == 0x0000ffff || *l == 0xffff0000) |
1137 | return NULL; | 1232 | return false; |
1138 | 1233 | ||
1139 | /* Configuration request Retry Status */ | 1234 | /* Configuration request Retry Status */ |
1140 | while (l == 0xffff0001) { | 1235 | while (*l == 0xffff0001) { |
1236 | if (!crs_timeout) | ||
1237 | return false; | ||
1238 | |||
1141 | msleep(delay); | 1239 | msleep(delay); |
1142 | delay *= 2; | 1240 | delay *= 2; |
1143 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l)) | 1241 | if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) |
1144 | return NULL; | 1242 | return false; |
1145 | /* Card hasn't responded in 60 seconds? Must be stuck. */ | 1243 | /* Card hasn't responded in 60 seconds? Must be stuck. */ |
1146 | if (delay > 60 * 1000) { | 1244 | if (delay > crs_timeout) { |
1147 | printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " | 1245 | printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not " |
1148 | "responding\n", pci_domain_nr(bus), | 1246 | "responding\n", pci_domain_nr(bus), |
1149 | bus->number, PCI_SLOT(devfn), | 1247 | bus->number, PCI_SLOT(devfn), |
1150 | PCI_FUNC(devfn)); | 1248 | PCI_FUNC(devfn)); |
1151 | return NULL; | 1249 | return false; |
1152 | } | 1250 | } |
1153 | } | 1251 | } |
1154 | 1252 | ||
1253 | return true; | ||
1254 | } | ||
1255 | EXPORT_SYMBOL(pci_bus_read_dev_vendor_id); | ||
1256 | |||
1257 | /* | ||
1258 | * Read the config data for a PCI device, sanity-check it | ||
1259 | * and fill in the dev structure... | ||
1260 | */ | ||
1261 | static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | ||
1262 | { | ||
1263 | struct pci_dev *dev; | ||
1264 | u32 l; | ||
1265 | |||
1266 | if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) | ||
1267 | return NULL; | ||
1268 | |||
1155 | dev = alloc_pci_dev(); | 1269 | dev = alloc_pci_dev(); |
1156 | if (!dev) | 1270 | if (!dev) |
1157 | return NULL; | 1271 | return NULL; |
@@ -1212,6 +1326,9 @@ void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) | |||
1212 | /* Fix up broken headers */ | 1326 | /* Fix up broken headers */ |
1213 | pci_fixup_device(pci_fixup_header, dev); | 1327 | pci_fixup_device(pci_fixup_header, dev); |
1214 | 1328 | ||
1329 | /* moved out from quirk header fixup code */ | ||
1330 | pci_reassigndev_resource_alignment(dev); | ||
1331 | |||
1215 | /* Clear the state_saved flag. */ | 1332 | /* Clear the state_saved flag. */ |
1216 | dev->state_saved = false; | 1333 | dev->state_saved = false; |
1217 | 1334 | ||
@@ -1530,21 +1647,27 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) | |||
1530 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1647 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1531 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1648 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1532 | { | 1649 | { |
1533 | int error, i; | 1650 | int error; |
1651 | struct pci_host_bridge *bridge; | ||
1534 | struct pci_bus *b, *b2; | 1652 | struct pci_bus *b, *b2; |
1535 | struct device *dev; | 1653 | struct device *dev; |
1536 | struct pci_bus_resource *bus_res, *n; | 1654 | struct pci_host_bridge_window *window, *n; |
1537 | struct resource *res; | 1655 | struct resource *res; |
1656 | resource_size_t offset; | ||
1657 | char bus_addr[64]; | ||
1658 | char *fmt; | ||
1659 | |||
1660 | bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); | ||
1661 | if (!bridge) | ||
1662 | return NULL; | ||
1538 | 1663 | ||
1539 | b = pci_alloc_bus(); | 1664 | b = pci_alloc_bus(); |
1540 | if (!b) | 1665 | if (!b) |
1541 | return NULL; | 1666 | goto err_bus; |
1542 | 1667 | ||
1543 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 1668 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
1544 | if (!dev) { | 1669 | if (!dev) |
1545 | kfree(b); | 1670 | goto err_dev; |
1546 | return NULL; | ||
1547 | } | ||
1548 | 1671 | ||
1549 | b->sysdata = sysdata; | 1672 | b->sysdata = sysdata; |
1550 | b->ops = ops; | 1673 | b->ops = ops; |
@@ -1556,10 +1679,6 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1556 | goto err_out; | 1679 | goto err_out; |
1557 | } | 1680 | } |
1558 | 1681 | ||
1559 | down_write(&pci_bus_sem); | ||
1560 | list_add_tail(&b->node, &pci_root_buses); | ||
1561 | up_write(&pci_bus_sem); | ||
1562 | |||
1563 | dev->parent = parent; | 1682 | dev->parent = parent; |
1564 | dev->release = pci_release_bus_bridge_dev; | 1683 | dev->release = pci_release_bus_bridge_dev; |
1565 | dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); | 1684 | dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
@@ -1585,31 +1704,53 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1585 | 1704 | ||
1586 | b->number = b->secondary = bus; | 1705 | b->number = b->secondary = bus; |
1587 | 1706 | ||
1588 | /* Add initial resources to the bus */ | 1707 | bridge->bus = b; |
1589 | list_for_each_entry_safe(bus_res, n, resources, list) | 1708 | INIT_LIST_HEAD(&bridge->windows); |
1590 | list_move_tail(&bus_res->list, &b->resources); | ||
1591 | 1709 | ||
1592 | if (parent) | 1710 | if (parent) |
1593 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1711 | dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1594 | else | 1712 | else |
1595 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); | 1713 | printk(KERN_INFO "PCI host bridge to bus %s\n", dev_name(&b->dev)); |
1596 | 1714 | ||
1597 | pci_bus_for_each_resource(b, res, i) { | 1715 | /* Add initial resources to the bus */ |
1598 | if (res) | 1716 | list_for_each_entry_safe(window, n, resources, list) { |
1599 | dev_info(&b->dev, "root bus resource %pR\n", res); | 1717 | list_move_tail(&window->list, &bridge->windows); |
1718 | res = window->res; | ||
1719 | offset = window->offset; | ||
1720 | pci_bus_add_resource(b, res, 0); | ||
1721 | if (offset) { | ||
1722 | if (resource_type(res) == IORESOURCE_IO) | ||
1723 | fmt = " (bus address [%#06llx-%#06llx])"; | ||
1724 | else | ||
1725 | fmt = " (bus address [%#010llx-%#010llx])"; | ||
1726 | snprintf(bus_addr, sizeof(bus_addr), fmt, | ||
1727 | (unsigned long long) (res->start - offset), | ||
1728 | (unsigned long long) (res->end - offset)); | ||
1729 | } else | ||
1730 | bus_addr[0] = '\0'; | ||
1731 | dev_info(&b->dev, "root bus resource %pR%s\n", res, bus_addr); | ||
1600 | } | 1732 | } |
1601 | 1733 | ||
1734 | down_write(&pci_bus_sem); | ||
1735 | list_add_tail(&bridge->list, &pci_host_bridges); | ||
1736 | list_add_tail(&b->node, &pci_root_buses); | ||
1737 | up_write(&pci_bus_sem); | ||
1738 | |||
1602 | return b; | 1739 | return b; |
1603 | 1740 | ||
1604 | class_dev_reg_err: | 1741 | class_dev_reg_err: |
1605 | device_unregister(dev); | 1742 | device_unregister(dev); |
1606 | dev_reg_err: | 1743 | dev_reg_err: |
1607 | down_write(&pci_bus_sem); | 1744 | down_write(&pci_bus_sem); |
1745 | list_del(&bridge->list); | ||
1608 | list_del(&b->node); | 1746 | list_del(&b->node); |
1609 | up_write(&pci_bus_sem); | 1747 | up_write(&pci_bus_sem); |
1610 | err_out: | 1748 | err_out: |
1611 | kfree(dev); | 1749 | kfree(dev); |
1750 | err_dev: | ||
1612 | kfree(b); | 1751 | kfree(b); |
1752 | err_bus: | ||
1753 | kfree(bridge); | ||
1613 | return NULL; | 1754 | return NULL; |
1614 | } | 1755 | } |
1615 | 1756 | ||
@@ -1667,36 +1808,29 @@ EXPORT_SYMBOL(pci_scan_bus); | |||
1667 | 1808 | ||
1668 | #ifdef CONFIG_HOTPLUG | 1809 | #ifdef CONFIG_HOTPLUG |
1669 | /** | 1810 | /** |
1670 | * pci_rescan_bus - scan a PCI bus for devices. | 1811 | * pci_rescan_bus_bridge_resize - scan a PCI bus for devices. |
1671 | * @bus: PCI bus to scan | 1812 | * @bridge: PCI bridge for the bus to scan |
1672 | * | 1813 | * |
1673 | * Scan a PCI bus and child buses for new devices, adds them, | 1814 | * Scan a PCI bus and child buses for new devices, add them, |
1674 | * and enables them. | 1815 | * and enable them, resizing bridge mmio/io resource if necessary |
1816 | * and possible. The caller must ensure the child devices are already | ||
1817 | * removed for resizing to occur. | ||
1675 | * | 1818 | * |
1676 | * Returns the max number of subordinate bus discovered. | 1819 | * Returns the max number of subordinate bus discovered. |
1677 | */ | 1820 | */ |
1678 | unsigned int __ref pci_rescan_bus(struct pci_bus *bus) | 1821 | unsigned int __ref pci_rescan_bus_bridge_resize(struct pci_dev *bridge) |
1679 | { | 1822 | { |
1680 | unsigned int max; | 1823 | unsigned int max; |
1681 | struct pci_dev *dev; | 1824 | struct pci_bus *bus = bridge->subordinate; |
1682 | 1825 | ||
1683 | max = pci_scan_child_bus(bus); | 1826 | max = pci_scan_child_bus(bus); |
1684 | 1827 | ||
1685 | down_read(&pci_bus_sem); | 1828 | pci_assign_unassigned_bridge_resources(bridge); |
1686 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1687 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
1688 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
1689 | if (dev->subordinate) | ||
1690 | pci_bus_size_bridges(dev->subordinate); | ||
1691 | up_read(&pci_bus_sem); | ||
1692 | 1829 | ||
1693 | pci_bus_assign_resources(bus); | ||
1694 | pci_enable_bridges(bus); | ||
1695 | pci_bus_add_devices(bus); | 1830 | pci_bus_add_devices(bus); |
1696 | 1831 | ||
1697 | return max; | 1832 | return max; |
1698 | } | 1833 | } |
1699 | EXPORT_SYMBOL_GPL(pci_rescan_bus); | ||
1700 | 1834 | ||
1701 | EXPORT_SYMBOL(pci_add_new_bus); | 1835 | EXPORT_SYMBOL(pci_add_new_bus); |
1702 | EXPORT_SYMBOL(pci_scan_slot); | 1836 | EXPORT_SYMBOL(pci_scan_slot); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index f722c5f6951a..4bf71028556b 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -26,73 +26,12 @@ | |||
26 | #include <linux/dmi.h> | 26 | #include <linux/dmi.h> |
27 | #include <linux/pci-aspm.h> | 27 | #include <linux/pci-aspm.h> |
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/sched.h> | ||
30 | #include <linux/ktime.h> | ||
29 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ | 31 | #include <asm/dma.h> /* isa_dma_bridge_buggy */ |
30 | #include "pci.h" | 32 | #include "pci.h" |
31 | 33 | ||
32 | /* | 34 | /* |
33 | * This quirk function disables memory decoding and releases memory resources | ||
34 | * of the device specified by kernel's boot parameter 'pci=resource_alignment='. | ||
35 | * It also rounds up size to specified alignment. | ||
36 | * Later on, the kernel will assign page-aligned memory resource back | ||
37 | * to the device. | ||
38 | */ | ||
39 | static void __devinit quirk_resource_alignment(struct pci_dev *dev) | ||
40 | { | ||
41 | int i; | ||
42 | struct resource *r; | ||
43 | resource_size_t align, size; | ||
44 | u16 command; | ||
45 | |||
46 | if (!pci_is_reassigndev(dev)) | ||
47 | return; | ||
48 | |||
49 | if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL && | ||
50 | (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) { | ||
51 | dev_warn(&dev->dev, | ||
52 | "Can't reassign resources to host bridge.\n"); | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | dev_info(&dev->dev, | ||
57 | "Disabling memory decoding and releasing memory resources.\n"); | ||
58 | pci_read_config_word(dev, PCI_COMMAND, &command); | ||
59 | command &= ~PCI_COMMAND_MEMORY; | ||
60 | pci_write_config_word(dev, PCI_COMMAND, command); | ||
61 | |||
62 | align = pci_specified_resource_alignment(dev); | ||
63 | for (i=0; i < PCI_BRIDGE_RESOURCES; i++) { | ||
64 | r = &dev->resource[i]; | ||
65 | if (!(r->flags & IORESOURCE_MEM)) | ||
66 | continue; | ||
67 | size = resource_size(r); | ||
68 | if (size < align) { | ||
69 | size = align; | ||
70 | dev_info(&dev->dev, | ||
71 | "Rounding up size of resource #%d to %#llx.\n", | ||
72 | i, (unsigned long long)size); | ||
73 | } | ||
74 | r->end = size - 1; | ||
75 | r->start = 0; | ||
76 | } | ||
77 | /* Need to disable bridge's resource window, | ||
78 | * to enable the kernel to reassign new resource | ||
79 | * window later on. | ||
80 | */ | ||
81 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && | ||
82 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { | ||
83 | for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) { | ||
84 | r = &dev->resource[i]; | ||
85 | if (!(r->flags & IORESOURCE_MEM)) | ||
86 | continue; | ||
87 | r->end = resource_size(r) - 1; | ||
88 | r->start = 0; | ||
89 | } | ||
90 | pci_disable_bridge_window(dev); | ||
91 | } | ||
92 | } | ||
93 | DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | ||
94 | |||
95 | /* | ||
96 | * Decoding should be disabled for a PCI device during BAR sizing to avoid | 35 | * Decoding should be disabled for a PCI device during BAR sizing to avoid |
97 | * conflict. But doing so may cause problems on host bridge and perhaps other | 36 | * conflict. But doing so may cause problems on host bridge and perhaps other |
98 | * key system devices. For devices that need to have mmio decoding always-on, | 37 | * key system devices. For devices that need to have mmio decoding always-on, |
@@ -100,10 +39,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment); | |||
100 | */ | 39 | */ |
101 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) | 40 | static void __devinit quirk_mmio_always_on(struct pci_dev *dev) |
102 | { | 41 | { |
103 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | 42 | dev->mmio_always_on = 1; |
104 | dev->mmio_always_on = 1; | ||
105 | } | 43 | } |
106 | DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on); | 44 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_ANY_ID, PCI_ANY_ID, |
45 | PCI_CLASS_BRIDGE_HOST, 8, quirk_mmio_always_on); | ||
107 | 46 | ||
108 | /* The Mellanox Tavor device gives false positive parity errors | 47 | /* The Mellanox Tavor device gives false positive parity errors |
109 | * Mark this device with a broken_parity_status, to allow | 48 | * Mark this device with a broken_parity_status, to allow |
@@ -1002,12 +941,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt | |||
1002 | */ | 941 | */ |
1003 | static void quirk_cardbus_legacy(struct pci_dev *dev) | 942 | static void quirk_cardbus_legacy(struct pci_dev *dev) |
1004 | { | 943 | { |
1005 | if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class) | ||
1006 | return; | ||
1007 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); | 944 | pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0); |
1008 | } | 945 | } |
1009 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 946 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
1010 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy); | 947 | PCI_CLASS_BRIDGE_CARDBUS, 8, quirk_cardbus_legacy); |
948 | DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(PCI_ANY_ID, PCI_ANY_ID, | ||
949 | PCI_CLASS_BRIDGE_CARDBUS, 8, quirk_cardbus_legacy); | ||
1011 | 950 | ||
1012 | /* | 951 | /* |
1013 | * Following the PCI ordering rules is optional on the AMD762. I'm not | 952 | * Following the PCI ordering rules is optional on the AMD762. I'm not |
@@ -1164,17 +1103,20 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_10, qui | |||
1164 | 1103 | ||
1165 | static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) | 1104 | static void __devinit quirk_no_ata_d3(struct pci_dev *pdev) |
1166 | { | 1105 | { |
1167 | /* Quirk the legacy ATA devices only. The AHCI ones are ok */ | 1106 | pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; |
1168 | if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) | ||
1169 | pdev->dev_flags |= PCI_DEV_FLAGS_NO_D3; | ||
1170 | } | 1107 | } |
1171 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, quirk_no_ata_d3); | 1108 | /* Quirk the legacy ATA devices only. The AHCI ones are ok */ |
1172 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, quirk_no_ata_d3); | 1109 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_SERVERWORKS, PCI_ANY_ID, |
1110 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1111 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_ATI, PCI_ANY_ID, | ||
1112 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1173 | /* ALi loses some register settings that we cannot then restore */ | 1113 | /* ALi loses some register settings that we cannot then restore */ |
1174 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, quirk_no_ata_d3); | 1114 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_AL, PCI_ANY_ID, |
1115 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1175 | /* VIA comes back fine but we need to keep it alive or ACPI GTM failures | 1116 | /* VIA comes back fine but we need to keep it alive or ACPI GTM failures |
1176 | occur when mode detecting */ | 1117 | occur when mode detecting */ |
1177 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_no_ata_d3); | 1118 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_VIA, PCI_ANY_ID, |
1119 | PCI_CLASS_STORAGE_IDE, 8, quirk_no_ata_d3); | ||
1178 | 1120 | ||
1179 | /* This was originally an Alpha specific thing, but it really fits here. | 1121 | /* This was originally an Alpha specific thing, but it really fits here. |
1180 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. | 1122 | * The i82375 PCI/EISA bridge appears as non-classified. Fix that. |
@@ -1873,8 +1815,7 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1873 | case PCI_DEVICE_ID_NETMOS_9745: | 1815 | case PCI_DEVICE_ID_NETMOS_9745: |
1874 | case PCI_DEVICE_ID_NETMOS_9845: | 1816 | case PCI_DEVICE_ID_NETMOS_9845: |
1875 | case PCI_DEVICE_ID_NETMOS_9855: | 1817 | case PCI_DEVICE_ID_NETMOS_9855: |
1876 | if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL && | 1818 | if (num_parallel) { |
1877 | num_parallel) { | ||
1878 | dev_info(&dev->dev, "Netmos %04x (%u parallel, " | 1819 | dev_info(&dev->dev, "Netmos %04x (%u parallel, " |
1879 | "%u serial); changing class SERIAL to OTHER " | 1820 | "%u serial); changing class SERIAL to OTHER " |
1880 | "(use parport_serial)\n", | 1821 | "(use parport_serial)\n", |
@@ -1884,7 +1825,8 @@ static void __devinit quirk_netmos(struct pci_dev *dev) | |||
1884 | } | 1825 | } |
1885 | } | 1826 | } |
1886 | } | 1827 | } |
1887 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); | 1828 | DECLARE_PCI_FIXUP_CLASS_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, |
1829 | PCI_CLASS_COMMUNICATION_SERIAL, 8, quirk_netmos); | ||
1888 | 1830 | ||
1889 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | 1831 | static void __devinit quirk_e100_interrupt(struct pci_dev *dev) |
1890 | { | 1832 | { |
@@ -1952,7 +1894,8 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) | |||
1952 | 1894 | ||
1953 | iounmap(csr); | 1895 | iounmap(csr); |
1954 | } | 1896 | } |
1955 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); | 1897 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, |
1898 | PCI_CLASS_NETWORK_ETHERNET, 8, quirk_e100_interrupt); | ||
1956 | 1899 | ||
1957 | /* | 1900 | /* |
1958 | * The 82575 and 82598 may experience data corruption issues when transitioning | 1901 | * The 82575 and 82598 may experience data corruption issues when transitioning |
@@ -2834,12 +2777,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | |||
2834 | static void __devinit fixup_ti816x_class(struct pci_dev* dev) | 2777 | static void __devinit fixup_ti816x_class(struct pci_dev* dev) |
2835 | { | 2778 | { |
2836 | /* TI 816x devices do not have class code set when in PCIe boot mode */ | 2779 | /* TI 816x devices do not have class code set when in PCIe boot mode */ |
2837 | if (dev->class == PCI_CLASS_NOT_DEFINED) { | 2780 | dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); |
2838 | dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n"); | 2781 | dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; |
2839 | dev->class = PCI_CLASS_MULTIMEDIA_VIDEO; | ||
2840 | } | ||
2841 | } | 2782 | } |
2842 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class); | 2783 | DECLARE_PCI_FIXUP_CLASS_EARLY(PCI_VENDOR_ID_TI, 0xb800, |
2784 | PCI_CLASS_NOT_DEFINED, 0, fixup_ti816x_class); | ||
2843 | 2785 | ||
2844 | /* Some PCIe devices do not work reliably with the claimed maximum | 2786 | /* Some PCIe devices do not work reliably with the claimed maximum |
2845 | * payload size supported. | 2787 | * payload size supported. |
@@ -2924,17 +2866,73 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f8, quirk_intel_mc_errata); | |||
2924 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); | 2866 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65f9, quirk_intel_mc_errata); |
2925 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); | 2867 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x65fa, quirk_intel_mc_errata); |
2926 | 2868 | ||
2869 | |||
2870 | static void do_one_fixup_debug(void (*fn)(struct pci_dev *dev), struct pci_dev *dev) | ||
2871 | { | ||
2872 | ktime_t calltime, delta, rettime; | ||
2873 | unsigned long long duration; | ||
2874 | |||
2875 | printk(KERN_DEBUG "calling %pF @ %i for %s\n", | ||
2876 | fn, task_pid_nr(current), dev_name(&dev->dev)); | ||
2877 | calltime = ktime_get(); | ||
2878 | fn(dev); | ||
2879 | rettime = ktime_get(); | ||
2880 | delta = ktime_sub(rettime, calltime); | ||
2881 | duration = (unsigned long long) ktime_to_ns(delta) >> 10; | ||
2882 | printk(KERN_DEBUG "pci fixup %pF returned after %lld usecs for %s\n", | ||
2883 | fn, duration, dev_name(&dev->dev)); | ||
2884 | } | ||
2885 | |||
2886 | /* | ||
2887 | * Some BIOS implementations leave the Intel GPU interrupts enabled, | ||
2888 | * even though no one is handling them (f.e. i915 driver is never loaded). | ||
2889 | * Additionally the interrupt destination is not set up properly | ||
2890 | * and the interrupt ends up -somewhere-. | ||
2891 | * | ||
2892 | * These spurious interrupts are "sticky" and the kernel disables | ||
2893 | * the (shared) interrupt line after 100.000+ generated interrupts. | ||
2894 | * | ||
2895 | * Fix it by disabling the still enabled interrupts. | ||
2896 | * This resolves crashes often seen on monitor unplug. | ||
2897 | */ | ||
2898 | #define I915_DEIER_REG 0x4400c | ||
2899 | static void __devinit disable_igfx_irq(struct pci_dev *dev) | ||
2900 | { | ||
2901 | void __iomem *regs = pci_iomap(dev, 0, 0); | ||
2902 | if (regs == NULL) { | ||
2903 | dev_warn(&dev->dev, "igfx quirk: Can't iomap PCI device\n"); | ||
2904 | return; | ||
2905 | } | ||
2906 | |||
2907 | /* Check if any interrupt line is still enabled */ | ||
2908 | if (readl(regs + I915_DEIER_REG) != 0) { | ||
2909 | dev_warn(&dev->dev, "BIOS left Intel GPU interrupts enabled; " | ||
2910 | "disabling\n"); | ||
2911 | |||
2912 | writel(0, regs + I915_DEIER_REG); | ||
2913 | } | ||
2914 | |||
2915 | pci_iounmap(dev, regs); | ||
2916 | } | ||
2917 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0102, disable_igfx_irq); | ||
2918 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x010a, disable_igfx_irq); | ||
2919 | |||
2927 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2920 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2928 | struct pci_fixup *end) | 2921 | struct pci_fixup *end) |
2929 | { | 2922 | { |
2930 | while (f < end) { | 2923 | for (; f < end; f++) |
2931 | if ((f->vendor == dev->vendor || f->vendor == (u16) PCI_ANY_ID) && | 2924 | if ((f->class == (u32) (dev->class >> f->class_shift) || |
2932 | (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { | 2925 | f->class == (u32) PCI_ANY_ID) && |
2926 | (f->vendor == dev->vendor || | ||
2927 | f->vendor == (u16) PCI_ANY_ID) && | ||
2928 | (f->device == dev->device || | ||
2929 | f->device == (u16) PCI_ANY_ID)) { | ||
2933 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); | 2930 | dev_dbg(&dev->dev, "calling %pF\n", f->hook); |
2934 | f->hook(dev); | 2931 | if (initcall_debug) |
2932 | do_one_fixup_debug(f->hook, dev); | ||
2933 | else | ||
2934 | f->hook(dev); | ||
2935 | } | 2935 | } |
2936 | f++; | ||
2937 | } | ||
2938 | } | 2936 | } |
2939 | 2937 | ||
2940 | extern struct pci_fixup __start_pci_fixups_early[]; | 2938 | extern struct pci_fixup __start_pci_fixups_early[]; |
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index ef8b18c48f26..fd77e2bde2e8 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(pci_remove_bus); | |||
79 | 79 | ||
80 | static void __pci_remove_behind_bridge(struct pci_dev *dev); | 80 | static void __pci_remove_behind_bridge(struct pci_dev *dev); |
81 | /** | 81 | /** |
82 | * pci_remove_bus_device - remove a PCI device and any children | 82 | * pci_stop_and_remove_bus_device - remove a PCI device and any children |
83 | * @dev: the device to remove | 83 | * @dev: the device to remove |
84 | * | 84 | * |
85 | * Remove a PCI device from the device lists, informing the drivers | 85 | * Remove a PCI device from the device lists, informing the drivers |
@@ -90,7 +90,7 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev); | |||
90 | * device lists, remove the /proc entry, and notify userspace | 90 | * device lists, remove the /proc entry, and notify userspace |
91 | * (/sbin/hotplug). | 91 | * (/sbin/hotplug). |
92 | */ | 92 | */ |
93 | static void __pci_remove_bus_device(struct pci_dev *dev) | 93 | void __pci_remove_bus_device(struct pci_dev *dev) |
94 | { | 94 | { |
95 | if (dev->subordinate) { | 95 | if (dev->subordinate) { |
96 | struct pci_bus *b = dev->subordinate; | 96 | struct pci_bus *b = dev->subordinate; |
@@ -102,7 +102,9 @@ static void __pci_remove_bus_device(struct pci_dev *dev) | |||
102 | 102 | ||
103 | pci_destroy_dev(dev); | 103 | pci_destroy_dev(dev); |
104 | } | 104 | } |
105 | void pci_remove_bus_device(struct pci_dev *dev) | 105 | EXPORT_SYMBOL(__pci_remove_bus_device); |
106 | |||
107 | void pci_stop_and_remove_bus_device(struct pci_dev *dev) | ||
106 | { | 108 | { |
107 | pci_stop_bus_device(dev); | 109 | pci_stop_bus_device(dev); |
108 | __pci_remove_bus_device(dev); | 110 | __pci_remove_bus_device(dev); |
@@ -127,14 +129,15 @@ static void pci_stop_behind_bridge(struct pci_dev *dev) | |||
127 | } | 129 | } |
128 | 130 | ||
129 | /** | 131 | /** |
130 | * pci_remove_behind_bridge - remove all devices behind a PCI bridge | 132 | * pci_stop_and_remove_behind_bridge - stop and remove all devices behind |
133 | * a PCI bridge | ||
131 | * @dev: PCI bridge device | 134 | * @dev: PCI bridge device |
132 | * | 135 | * |
133 | * Remove all devices on the bus, except for the parent bridge. | 136 | * Remove all devices on the bus, except for the parent bridge. |
134 | * This also removes any child buses, and any devices they may | 137 | * This also removes any child buses, and any devices they may |
135 | * contain in a depth-first manner. | 138 | * contain in a depth-first manner. |
136 | */ | 139 | */ |
137 | void pci_remove_behind_bridge(struct pci_dev *dev) | 140 | void pci_stop_and_remove_behind_bridge(struct pci_dev *dev) |
138 | { | 141 | { |
139 | pci_stop_behind_bridge(dev); | 142 | pci_stop_behind_bridge(dev); |
140 | __pci_remove_behind_bridge(dev); | 143 | __pci_remove_behind_bridge(dev); |
@@ -144,7 +147,15 @@ static void pci_stop_bus_devices(struct pci_bus *bus) | |||
144 | { | 147 | { |
145 | struct list_head *l, *n; | 148 | struct list_head *l, *n; |
146 | 149 | ||
147 | list_for_each_safe(l, n, &bus->devices) { | 150 | /* |
151 | * VFs could be removed by pci_stop_and_remove_bus_device() in the | ||
152 | * pci_stop_bus_devices() code path for PF. | ||
153 | * aka, bus->devices get updated in the process. | ||
154 | * but VFs are inserted after PFs when SRIOV is enabled for PF, | ||
155 | * We can iterate the list backwards to get prev valid PF instead | ||
156 | * of removed VF. | ||
157 | */ | ||
158 | list_for_each_prev_safe(l, n, &bus->devices) { | ||
148 | struct pci_dev *dev = pci_dev_b(l); | 159 | struct pci_dev *dev = pci_dev_b(l); |
149 | pci_stop_bus_device(dev); | 160 | pci_stop_bus_device(dev); |
150 | } | 161 | } |
@@ -166,6 +177,6 @@ void pci_stop_bus_device(struct pci_dev *dev) | |||
166 | pci_stop_dev(dev); | 177 | pci_stop_dev(dev); |
167 | } | 178 | } |
168 | 179 | ||
169 | EXPORT_SYMBOL(pci_remove_bus_device); | 180 | EXPORT_SYMBOL(pci_stop_and_remove_bus_device); |
170 | EXPORT_SYMBOL(pci_remove_behind_bridge); | 181 | EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge); |
171 | EXPORT_SYMBOL_GPL(pci_stop_bus_device); | 182 | EXPORT_SYMBOL_GPL(pci_stop_bus_device); |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 86b69f85f900..8fa2d4be88de 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -25,10 +25,13 @@ | |||
25 | #include <linux/ioport.h> | 25 | #include <linux/ioport.h> |
26 | #include <linux/cache.h> | 26 | #include <linux/cache.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <asm-generic/pci-bridge.h> | ||
28 | #include "pci.h" | 29 | #include "pci.h" |
29 | 30 | ||
30 | struct resource_list_x { | 31 | unsigned int pci_flags; |
31 | struct resource_list_x *next; | 32 | |
33 | struct pci_dev_resource { | ||
34 | struct list_head list; | ||
32 | struct resource *res; | 35 | struct resource *res; |
33 | struct pci_dev *dev; | 36 | struct pci_dev *dev; |
34 | resource_size_t start; | 37 | resource_size_t start; |
@@ -38,21 +41,14 @@ struct resource_list_x { | |||
38 | unsigned long flags; | 41 | unsigned long flags; |
39 | }; | 42 | }; |
40 | 43 | ||
41 | #define free_list(type, head) do { \ | 44 | static void free_list(struct list_head *head) |
42 | struct type *list, *tmp; \ | ||
43 | for (list = (head)->next; list;) { \ | ||
44 | tmp = list; \ | ||
45 | list = list->next; \ | ||
46 | kfree(tmp); \ | ||
47 | } \ | ||
48 | (head)->next = NULL; \ | ||
49 | } while (0) | ||
50 | |||
51 | int pci_realloc_enable = 0; | ||
52 | #define pci_realloc_enabled() pci_realloc_enable | ||
53 | void pci_realloc(void) | ||
54 | { | 45 | { |
55 | pci_realloc_enable = 1; | 46 | struct pci_dev_resource *dev_res, *tmp; |
47 | |||
48 | list_for_each_entry_safe(dev_res, tmp, head, list) { | ||
49 | list_del(&dev_res->list); | ||
50 | kfree(dev_res); | ||
51 | } | ||
56 | } | 52 | } |
57 | 53 | ||
58 | /** | 54 | /** |
@@ -64,21 +60,18 @@ void pci_realloc(void) | |||
64 | * @add_size: additional size to be optionally added | 60 | * @add_size: additional size to be optionally added |
65 | * to the resource | 61 | * to the resource |
66 | */ | 62 | */ |
67 | static void add_to_list(struct resource_list_x *head, | 63 | static int add_to_list(struct list_head *head, |
68 | struct pci_dev *dev, struct resource *res, | 64 | struct pci_dev *dev, struct resource *res, |
69 | resource_size_t add_size, resource_size_t min_align) | 65 | resource_size_t add_size, resource_size_t min_align) |
70 | { | 66 | { |
71 | struct resource_list_x *list = head; | 67 | struct pci_dev_resource *tmp; |
72 | struct resource_list_x *ln = list->next; | ||
73 | struct resource_list_x *tmp; | ||
74 | 68 | ||
75 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | 69 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); |
76 | if (!tmp) { | 70 | if (!tmp) { |
77 | pr_warning("add_to_list: kmalloc() failed!\n"); | 71 | pr_warning("add_to_list: kmalloc() failed!\n"); |
78 | return; | 72 | return -ENOMEM; |
79 | } | 73 | } |
80 | 74 | ||
81 | tmp->next = ln; | ||
82 | tmp->res = res; | 75 | tmp->res = res; |
83 | tmp->dev = dev; | 76 | tmp->dev = dev; |
84 | tmp->start = res->start; | 77 | tmp->start = res->start; |
@@ -86,19 +79,100 @@ static void add_to_list(struct resource_list_x *head, | |||
86 | tmp->flags = res->flags; | 79 | tmp->flags = res->flags; |
87 | tmp->add_size = add_size; | 80 | tmp->add_size = add_size; |
88 | tmp->min_align = min_align; | 81 | tmp->min_align = min_align; |
89 | list->next = tmp; | 82 | |
83 | list_add(&tmp->list, head); | ||
84 | |||
85 | return 0; | ||
90 | } | 86 | } |
91 | 87 | ||
92 | static void add_to_failed_list(struct resource_list_x *head, | 88 | static void remove_from_list(struct list_head *head, |
93 | struct pci_dev *dev, struct resource *res) | 89 | struct resource *res) |
94 | { | 90 | { |
95 | add_to_list(head, dev, res, | 91 | struct pci_dev_resource *dev_res, *tmp; |
96 | 0 /* dont care */, | 92 | |
97 | 0 /* dont care */); | 93 | list_for_each_entry_safe(dev_res, tmp, head, list) { |
94 | if (dev_res->res == res) { | ||
95 | list_del(&dev_res->list); | ||
96 | kfree(dev_res); | ||
97 | break; | ||
98 | } | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static resource_size_t get_res_add_size(struct list_head *head, | ||
103 | struct resource *res) | ||
104 | { | ||
105 | struct pci_dev_resource *dev_res; | ||
106 | |||
107 | list_for_each_entry(dev_res, head, list) { | ||
108 | if (dev_res->res == res) { | ||
109 | int idx = res - &dev_res->dev->resource[0]; | ||
110 | |||
111 | dev_printk(KERN_DEBUG, &dev_res->dev->dev, | ||
112 | "res[%d]=%pR get_res_add_size add_size %llx\n", | ||
113 | idx, dev_res->res, | ||
114 | (unsigned long long)dev_res->add_size); | ||
115 | |||
116 | return dev_res->add_size; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* Sort resources by alignment */ | ||
124 | static void pdev_sort_resources(struct pci_dev *dev, struct list_head *head) | ||
125 | { | ||
126 | int i; | ||
127 | |||
128 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
129 | struct resource *r; | ||
130 | struct pci_dev_resource *dev_res, *tmp; | ||
131 | resource_size_t r_align; | ||
132 | struct list_head *n; | ||
133 | |||
134 | r = &dev->resource[i]; | ||
135 | |||
136 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
137 | continue; | ||
138 | |||
139 | if (!(r->flags) || r->parent) | ||
140 | continue; | ||
141 | |||
142 | r_align = pci_resource_alignment(dev, r); | ||
143 | if (!r_align) { | ||
144 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", | ||
145 | i, r); | ||
146 | continue; | ||
147 | } | ||
148 | |||
149 | tmp = kzalloc(sizeof(*tmp), GFP_KERNEL); | ||
150 | if (!tmp) | ||
151 | panic("pdev_sort_resources(): " | ||
152 | "kmalloc() failed!\n"); | ||
153 | tmp->res = r; | ||
154 | tmp->dev = dev; | ||
155 | |||
156 | /* fallback is smallest one or list is empty*/ | ||
157 | n = head; | ||
158 | list_for_each_entry(dev_res, head, list) { | ||
159 | resource_size_t align; | ||
160 | |||
161 | align = pci_resource_alignment(dev_res->dev, | ||
162 | dev_res->res); | ||
163 | |||
164 | if (r_align > align) { | ||
165 | n = &dev_res->list; | ||
166 | break; | ||
167 | } | ||
168 | } | ||
169 | /* Insert it just before n*/ | ||
170 | list_add_tail(&tmp->list, n); | ||
171 | } | ||
98 | } | 172 | } |
99 | 173 | ||
100 | static void __dev_sort_resources(struct pci_dev *dev, | 174 | static void __dev_sort_resources(struct pci_dev *dev, |
101 | struct resource_list *head) | 175 | struct list_head *head) |
102 | { | 176 | { |
103 | u16 class = dev->class >> 8; | 177 | u16 class = dev->class >> 8; |
104 | 178 | ||
@@ -136,49 +210,54 @@ static inline void reset_resource(struct resource *res) | |||
136 | * additional resources for the element, provided the element | 210 | * additional resources for the element, provided the element |
137 | * is in the head list. | 211 | * is in the head list. |
138 | */ | 212 | */ |
139 | static void reassign_resources_sorted(struct resource_list_x *realloc_head, | 213 | static void reassign_resources_sorted(struct list_head *realloc_head, |
140 | struct resource_list *head) | 214 | struct list_head *head) |
141 | { | 215 | { |
142 | struct resource *res; | 216 | struct resource *res; |
143 | struct resource_list_x *list, *tmp, *prev; | 217 | struct pci_dev_resource *add_res, *tmp; |
144 | struct resource_list *hlist; | 218 | struct pci_dev_resource *dev_res; |
145 | resource_size_t add_size; | 219 | resource_size_t add_size; |
146 | int idx; | 220 | int idx; |
147 | 221 | ||
148 | prev = realloc_head; | 222 | list_for_each_entry_safe(add_res, tmp, realloc_head, list) { |
149 | for (list = realloc_head->next; list;) { | 223 | bool found_match = false; |
150 | res = list->res; | 224 | |
225 | res = add_res->res; | ||
151 | /* skip resource that has been reset */ | 226 | /* skip resource that has been reset */ |
152 | if (!res->flags) | 227 | if (!res->flags) |
153 | goto out; | 228 | goto out; |
154 | 229 | ||
155 | /* skip this resource if not found in head list */ | 230 | /* skip this resource if not found in head list */ |
156 | for (hlist = head->next; hlist && hlist->res != res; | 231 | list_for_each_entry(dev_res, head, list) { |
157 | hlist = hlist->next); | 232 | if (dev_res->res == res) { |
158 | if (!hlist) { /* just skip */ | 233 | found_match = true; |
159 | prev = list; | 234 | break; |
160 | list = list->next; | 235 | } |
161 | continue; | ||
162 | } | 236 | } |
237 | if (!found_match)/* just skip */ | ||
238 | continue; | ||
163 | 239 | ||
164 | idx = res - &list->dev->resource[0]; | 240 | idx = res - &add_res->dev->resource[0]; |
165 | add_size=list->add_size; | 241 | add_size = add_res->add_size; |
166 | if (!resource_size(res)) { | 242 | if (!resource_size(res)) { |
167 | res->start = list->start; | 243 | res->start = add_res->start; |
168 | res->end = res->start + add_size - 1; | 244 | res->end = res->start + add_size - 1; |
169 | if(pci_assign_resource(list->dev, idx)) | 245 | if (pci_assign_resource(add_res->dev, idx)) |
170 | reset_resource(res); | 246 | reset_resource(res); |
171 | } else { | 247 | } else { |
172 | resource_size_t align = list->min_align; | 248 | resource_size_t align = add_res->min_align; |
173 | res->flags |= list->flags & (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); | 249 | res->flags |= add_res->flags & |
174 | if (pci_reassign_resource(list->dev, idx, add_size, align)) | 250 | (IORESOURCE_STARTALIGN|IORESOURCE_SIZEALIGN); |
175 | dev_printk(KERN_DEBUG, &list->dev->dev, "failed to add optional resources res=%pR\n", | 251 | if (pci_reassign_resource(add_res->dev, idx, |
176 | res); | 252 | add_size, align)) |
253 | dev_printk(KERN_DEBUG, &add_res->dev->dev, | ||
254 | "failed to add %llx res[%d]=%pR\n", | ||
255 | (unsigned long long)add_size, | ||
256 | idx, res); | ||
177 | } | 257 | } |
178 | out: | 258 | out: |
179 | tmp = list; | 259 | list_del(&add_res->list); |
180 | prev->next = list = list->next; | 260 | kfree(add_res); |
181 | kfree(tmp); | ||
182 | } | 261 | } |
183 | } | 262 | } |
184 | 263 | ||
@@ -192,35 +271,99 @@ out: | |||
192 | * Satisfy resource requests of each element in the list. Add | 271 | * Satisfy resource requests of each element in the list. Add |
193 | * requests that could not satisfied to the failed_list. | 272 | * requests that could not satisfied to the failed_list. |
194 | */ | 273 | */ |
195 | static void assign_requested_resources_sorted(struct resource_list *head, | 274 | static void assign_requested_resources_sorted(struct list_head *head, |
196 | struct resource_list_x *fail_head) | 275 | struct list_head *fail_head) |
197 | { | 276 | { |
198 | struct resource *res; | 277 | struct resource *res; |
199 | struct resource_list *list; | 278 | struct pci_dev_resource *dev_res; |
200 | int idx; | 279 | int idx; |
201 | 280 | ||
202 | for (list = head->next; list; list = list->next) { | 281 | list_for_each_entry(dev_res, head, list) { |
203 | res = list->res; | 282 | res = dev_res->res; |
204 | idx = res - &list->dev->resource[0]; | 283 | idx = res - &dev_res->dev->resource[0]; |
205 | if (resource_size(res) && pci_assign_resource(list->dev, idx)) { | 284 | if (resource_size(res) && |
206 | if (fail_head && !pci_is_root_bus(list->dev->bus)) { | 285 | pci_assign_resource(dev_res->dev, idx)) { |
286 | if (fail_head && !pci_is_root_bus(dev_res->dev->bus)) { | ||
207 | /* | 287 | /* |
208 | * if the failed res is for ROM BAR, and it will | 288 | * if the failed res is for ROM BAR, and it will |
209 | * be enabled later, don't add it to the list | 289 | * be enabled later, don't add it to the list |
210 | */ | 290 | */ |
211 | if (!((idx == PCI_ROM_RESOURCE) && | 291 | if (!((idx == PCI_ROM_RESOURCE) && |
212 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) | 292 | (!(res->flags & IORESOURCE_ROM_ENABLE)))) |
213 | add_to_failed_list(fail_head, list->dev, res); | 293 | add_to_list(fail_head, |
294 | dev_res->dev, res, | ||
295 | 0 /* dont care */, | ||
296 | 0 /* dont care */); | ||
214 | } | 297 | } |
215 | reset_resource(res); | 298 | reset_resource(res); |
216 | } | 299 | } |
217 | } | 300 | } |
218 | } | 301 | } |
219 | 302 | ||
220 | static void __assign_resources_sorted(struct resource_list *head, | 303 | static void __assign_resources_sorted(struct list_head *head, |
221 | struct resource_list_x *realloc_head, | 304 | struct list_head *realloc_head, |
222 | struct resource_list_x *fail_head) | 305 | struct list_head *fail_head) |
223 | { | 306 | { |
307 | /* | ||
308 | * Should not assign requested resources at first. | ||
309 | * they could be adjacent, so later reassign can not reallocate | ||
310 | * them one by one in parent resource window. | ||
311 | * Try to assign requested + add_size at begining | ||
312 | * if could do that, could get out early. | ||
313 | * if could not do that, we still try to assign requested at first, | ||
314 | * then try to reassign add_size for some resources. | ||
315 | */ | ||
316 | LIST_HEAD(save_head); | ||
317 | LIST_HEAD(local_fail_head); | ||
318 | struct pci_dev_resource *save_res; | ||
319 | struct pci_dev_resource *dev_res; | ||
320 | |||
321 | /* Check if optional add_size is there */ | ||
322 | if (!realloc_head || list_empty(realloc_head)) | ||
323 | goto requested_and_reassign; | ||
324 | |||
325 | /* Save original start, end, flags etc at first */ | ||
326 | list_for_each_entry(dev_res, head, list) { | ||
327 | if (add_to_list(&save_head, dev_res->dev, dev_res->res, 0, 0)) { | ||
328 | free_list(&save_head); | ||
329 | goto requested_and_reassign; | ||
330 | } | ||
331 | } | ||
332 | |||
333 | /* Update res in head list with add_size in realloc_head list */ | ||
334 | list_for_each_entry(dev_res, head, list) | ||
335 | dev_res->res->end += get_res_add_size(realloc_head, | ||
336 | dev_res->res); | ||
337 | |||
338 | /* Try updated head list with add_size added */ | ||
339 | assign_requested_resources_sorted(head, &local_fail_head); | ||
340 | |||
341 | /* all assigned with add_size ? */ | ||
342 | if (list_empty(&local_fail_head)) { | ||
343 | /* Remove head list from realloc_head list */ | ||
344 | list_for_each_entry(dev_res, head, list) | ||
345 | remove_from_list(realloc_head, dev_res->res); | ||
346 | free_list(&save_head); | ||
347 | free_list(head); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | free_list(&local_fail_head); | ||
352 | /* Release assigned resource */ | ||
353 | list_for_each_entry(dev_res, head, list) | ||
354 | if (dev_res->res->parent) | ||
355 | release_resource(dev_res->res); | ||
356 | /* Restore start/end/flags from saved list */ | ||
357 | list_for_each_entry(save_res, &save_head, list) { | ||
358 | struct resource *res = save_res->res; | ||
359 | |||
360 | res->start = save_res->start; | ||
361 | res->end = save_res->end; | ||
362 | res->flags = save_res->flags; | ||
363 | } | ||
364 | free_list(&save_head); | ||
365 | |||
366 | requested_and_reassign: | ||
224 | /* Satisfy the must-have resource requests */ | 367 | /* Satisfy the must-have resource requests */ |
225 | assign_requested_resources_sorted(head, fail_head); | 368 | assign_requested_resources_sorted(head, fail_head); |
226 | 369 | ||
@@ -228,28 +371,27 @@ static void __assign_resources_sorted(struct resource_list *head, | |||
228 | requests */ | 371 | requests */ |
229 | if (realloc_head) | 372 | if (realloc_head) |
230 | reassign_resources_sorted(realloc_head, head); | 373 | reassign_resources_sorted(realloc_head, head); |
231 | free_list(resource_list, head); | 374 | free_list(head); |
232 | } | 375 | } |
233 | 376 | ||
234 | static void pdev_assign_resources_sorted(struct pci_dev *dev, | 377 | static void pdev_assign_resources_sorted(struct pci_dev *dev, |
235 | struct resource_list_x *fail_head) | 378 | struct list_head *add_head, |
379 | struct list_head *fail_head) | ||
236 | { | 380 | { |
237 | struct resource_list head; | 381 | LIST_HEAD(head); |
238 | 382 | ||
239 | head.next = NULL; | ||
240 | __dev_sort_resources(dev, &head); | 383 | __dev_sort_resources(dev, &head); |
241 | __assign_resources_sorted(&head, NULL, fail_head); | 384 | __assign_resources_sorted(&head, add_head, fail_head); |
242 | 385 | ||
243 | } | 386 | } |
244 | 387 | ||
245 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, | 388 | static void pbus_assign_resources_sorted(const struct pci_bus *bus, |
246 | struct resource_list_x *realloc_head, | 389 | struct list_head *realloc_head, |
247 | struct resource_list_x *fail_head) | 390 | struct list_head *fail_head) |
248 | { | 391 | { |
249 | struct pci_dev *dev; | 392 | struct pci_dev *dev; |
250 | struct resource_list head; | 393 | LIST_HEAD(head); |
251 | 394 | ||
252 | head.next = NULL; | ||
253 | list_for_each_entry(dev, &bus->devices, bus_list) | 395 | list_for_each_entry(dev, &bus->devices, bus_list) |
254 | __dev_sort_resources(dev, &head); | 396 | __dev_sort_resources(dev, &head); |
255 | 397 | ||
@@ -548,20 +690,6 @@ static resource_size_t calculate_memsize(resource_size_t size, | |||
548 | return size; | 690 | return size; |
549 | } | 691 | } |
550 | 692 | ||
551 | static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | ||
552 | struct resource *res) | ||
553 | { | ||
554 | struct resource_list_x *list; | ||
555 | |||
556 | /* check if it is in realloc_head list */ | ||
557 | for (list = realloc_head->next; list && list->res != res; | ||
558 | list = list->next); | ||
559 | if (list) | ||
560 | return list->add_size; | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | /** | 693 | /** |
566 | * pbus_size_io() - size the io window of a given bus | 694 | * pbus_size_io() - size the io window of a given bus |
567 | * | 695 | * |
@@ -576,7 +704,7 @@ static resource_size_t get_res_add_size(struct resource_list_x *realloc_head, | |||
576 | * We must be careful with the ISA aliasing though. | 704 | * We must be careful with the ISA aliasing though. |
577 | */ | 705 | */ |
578 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | 706 | static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, |
579 | resource_size_t add_size, struct resource_list_x *realloc_head) | 707 | resource_size_t add_size, struct list_head *realloc_head) |
580 | { | 708 | { |
581 | struct pci_dev *dev; | 709 | struct pci_dev *dev; |
582 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); | 710 | struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); |
@@ -612,7 +740,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
612 | if (children_add_size > add_size) | 740 | if (children_add_size > add_size) |
613 | add_size = children_add_size; | 741 | add_size = children_add_size; |
614 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | 742 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : |
615 | calculate_iosize(size, min_size+add_size, size1, | 743 | calculate_iosize(size, min_size, add_size + size1, |
616 | resource_size(b_res), 4096); | 744 | resource_size(b_res), 4096); |
617 | if (!size0 && !size1) { | 745 | if (!size0 && !size1) { |
618 | if (b_res->start || b_res->end) | 746 | if (b_res->start || b_res->end) |
@@ -626,8 +754,12 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
626 | b_res->start = 4096; | 754 | b_res->start = 4096; |
627 | b_res->end = b_res->start + size0 - 1; | 755 | b_res->end = b_res->start + size0 - 1; |
628 | b_res->flags |= IORESOURCE_STARTALIGN; | 756 | b_res->flags |= IORESOURCE_STARTALIGN; |
629 | if (size1 > size0 && realloc_head) | 757 | if (size1 > size0 && realloc_head) { |
630 | add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); | 758 | add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096); |
759 | dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " | ||
760 | "%pR to [bus %02x-%02x] add_size %lx\n", b_res, | ||
761 | bus->secondary, bus->subordinate, size1-size0); | ||
762 | } | ||
631 | } | 763 | } |
632 | 764 | ||
633 | /** | 765 | /** |
@@ -644,7 +776,7 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, | |||
644 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | 776 | static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, |
645 | unsigned long type, resource_size_t min_size, | 777 | unsigned long type, resource_size_t min_size, |
646 | resource_size_t add_size, | 778 | resource_size_t add_size, |
647 | struct resource_list_x *realloc_head) | 779 | struct list_head *realloc_head) |
648 | { | 780 | { |
649 | struct pci_dev *dev; | 781 | struct pci_dev *dev; |
650 | resource_size_t min_align, align, size, size0, size1; | 782 | resource_size_t min_align, align, size, size0, size1; |
@@ -726,7 +858,7 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
726 | if (children_add_size > add_size) | 858 | if (children_add_size > add_size) |
727 | add_size = children_add_size; | 859 | add_size = children_add_size; |
728 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : | 860 | size1 = (!realloc_head || (realloc_head && !add_size)) ? size0 : |
729 | calculate_memsize(size, min_size+add_size, 0, | 861 | calculate_memsize(size, min_size, add_size, |
730 | resource_size(b_res), min_align); | 862 | resource_size(b_res), min_align); |
731 | if (!size0 && !size1) { | 863 | if (!size0 && !size1) { |
732 | if (b_res->start || b_res->end) | 864 | if (b_res->start || b_res->end) |
@@ -739,8 +871,12 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, | |||
739 | b_res->start = min_align; | 871 | b_res->start = min_align; |
740 | b_res->end = size0 + min_align - 1; | 872 | b_res->end = size0 + min_align - 1; |
741 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; | 873 | b_res->flags |= IORESOURCE_STARTALIGN | mem64_mask; |
742 | if (size1 > size0 && realloc_head) | 874 | if (size1 > size0 && realloc_head) { |
743 | add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); | 875 | add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align); |
876 | dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window " | ||
877 | "%pR to [bus %02x-%02x] add_size %llx\n", b_res, | ||
878 | bus->secondary, bus->subordinate, (unsigned long long)size1-size0); | ||
879 | } | ||
744 | return 1; | 880 | return 1; |
745 | } | 881 | } |
746 | 882 | ||
@@ -754,25 +890,48 @@ unsigned long pci_cardbus_resource_alignment(struct resource *res) | |||
754 | } | 890 | } |
755 | 891 | ||
756 | static void pci_bus_size_cardbus(struct pci_bus *bus, | 892 | static void pci_bus_size_cardbus(struct pci_bus *bus, |
757 | struct resource_list_x *realloc_head) | 893 | struct list_head *realloc_head) |
758 | { | 894 | { |
759 | struct pci_dev *bridge = bus->self; | 895 | struct pci_dev *bridge = bus->self; |
760 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; | 896 | struct resource *b_res = &bridge->resource[PCI_BRIDGE_RESOURCES]; |
897 | resource_size_t b_res_3_size = pci_cardbus_mem_size * 2; | ||
761 | u16 ctrl; | 898 | u16 ctrl; |
762 | 899 | ||
900 | if (b_res[0].parent) | ||
901 | goto handle_b_res_1; | ||
763 | /* | 902 | /* |
764 | * Reserve some resources for CardBus. We reserve | 903 | * Reserve some resources for CardBus. We reserve |
765 | * a fixed amount of bus space for CardBus bridges. | 904 | * a fixed amount of bus space for CardBus bridges. |
766 | */ | 905 | */ |
767 | b_res[0].start = 0; | 906 | b_res[0].start = pci_cardbus_io_size; |
768 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 907 | b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1; |
769 | if (realloc_head) | 908 | b_res[0].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; |
770 | add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, 0 /* dont care */); | 909 | if (realloc_head) { |
910 | b_res[0].end -= pci_cardbus_io_size; | ||
911 | add_to_list(realloc_head, bridge, b_res, pci_cardbus_io_size, | ||
912 | pci_cardbus_io_size); | ||
913 | } | ||
771 | 914 | ||
772 | b_res[1].start = 0; | 915 | handle_b_res_1: |
773 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_SIZEALIGN; | 916 | if (b_res[1].parent) |
774 | if (realloc_head) | 917 | goto handle_b_res_2; |
775 | add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, 0 /* dont care */); | 918 | b_res[1].start = pci_cardbus_io_size; |
919 | b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1; | ||
920 | b_res[1].flags |= IORESOURCE_IO | IORESOURCE_STARTALIGN; | ||
921 | if (realloc_head) { | ||
922 | b_res[1].end -= pci_cardbus_io_size; | ||
923 | add_to_list(realloc_head, bridge, b_res+1, pci_cardbus_io_size, | ||
924 | pci_cardbus_io_size); | ||
925 | } | ||
926 | |||
927 | handle_b_res_2: | ||
928 | /* MEM1 must not be pref mmio */ | ||
929 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
930 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM1) { | ||
931 | ctrl &= ~PCI_CB_BRIDGE_CTL_PREFETCH_MEM1; | ||
932 | pci_write_config_word(bridge, PCI_CB_BRIDGE_CONTROL, ctrl); | ||
933 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | ||
934 | } | ||
776 | 935 | ||
777 | /* | 936 | /* |
778 | * Check whether prefetchable memory is supported | 937 | * Check whether prefetchable memory is supported |
@@ -785,38 +944,46 @@ static void pci_bus_size_cardbus(struct pci_bus *bus, | |||
785 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); | 944 | pci_read_config_word(bridge, PCI_CB_BRIDGE_CONTROL, &ctrl); |
786 | } | 945 | } |
787 | 946 | ||
947 | if (b_res[2].parent) | ||
948 | goto handle_b_res_3; | ||
788 | /* | 949 | /* |
789 | * If we have prefetchable memory support, allocate | 950 | * If we have prefetchable memory support, allocate |
790 | * two regions. Otherwise, allocate one region of | 951 | * two regions. Otherwise, allocate one region of |
791 | * twice the size. | 952 | * twice the size. |
792 | */ | 953 | */ |
793 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { | 954 | if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { |
794 | b_res[2].start = 0; | 955 | b_res[2].start = pci_cardbus_mem_size; |
795 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | IORESOURCE_SIZEALIGN; | 956 | b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1; |
796 | if (realloc_head) | 957 | b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH | |
797 | add_to_list(realloc_head, bridge, b_res+2, pci_cardbus_mem_size, 0 /* dont care */); | 958 | IORESOURCE_STARTALIGN; |
798 | 959 | if (realloc_head) { | |
799 | b_res[3].start = 0; | 960 | b_res[2].end -= pci_cardbus_mem_size; |
800 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 961 | add_to_list(realloc_head, bridge, b_res+2, |
801 | if (realloc_head) | 962 | pci_cardbus_mem_size, pci_cardbus_mem_size); |
802 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size, 0 /* dont care */); | 963 | } |
803 | } else { | 964 | |
804 | b_res[3].start = 0; | 965 | /* reduce that to half */ |
805 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_SIZEALIGN; | 966 | b_res_3_size = pci_cardbus_mem_size; |
806 | if (realloc_head) | 967 | } |
807 | add_to_list(realloc_head, bridge, b_res+3, pci_cardbus_mem_size * 2, 0 /* dont care */); | 968 | |
969 | handle_b_res_3: | ||
970 | if (b_res[3].parent) | ||
971 | goto handle_done; | ||
972 | b_res[3].start = pci_cardbus_mem_size; | ||
973 | b_res[3].end = b_res[3].start + b_res_3_size - 1; | ||
974 | b_res[3].flags |= IORESOURCE_MEM | IORESOURCE_STARTALIGN; | ||
975 | if (realloc_head) { | ||
976 | b_res[3].end -= b_res_3_size; | ||
977 | add_to_list(realloc_head, bridge, b_res+3, b_res_3_size, | ||
978 | pci_cardbus_mem_size); | ||
808 | } | 979 | } |
809 | 980 | ||
810 | /* set the size of the resource to zero, so that the resource does not | 981 | handle_done: |
811 | * get assigned during required-resource allocation cycle but gets assigned | 982 | ; |
812 | * during the optional-resource allocation cycle. | ||
813 | */ | ||
814 | b_res[0].start = b_res[1].start = b_res[2].start = b_res[3].start = 1; | ||
815 | b_res[0].end = b_res[1].end = b_res[2].end = b_res[3].end = 0; | ||
816 | } | 983 | } |
817 | 984 | ||
818 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, | 985 | void __ref __pci_bus_size_bridges(struct pci_bus *bus, |
819 | struct resource_list_x *realloc_head) | 986 | struct list_head *realloc_head) |
820 | { | 987 | { |
821 | struct pci_dev *dev; | 988 | struct pci_dev *dev; |
822 | unsigned long mask, prefmask; | 989 | unsigned long mask, prefmask; |
@@ -858,7 +1025,8 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
858 | * Follow thru | 1025 | * Follow thru |
859 | */ | 1026 | */ |
860 | default: | 1027 | default: |
861 | pbus_size_io(bus, 0, additional_io_size, realloc_head); | 1028 | pbus_size_io(bus, realloc_head ? 0 : additional_io_size, |
1029 | additional_io_size, realloc_head); | ||
862 | /* If the bridge supports prefetchable range, size it | 1030 | /* If the bridge supports prefetchable range, size it |
863 | separately. If it doesn't, or its prefetchable window | 1031 | separately. If it doesn't, or its prefetchable window |
864 | has already been allocated by arch code, try | 1032 | has already been allocated by arch code, try |
@@ -866,11 +1034,15 @@ void __ref __pci_bus_size_bridges(struct pci_bus *bus, | |||
866 | resources. */ | 1034 | resources. */ |
867 | mask = IORESOURCE_MEM; | 1035 | mask = IORESOURCE_MEM; |
868 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; | 1036 | prefmask = IORESOURCE_MEM | IORESOURCE_PREFETCH; |
869 | if (pbus_size_mem(bus, prefmask, prefmask, 0, additional_mem_size, realloc_head)) | 1037 | if (pbus_size_mem(bus, prefmask, prefmask, |
1038 | realloc_head ? 0 : additional_mem_size, | ||
1039 | additional_mem_size, realloc_head)) | ||
870 | mask = prefmask; /* Success, size non-prefetch only. */ | 1040 | mask = prefmask; /* Success, size non-prefetch only. */ |
871 | else | 1041 | else |
872 | additional_mem_size += additional_mem_size; | 1042 | additional_mem_size += additional_mem_size; |
873 | pbus_size_mem(bus, mask, IORESOURCE_MEM, 0, additional_mem_size, realloc_head); | 1043 | pbus_size_mem(bus, mask, IORESOURCE_MEM, |
1044 | realloc_head ? 0 : additional_mem_size, | ||
1045 | additional_mem_size, realloc_head); | ||
874 | break; | 1046 | break; |
875 | } | 1047 | } |
876 | } | 1048 | } |
@@ -882,8 +1054,8 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus) | |||
882 | EXPORT_SYMBOL(pci_bus_size_bridges); | 1054 | EXPORT_SYMBOL(pci_bus_size_bridges); |
883 | 1055 | ||
884 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, | 1056 | static void __ref __pci_bus_assign_resources(const struct pci_bus *bus, |
885 | struct resource_list_x *realloc_head, | 1057 | struct list_head *realloc_head, |
886 | struct resource_list_x *fail_head) | 1058 | struct list_head *fail_head) |
887 | { | 1059 | { |
888 | struct pci_bus *b; | 1060 | struct pci_bus *b; |
889 | struct pci_dev *dev; | 1061 | struct pci_dev *dev; |
@@ -922,17 +1094,19 @@ void __ref pci_bus_assign_resources(const struct pci_bus *bus) | |||
922 | EXPORT_SYMBOL(pci_bus_assign_resources); | 1094 | EXPORT_SYMBOL(pci_bus_assign_resources); |
923 | 1095 | ||
924 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, | 1096 | static void __ref __pci_bridge_assign_resources(const struct pci_dev *bridge, |
925 | struct resource_list_x *fail_head) | 1097 | struct list_head *add_head, |
1098 | struct list_head *fail_head) | ||
926 | { | 1099 | { |
927 | struct pci_bus *b; | 1100 | struct pci_bus *b; |
928 | 1101 | ||
929 | pdev_assign_resources_sorted((struct pci_dev *)bridge, fail_head); | 1102 | pdev_assign_resources_sorted((struct pci_dev *)bridge, |
1103 | add_head, fail_head); | ||
930 | 1104 | ||
931 | b = bridge->subordinate; | 1105 | b = bridge->subordinate; |
932 | if (!b) | 1106 | if (!b) |
933 | return; | 1107 | return; |
934 | 1108 | ||
935 | __pci_bus_assign_resources(b, NULL, fail_head); | 1109 | __pci_bus_assign_resources(b, add_head, fail_head); |
936 | 1110 | ||
937 | switch (bridge->class >> 8) { | 1111 | switch (bridge->class >> 8) { |
938 | case PCI_CLASS_BRIDGE_PCI: | 1112 | case PCI_CLASS_BRIDGE_PCI: |
@@ -1095,6 +1269,58 @@ static int __init pci_get_max_depth(void) | |||
1095 | return depth; | 1269 | return depth; |
1096 | } | 1270 | } |
1097 | 1271 | ||
1272 | /* | ||
1273 | * -1: undefined, will auto detect later | ||
1274 | * 0: disabled by user | ||
1275 | * 1: disabled by auto detect | ||
1276 | * 2: enabled by user | ||
1277 | * 3: enabled by auto detect | ||
1278 | */ | ||
1279 | enum enable_type { | ||
1280 | undefined = -1, | ||
1281 | user_disabled, | ||
1282 | auto_disabled, | ||
1283 | user_enabled, | ||
1284 | auto_enabled, | ||
1285 | }; | ||
1286 | |||
1287 | static enum enable_type pci_realloc_enable __initdata = undefined; | ||
1288 | void __init pci_realloc_get_opt(char *str) | ||
1289 | { | ||
1290 | if (!strncmp(str, "off", 3)) | ||
1291 | pci_realloc_enable = user_disabled; | ||
1292 | else if (!strncmp(str, "on", 2)) | ||
1293 | pci_realloc_enable = user_enabled; | ||
1294 | } | ||
1295 | static bool __init pci_realloc_enabled(void) | ||
1296 | { | ||
1297 | return pci_realloc_enable >= user_enabled; | ||
1298 | } | ||
1299 | |||
1300 | static void __init pci_realloc_detect(void) | ||
1301 | { | ||
1302 | #if defined(CONFIG_PCI_IOV) && defined(CONFIG_PCI_REALLOC_ENABLE_AUTO) | ||
1303 | struct pci_dev *dev = NULL; | ||
1304 | |||
1305 | if (pci_realloc_enable != undefined) | ||
1306 | return; | ||
1307 | |||
1308 | for_each_pci_dev(dev) { | ||
1309 | int i; | ||
1310 | |||
1311 | for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++) { | ||
1312 | struct resource *r = &dev->resource[i]; | ||
1313 | |||
1314 | /* Not assigned, or rejected by kernel ? */ | ||
1315 | if (r->flags && !r->start) { | ||
1316 | pci_realloc_enable = auto_enabled; | ||
1317 | |||
1318 | return; | ||
1319 | } | ||
1320 | } | ||
1321 | } | ||
1322 | #endif | ||
1323 | } | ||
1098 | 1324 | ||
1099 | /* | 1325 | /* |
1100 | * first try will not touch pci bridge res | 1326 | * first try will not touch pci bridge res |
@@ -1105,59 +1331,57 @@ void __init | |||
1105 | pci_assign_unassigned_resources(void) | 1331 | pci_assign_unassigned_resources(void) |
1106 | { | 1332 | { |
1107 | struct pci_bus *bus; | 1333 | struct pci_bus *bus; |
1108 | struct resource_list_x realloc_list; /* list of resources that | 1334 | LIST_HEAD(realloc_head); /* list of resources that |
1109 | want additional resources */ | 1335 | want additional resources */ |
1336 | struct list_head *add_list = NULL; | ||
1110 | int tried_times = 0; | 1337 | int tried_times = 0; |
1111 | enum release_type rel_type = leaf_only; | 1338 | enum release_type rel_type = leaf_only; |
1112 | struct resource_list_x head, *list; | 1339 | LIST_HEAD(fail_head); |
1340 | struct pci_dev_resource *fail_res; | ||
1113 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1341 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1114 | IORESOURCE_PREFETCH; | 1342 | IORESOURCE_PREFETCH; |
1115 | unsigned long failed_type; | 1343 | int pci_try_num = 1; |
1116 | int max_depth = pci_get_max_depth(); | ||
1117 | int pci_try_num; | ||
1118 | |||
1119 | 1344 | ||
1120 | head.next = NULL; | 1345 | /* don't realloc if asked to do so */ |
1121 | realloc_list.next = NULL; | 1346 | pci_realloc_detect(); |
1347 | if (pci_realloc_enabled()) { | ||
1348 | int max_depth = pci_get_max_depth(); | ||
1122 | 1349 | ||
1123 | pci_try_num = max_depth + 1; | 1350 | pci_try_num = max_depth + 1; |
1124 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", | 1351 | printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n", |
1125 | max_depth, pci_try_num); | 1352 | max_depth, pci_try_num); |
1353 | } | ||
1126 | 1354 | ||
1127 | again: | 1355 | again: |
1356 | /* | ||
1357 | * last try will use add_list, otherwise will try good to have as | ||
1358 | * must have, so can realloc parent bridge resource | ||
1359 | */ | ||
1360 | if (tried_times + 1 == pci_try_num) | ||
1361 | add_list = &realloc_head; | ||
1128 | /* Depth first, calculate sizes and alignments of all | 1362 | /* Depth first, calculate sizes and alignments of all |
1129 | subordinate buses. */ | 1363 | subordinate buses. */ |
1130 | list_for_each_entry(bus, &pci_root_buses, node) | 1364 | list_for_each_entry(bus, &pci_root_buses, node) |
1131 | __pci_bus_size_bridges(bus, &realloc_list); | 1365 | __pci_bus_size_bridges(bus, add_list); |
1132 | 1366 | ||
1133 | /* Depth last, allocate resources and update the hardware. */ | 1367 | /* Depth last, allocate resources and update the hardware. */ |
1134 | list_for_each_entry(bus, &pci_root_buses, node) | 1368 | list_for_each_entry(bus, &pci_root_buses, node) |
1135 | __pci_bus_assign_resources(bus, &realloc_list, &head); | 1369 | __pci_bus_assign_resources(bus, add_list, &fail_head); |
1136 | BUG_ON(realloc_list.next); | 1370 | if (add_list) |
1371 | BUG_ON(!list_empty(add_list)); | ||
1137 | tried_times++; | 1372 | tried_times++; |
1138 | 1373 | ||
1139 | /* any device complain? */ | 1374 | /* any device complain? */ |
1140 | if (!head.next) | 1375 | if (list_empty(&fail_head)) |
1141 | goto enable_and_dump; | 1376 | goto enable_and_dump; |
1142 | 1377 | ||
1143 | /* don't realloc if asked to do so */ | 1378 | if (tried_times >= pci_try_num) { |
1144 | if (!pci_realloc_enabled()) { | 1379 | if (pci_realloc_enable == undefined) |
1145 | free_list(resource_list_x, &head); | 1380 | printk(KERN_INFO "Some PCI device resources are unassigned, try booting with pci=realloc\n"); |
1146 | goto enable_and_dump; | 1381 | else if (pci_realloc_enable == auto_enabled) |
1147 | } | 1382 | printk(KERN_INFO "Automatically enabled pci realloc, if you have problem, try booting with pci=realloc=off\n"); |
1148 | 1383 | ||
1149 | failed_type = 0; | 1384 | free_list(&fail_head); |
1150 | for (list = head.next; list;) { | ||
1151 | failed_type |= list->flags; | ||
1152 | list = list->next; | ||
1153 | } | ||
1154 | /* | ||
1155 | * io port are tight, don't try extra | ||
1156 | * or if reach the limit, don't want to try more | ||
1157 | */ | ||
1158 | failed_type &= type_mask; | ||
1159 | if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) { | ||
1160 | free_list(resource_list_x, &head); | ||
1161 | goto enable_and_dump; | 1385 | goto enable_and_dump; |
1162 | } | 1386 | } |
1163 | 1387 | ||
@@ -1172,25 +1396,23 @@ again: | |||
1172 | * Try to release leaf bridge's resources that doesn't fit resource of | 1396 | * Try to release leaf bridge's resources that doesn't fit resource of |
1173 | * child device under that bridge | 1397 | * child device under that bridge |
1174 | */ | 1398 | */ |
1175 | for (list = head.next; list;) { | 1399 | list_for_each_entry(fail_res, &fail_head, list) { |
1176 | bus = list->dev->bus; | 1400 | bus = fail_res->dev->bus; |
1177 | pci_bus_release_bridge_resources(bus, list->flags & type_mask, | 1401 | pci_bus_release_bridge_resources(bus, |
1178 | rel_type); | 1402 | fail_res->flags & type_mask, |
1179 | list = list->next; | 1403 | rel_type); |
1180 | } | 1404 | } |
1181 | /* restore size and flags */ | 1405 | /* restore size and flags */ |
1182 | for (list = head.next; list;) { | 1406 | list_for_each_entry(fail_res, &fail_head, list) { |
1183 | struct resource *res = list->res; | 1407 | struct resource *res = fail_res->res; |
1184 | 1408 | ||
1185 | res->start = list->start; | 1409 | res->start = fail_res->start; |
1186 | res->end = list->end; | 1410 | res->end = fail_res->end; |
1187 | res->flags = list->flags; | 1411 | res->flags = fail_res->flags; |
1188 | if (list->dev->subordinate) | 1412 | if (fail_res->dev->subordinate) |
1189 | res->flags = 0; | 1413 | res->flags = 0; |
1190 | |||
1191 | list = list->next; | ||
1192 | } | 1414 | } |
1193 | free_list(resource_list_x, &head); | 1415 | free_list(&fail_head); |
1194 | 1416 | ||
1195 | goto again; | 1417 | goto again; |
1196 | 1418 | ||
@@ -1207,26 +1429,27 @@ enable_and_dump: | |||
1207 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) | 1429 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge) |
1208 | { | 1430 | { |
1209 | struct pci_bus *parent = bridge->subordinate; | 1431 | struct pci_bus *parent = bridge->subordinate; |
1432 | LIST_HEAD(add_list); /* list of resources that | ||
1433 | want additional resources */ | ||
1210 | int tried_times = 0; | 1434 | int tried_times = 0; |
1211 | struct resource_list_x head, *list; | 1435 | LIST_HEAD(fail_head); |
1436 | struct pci_dev_resource *fail_res; | ||
1212 | int retval; | 1437 | int retval; |
1213 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | | 1438 | unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM | |
1214 | IORESOURCE_PREFETCH; | 1439 | IORESOURCE_PREFETCH; |
1215 | 1440 | ||
1216 | head.next = NULL; | ||
1217 | |||
1218 | again: | 1441 | again: |
1219 | pci_bus_size_bridges(parent); | 1442 | __pci_bus_size_bridges(parent, &add_list); |
1220 | __pci_bridge_assign_resources(bridge, &head); | 1443 | __pci_bridge_assign_resources(bridge, &add_list, &fail_head); |
1221 | 1444 | BUG_ON(!list_empty(&add_list)); | |
1222 | tried_times++; | 1445 | tried_times++; |
1223 | 1446 | ||
1224 | if (!head.next) | 1447 | if (list_empty(&fail_head)) |
1225 | goto enable_all; | 1448 | goto enable_all; |
1226 | 1449 | ||
1227 | if (tried_times >= 2) { | 1450 | if (tried_times >= 2) { |
1228 | /* still fail, don't need to try more */ | 1451 | /* still fail, don't need to try more */ |
1229 | free_list(resource_list_x, &head); | 1452 | free_list(&fail_head); |
1230 | goto enable_all; | 1453 | goto enable_all; |
1231 | } | 1454 | } |
1232 | 1455 | ||
@@ -1237,27 +1460,24 @@ again: | |||
1237 | * Try to release leaf bridge's resources that doesn't fit resource of | 1460 | * Try to release leaf bridge's resources that doesn't fit resource of |
1238 | * child device under that bridge | 1461 | * child device under that bridge |
1239 | */ | 1462 | */ |
1240 | for (list = head.next; list;) { | 1463 | list_for_each_entry(fail_res, &fail_head, list) { |
1241 | struct pci_bus *bus = list->dev->bus; | 1464 | struct pci_bus *bus = fail_res->dev->bus; |
1242 | unsigned long flags = list->flags; | 1465 | unsigned long flags = fail_res->flags; |
1243 | 1466 | ||
1244 | pci_bus_release_bridge_resources(bus, flags & type_mask, | 1467 | pci_bus_release_bridge_resources(bus, flags & type_mask, |
1245 | whole_subtree); | 1468 | whole_subtree); |
1246 | list = list->next; | ||
1247 | } | 1469 | } |
1248 | /* restore size and flags */ | 1470 | /* restore size and flags */ |
1249 | for (list = head.next; list;) { | 1471 | list_for_each_entry(fail_res, &fail_head, list) { |
1250 | struct resource *res = list->res; | 1472 | struct resource *res = fail_res->res; |
1251 | 1473 | ||
1252 | res->start = list->start; | 1474 | res->start = fail_res->start; |
1253 | res->end = list->end; | 1475 | res->end = fail_res->end; |
1254 | res->flags = list->flags; | 1476 | res->flags = fail_res->flags; |
1255 | if (list->dev->subordinate) | 1477 | if (fail_res->dev->subordinate) |
1256 | res->flags = 0; | 1478 | res->flags = 0; |
1257 | |||
1258 | list = list->next; | ||
1259 | } | 1479 | } |
1260 | free_list(resource_list_x, &head); | 1480 | free_list(&fail_head); |
1261 | 1481 | ||
1262 | goto again; | 1482 | goto again; |
1263 | 1483 | ||
@@ -1267,3 +1487,41 @@ enable_all: | |||
1267 | pci_enable_bridges(parent); | 1487 | pci_enable_bridges(parent); |
1268 | } | 1488 | } |
1269 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); | 1489 | EXPORT_SYMBOL_GPL(pci_assign_unassigned_bridge_resources); |
1490 | |||
1491 | #ifdef CONFIG_HOTPLUG | ||
1492 | /** | ||
1493 | * pci_rescan_bus - scan a PCI bus for devices. | ||
1494 | * @bus: PCI bus to scan | ||
1495 | * | ||
1496 | * Scan a PCI bus and child buses for new devices, adds them, | ||
1497 | * and enables them. | ||
1498 | * | ||
1499 | * Returns the max number of subordinate bus discovered. | ||
1500 | */ | ||
1501 | unsigned int __ref pci_rescan_bus(struct pci_bus *bus) | ||
1502 | { | ||
1503 | unsigned int max; | ||
1504 | struct pci_dev *dev; | ||
1505 | LIST_HEAD(add_list); /* list of resources that | ||
1506 | want additional resources */ | ||
1507 | |||
1508 | max = pci_scan_child_bus(bus); | ||
1509 | |||
1510 | down_read(&pci_bus_sem); | ||
1511 | list_for_each_entry(dev, &bus->devices, bus_list) | ||
1512 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || | ||
1513 | dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) | ||
1514 | if (dev->subordinate) | ||
1515 | __pci_bus_size_bridges(dev->subordinate, | ||
1516 | &add_list); | ||
1517 | up_read(&pci_bus_sem); | ||
1518 | __pci_bus_assign_resources(bus, &add_list, NULL); | ||
1519 | BUG_ON(!list_empty(&add_list)); | ||
1520 | |||
1521 | pci_enable_bridges(bus); | ||
1522 | pci_bus_add_devices(bus); | ||
1523 | |||
1524 | return max; | ||
1525 | } | ||
1526 | EXPORT_SYMBOL_GPL(pci_rescan_bus); | ||
1527 | #endif | ||
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index b66bfdbd21f7..eea85dafc763 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -114,7 +114,6 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
114 | } | 114 | } |
115 | EXPORT_SYMBOL(pci_claim_resource); | 115 | EXPORT_SYMBOL(pci_claim_resource); |
116 | 116 | ||
117 | #ifdef CONFIG_PCI_QUIRKS | ||
118 | void pci_disable_bridge_window(struct pci_dev *dev) | 117 | void pci_disable_bridge_window(struct pci_dev *dev) |
119 | { | 118 | { |
120 | dev_info(&dev->dev, "disabling bridge mem windows\n"); | 119 | dev_info(&dev->dev, "disabling bridge mem windows\n"); |
@@ -127,9 +126,6 @@ void pci_disable_bridge_window(struct pci_dev *dev) | |||
127 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); | 126 | pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0); |
128 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); | 127 | pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff); |
129 | } | 128 | } |
130 | #endif /* CONFIG_PCI_QUIRKS */ | ||
131 | |||
132 | |||
133 | 129 | ||
134 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | 130 | static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, |
135 | int resno, resource_size_t size, resource_size_t align) | 131 | int resno, resource_size_t size, resource_size_t align) |
@@ -158,22 +154,44 @@ static int __pci_assign_resource(struct pci_bus *bus, struct pci_dev *dev, | |||
158 | return ret; | 154 | return ret; |
159 | } | 155 | } |
160 | 156 | ||
157 | /* | ||
158 | * Generic function that returns a value indicating that the device's | ||
159 | * original BIOS BAR address was not saved and so is not available for | ||
160 | * reinstatement. | ||
161 | * | ||
162 | * Can be over-ridden by architecture specific code that implements | ||
163 | * reinstatement functionality rather than leaving it disabled when | ||
164 | * normal allocation attempts fail. | ||
165 | */ | ||
166 | resource_size_t __weak pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx) | ||
167 | { | ||
168 | return 0; | ||
169 | } | ||
170 | |||
161 | static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, | 171 | static int pci_revert_fw_address(struct resource *res, struct pci_dev *dev, |
162 | int resno, resource_size_t size) | 172 | int resno, resource_size_t size) |
163 | { | 173 | { |
164 | struct resource *root, *conflict; | 174 | struct resource *root, *conflict; |
165 | resource_size_t start, end; | 175 | resource_size_t fw_addr, start, end; |
166 | int ret = 0; | 176 | int ret = 0; |
167 | 177 | ||
168 | if (res->flags & IORESOURCE_IO) | 178 | fw_addr = pcibios_retrieve_fw_addr(dev, resno); |
169 | root = &ioport_resource; | 179 | if (!fw_addr) |
170 | else | 180 | return 1; |
171 | root = &iomem_resource; | ||
172 | 181 | ||
173 | start = res->start; | 182 | start = res->start; |
174 | end = res->end; | 183 | end = res->end; |
175 | res->start = dev->fw_addr[resno]; | 184 | res->start = fw_addr; |
176 | res->end = res->start + size - 1; | 185 | res->end = res->start + size - 1; |
186 | |||
187 | root = pci_find_parent_resource(dev, res); | ||
188 | if (!root) { | ||
189 | if (res->flags & IORESOURCE_IO) | ||
190 | root = &ioport_resource; | ||
191 | else | ||
192 | root = &iomem_resource; | ||
193 | } | ||
194 | |||
177 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", | 195 | dev_info(&dev->dev, "BAR %d: trying firmware assignment %pR\n", |
178 | resno, res); | 196 | resno, res); |
179 | conflict = request_resource_conflict(root, res); | 197 | conflict = request_resource_conflict(root, res); |
@@ -228,16 +246,17 @@ int pci_reassign_resource(struct pci_dev *dev, int resno, resource_size_t addsiz | |||
228 | int ret; | 246 | int ret; |
229 | 247 | ||
230 | if (!res->parent) { | 248 | if (!res->parent) { |
231 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resouce %pR " | 249 | dev_info(&dev->dev, "BAR %d: can't reassign an unassigned resource %pR " |
232 | "\n", resno, res); | 250 | "\n", resno, res); |
233 | return -EINVAL; | 251 | return -EINVAL; |
234 | } | 252 | } |
235 | 253 | ||
236 | new_size = resource_size(res) + addsize + min_align; | 254 | /* already aligned with min_align */ |
255 | new_size = resource_size(res) + addsize; | ||
237 | ret = _pci_assign_resource(dev, resno, new_size, min_align); | 256 | ret = _pci_assign_resource(dev, resno, new_size, min_align); |
238 | if (!ret) { | 257 | if (!ret) { |
239 | res->flags &= ~IORESOURCE_STARTALIGN; | 258 | res->flags &= ~IORESOURCE_STARTALIGN; |
240 | dev_info(&dev->dev, "BAR %d: assigned %pR\n", resno, res); | 259 | dev_info(&dev->dev, "BAR %d: reassigned %pR\n", resno, res); |
241 | if (resno < PCI_BRIDGE_RESOURCES) | 260 | if (resno < PCI_BRIDGE_RESOURCES) |
242 | pci_update_resource(dev, resno); | 261 | pci_update_resource(dev, resno); |
243 | } | 262 | } |
@@ -267,7 +286,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
267 | * where firmware left it. That at least has a chance of | 286 | * where firmware left it. That at least has a chance of |
268 | * working, which is better than just leaving it disabled. | 287 | * working, which is better than just leaving it disabled. |
269 | */ | 288 | */ |
270 | if (ret < 0 && dev->fw_addr[resno]) | 289 | if (ret < 0) |
271 | ret = pci_revert_fw_address(res, dev, resno, size); | 290 | ret = pci_revert_fw_address(res, dev, resno, size); |
272 | 291 | ||
273 | if (!ret) { | 292 | if (!ret) { |
@@ -279,53 +298,6 @@ int pci_assign_resource(struct pci_dev *dev, int resno) | |||
279 | return ret; | 298 | return ret; |
280 | } | 299 | } |
281 | 300 | ||
282 | |||
283 | /* Sort resources by alignment */ | ||
284 | void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) | ||
285 | { | ||
286 | int i; | ||
287 | |||
288 | for (i = 0; i < PCI_NUM_RESOURCES; i++) { | ||
289 | struct resource *r; | ||
290 | struct resource_list *list, *tmp; | ||
291 | resource_size_t r_align; | ||
292 | |||
293 | r = &dev->resource[i]; | ||
294 | |||
295 | if (r->flags & IORESOURCE_PCI_FIXED) | ||
296 | continue; | ||
297 | |||
298 | if (!(r->flags) || r->parent) | ||
299 | continue; | ||
300 | |||
301 | r_align = pci_resource_alignment(dev, r); | ||
302 | if (!r_align) { | ||
303 | dev_warn(&dev->dev, "BAR %d: %pR has bogus alignment\n", | ||
304 | i, r); | ||
305 | continue; | ||
306 | } | ||
307 | for (list = head; ; list = list->next) { | ||
308 | resource_size_t align = 0; | ||
309 | struct resource_list *ln = list->next; | ||
310 | |||
311 | if (ln) | ||
312 | align = pci_resource_alignment(ln->dev, ln->res); | ||
313 | |||
314 | if (r_align > align) { | ||
315 | tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); | ||
316 | if (!tmp) | ||
317 | panic("pdev_sort_resources(): " | ||
318 | "kmalloc() failed!\n"); | ||
319 | tmp->next = ln; | ||
320 | tmp->res = r; | ||
321 | tmp->dev = dev; | ||
322 | list->next = tmp; | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | } | ||
327 | } | ||
328 | |||
329 | int pci_enable_resources(struct pci_dev *dev, int mask) | 301 | int pci_enable_resources(struct pci_dev *dev, int mask) |
330 | { | 302 | { |
331 | u16 cmd, old_cmd; | 303 | u16 cmd, old_cmd; |
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 401090110922..fd00ff02ab4d 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c | |||
@@ -544,7 +544,7 @@ static void free_root_bus_devs(struct pci_bus *bus) | |||
544 | dev = container_of(bus->devices.next, struct pci_dev, | 544 | dev = container_of(bus->devices.next, struct pci_dev, |
545 | bus_list); | 545 | bus_list); |
546 | dev_dbg(&dev->dev, "removing device\n"); | 546 | dev_dbg(&dev->dev, "removing device\n"); |
547 | pci_remove_bus_device(dev); | 547 | pci_stop_and_remove_bus_device(dev); |
548 | } | 548 | } |
549 | } | 549 | } |
550 | 550 | ||
@@ -1044,7 +1044,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) | |||
1044 | domain, bus, slot, func); | 1044 | domain, bus, slot, func); |
1045 | continue; | 1045 | continue; |
1046 | } | 1046 | } |
1047 | pci_remove_bus_device(pci_dev); | 1047 | pci_stop_and_remove_bus_device(pci_dev); |
1048 | pci_dev_put(pci_dev); | 1048 | pci_dev_put(pci_dev); |
1049 | 1049 | ||
1050 | dev_dbg(&pdev->xdev->dev, | 1050 | dev_dbg(&pdev->xdev->dev, |
diff --git a/drivers/pcmcia/cardbus.c b/drivers/pcmcia/cardbus.c index 9a58862f1401..6e75153c5b4f 100644 --- a/drivers/pcmcia/cardbus.c +++ b/drivers/pcmcia/cardbus.c | |||
@@ -108,5 +108,5 @@ void cb_free(struct pcmcia_socket *s) | |||
108 | struct pci_dev *bridge = s->cb_dev; | 108 | struct pci_dev *bridge = s->cb_dev; |
109 | 109 | ||
110 | if (bridge) | 110 | if (bridge) |
111 | pci_remove_behind_bridge(bridge); | 111 | pci_stop_and_remove_behind_bridge(bridge); |
112 | } | 112 | } |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 72d731c21d45..9929246895de 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -571,7 +571,7 @@ static void asus_rfkill_hotplug(struct asus_wmi *asus) | |||
571 | } else { | 571 | } else { |
572 | dev = pci_get_slot(bus, 0); | 572 | dev = pci_get_slot(bus, 0); |
573 | if (dev) { | 573 | if (dev) { |
574 | pci_remove_bus_device(dev); | 574 | pci_stop_and_remove_bus_device(dev); |
575 | pci_dev_put(dev); | 575 | pci_dev_put(dev); |
576 | } | 576 | } |
577 | } | 577 | } |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index ea44abd8df48..d9a9e2bedb30 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -646,7 +646,7 @@ static void eeepc_rfkill_hotplug(struct eeepc_laptop *eeepc, acpi_handle handle) | |||
646 | } else { | 646 | } else { |
647 | dev = pci_get_slot(bus, 0); | 647 | dev = pci_get_slot(bus, 0); |
648 | if (dev) { | 648 | if (dev) { |
649 | pci_remove_bus_device(dev); | 649 | pci_stop_and_remove_bus_device(dev); |
650 | pci_dev_put(dev); | 650 | pci_dev_put(dev); |
651 | } | 651 | } |
652 | } | 652 | } |
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 82fa6ce481f0..5e69f468535f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c | |||
@@ -132,7 +132,7 @@ static int mpt2sas_remove_dead_ioc_func(void *arg) | |||
132 | pdev = ioc->pdev; | 132 | pdev = ioc->pdev; |
133 | if ((pdev == NULL)) | 133 | if ((pdev == NULL)) |
134 | return -1; | 134 | return -1; |
135 | pci_remove_bus_device(pdev); | 135 | pci_stop_and_remove_bus_device(pdev); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 7732d69e49e0..11de5f1be981 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -893,4 +893,5 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev) | |||
893 | quirk_usb_handoff_xhci(pdev); | 893 | quirk_usb_handoff_xhci(pdev); |
894 | pci_disable_device(pdev); | 894 | pci_disable_device(pdev); |
895 | } | 895 | } |
896 | DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff); | 896 | DECLARE_PCI_FIXUP_CLASS_FINAL(PCI_ANY_ID, PCI_ANY_ID, |
897 | PCI_CLASS_SERIAL_USB, 8, quirk_usb_early_handoff); | ||
diff --git a/include/asm-generic/pci-bridge.h b/include/asm-generic/pci-bridge.h index 4a5aca2a2c94..a5b5d5a89a4f 100644 --- a/include/asm-generic/pci-bridge.h +++ b/include/asm-generic/pci-bridge.h | |||
@@ -45,6 +45,11 @@ static inline void pci_add_flags(int flags) | |||
45 | pci_flags |= flags; | 45 | pci_flags |= flags; |
46 | } | 46 | } |
47 | 47 | ||
48 | static inline void pci_clear_flags(int flags) | ||
49 | { | ||
50 | pci_flags &= ~flags; | ||
51 | } | ||
52 | |||
48 | static inline int pci_has_flag(int flag) | 53 | static inline int pci_has_flag(int flag) |
49 | { | 54 | { |
50 | return pci_flags & flag; | 55 | return pci_flags & flag; |
@@ -52,6 +57,7 @@ static inline int pci_has_flag(int flag) | |||
52 | #else | 57 | #else |
53 | static inline void pci_set_flags(int flags) { } | 58 | static inline void pci_set_flags(int flags) { } |
54 | static inline void pci_add_flags(int flags) { } | 59 | static inline void pci_add_flags(int flags) { } |
60 | static inline void pci_clear_flags(int flags) { } | ||
55 | static inline int pci_has_flag(int flag) | 61 | static inline int pci_has_flag(int flag) |
56 | { | 62 | { |
57 | return 0; | 63 | return 0; |
diff --git a/include/asm-generic/pci.h b/include/asm-generic/pci.h index 26373cff4546..e80a0495e5b0 100644 --- a/include/asm-generic/pci.h +++ b/include/asm-generic/pci.h | |||
@@ -6,30 +6,6 @@ | |||
6 | #ifndef _ASM_GENERIC_PCI_H | 6 | #ifndef _ASM_GENERIC_PCI_H |
7 | #define _ASM_GENERIC_PCI_H | 7 | #define _ASM_GENERIC_PCI_H |
8 | 8 | ||
9 | /** | ||
10 | * pcibios_resource_to_bus - convert resource to PCI bus address | ||
11 | * @dev: device which owns this resource | ||
12 | * @region: converted bus-centric region (start,end) | ||
13 | * @res: resource to convert | ||
14 | * | ||
15 | * Convert a resource to a PCI device bus address or bus window. | ||
16 | */ | ||
17 | static inline void | ||
18 | pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
19 | struct resource *res) | ||
20 | { | ||
21 | region->start = res->start; | ||
22 | region->end = res->end; | ||
23 | } | ||
24 | |||
25 | static inline void | ||
26 | pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
27 | struct pci_bus_region *region) | ||
28 | { | ||
29 | res->start = region->start; | ||
30 | res->end = region->end; | ||
31 | } | ||
32 | |||
33 | static inline struct resource * | 9 | static inline struct resource * |
34 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) | 10 | pcibios_select_root(struct pci_dev *pdev, struct resource *res) |
35 | { | 11 | { |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index 9d57a71775b5..e885ba23de70 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -23,12 +23,6 @@ struct resource { | |||
23 | struct resource *parent, *sibling, *child; | 23 | struct resource *parent, *sibling, *child; |
24 | }; | 24 | }; |
25 | 25 | ||
26 | struct resource_list { | ||
27 | struct resource_list *next; | ||
28 | struct resource *res; | ||
29 | struct pci_dev *dev; | ||
30 | }; | ||
31 | |||
32 | /* | 26 | /* |
33 | * IO resources have these defined flags. | 27 | * IO resources have these defined flags. |
34 | */ | 28 | */ |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 900da5db60ee..e444f5b49118 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -299,7 +299,6 @@ struct pci_dev { | |||
299 | */ | 299 | */ |
300 | unsigned int irq; | 300 | unsigned int irq; |
301 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ | 301 | struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ |
302 | resource_size_t fw_addr[DEVICE_COUNT_RESOURCE]; /* FW-assigned addr */ | ||
303 | 302 | ||
304 | /* These fields are used by common fixups */ | 303 | /* These fields are used by common fixups */ |
305 | unsigned int transparent:1; /* Transparent PCI bridge */ | 304 | unsigned int transparent:1; /* Transparent PCI bridge */ |
@@ -369,24 +368,17 @@ static inline int pci_channel_offline(struct pci_dev *pdev) | |||
369 | return (pdev->error_state != pci_channel_io_normal); | 368 | return (pdev->error_state != pci_channel_io_normal); |
370 | } | 369 | } |
371 | 370 | ||
372 | static inline struct pci_cap_saved_state *pci_find_saved_cap( | 371 | struct pci_host_bridge_window { |
373 | struct pci_dev *pci_dev, char cap) | 372 | struct list_head list; |
374 | { | 373 | struct resource *res; /* host bridge aperture (CPU address) */ |
375 | struct pci_cap_saved_state *tmp; | 374 | resource_size_t offset; /* bus address + offset = CPU address */ |
376 | struct hlist_node *pos; | 375 | }; |
377 | |||
378 | hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { | ||
379 | if (tmp->cap.cap_nr == cap) | ||
380 | return tmp; | ||
381 | } | ||
382 | return NULL; | ||
383 | } | ||
384 | 376 | ||
385 | static inline void pci_add_saved_cap(struct pci_dev *pci_dev, | 377 | struct pci_host_bridge { |
386 | struct pci_cap_saved_state *new_cap) | 378 | struct list_head list; |
387 | { | 379 | struct pci_bus *bus; /* root bus */ |
388 | hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); | 380 | struct list_head windows; /* pci_host_bridge_windows */ |
389 | } | 381 | }; |
390 | 382 | ||
391 | /* | 383 | /* |
392 | * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond | 384 | * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond |
@@ -656,6 +648,10 @@ void pci_fixup_cardbus(struct pci_bus *); | |||
656 | 648 | ||
657 | /* Generic PCI functions used internally */ | 649 | /* Generic PCI functions used internally */ |
658 | 650 | ||
651 | void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, | ||
652 | struct resource *res); | ||
653 | void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, | ||
654 | struct pci_bus_region *region); | ||
659 | void pcibios_scan_specific_bus(int busn); | 655 | void pcibios_scan_specific_bus(int busn); |
660 | extern struct pci_bus *pci_find_bus(int domain, int busnr); | 656 | extern struct pci_bus *pci_find_bus(int domain, int busnr); |
661 | void pci_bus_add_devices(const struct pci_bus *bus); | 657 | void pci_bus_add_devices(const struct pci_bus *bus); |
@@ -690,7 +686,8 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); | |||
690 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); | 686 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); |
691 | extern void pci_dev_put(struct pci_dev *dev); | 687 | extern void pci_dev_put(struct pci_dev *dev); |
692 | extern void pci_remove_bus(struct pci_bus *b); | 688 | extern void pci_remove_bus(struct pci_bus *b); |
693 | extern void pci_remove_bus_device(struct pci_dev *dev); | 689 | extern void __pci_remove_bus_device(struct pci_dev *dev); |
690 | extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); | ||
694 | extern void pci_stop_bus_device(struct pci_dev *dev); | 691 | extern void pci_stop_bus_device(struct pci_dev *dev); |
695 | void pci_setup_cardbus(struct pci_bus *bus); | 692 | void pci_setup_cardbus(struct pci_bus *bus); |
696 | extern void pci_sort_breadthfirst(void); | 693 | extern void pci_sort_breadthfirst(void); |
@@ -883,6 +880,7 @@ void set_pcie_hotplug_bridge(struct pci_dev *pdev); | |||
883 | /* Functions for PCI Hotplug drivers to use */ | 880 | /* Functions for PCI Hotplug drivers to use */ |
884 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); | 881 | int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap); |
885 | #ifdef CONFIG_HOTPLUG | 882 | #ifdef CONFIG_HOTPLUG |
883 | unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge); | ||
886 | unsigned int pci_rescan_bus(struct pci_bus *bus); | 884 | unsigned int pci_rescan_bus(struct pci_bus *bus); |
887 | #endif | 885 | #endif |
888 | 886 | ||
@@ -892,13 +890,13 @@ ssize_t pci_write_vpd(struct pci_dev *dev, loff_t pos, size_t count, const void | |||
892 | int pci_vpd_truncate(struct pci_dev *dev, size_t size); | 890 | int pci_vpd_truncate(struct pci_dev *dev, size_t size); |
893 | 891 | ||
894 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ | 892 | /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ |
893 | resource_size_t pcibios_retrieve_fw_addr(struct pci_dev *dev, int idx); | ||
895 | void pci_bus_assign_resources(const struct pci_bus *bus); | 894 | void pci_bus_assign_resources(const struct pci_bus *bus); |
896 | void pci_bus_size_bridges(struct pci_bus *bus); | 895 | void pci_bus_size_bridges(struct pci_bus *bus); |
897 | int pci_claim_resource(struct pci_dev *, int); | 896 | int pci_claim_resource(struct pci_dev *, int); |
898 | void pci_assign_unassigned_resources(void); | 897 | void pci_assign_unassigned_resources(void); |
899 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); | 898 | void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge); |
900 | void pdev_enable_device(struct pci_dev *); | 899 | void pdev_enable_device(struct pci_dev *); |
901 | void pdev_sort_resources(struct pci_dev *, struct resource_list *); | ||
902 | int pci_enable_resources(struct pci_dev *, int mask); | 900 | int pci_enable_resources(struct pci_dev *, int mask); |
903 | void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), | 901 | void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), |
904 | int (*)(const struct pci_dev *, u8, u8)); | 902 | int (*)(const struct pci_dev *, u8, u8)); |
@@ -915,6 +913,8 @@ void pci_release_selected_regions(struct pci_dev *, int); | |||
915 | 913 | ||
916 | /* drivers/pci/bus.c */ | 914 | /* drivers/pci/bus.c */ |
917 | void pci_add_resource(struct list_head *resources, struct resource *res); | 915 | void pci_add_resource(struct list_head *resources, struct resource *res); |
916 | void pci_add_resource_offset(struct list_head *resources, struct resource *res, | ||
917 | resource_size_t offset); | ||
918 | void pci_free_resource_list(struct list_head *resources); | 918 | void pci_free_resource_list(struct list_head *resources); |
919 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags); | 919 | void pci_bus_add_resource(struct pci_bus *bus, struct resource *res, unsigned int flags); |
920 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); | 920 | struct resource *pci_bus_resource_n(const struct pci_bus *bus, int n); |
@@ -960,7 +960,7 @@ void pci_unregister_driver(struct pci_driver *dev); | |||
960 | module_driver(__pci_driver, pci_register_driver, \ | 960 | module_driver(__pci_driver, pci_register_driver, \ |
961 | pci_unregister_driver) | 961 | pci_unregister_driver) |
962 | 962 | ||
963 | void pci_remove_behind_bridge(struct pci_dev *dev); | 963 | void pci_stop_and_remove_behind_bridge(struct pci_dev *dev); |
964 | struct pci_driver *pci_dev_driver(const struct pci_dev *dev); | 964 | struct pci_driver *pci_dev_driver(const struct pci_dev *dev); |
965 | int pci_add_dynid(struct pci_driver *drv, | 965 | int pci_add_dynid(struct pci_driver *drv, |
966 | unsigned int vendor, unsigned int device, | 966 | unsigned int vendor, unsigned int device, |
@@ -1396,7 +1396,10 @@ static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, | |||
1396 | */ | 1396 | */ |
1397 | 1397 | ||
1398 | struct pci_fixup { | 1398 | struct pci_fixup { |
1399 | u16 vendor, device; /* You can use PCI_ANY_ID here of course */ | 1399 | u16 vendor; /* You can use PCI_ANY_ID here of course */ |
1400 | u16 device; /* You can use PCI_ANY_ID here of course */ | ||
1401 | u32 class; /* You can use PCI_ANY_ID here too */ | ||
1402 | unsigned int class_shift; /* should be 0, 8, 16 */ | ||
1400 | void (*hook)(struct pci_dev *dev); | 1403 | void (*hook)(struct pci_dev *dev); |
1401 | }; | 1404 | }; |
1402 | 1405 | ||
@@ -1411,30 +1414,68 @@ enum pci_fixup_pass { | |||
1411 | }; | 1414 | }; |
1412 | 1415 | ||
1413 | /* Anonymous variables would be nice... */ | 1416 | /* Anonymous variables would be nice... */ |
1414 | #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \ | 1417 | #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ |
1415 | static const struct pci_fixup __pci_fixup_##name __used \ | 1418 | class_shift, hook) \ |
1416 | __attribute__((__section__(#section))) = { vendor, device, hook }; | 1419 | static const struct pci_fixup const __pci_fixup_##name __used \ |
1420 | __attribute__((__section__(#section), aligned((sizeof(void *))))) \ | ||
1421 | = { vendor, device, class, class_shift, hook }; | ||
1422 | |||
1423 | #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ | ||
1424 | class_shift, hook) \ | ||
1425 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ | ||
1426 | vendor##device##hook, vendor, device, class, class_shift, hook) | ||
1427 | #define DECLARE_PCI_FIXUP_CLASS_HEADER(vendor, device, class, \ | ||
1428 | class_shift, hook) \ | ||
1429 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ | ||
1430 | vendor##device##hook, vendor, device, class, class_shift, hook) | ||
1431 | #define DECLARE_PCI_FIXUP_CLASS_FINAL(vendor, device, class, \ | ||
1432 | class_shift, hook) \ | ||
1433 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ | ||
1434 | vendor##device##hook, vendor, device, class, class_shift, hook) | ||
1435 | #define DECLARE_PCI_FIXUP_CLASS_ENABLE(vendor, device, class, \ | ||
1436 | class_shift, hook) \ | ||
1437 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ | ||
1438 | vendor##device##hook, vendor, device, class, class_shift, hook) | ||
1439 | #define DECLARE_PCI_FIXUP_CLASS_RESUME(vendor, device, class, \ | ||
1440 | class_shift, hook) \ | ||
1441 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ | ||
1442 | resume##vendor##device##hook, vendor, device, class, \ | ||
1443 | class_shift, hook) | ||
1444 | #define DECLARE_PCI_FIXUP_CLASS_RESUME_EARLY(vendor, device, class, \ | ||
1445 | class_shift, hook) \ | ||
1446 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ | ||
1447 | resume_early##vendor##device##hook, vendor, device, \ | ||
1448 | class, class_shift, hook) | ||
1449 | #define DECLARE_PCI_FIXUP_CLASS_SUSPEND(vendor, device, class, \ | ||
1450 | class_shift, hook) \ | ||
1451 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ | ||
1452 | suspend##vendor##device##hook, vendor, device, class, \ | ||
1453 | class_shift, hook) | ||
1454 | |||
1417 | #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ | 1455 | #define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ |
1418 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ | 1456 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ |
1419 | vendor##device##hook, vendor, device, hook) | 1457 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) |
1420 | #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ | 1458 | #define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ |
1421 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ | 1459 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ |
1422 | vendor##device##hook, vendor, device, hook) | 1460 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) |
1423 | #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ | 1461 | #define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ |
1424 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ | 1462 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ |
1425 | vendor##device##hook, vendor, device, hook) | 1463 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) |
1426 | #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ | 1464 | #define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ |
1427 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ | 1465 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ |
1428 | vendor##device##hook, vendor, device, hook) | 1466 | vendor##device##hook, vendor, device, PCI_ANY_ID, 0, hook) |
1429 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ | 1467 | #define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \ |
1430 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ | 1468 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \ |
1431 | resume##vendor##device##hook, vendor, device, hook) | 1469 | resume##vendor##device##hook, vendor, device, \ |
1470 | PCI_ANY_ID, 0, hook) | ||
1432 | #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ | 1471 | #define DECLARE_PCI_FIXUP_RESUME_EARLY(vendor, device, hook) \ |
1433 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ | 1472 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume_early, \ |
1434 | resume_early##vendor##device##hook, vendor, device, hook) | 1473 | resume_early##vendor##device##hook, vendor, device, \ |
1474 | PCI_ANY_ID, 0, hook) | ||
1435 | #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ | 1475 | #define DECLARE_PCI_FIXUP_SUSPEND(vendor, device, hook) \ |
1436 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ | 1476 | DECLARE_PCI_FIXUP_SECTION(.pci_fixup_suspend, \ |
1437 | suspend##vendor##device##hook, vendor, device, hook) | 1477 | suspend##vendor##device##hook, vendor, device, \ |
1478 | PCI_ANY_ID, 0, hook) | ||
1438 | 1479 | ||
1439 | #ifdef CONFIG_PCI_QUIRKS | 1480 | #ifdef CONFIG_PCI_QUIRKS |
1440 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); | 1481 | void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); |
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index e41a10f5ae83..4b608f543412 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h | |||
@@ -391,6 +391,7 @@ | |||
391 | #define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ | 391 | #define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ |
392 | #define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ | 392 | #define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ |
393 | #define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ | 393 | #define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ |
394 | #define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIE Bridge */ | ||
394 | #define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */ | 395 | #define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */ |
395 | #define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ | 396 | #define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */ |
396 | #define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ | 397 | #define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ |