]> git.karo-electronics.de Git - linux-beck.git/commitdiff
PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
authorYijing Wang <wangyijing@huawei.com>
Tue, 15 Jan 2013 03:12:20 +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 cpci_unconfigure_slot()]
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/pci/hotplug/cpci_hotplug_pci.c

index dcc75c78544324d9c761a71c0b4d392243a9446c..d8add34177f2cfa2725972bb3d57308d61b603df 100644 (file)
@@ -252,8 +252,8 @@ int cpci_led_off(struct slot* slot)
 
 int __ref cpci_configure_slot(struct slot *slot)
 {
+       struct pci_dev *dev;
        struct pci_bus *parent;
-       int fn;
 
        dbg("%s - enter", __func__);
 
@@ -282,18 +282,13 @@ int __ref cpci_configure_slot(struct slot *slot)
        }
        parent = slot->dev->bus;
 
-       for (fn = 0; fn < 8; fn++) {
-               struct pci_dev *dev;
-
-               dev = pci_get_slot(parent,
-                                  PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
-               if (!dev)
+       list_for_each_entry(dev, &parent->devices, bus_list)
+               if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
                        continue;
                if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
                    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
                        pci_hp_add_bridge(dev);
-               pci_dev_put(dev);
-       }
+
 
        pci_assign_unassigned_bridge_resources(parent->self);
 
@@ -305,8 +300,7 @@ int __ref cpci_configure_slot(struct slot *slot)
 
 int cpci_unconfigure_slot(struct slot* slot)
 {
-       int i;
-       struct pci_dev *dev;
+       struct pci_dev *dev, *temp;
 
        dbg("%s - enter", __func__);
        if (!slot->dev) {
@@ -314,13 +308,12 @@ int cpci_unconfigure_slot(struct slot* slot)
                return -ENODEV;
        }
 
-       for (i = 0; i < 8; i++) {
-               dev = pci_get_slot(slot->bus,
-                                   PCI_DEVFN(PCI_SLOT(slot->devfn), i));
-               if (dev) {
-                       pci_stop_and_remove_bus_device(dev);
-                       pci_dev_put(dev);
-               }
+       list_for_each_entry_safe(dev, temp, &slot->bus->devices, bus_list) {
+               if (PCI_SLOT(dev->devfn) != PCI_SLOT(slot->devfn))
+                       continue;
+               pci_dev_get(dev);
+               pci_stop_and_remove_bus_device(dev);
+               pci_dev_put(dev);
        }
        pci_dev_put(slot->dev);
        slot->dev = NULL;