]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
PCI: sgihp: Iterate over all devices in slot, not functions 0-7
authorYijing Wang <wangyijing@huawei.com>
Tue, 15 Jan 2013 03:12:21 +0000 (11:12 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 25 Jan 2013 16:23:08 +0000 (09:23 -0700)
Iterate through devices in a slot by using the upstream bridge's
"bus->devices" list instead of assuming they are functions 0-7.  It's
possible there are several slots on the same pci_bus, so restrict it to
only devices matching this slot's device number.

ARI (which allows functions 0-255) is a PCIe-only feature, and this is
a PCI hotplug driver, so we shouldn't find anything other than functions
0-7, but it's better to iterate the same way as other hotplug drivers.

[bhelgaas: changelog, check PCI_SLOT, fix disable_slot()]
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/hotplug/sgi_hotplug.c

index f64ca92253da527ea49b84af968df516f53e43f0..14ad22e07e00983bea6b9e24b42e962b88019c5c 100644 (file)
@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
        struct slot *slot = bss_hotplug_slot->private;
        struct pci_bus *new_bus = NULL;
        struct pci_dev *dev;
-       int func, num_funcs;
+       int num_funcs;
        int new_ppb = 0;
        int rc;
        char *ssdt = NULL;
@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
         * to the Linux PCI interface and tell the drivers
         * about them.
         */
-       for (func = 0; func < num_funcs;  func++) {
-               dev = pci_get_slot(slot->pci_bus,
-                                  PCI_DEVFN(slot->device_num + 1,
-                                            PCI_FUNC(func)));
-               if (dev) {
-                       /* Need to do slot fixup on PPB before fixup of children
-                        * (PPB's pcidev_info needs to be in pcidev_info list
-                        * before child's SN_PCIDEV_INFO() call to setup
-                        * pdi_host_pcidev_info).
-                        */
-                       pcibios_fixup_device_resources(dev);
-                       if (SN_ACPI_BASE_SUPPORT())
-                               sn_acpi_slot_fixup(dev);
-                       else
-                               sn_io_slot_fixup(dev);
-                       if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
-                               pci_hp_add_bridge(dev);
-                               if (dev->subordinate) {
-                                       new_bus = dev->subordinate;
-                                       new_ppb = 1;
-                               }
+       list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) {
+               if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
+                       continue;
+
+               /* Need to do slot fixup on PPB before fixup of children
+                * (PPB's pcidev_info needs to be in pcidev_info list
+                * before child's SN_PCIDEV_INFO() call to setup
+                * pdi_host_pcidev_info).
+                */
+               pcibios_fixup_device_resources(dev);
+               if (SN_ACPI_BASE_SUPPORT())
+                       sn_acpi_slot_fixup(dev);
+               else
+                       sn_io_slot_fixup(dev);
+               if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
+                       pci_hp_add_bridge(dev);
+                       if (dev->subordinate) {
+                               new_bus = dev->subordinate;
+                               new_ppb = 1;
                        }
-                       pci_dev_put(dev);
                }
        }
 
@@ -485,8 +482,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
 static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
 {
        struct slot *slot = bss_hotplug_slot->private;
-       struct pci_dev *dev;
-       int func;
+       struct pci_dev *dev, *temp;
        int rc;
        acpi_owner_id ssdt_id = 0;
 
@@ -546,15 +542,14 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
        }
 
        /* Free the SN resources assigned to the Linux device.*/
-       for (func = 0; func < 8;  func++) {
-               dev = pci_get_slot(slot->pci_bus,
-                                  PCI_DEVFN(slot->device_num + 1,
-                                            PCI_FUNC(func)));
-               if (dev) {
-                       sn_bus_free_data(dev);
-                       pci_stop_and_remove_bus_device(dev);
-                       pci_dev_put(dev);
-               }
+       list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) {
+               if (PCI_SLOT(dev->devfn) != slot->device_num + 1)
+                       continue;
+
+               pci_dev_get(dev);
+               sn_bus_free_data(dev);
+               pci_stop_and_remove_bus_device(dev);
+               pci_dev_put(dev);
        }
 
        /* Remove the SSDT for the slot from the ACPI namespace */