diff options
-rw-r--r-- | arch/frv/mb93090-mb00/pci-frv.h | 1 | ||||
-rw-r--r-- | arch/frv/mb93090-mb00/pci-vdk.c | 4 | ||||
-rw-r--r-- | arch/ia64/pci/pci.c | 8 | ||||
-rw-r--r-- | arch/mn10300/unit-asb2305/pci-asb2305.h | 1 | ||||
-rw-r--r-- | arch/mn10300/unit-asb2305/pci.c | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/pci.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/pci_x86.h | 1 | ||||
-rw-r--r-- | arch/x86/pci/acpi.c | 9 | ||||
-rw-r--r-- | arch/x86/pci/common.c | 1 | ||||
-rw-r--r-- | arch/x86/pci/legacy.c | 2 | ||||
-rw-r--r-- | arch/x86/pci/numaq_32.c | 2 | ||||
-rw-r--r-- | drivers/acpi/pci_root.c | 18 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 29 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 57 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_pci.c | 44 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 63 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_pci.c | 36 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 19 | ||||
-rw-r--r-- | drivers/pci/pci.c | 30 | ||||
-rw-r--r-- | drivers/pci/pci.h | 3 | ||||
-rw-r--r-- | drivers/pci/probe.c | 66 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 1 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
23 files changed, 176 insertions, 228 deletions
diff --git a/arch/frv/mb93090-mb00/pci-frv.h b/arch/frv/mb93090-mb00/pci-frv.h index 089eeba4f3bc..76c4e73d643d 100644 --- a/arch/frv/mb93090-mb00/pci-frv.h +++ b/arch/frv/mb93090-mb00/pci-frv.h | |||
@@ -31,7 +31,6 @@ void pcibios_resource_survey(void); | |||
31 | /* pci-vdk.c */ | 31 | /* pci-vdk.c */ |
32 | 32 | ||
33 | extern int __nongpreldata pcibios_last_bus; | 33 | extern int __nongpreldata pcibios_last_bus; |
34 | extern struct pci_bus *__nongpreldata pci_root_bus; | ||
35 | extern struct pci_ops *__nongpreldata pci_root_ops; | 34 | extern struct pci_ops *__nongpreldata pci_root_ops; |
36 | 35 | ||
37 | /* pci-irq.c */ | 36 | /* pci-irq.c */ |
diff --git a/arch/frv/mb93090-mb00/pci-vdk.c b/arch/frv/mb93090-mb00/pci-vdk.c index 71e9bcf58105..1152a1e3cabb 100644 --- a/arch/frv/mb93090-mb00/pci-vdk.c +++ b/arch/frv/mb93090-mb00/pci-vdk.c | |||
@@ -26,7 +26,6 @@ | |||
26 | unsigned int __nongpreldata pci_probe = 1; | 26 | unsigned int __nongpreldata pci_probe = 1; |
27 | 27 | ||
28 | int __nongpreldata pcibios_last_bus = -1; | 28 | int __nongpreldata pcibios_last_bus = -1; |
29 | struct pci_bus *__nongpreldata pci_root_bus; | ||
30 | struct pci_ops *__nongpreldata pci_root_ops; | 29 | struct pci_ops *__nongpreldata pci_root_ops; |
31 | 30 | ||
32 | /* | 31 | /* |
@@ -416,8 +415,7 @@ int __init pcibios_init(void) | |||
416 | printk("PCI: Probing PCI hardware\n"); | 415 | printk("PCI: Probing PCI hardware\n"); |
417 | pci_add_resource(&resources, &pci_ioport_resource); | 416 | pci_add_resource(&resources, &pci_ioport_resource); |
418 | pci_add_resource(&resources, &pci_iomem_resource); | 417 | pci_add_resource(&resources, &pci_iomem_resource); |
419 | pci_root_bus = pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, | 418 | pci_scan_root_bus(NULL, 0, pci_root_ops, NULL, &resources); |
420 | &resources); | ||
421 | 419 | ||
422 | pcibios_irq_init(); | 420 | pcibios_irq_init(); |
423 | pcibios_fixup_peer_bridges(); | 421 | pcibios_fixup_peer_bridges(); |
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 5faa66c5c2a8..00e59c7ad3c0 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -396,6 +396,14 @@ out1: | |||
396 | return NULL; | 396 | return NULL; |
397 | } | 397 | } |
398 | 398 | ||
399 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
400 | { | ||
401 | struct pci_controller *controller = bridge->bus->sysdata; | ||
402 | |||
403 | ACPI_HANDLE_SET(&bridge->dev, controller->acpi_handle); | ||
404 | return 0; | ||
405 | } | ||
406 | |||
399 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | 407 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) |
400 | { | 408 | { |
401 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; | 409 | unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; |
diff --git a/arch/mn10300/unit-asb2305/pci-asb2305.h b/arch/mn10300/unit-asb2305/pci-asb2305.h index 1194fe486b01..7fa66a0e4624 100644 --- a/arch/mn10300/unit-asb2305/pci-asb2305.h +++ b/arch/mn10300/unit-asb2305/pci-asb2305.h | |||
@@ -36,7 +36,6 @@ extern void pcibios_resource_survey(void); | |||
36 | /* pci.c */ | 36 | /* pci.c */ |
37 | 37 | ||
38 | extern int pcibios_last_bus; | 38 | extern int pcibios_last_bus; |
39 | extern struct pci_bus *pci_root_bus; | ||
40 | extern struct pci_ops *pci_root_ops; | 39 | extern struct pci_ops *pci_root_ops; |
41 | 40 | ||
42 | extern struct irq_routing_table *pcibios_get_irq_routing_table(void); | 41 | extern struct irq_routing_table *pcibios_get_irq_routing_table(void); |
diff --git a/arch/mn10300/unit-asb2305/pci.c b/arch/mn10300/unit-asb2305/pci.c index e2059486d3f8..426bf51605f3 100644 --- a/arch/mn10300/unit-asb2305/pci.c +++ b/arch/mn10300/unit-asb2305/pci.c | |||
@@ -24,7 +24,6 @@ | |||
24 | unsigned int pci_probe = 1; | 24 | unsigned int pci_probe = 1; |
25 | 25 | ||
26 | int pcibios_last_bus = -1; | 26 | int pcibios_last_bus = -1; |
27 | struct pci_bus *pci_root_bus; | ||
28 | struct pci_ops *pci_root_ops; | 27 | struct pci_ops *pci_root_ops; |
29 | 28 | ||
30 | /* | 29 | /* |
@@ -377,8 +376,7 @@ static int __init pcibios_init(void) | |||
377 | 376 | ||
378 | pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset); | 377 | pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset); |
379 | pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset); | 378 | pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset); |
380 | pci_root_bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, | 379 | pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources); |
381 | &resources); | ||
382 | 380 | ||
383 | pcibios_irq_init(); | 381 | pcibios_irq_init(); |
384 | pcibios_fixup_irqs(); | 382 | pcibios_fixup_irqs(); |
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index dba7805176bf..9f437e97e9e8 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h | |||
@@ -14,6 +14,9 @@ | |||
14 | struct pci_sysdata { | 14 | struct pci_sysdata { |
15 | int domain; /* PCI domain */ | 15 | int domain; /* PCI domain */ |
16 | int node; /* NUMA node */ | 16 | int node; /* NUMA node */ |
17 | #ifdef CONFIG_ACPI | ||
18 | void *acpi; /* ACPI-specific data */ | ||
19 | #endif | ||
17 | #ifdef CONFIG_X86_64 | 20 | #ifdef CONFIG_X86_64 |
18 | void *iommu; /* IOMMU private data */ | 21 | void *iommu; /* IOMMU private data */ |
19 | #endif | 22 | #endif |
diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index 73e8eeff22ee..0126f104f0a5 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h | |||
@@ -54,7 +54,6 @@ void pcibios_set_cache_line_size(void); | |||
54 | /* pci-pc.c */ | 54 | /* pci-pc.c */ |
55 | 55 | ||
56 | extern int pcibios_last_bus; | 56 | extern int pcibios_last_bus; |
57 | extern struct pci_bus *pci_root_bus; | ||
58 | extern struct pci_ops pci_root_ops; | 57 | extern struct pci_ops pci_root_ops; |
59 | 58 | ||
60 | void pcibios_scan_specific_bus(int busn); | 59 | void pcibios_scan_specific_bus(int busn); |
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 0c01261fe5a8..3d49094ed3e8 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c | |||
@@ -522,6 +522,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
522 | sd = &info->sd; | 522 | sd = &info->sd; |
523 | sd->domain = domain; | 523 | sd->domain = domain; |
524 | sd->node = node; | 524 | sd->node = node; |
525 | sd->acpi = device->handle; | ||
525 | /* | 526 | /* |
526 | * Maybe the desired pci bus has been already scanned. In such case | 527 | * Maybe the desired pci bus has been already scanned. In such case |
527 | * it is unnecessary to scan the pci bus with the given domain,busnum. | 528 | * it is unnecessary to scan the pci bus with the given domain,busnum. |
@@ -593,6 +594,14 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root) | |||
593 | return bus; | 594 | return bus; |
594 | } | 595 | } |
595 | 596 | ||
597 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
598 | { | ||
599 | struct pci_sysdata *sd = bridge->bus->sysdata; | ||
600 | |||
601 | ACPI_HANDLE_SET(&bridge->dev, sd->acpi); | ||
602 | return 0; | ||
603 | } | ||
604 | |||
596 | int __init pci_acpi_init(void) | 605 | int __init pci_acpi_init(void) |
597 | { | 606 | { |
598 | struct pci_dev *dev = NULL; | 607 | struct pci_dev *dev = NULL; |
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c index 412e1286d1fc..505731b139f4 100644 --- a/arch/x86/pci/common.c +++ b/arch/x86/pci/common.c | |||
@@ -34,7 +34,6 @@ int noioapicreroute = 1; | |||
34 | #endif | 34 | #endif |
35 | int pcibios_last_bus = -1; | 35 | int pcibios_last_bus = -1; |
36 | unsigned long pirq_table_addr; | 36 | unsigned long pirq_table_addr; |
37 | struct pci_bus *pci_root_bus; | ||
38 | const struct pci_raw_ops *__read_mostly raw_pci_ops; | 37 | const struct pci_raw_ops *__read_mostly raw_pci_ops; |
39 | const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; | 38 | const struct pci_raw_ops *__read_mostly raw_pci_ext_ops; |
40 | 39 | ||
diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index a1df191129d3..a9e83083fb85 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c | |||
@@ -30,7 +30,7 @@ int __init pci_legacy_init(void) | |||
30 | } | 30 | } |
31 | 31 | ||
32 | printk("PCI: Probing PCI hardware\n"); | 32 | printk("PCI: Probing PCI hardware\n"); |
33 | pci_root_bus = pcibios_scan_root(0); | 33 | pcibios_scan_root(0); |
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
diff --git a/arch/x86/pci/numaq_32.c b/arch/x86/pci/numaq_32.c index 83e125b95ca6..00edfe652b72 100644 --- a/arch/x86/pci/numaq_32.c +++ b/arch/x86/pci/numaq_32.c | |||
@@ -152,7 +152,7 @@ int __init pci_numaq_init(void) | |||
152 | 152 | ||
153 | raw_pci_ops = &pci_direct_conf1_mq; | 153 | raw_pci_ops = &pci_direct_conf1_mq; |
154 | 154 | ||
155 | pci_root_bus = pcibios_scan_root(0); | 155 | pcibios_scan_root(0); |
156 | if (num_online_nodes() > 1) | 156 | if (num_online_nodes() > 1) |
157 | for_each_online_node(quad) { | 157 | for_each_online_node(quad) { |
158 | if (quad == 0) | 158 | if (quad == 0) |
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index fd59f57d3829..417487a201fb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -107,24 +107,6 @@ void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | |||
107 | } | 107 | } |
108 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 108 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
109 | 109 | ||
110 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | ||
111 | { | ||
112 | struct acpi_pci_root *root; | ||
113 | acpi_handle handle = NULL; | ||
114 | |||
115 | mutex_lock(&acpi_pci_root_lock); | ||
116 | list_for_each_entry(root, &acpi_pci_roots, node) | ||
117 | if ((root->segment == (u16) seg) && | ||
118 | (root->secondary.start == (u16) bus)) { | ||
119 | handle = root->device->handle; | ||
120 | break; | ||
121 | } | ||
122 | mutex_unlock(&acpi_pci_root_lock); | ||
123 | return handle; | ||
124 | } | ||
125 | |||
126 | EXPORT_SYMBOL_GPL(acpi_get_pci_rootbridge_handle); | ||
127 | |||
128 | /** | 110 | /** |
129 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge | 111 | * acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge |
130 | * @handle - the ACPI CA node in question. | 112 | * @handle - the ACPI CA node in question. |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index dcc75c785443..d8add34177f2 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot) | |||
252 | 252 | ||
253 | int __ref cpci_configure_slot(struct slot *slot) | 253 | int __ref cpci_configure_slot(struct slot *slot) |
254 | { | 254 | { |
255 | struct pci_dev *dev; | ||
255 | struct pci_bus *parent; | 256 | struct pci_bus *parent; |
256 | int fn; | ||
257 | 257 | ||
258 | dbg("%s - enter", __func__); | 258 | dbg("%s - enter", __func__); |
259 | 259 | ||
@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot) | |||
282 | } | 282 | } |
283 | parent = slot->dev->bus; | 283 | parent = slot->dev->bus; |
284 | 284 | ||
285 | for (fn = 0; fn < 8; fn++) { | 285 | list_for_each_entry(dev, &parent->devices, bus_list) |
286 | struct pci_dev *dev; | 286 | if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) |
287 | |||
288 | dev = pci_get_slot(parent, | ||
289 | PCI_DEVFN(PCI_SLOT(slot->devfn), fn)); | ||
290 | if (!dev) | ||
291 | continue; | 287 | continue; |
292 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 288 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
293 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 289 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
294 | pci_hp_add_bridge(dev); | 290 | pci_hp_add_bridge(dev); |
295 | pci_dev_put(dev); | 291 | |
296 | } | ||
297 | 292 | ||
298 | pci_assign_unassigned_bridge_resources(parent->self); | 293 | pci_assign_unassigned_bridge_resources(parent->self); |
299 | 294 | ||
@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot) | |||
305 | 300 | ||
306 | int cpci_unconfigure_slot(struct slot* slot) | 301 | int cpci_unconfigure_slot(struct slot* slot) |
307 | { | 302 | { |
308 | int i; | 303 | struct pci_dev *dev, *temp; |
309 | struct pci_dev *dev; | ||
310 | 304 | ||
311 | dbg("%s - enter", __func__); | 305 | dbg("%s - enter", __func__); |
312 | if (!slot->dev) { | 306 | if (!slot->dev) { |
@@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot) | |||
314 | return -ENODEV; | 308 | return -ENODEV; |
315 | } | 309 | } |
316 | 310 | ||
317 | for (i = 0; i < 8; i++) { | 311 | list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) { |
318 | dev = pci_get_slot(slot->bus, | 312 | if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn)) |
319 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 313 | continue; |
320 | if (dev) { | 314 | pci_dev_get(dev); |
321 | pci_stop_and_remove_bus_device(dev); | 315 | pci_stop_and_remove_bus_device(dev); |
322 | pci_dev_put(dev); | 316 | pci_dev_put(dev); |
323 | } | ||
324 | } | 317 | } |
325 | pci_dev_put(slot->dev); | 318 | pci_dev_put(slot->dev); |
326 | slot->dev = NULL; | 319 | slot->dev = NULL; |
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 36112fe212d3..d282019cda5f 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -1900,8 +1900,7 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
1900 | dbg("power fault\n"); | 1900 | dbg("power fault\n"); |
1901 | } else { | 1901 | } else { |
1902 | /* refresh notification */ | 1902 | /* refresh notification */ |
1903 | if (p_slot) | 1903 | update_slot_info(ctrl, p_slot); |
1904 | update_slot_info(ctrl, p_slot); | ||
1905 | } | 1904 | } |
1906 | 1905 | ||
1907 | ctrl->event_queue[loop].event_type = 0; | 1906 | ctrl->event_queue[loop].event_type = 0; |
@@ -2520,44 +2519,28 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2520 | 2519 | ||
2521 | /* If we have IO resources copy them and fill in the bridge's | 2520 | /* If we have IO resources copy them and fill in the bridge's |
2522 | * IO range registers */ | 2521 | * IO range registers */ |
2523 | if (io_node) { | 2522 | memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); |
2524 | memcpy(hold_IO_node, io_node, sizeof(struct pci_resource)); | 2523 | io_node->next = NULL; |
2525 | io_node->next = NULL; | ||
2526 | 2524 | ||
2527 | /* set IO base and Limit registers */ | 2525 | /* set IO base and Limit registers */ |
2528 | temp_byte = io_node->base >> 8; | 2526 | temp_byte = io_node->base >> 8; |
2529 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); | 2527 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte); |
2530 | 2528 | ||
2531 | temp_byte = (io_node->base + io_node->length - 1) >> 8; | 2529 | temp_byte = (io_node->base + io_node->length - 1) >> 8; |
2532 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); | 2530 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte); |
2533 | } else { | ||
2534 | kfree(hold_IO_node); | ||
2535 | hold_IO_node = NULL; | ||
2536 | } | ||
2537 | |||
2538 | /* If we have memory resources copy them and fill in the | ||
2539 | * bridge's memory range registers. Otherwise, fill in the | ||
2540 | * range registers with values that disable them. */ | ||
2541 | if (mem_node) { | ||
2542 | memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); | ||
2543 | mem_node->next = NULL; | ||
2544 | |||
2545 | /* set Mem base and Limit registers */ | ||
2546 | temp_word = mem_node->base >> 16; | ||
2547 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | ||
2548 | 2531 | ||
2549 | temp_word = (mem_node->base + mem_node->length - 1) >> 16; | 2532 | /* Copy the memory resources and fill in the bridge's memory |
2550 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); | 2533 | * range registers. |
2551 | } else { | 2534 | */ |
2552 | temp_word = 0xFFFF; | 2535 | memcpy(hold_mem_node, mem_node, sizeof(struct pci_resource)); |
2553 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | 2536 | mem_node->next = NULL; |
2554 | 2537 | ||
2555 | temp_word = 0x0000; | 2538 | /* set Mem base and Limit registers */ |
2556 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); | 2539 | temp_word = mem_node->base >> 16; |
2540 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word); | ||
2557 | 2541 | ||
2558 | kfree(hold_mem_node); | 2542 | temp_word = (mem_node->base + mem_node->length - 1) >> 16; |
2559 | hold_mem_node = NULL; | 2543 | rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word); |
2560 | } | ||
2561 | 2544 | ||
2562 | memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); | 2545 | memcpy(hold_p_mem_node, p_mem_node, sizeof(struct pci_resource)); |
2563 | p_mem_node->next = NULL; | 2546 | p_mem_node->next = NULL; |
@@ -2627,7 +2610,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2627 | /* Return unused bus resources | 2610 | /* Return unused bus resources |
2628 | * First use the temporary node to store information for | 2611 | * First use the temporary node to store information for |
2629 | * the board */ | 2612 | * the board */ |
2630 | if (hold_bus_node && bus_node && temp_resources.bus_head) { | 2613 | if (bus_node && temp_resources.bus_head) { |
2631 | hold_bus_node->length = bus_node->base - hold_bus_node->base; | 2614 | hold_bus_node->length = bus_node->base - hold_bus_node->base; |
2632 | 2615 | ||
2633 | hold_bus_node->next = func->bus_head; | 2616 | hold_bus_node->next = func->bus_head; |
@@ -2751,7 +2734,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2751 | } | 2734 | } |
2752 | /* If we have prefetchable memory space available and there | 2735 | /* If we have prefetchable memory space available and there |
2753 | * is some left at the end, return the unused portion */ | 2736 | * is some left at the end, return the unused portion */ |
2754 | if (hold_p_mem_node && temp_resources.p_mem_head) { | 2737 | if (temp_resources.p_mem_head) { |
2755 | p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), | 2738 | p_mem_node = do_pre_bridge_resource_split(&(temp_resources.p_mem_head), |
2756 | &hold_p_mem_node, 0x100000); | 2739 | &hold_p_mem_node, 0x100000); |
2757 | 2740 | ||
diff --git a/drivers/pci/hotplug/pciehp_pci.c b/drivers/pci/hotplug/pciehp_pci.c index 09cecaf450c5..aac7a40e4a4a 100644 --- a/drivers/pci/hotplug/pciehp_pci.c +++ b/drivers/pci/hotplug/pciehp_pci.c | |||
@@ -39,7 +39,7 @@ int pciehp_configure_device(struct slot *p_slot) | |||
39 | struct pci_dev *dev; | 39 | struct pci_dev *dev; |
40 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; | 40 | struct pci_dev *bridge = p_slot->ctrl->pcie->port; |
41 | struct pci_bus *parent = bridge->subordinate; | 41 | struct pci_bus *parent = bridge->subordinate; |
42 | int num, fn; | 42 | int num; |
43 | struct controller *ctrl = p_slot->ctrl; | 43 | struct controller *ctrl = p_slot->ctrl; |
44 | 44 | ||
45 | dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); | 45 | dev = pci_get_slot(parent, PCI_DEVFN(0, 0)); |
@@ -57,28 +57,18 @@ int pciehp_configure_device(struct slot *p_slot) | |||
57 | return -ENODEV; | 57 | return -ENODEV; |
58 | } | 58 | } |
59 | 59 | ||
60 | for (fn = 0; fn < 8; fn++) { | 60 | list_for_each_entry(dev, &parent->devices, bus_list) |
61 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | ||
62 | if (!dev) | ||
63 | continue; | ||
64 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 61 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
65 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 62 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
66 | pci_hp_add_bridge(dev); | 63 | pci_hp_add_bridge(dev); |
67 | pci_dev_put(dev); | ||
68 | } | ||
69 | 64 | ||
70 | pci_assign_unassigned_bridge_resources(bridge); | 65 | pci_assign_unassigned_bridge_resources(bridge); |
71 | 66 | ||
72 | for (fn = 0; fn < 8; fn++) { | 67 | list_for_each_entry(dev, &parent->devices, bus_list) { |
73 | dev = pci_get_slot(parent, PCI_DEVFN(0, fn)); | 68 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) |
74 | if (!dev) | ||
75 | continue; | 69 | continue; |
76 | if ((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) { | 70 | |
77 | pci_dev_put(dev); | ||
78 | continue; | ||
79 | } | ||
80 | pci_configure_slot(dev); | 71 | pci_configure_slot(dev); |
81 | pci_dev_put(dev); | ||
82 | } | 72 | } |
83 | 73 | ||
84 | pci_bus_add_devices(parent); | 74 | pci_bus_add_devices(parent); |
@@ -89,9 +79,9 @@ int pciehp_configure_device(struct slot *p_slot) | |||
89 | int pciehp_unconfigure_device(struct slot *p_slot) | 79 | int pciehp_unconfigure_device(struct slot *p_slot) |
90 | { | 80 | { |
91 | int ret, rc = 0; | 81 | int ret, rc = 0; |
92 | int j; | ||
93 | u8 bctl = 0; | 82 | u8 bctl = 0; |
94 | u8 presence = 0; | 83 | u8 presence = 0; |
84 | struct pci_dev *dev, *temp; | ||
95 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; | 85 | struct pci_bus *parent = p_slot->ctrl->pcie->port->subordinate; |
96 | u16 command; | 86 | u16 command; |
97 | struct controller *ctrl = p_slot->ctrl; | 87 | struct controller *ctrl = p_slot->ctrl; |
@@ -102,33 +92,31 @@ int pciehp_unconfigure_device(struct slot *p_slot) | |||
102 | if (ret) | 92 | if (ret) |
103 | presence = 0; | 93 | presence = 0; |
104 | 94 | ||
105 | for (j = 0; j < 8; j++) { | 95 | list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { |
106 | struct pci_dev *temp = pci_get_slot(parent, PCI_DEVFN(0, j)); | 96 | pci_dev_get(dev); |
107 | if (!temp) | 97 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { |
108 | continue; | 98 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); |
109 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE && presence) { | ||
110 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | ||
111 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 99 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
112 | ctrl_err(ctrl, | 100 | ctrl_err(ctrl, |
113 | "Cannot remove display device %s\n", | 101 | "Cannot remove display device %s\n", |
114 | pci_name(temp)); | 102 | pci_name(dev)); |
115 | pci_dev_put(temp); | 103 | pci_dev_put(dev); |
116 | rc = -EINVAL; | 104 | rc = -EINVAL; |
117 | break; | 105 | break; |
118 | } | 106 | } |
119 | } | 107 | } |
120 | pci_stop_and_remove_bus_device(temp); | 108 | pci_stop_and_remove_bus_device(dev); |
121 | /* | 109 | /* |
122 | * Ensure that no new Requests will be generated from | 110 | * Ensure that no new Requests will be generated from |
123 | * the device. | 111 | * the device. |
124 | */ | 112 | */ |
125 | if (presence) { | 113 | if (presence) { |
126 | pci_read_config_word(temp, PCI_COMMAND, &command); | 114 | pci_read_config_word(dev, PCI_COMMAND, &command); |
127 | command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); | 115 | command &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_SERR); |
128 | command |= PCI_COMMAND_INTX_DISABLE; | 116 | command |= PCI_COMMAND_INTX_DISABLE; |
129 | pci_write_config_word(temp, PCI_COMMAND, command); | 117 | pci_write_config_word(dev, PCI_COMMAND, command); |
130 | } | 118 | } |
131 | pci_dev_put(temp); | 119 | pci_dev_put(dev); |
132 | } | 120 | } |
133 | 121 | ||
134 | return rc; | 122 | return rc; |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index ae606b3e991e..180e760c1653 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
334 | struct slot *slot = bss_hotplug_slot->private; | 334 | struct slot *slot = bss_hotplug_slot->private; |
335 | struct pci_bus *new_bus = NULL; | 335 | struct pci_bus *new_bus = NULL; |
336 | struct pci_dev *dev; | 336 | struct pci_dev *dev; |
337 | int func, num_funcs; | 337 | int num_funcs; |
338 | int new_ppb = 0; | 338 | int new_ppb = 0; |
339 | int rc; | 339 | int rc; |
340 | char *ssdt = NULL; | 340 | char *ssdt = NULL; |
@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
381 | * to the Linux PCI interface and tell the drivers | 381 | * to the Linux PCI interface and tell the drivers |
382 | * about them. | 382 | * about them. |
383 | */ | 383 | */ |
384 | for (func = 0; func < num_funcs; func++) { | 384 | list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) { |
385 | dev = pci_get_slot(slot->pci_bus, | 385 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
386 | PCI_DEVFN(slot->device_num + 1, | 386 | continue; |
387 | PCI_FUNC(func))); | 387 | |
388 | if (dev) { | 388 | /* Need to do slot fixup on PPB before fixup of children |
389 | /* Need to do slot fixup on PPB before fixup of children | 389 | * (PPB's pcidev_info needs to be in pcidev_info list |
390 | * (PPB's pcidev_info needs to be in pcidev_info list | 390 | * before child's SN_PCIDEV_INFO() call to setup |
391 | * before child's SN_PCIDEV_INFO() call to setup | 391 | * pdi_host_pcidev_info). |
392 | * pdi_host_pcidev_info). | 392 | */ |
393 | */ | 393 | pcibios_fixup_device_resources(dev); |
394 | pcibios_fixup_device_resources(dev); | 394 | if (SN_ACPI_BASE_SUPPORT()) |
395 | if (SN_ACPI_BASE_SUPPORT()) | 395 | sn_acpi_slot_fixup(dev); |
396 | sn_acpi_slot_fixup(dev); | 396 | else |
397 | else | 397 | sn_io_slot_fixup(dev); |
398 | sn_io_slot_fixup(dev); | 398 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
399 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 399 | pci_hp_add_bridge(dev); |
400 | pci_hp_add_bridge(dev); | 400 | if (dev->subordinate) { |
401 | if (dev->subordinate) { | 401 | new_bus = dev->subordinate; |
402 | new_bus = dev->subordinate; | 402 | new_ppb = 1; |
403 | new_ppb = 1; | ||
404 | } | ||
405 | } | 403 | } |
406 | pci_dev_put(dev); | ||
407 | } | 404 | } |
408 | } | 405 | } |
409 | 406 | ||
@@ -481,8 +478,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
481 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | 478 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) |
482 | { | 479 | { |
483 | struct slot *slot = bss_hotplug_slot->private; | 480 | struct slot *slot = bss_hotplug_slot->private; |
484 | struct pci_dev *dev; | 481 | struct pci_dev *dev, *temp; |
485 | int func; | ||
486 | int rc; | 482 | int rc; |
487 | acpi_owner_id ssdt_id = 0; | 483 | acpi_owner_id ssdt_id = 0; |
488 | 484 | ||
@@ -542,15 +538,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
542 | } | 538 | } |
543 | 539 | ||
544 | /* Free the SN resources assigned to the Linux device.*/ | 540 | /* Free the SN resources assigned to the Linux device.*/ |
545 | for (func = 0; func < 8; func++) { | 541 | list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { |
546 | dev = pci_get_slot(slot->pci_bus, | 542 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
547 | PCI_DEVFN(slot->device_num + 1, | 543 | continue; |
548 | PCI_FUNC(func))); | 544 | |
549 | if (dev) { | 545 | pci_dev_get(dev); |
550 | sn_bus_free_data(dev); | 546 | sn_bus_free_data(dev); |
551 | pci_stop_and_remove_bus_device(dev); | 547 | pci_stop_and_remove_bus_device(dev); |
552 | pci_dev_put(dev); | 548 | pci_dev_put(dev); |
553 | } | ||
554 | } | 549 | } |
555 | 550 | ||
556 | /* Remove the SSDT for the slot from the ACPI namespace */ | 551 | /* Remove the SSDT for the slot from the ACPI namespace */ |
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c index c627ed9957d1..b0e83132542e 100644 --- a/drivers/pci/hotplug/shpchp_pci.c +++ b/drivers/pci/hotplug/shpchp_pci.c | |||
@@ -40,7 +40,7 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
40 | struct controller *ctrl = p_slot->ctrl; | 40 | struct controller *ctrl = p_slot->ctrl; |
41 | struct pci_dev *bridge = ctrl->pci_dev; | 41 | struct pci_dev *bridge = ctrl->pci_dev; |
42 | struct pci_bus *parent = bridge->subordinate; | 42 | struct pci_bus *parent = bridge->subordinate; |
43 | int num, fn; | 43 | int num; |
44 | 44 | ||
45 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); | 45 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0)); |
46 | if (dev) { | 46 | if (dev) { |
@@ -57,24 +57,20 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
57 | return -ENODEV; | 57 | return -ENODEV; |
58 | } | 58 | } |
59 | 59 | ||
60 | for (fn = 0; fn < 8; fn++) { | 60 | list_for_each_entry(dev, &parent->devices, bus_list) { |
61 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); | 61 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
62 | if (!dev) | ||
63 | continue; | 62 | continue; |
64 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || | 63 | if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) || |
65 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) | 64 | (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) |
66 | pci_hp_add_bridge(dev); | 65 | pci_hp_add_bridge(dev); |
67 | pci_dev_put(dev); | ||
68 | } | 66 | } |
69 | 67 | ||
70 | pci_assign_unassigned_bridge_resources(bridge); | 68 | pci_assign_unassigned_bridge_resources(bridge); |
71 | 69 | ||
72 | for (fn = 0; fn < 8; fn++) { | 70 | list_for_each_entry(dev, &parent->devices, bus_list) { |
73 | dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn)); | 71 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
74 | if (!dev) | ||
75 | continue; | 72 | continue; |
76 | pci_configure_slot(dev); | 73 | pci_configure_slot(dev); |
77 | pci_dev_put(dev); | ||
78 | } | 74 | } |
79 | 75 | ||
80 | pci_bus_add_devices(parent); | 76 | pci_bus_add_devices(parent); |
@@ -85,32 +81,32 @@ int __ref shpchp_configure_device(struct slot *p_slot) | |||
85 | int shpchp_unconfigure_device(struct slot *p_slot) | 81 | int shpchp_unconfigure_device(struct slot *p_slot) |
86 | { | 82 | { |
87 | int rc = 0; | 83 | int rc = 0; |
88 | int j; | ||
89 | u8 bctl = 0; | 84 | u8 bctl = 0; |
90 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; | 85 | struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate; |
86 | struct pci_dev *dev, *temp; | ||
91 | struct controller *ctrl = p_slot->ctrl; | 87 | struct controller *ctrl = p_slot->ctrl; |
92 | 88 | ||
93 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", | 89 | ctrl_dbg(ctrl, "%s: domain:bus:dev = %04x:%02x:%02x\n", |
94 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); | 90 | __func__, pci_domain_nr(parent), p_slot->bus, p_slot->device); |
95 | 91 | ||
96 | for (j = 0; j < 8 ; j++) { | 92 | list_for_each_entry_safe(dev, temp, &parent->devices, bus_list) { |
97 | struct pci_dev *temp = pci_get_slot(parent, | 93 | if (PCI_SLOT(dev->devfn) != p_slot->device) |
98 | (p_slot->device << 3) | j); | ||
99 | if (!temp) | ||
100 | continue; | 94 | continue; |
101 | if (temp->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 95 | |
102 | pci_read_config_byte(temp, PCI_BRIDGE_CONTROL, &bctl); | 96 | pci_dev_get(dev); |
97 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | ||
98 | pci_read_config_byte(dev, PCI_BRIDGE_CONTROL, &bctl); | ||
103 | if (bctl & PCI_BRIDGE_CTL_VGA) { | 99 | if (bctl & PCI_BRIDGE_CTL_VGA) { |
104 | ctrl_err(ctrl, | 100 | ctrl_err(ctrl, |
105 | "Cannot remove display device %s\n", | 101 | "Cannot remove display device %s\n", |
106 | pci_name(temp)); | 102 | pci_name(dev)); |
107 | pci_dev_put(temp); | 103 | pci_dev_put(dev); |
108 | rc = -EINVAL; | 104 | rc = -EINVAL; |
109 | break; | 105 | break; |
110 | } | 106 | } |
111 | } | 107 | } |
112 | pci_stop_and_remove_bus_device(temp); | 108 | pci_stop_and_remove_bus_device(dev); |
113 | pci_dev_put(temp); | 109 | pci_dev_put(dev); |
114 | } | 110 | } |
115 | return rc; | 111 | return rc; |
116 | } | 112 | } |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 42736e213f25..1c2587c40299 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -302,24 +302,6 @@ static int acpi_pci_find_device(struct device *dev, acpi_handle *handle) | |||
302 | return 0; | 302 | return 0; |
303 | } | 303 | } |
304 | 304 | ||
305 | static int acpi_pci_find_root_bridge(struct device *dev, acpi_handle *handle) | ||
306 | { | ||
307 | int num; | ||
308 | unsigned int seg, bus; | ||
309 | |||
310 | /* | ||
311 | * The string should be the same as root bridge's name | ||
312 | * Please look at 'pci_scan_bus_parented' | ||
313 | */ | ||
314 | num = sscanf(dev_name(dev), "pci%04x:%02x", &seg, &bus); | ||
315 | if (num != 2) | ||
316 | return -ENODEV; | ||
317 | *handle = acpi_get_pci_rootbridge_handle(seg, bus); | ||
318 | if (!*handle) | ||
319 | return -ENODEV; | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static void pci_acpi_setup(struct device *dev) | 305 | static void pci_acpi_setup(struct device *dev) |
324 | { | 306 | { |
325 | struct pci_dev *pci_dev = to_pci_dev(dev); | 307 | struct pci_dev *pci_dev = to_pci_dev(dev); |
@@ -378,7 +360,6 @@ static void pci_acpi_cleanup(struct device *dev) | |||
378 | static struct acpi_bus_type acpi_pci_bus = { | 360 | static struct acpi_bus_type acpi_pci_bus = { |
379 | .bus = &pci_bus_type, | 361 | .bus = &pci_bus_type, |
380 | .find_device = acpi_pci_find_device, | 362 | .find_device = acpi_pci_find_device, |
381 | .find_bridge = acpi_pci_find_root_bridge, | ||
382 | .setup = pci_acpi_setup, | 363 | .setup = pci_acpi_setup, |
383 | .cleanup = pci_acpi_cleanup, | 364 | .cleanup = pci_acpi_cleanup, |
384 | }; | 365 | }; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 0c4f641b7be1..177a50ff6454 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -1151,8 +1151,7 @@ int pci_reenable_device(struct pci_dev *dev) | |||
1151 | return 0; | 1151 | return 0; |
1152 | } | 1152 | } |
1153 | 1153 | ||
1154 | static int __pci_enable_device_flags(struct pci_dev *dev, | 1154 | static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags) |
1155 | resource_size_t flags) | ||
1156 | { | 1155 | { |
1157 | int err; | 1156 | int err; |
1158 | int i, bars = 0; | 1157 | int i, bars = 0; |
@@ -1196,7 +1195,7 @@ static int __pci_enable_device_flags(struct pci_dev *dev, | |||
1196 | */ | 1195 | */ |
1197 | int pci_enable_device_io(struct pci_dev *dev) | 1196 | int pci_enable_device_io(struct pci_dev *dev) |
1198 | { | 1197 | { |
1199 | return __pci_enable_device_flags(dev, IORESOURCE_IO); | 1198 | return pci_enable_device_flags(dev, IORESOURCE_IO); |
1200 | } | 1199 | } |
1201 | 1200 | ||
1202 | /** | 1201 | /** |
@@ -1209,7 +1208,7 @@ int pci_enable_device_io(struct pci_dev *dev) | |||
1209 | */ | 1208 | */ |
1210 | int pci_enable_device_mem(struct pci_dev *dev) | 1209 | int pci_enable_device_mem(struct pci_dev *dev) |
1211 | { | 1210 | { |
1212 | return __pci_enable_device_flags(dev, IORESOURCE_MEM); | 1211 | return pci_enable_device_flags(dev, IORESOURCE_MEM); |
1213 | } | 1212 | } |
1214 | 1213 | ||
1215 | /** | 1214 | /** |
@@ -1225,7 +1224,7 @@ int pci_enable_device_mem(struct pci_dev *dev) | |||
1225 | */ | 1224 | */ |
1226 | int pci_enable_device(struct pci_dev *dev) | 1225 | int pci_enable_device(struct pci_dev *dev) |
1227 | { | 1226 | { |
1228 | return __pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); | 1227 | return pci_enable_device_flags(dev, IORESOURCE_MEM | IORESOURCE_IO); |
1229 | } | 1228 | } |
1230 | 1229 | ||
1231 | /* | 1230 | /* |
@@ -2043,10 +2042,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) | |||
2043 | } | 2042 | } |
2044 | 2043 | ||
2045 | /** | 2044 | /** |
2046 | * pci_enable_ari - enable ARI forwarding if hardware support it | 2045 | * pci_configure_ari - enable or disable ARI forwarding |
2047 | * @dev: the PCI device | 2046 | * @dev: the PCI device |
2047 | * | ||
2048 | * If @dev and its upstream bridge both support ARI, enable ARI in the | ||
2049 | * bridge. Otherwise, disable ARI in the bridge. | ||
2048 | */ | 2050 | */ |
2049 | void pci_enable_ari(struct pci_dev *dev) | 2051 | void pci_configure_ari(struct pci_dev *dev) |
2050 | { | 2052 | { |
2051 | u32 cap; | 2053 | u32 cap; |
2052 | struct pci_dev *bridge; | 2054 | struct pci_dev *bridge; |
@@ -2054,9 +2056,6 @@ void pci_enable_ari(struct pci_dev *dev) | |||
2054 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) | 2056 | if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) |
2055 | return; | 2057 | return; |
2056 | 2058 | ||
2057 | if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) | ||
2058 | return; | ||
2059 | |||
2060 | bridge = dev->bus->self; | 2059 | bridge = dev->bus->self; |
2061 | if (!bridge) | 2060 | if (!bridge) |
2062 | return; | 2061 | return; |
@@ -2065,8 +2064,15 @@ void pci_enable_ari(struct pci_dev *dev) | |||
2065 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) | 2064 | if (!(cap & PCI_EXP_DEVCAP2_ARI)) |
2066 | return; | 2065 | return; |
2067 | 2066 | ||
2068 | pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); | 2067 | if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) { |
2069 | bridge->ari_enabled = 1; | 2068 | pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, |
2069 | PCI_EXP_DEVCTL2_ARI); | ||
2070 | bridge->ari_enabled = 1; | ||
2071 | } else { | ||
2072 | pcie_capability_clear_word(bridge, PCI_EXP_DEVCTL2, | ||
2073 | PCI_EXP_DEVCTL2_ARI); | ||
2074 | bridge->ari_enabled = 0; | ||
2075 | } | ||
2070 | } | 2076 | } |
2071 | 2077 | ||
2072 | /** | 2078 | /** |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index d295e7b0e64f..7346ee68f47d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -203,7 +203,8 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
203 | struct resource *res, unsigned int reg); | 203 | struct resource *res, unsigned int reg); |
204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, | 204 | extern int pci_resource_bar(struct pci_dev *dev, int resno, |
205 | enum pci_bar_type *type); | 205 | enum pci_bar_type *type); |
206 | extern void pci_enable_ari(struct pci_dev *dev); | 206 | extern void pci_configure_ari(struct pci_dev *dev); |
207 | |||
207 | /** | 208 | /** |
208 | * pci_ari_enabled - query ARI forwarding status | 209 | * pci_ari_enabled - query ARI forwarding status |
209 | * @bus: the PCI bus | 210 | * @bus: the PCI bus |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 281d90f19c7a..b494066ef32f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1295,7 +1295,7 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1295 | pci_vpd_pci22_init(dev); | 1295 | pci_vpd_pci22_init(dev); |
1296 | 1296 | ||
1297 | /* Alternative Routing-ID Forwarding */ | 1297 | /* Alternative Routing-ID Forwarding */ |
1298 | pci_enable_ari(dev); | 1298 | pci_configure_ari(dev); |
1299 | 1299 | ||
1300 | /* Single Root I/O Virtualization */ | 1300 | /* Single Root I/O Virtualization */ |
1301 | pci_iov_init(dev); | 1301 | pci_iov_init(dev); |
@@ -1371,31 +1371,31 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
1371 | } | 1371 | } |
1372 | EXPORT_SYMBOL(pci_scan_single_device); | 1372 | EXPORT_SYMBOL(pci_scan_single_device); |
1373 | 1373 | ||
1374 | static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) | 1374 | static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn) |
1375 | { | 1375 | { |
1376 | u16 cap; | 1376 | int pos; |
1377 | unsigned pos, next_fn; | 1377 | u16 cap = 0; |
1378 | unsigned next_fn; | ||
1378 | 1379 | ||
1379 | if (!dev) | 1380 | if (pci_ari_enabled(bus)) { |
1380 | return 0; | 1381 | if (!dev) |
1382 | return 0; | ||
1383 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | ||
1384 | if (!pos) | ||
1385 | return 0; | ||
1381 | 1386 | ||
1382 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1387 | pci_read_config_word(dev, pos + PCI_ARI_CAP, &cap); |
1383 | if (!pos) | 1388 | next_fn = PCI_ARI_CAP_NFN(cap); |
1384 | return 0; | 1389 | if (next_fn <= fn) |
1385 | pci_read_config_word(dev, pos + 4, &cap); | 1390 | return 0; /* protect against malformed list */ |
1386 | next_fn = cap >> 8; | ||
1387 | if (next_fn <= fn) | ||
1388 | return 0; | ||
1389 | return next_fn; | ||
1390 | } | ||
1391 | 1391 | ||
1392 | static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) | 1392 | return next_fn; |
1393 | { | 1393 | } |
1394 | return (fn + 1) % 8; | 1394 | |
1395 | } | 1395 | /* dev may be NULL for non-contiguous multifunction devices */ |
1396 | if (!dev || dev->multifunction) | ||
1397 | return (fn + 1) % 8; | ||
1396 | 1398 | ||
1397 | static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | ||
1398 | { | ||
1399 | return 0; | 1399 | return 0; |
1400 | } | 1400 | } |
1401 | 1401 | ||
@@ -1428,7 +1428,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1428 | { | 1428 | { |
1429 | unsigned fn, nr = 0; | 1429 | unsigned fn, nr = 0; |
1430 | struct pci_dev *dev; | 1430 | struct pci_dev *dev; |
1431 | unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn; | ||
1432 | 1431 | ||
1433 | if (only_one_child(bus) && (devfn > 0)) | 1432 | if (only_one_child(bus) && (devfn > 0)) |
1434 | return 0; /* Already scanned the entire slot */ | 1433 | return 0; /* Already scanned the entire slot */ |
@@ -1439,12 +1438,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1439 | if (!dev->is_added) | 1438 | if (!dev->is_added) |
1440 | nr++; | 1439 | nr++; |
1441 | 1440 | ||
1442 | if (pci_ari_enabled(bus)) | 1441 | for (fn = next_fn(bus, dev, 0); fn > 0; fn = next_fn(bus, dev, fn)) { |
1443 | next_fn = next_ari_fn; | ||
1444 | else if (dev->multifunction) | ||
1445 | next_fn = next_trad_fn; | ||
1446 | |||
1447 | for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) { | ||
1448 | dev = pci_scan_single_device(bus, devfn + fn); | 1442 | dev = pci_scan_single_device(bus, devfn + fn); |
1449 | if (dev) { | 1443 | if (dev) { |
1450 | if (!dev->is_added) | 1444 | if (!dev->is_added) |
@@ -1655,6 +1649,18 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
1655 | return max; | 1649 | return max; |
1656 | } | 1650 | } |
1657 | 1651 | ||
1652 | /** | ||
1653 | * pcibios_root_bridge_prepare - Platform-specific host bridge setup. | ||
1654 | * @bridge: Host bridge to set up. | ||
1655 | * | ||
1656 | * Default empty implementation. Replace with an architecture-specific setup | ||
1657 | * routine, if necessary. | ||
1658 | */ | ||
1659 | int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
1660 | { | ||
1661 | return 0; | ||
1662 | } | ||
1663 | |||
1658 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1664 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1659 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1665 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1660 | { | 1666 | { |
@@ -1688,6 +1694,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1688 | bridge->dev.parent = parent; | 1694 | bridge->dev.parent = parent; |
1689 | bridge->dev.release = pci_release_bus_bridge_dev; | 1695 | bridge->dev.release = pci_release_bus_bridge_dev; |
1690 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); | 1696 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
1697 | error = pcibios_root_bridge_prepare(bridge); | ||
1698 | if (error) | ||
1699 | goto bridge_dev_reg_err; | ||
1700 | |||
1691 | error = device_register(&bridge->dev); | 1701 | error = device_register(&bridge->dev); |
1692 | if (error) | 1702 | if (error) |
1693 | goto bridge_dev_reg_err; | 1703 | goto bridge_dev_reg_err; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index d26c0d7a6d19..5ce8d5e86734 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -408,7 +408,6 @@ struct acpi_pci_root { | |||
408 | /* helper */ | 408 | /* helper */ |
409 | acpi_handle acpi_get_child(acpi_handle, u64); | 409 | acpi_handle acpi_get_child(acpi_handle, u64); |
410 | int acpi_is_root_bridge(acpi_handle); | 410 | int acpi_is_root_bridge(acpi_handle); |
411 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); | ||
412 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); | 411 | struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle); |
413 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) | 412 | #define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)ACPI_HANDLE(dev)) |
414 | 413 | ||
diff --git a/include/linux/pci.h b/include/linux/pci.h index 8ee7e4e46539..056d3d66b976 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -379,6 +379,8 @@ void pci_set_host_bridge_release(struct pci_host_bridge *bridge, | |||
379 | void (*release_fn)(struct pci_host_bridge *), | 379 | void (*release_fn)(struct pci_host_bridge *), |
380 | void *release_data); | 380 | void *release_data); |
381 | 381 | ||
382 | int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge); | ||
383 | |||
382 | /* | 384 | /* |
383 | * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond | 385 | * The first PCI_BRIDGE_RESOURCE_NUM PCI bus resources (those that correspond |
384 | * to P2P or CardBus bridge windows) go in a table. Additional ones (for | 386 | * to P2P or CardBus bridge windows) go in a table. Additional ones (for |