diff options
Diffstat (limited to 'drivers/pci')
-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 | 2 | ||||
-rw-r--r-- | drivers/pci/probe.c | 66 |
9 files changed, 149 insertions, 197 deletions
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 adfd172c5b9b..81b6a8752517 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -204,7 +204,7 @@ extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, | |||
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 int pci_bus_add_child(struct pci_bus *bus); | 206 | extern int pci_bus_add_child(struct pci_bus *bus); |
207 | extern void pci_enable_ari(struct pci_dev *dev); | 207 | extern void pci_configure_ari(struct pci_dev *dev); |
208 | /** | 208 | /** |
209 | * pci_ari_enabled - query ARI forwarding status | 209 | * pci_ari_enabled - query ARI forwarding status |
210 | * @bus: the PCI bus | 210 | * @bus: the PCI bus |
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2dcd22d9c816..b4a6ede8f17a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -1285,7 +1285,7 @@ static void pci_init_capabilities(struct pci_dev *dev) | |||
1285 | pci_vpd_pci22_init(dev); | 1285 | pci_vpd_pci22_init(dev); |
1286 | 1286 | ||
1287 | /* Alternative Routing-ID Forwarding */ | 1287 | /* Alternative Routing-ID Forwarding */ |
1288 | pci_enable_ari(dev); | 1288 | pci_configure_ari(dev); |
1289 | 1289 | ||
1290 | /* Single Root I/O Virtualization */ | 1290 | /* Single Root I/O Virtualization */ |
1291 | pci_iov_init(dev); | 1291 | pci_iov_init(dev); |
@@ -1348,31 +1348,31 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn) | |||
1348 | } | 1348 | } |
1349 | EXPORT_SYMBOL(pci_scan_single_device); | 1349 | EXPORT_SYMBOL(pci_scan_single_device); |
1350 | 1350 | ||
1351 | static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) | 1351 | static unsigned next_fn(struct pci_bus *bus, struct pci_dev *dev, unsigned fn) |
1352 | { | 1352 | { |
1353 | u16 cap; | 1353 | int pos; |
1354 | unsigned pos, next_fn; | 1354 | u16 cap = 0; |
1355 | unsigned next_fn; | ||
1355 | 1356 | ||
1356 | if (!dev) | 1357 | if (pci_ari_enabled(bus)) { |
1357 | return 0; | 1358 | if (!dev) |
1359 | return 0; | ||
1360 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | ||
1361 | if (!pos) | ||
1362 | return 0; | ||
1358 | 1363 | ||
1359 | pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); | 1364 | pci_read_config_word(dev, pos + PCI_ARI_CAP, &cap); |
1360 | if (!pos) | 1365 | next_fn = PCI_ARI_CAP_NFN(cap); |
1361 | return 0; | 1366 | if (next_fn <= fn) |
1362 | pci_read_config_word(dev, pos + 4, &cap); | 1367 | return 0; /* protect against malformed list */ |
1363 | next_fn = cap >> 8; | ||
1364 | if (next_fn <= fn) | ||
1365 | return 0; | ||
1366 | return next_fn; | ||
1367 | } | ||
1368 | 1368 | ||
1369 | static unsigned next_trad_fn(struct pci_dev *dev, unsigned fn) | 1369 | return next_fn; |
1370 | { | 1370 | } |
1371 | return (fn + 1) % 8; | 1371 | |
1372 | } | 1372 | /* dev may be NULL for non-contiguous multifunction devices */ |
1373 | if (!dev || dev->multifunction) | ||
1374 | return (fn + 1) % 8; | ||
1373 | 1375 | ||
1374 | static unsigned no_next_fn(struct pci_dev *dev, unsigned fn) | ||
1375 | { | ||
1376 | return 0; | 1376 | return 0; |
1377 | } | 1377 | } |
1378 | 1378 | ||
@@ -1405,7 +1405,6 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1405 | { | 1405 | { |
1406 | unsigned fn, nr = 0; | 1406 | unsigned fn, nr = 0; |
1407 | struct pci_dev *dev; | 1407 | struct pci_dev *dev; |
1408 | unsigned (*next_fn)(struct pci_dev *, unsigned) = no_next_fn; | ||
1409 | 1408 | ||
1410 | if (only_one_child(bus) && (devfn > 0)) | 1409 | if (only_one_child(bus) && (devfn > 0)) |
1411 | return 0; /* Already scanned the entire slot */ | 1410 | return 0; /* Already scanned the entire slot */ |
@@ -1416,12 +1415,7 @@ int pci_scan_slot(struct pci_bus *bus, int devfn) | |||
1416 | if (!dev->is_added) | 1415 | if (!dev->is_added) |
1417 | nr++; | 1416 | nr++; |
1418 | 1417 | ||
1419 | if (pci_ari_enabled(bus)) | 1418 | for (fn = next_fn(bus, dev, 0); fn > 0; fn = next_fn(bus, dev, fn)) { |
1420 | next_fn = next_ari_fn; | ||
1421 | else if (dev->multifunction) | ||
1422 | next_fn = next_trad_fn; | ||
1423 | |||
1424 | for (fn = next_fn(dev, 0); fn > 0; fn = next_fn(dev, fn)) { | ||
1425 | dev = pci_scan_single_device(bus, devfn + fn); | 1419 | dev = pci_scan_single_device(bus, devfn + fn); |
1426 | if (dev) { | 1420 | if (dev) { |
1427 | if (!dev->is_added) | 1421 | if (!dev->is_added) |
@@ -1632,6 +1626,18 @@ unsigned int pci_scan_child_bus(struct pci_bus *bus) | |||
1632 | return max; | 1626 | return max; |
1633 | } | 1627 | } |
1634 | 1628 | ||
1629 | /** | ||
1630 | * pcibios_root_bridge_prepare - Platform-specific host bridge setup. | ||
1631 | * @bridge: Host bridge to set up. | ||
1632 | * | ||
1633 | * Default empty implementation. Replace with an architecture-specific setup | ||
1634 | * routine, if necessary. | ||
1635 | */ | ||
1636 | int __weak pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) | ||
1637 | { | ||
1638 | return 0; | ||
1639 | } | ||
1640 | |||
1635 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | 1641 | struct pci_bus *pci_create_root_bus(struct device *parent, int bus, |
1636 | struct pci_ops *ops, void *sysdata, struct list_head *resources) | 1642 | struct pci_ops *ops, void *sysdata, struct list_head *resources) |
1637 | { | 1643 | { |
@@ -1665,6 +1671,10 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, | |||
1665 | bridge->dev.parent = parent; | 1671 | bridge->dev.parent = parent; |
1666 | bridge->dev.release = pci_release_bus_bridge_dev; | 1672 | bridge->dev.release = pci_release_bus_bridge_dev; |
1667 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); | 1673 | dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); |
1674 | error = pcibios_root_bridge_prepare(bridge); | ||
1675 | if (error) | ||
1676 | goto bridge_dev_reg_err; | ||
1677 | |||
1668 | error = device_register(&bridge->dev); | 1678 | error = device_register(&bridge->dev); |
1669 | if (error) | 1679 | if (error) |
1670 | goto bridge_dev_reg_err; | 1680 | goto bridge_dev_reg_err; |