PCI: cpcihp: Iterate over all devices in slot, not functions 0-7
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>
This commit is contained in:
parent
ba518e3c17
commit
05b1250048
1 changed files with 11 additions and 18 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue