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: Yijing Wang <wangyijing@huawei.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
Родитель
05b1250048
Коммит
ab6380ef01
|
@ -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,29 +381,26 @@ 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) {
|
||||
/* 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
|
||||
* pdi_host_pcidev_info).
|
||||
*/
|
||||
pcibios_fixup_device_resources(dev);
|
||||
if (SN_ACPI_BASE_SUPPORT())
|
||||
sn_acpi_slot_fixup(dev);
|
||||
else
|
||||
sn_io_slot_fixup(dev);
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
pci_hp_add_bridge(dev);
|
||||
if (dev->subordinate) {
|
||||
new_bus = dev->subordinate;
|
||||
new_ppb = 1;
|
||||
}
|
||||
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
|
||||
* pdi_host_pcidev_info).
|
||||
*/
|
||||
pcibios_fixup_device_resources(dev);
|
||||
if (SN_ACPI_BASE_SUPPORT())
|
||||
sn_acpi_slot_fixup(dev);
|
||||
else
|
||||
sn_io_slot_fixup(dev);
|
||||
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
|
||||
pci_hp_add_bridge(dev);
|
||||
if (dev->subordinate) {
|
||||
new_bus = dev->subordinate;
|
||||
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,15 +542,14 @@ 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) {
|
||||
sn_bus_free_data(dev);
|
||||
pci_stop_and_remove_bus_device(dev);
|
||||
pci_dev_put(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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче