Skip to content

Commit

Permalink
PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Yijing Wang authored and Bjorn Helgaas committed Jan 25, 2013
1 parent ba518e3 commit 05b1250
Showing 1 changed file with 11 additions and 18 deletions.
29 changes: 11 additions & 18 deletions drivers/pci/hotplug/cpci_hotplug_pci.c
Original file line number Diff line number Diff line change
@@ -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,22 +300,20 @@ 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) {
err("No device for slot %02x\n", slot->number);
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;

0 comments on commit 05b1250

Please sign in to comment.