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

PCI: sgihp: 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 disable_slot()]
Signed-off-by: default avatarYijing Wang <wangyijing@huawei.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent 05b12500
Loading
Loading
Loading
Loading
+29 −34
Original line number Diff line number Diff line
@@ -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,11 +381,10 @@ 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) {
	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
@@ -403,8 +402,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
				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,16 +542,15 @@ 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) {
	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 */
	if (SN_ACPI_BASE_SUPPORT() && ssdt_id) {