aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/hotplug/cpci_hotplug_pci.c29
-rw-r--r--drivers/pci/hotplug/pciehp_pci.c44
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c63
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c36
-rw-r--r--drivers/pci/pci.c21
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/probe.c50
7 files changed, 109 insertions, 136 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
253int __ref cpci_configure_slot(struct slot *slot) 253int __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
306int cpci_unconfigure_slot(struct slot* slot) 301int 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/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)
89int pciehp_unconfigure_device(struct slot *p_slot) 79int 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 f3c419256d2a..24dace645871 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)
481static int disable_slot(struct hotplug_slot *bss_hotplug_slot) 478static 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)
85int shpchp_unconfigure_device(struct slot *p_slot) 81int 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.c b/drivers/pci/pci.c
index 89dc8ac096ba..177a50ff6454 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -2042,10 +2042,13 @@ void pci_free_cap_save_buffers(struct pci_dev *dev)
2042} 2042}
2043 2043
2044/** 2044/**
2045 * pci_enable_ari - enable ARI forwarding if hardware support it 2045 * pci_configure_ari - enable or disable ARI forwarding
2046 * @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.
2047 */ 2050 */
2048void pci_enable_ari(struct pci_dev *dev) 2051void pci_configure_ari(struct pci_dev *dev)
2049{ 2052{
2050 u32 cap; 2053 u32 cap;
2051 struct pci_dev *bridge; 2054 struct pci_dev *bridge;
@@ -2053,9 +2056,6 @@ void pci_enable_ari(struct pci_dev *dev)
2053 if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) 2056 if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
2054 return; 2057 return;
2055 2058
2056 if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI))
2057 return;
2058
2059 bridge = dev->bus->self; 2059 bridge = dev->bus->self;
2060 if (!bridge) 2060 if (!bridge)
2061 return; 2061 return;
@@ -2064,8 +2064,15 @@ void pci_enable_ari(struct pci_dev *dev)
2064 if (!(cap & PCI_EXP_DEVCAP2_ARI)) 2064 if (!(cap & PCI_EXP_DEVCAP2_ARI))
2065 return; 2065 return;
2066 2066
2067 pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); 2067 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) {
2068 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 }
2069} 2076}
2070 2077
2071/** 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,
204extern int pci_resource_bar(struct pci_dev *dev, int resno, 204extern int pci_resource_bar(struct pci_dev *dev, int resno,
205 enum pci_bar_type *type); 205 enum pci_bar_type *type);
206extern int pci_bus_add_child(struct pci_bus *bus); 206extern int pci_bus_add_child(struct pci_bus *bus);
207extern void pci_enable_ari(struct pci_dev *dev); 207extern 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 bbe4be7fc685..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}
1349EXPORT_SYMBOL(pci_scan_single_device); 1349EXPORT_SYMBOL(pci_scan_single_device);
1350 1350
1351static unsigned next_ari_fn(struct pci_dev *dev, unsigned fn) 1351static 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
1369static 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
1374static 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)