Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 05b12500 authored by Yijing Wang's avatar Yijing Wang Committed by Bjorn Helgaas
Browse files

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: default avatarYijing Wang <wangyijing@huawei.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent ba518e3c
Loading
Loading
Loading
Loading
+11 −18
Original line number Diff line number Diff line
@@ -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,14 +308,13 @@ 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) {
	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;