@@ -269,8 +269,11 @@ int cpci_configure_slot(struct slot *slot)
parent = slot->dev->bus;
for_each_pci_bridge(dev, parent) {
- if (PCI_SLOT(dev->devfn) == PCI_SLOT(slot->devfn))
- pci_hp_add_bridge(dev);
+ if (PCI_SLOT(dev->devfn) == PCI_SLOT(slot->devfn)) {
+ ret = pci_hp_add_bridge(dev);
+ if (ret)
+ goto out;
+ }
}
pci_assign_unassigned_bridge_resources(parent->self);
@@ -70,7 +70,7 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom
int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
{
struct pci_bus *child;
- int num;
+ int num, ret = 0;
pci_lock_rescan_remove();
@@ -97,7 +97,10 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
}
if (func->pci_dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
- pci_hp_add_bridge(func->pci_dev);
+ ret = pci_hp_add_bridge(func->pci_dev);
+ if (ret)
+ goto out;
+
child = func->pci_dev->subordinate;
if (child)
pci_bus_add_devices(child);
@@ -107,7 +110,7 @@ int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func)
out:
pci_unlock_rescan_remove();
- return 0;
+ return ret;
}
@@ -663,6 +663,7 @@ static int ibm_configure_device(struct pci_func *func)
int num;
int flag = 0; /* this is to make sure we don't double scan the bus,
for bridged devices primarily */
+ int ret = 0;
pci_lock_rescan_remove();
@@ -690,7 +691,10 @@ static int ibm_configure_device(struct pci_func *func)
}
}
if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
- pci_hp_add_bridge(func->dev);
+ ret = pci_hp_add_bridge(func->dev);
+ if (ret)
+ goto out;
+
child = func->dev->subordinate;
if (child)
pci_bus_add_devices(child);
@@ -698,7 +702,7 @@ static int ibm_configure_device(struct pci_func *func)
out:
pci_unlock_rescan_remove();
- return 0;
+ return ret;
}
/*******************************************************
@@ -58,8 +58,11 @@ int pciehp_configure_device(struct controller *ctrl)
goto out;
}
- for_each_pci_bridge(dev, parent)
- pci_hp_add_bridge(dev);
+ for_each_pci_bridge(dev, parent) {
+ ret = pci_hp_add_bridge(dev);
+ if (ret)
+ goto out;
+ }
pci_assign_unassigned_bridge_resources(bridge);
pcie_bus_configure_settings(parent);
@@ -48,8 +48,11 @@ int shpchp_configure_device(struct slot *p_slot)
}
for_each_pci_bridge(dev, parent) {
- if (PCI_SLOT(dev->devfn) == p_slot->device)
- pci_hp_add_bridge(dev);
+ if (PCI_SLOT(dev->devfn) == p_slot->device) {
+ ret = pci_hp_add_bridge(dev);
+ if (ret)
+ goto out;
+ }
}
pci_assign_unassigned_bridge_resources(bridge);
@@ -3363,9 +3363,10 @@ int pci_hp_add_bridge(struct pci_dev *dev)
if (!pci_find_bus(pci_domain_nr(parent), busnr))
break;
}
+
if (busnr-- > end) {
pci_err(dev, "No bus number available for hot-added bridge\n");
- return -1;
+ return -ENODEV;
}
/* Scan bridges that are already configured */
@@ -3380,8 +3381,10 @@ int pci_hp_add_bridge(struct pci_dev *dev)
/* Scan bridges that need to be reconfigured */
pci_scan_bridge_extend(parent, dev, busnr, available_buses, 1);
- if (!dev->subordinate)
- return -1;
+ if (!dev->subordinate) {
+ pci_err(dev, "No dev subordinate\n");
+ return -ENODEV;
+ }
return 0;
}
In some pci drivers, when the pci bridge is added if the process return an error, the drivers don't check this and continue your execute normally. Then, this patch change this drivers for check return of pci_hp_add_bridge(), and if has an error, then the drivers call goto lable , free your mutex and return the error for your caller. Signed-off-by: Guilherme Giacomo Simoes <trintaeoitogc@gmail.com> --- drivers/pci/hotplug/cpci_hotplug_pci.c | 7 +++++-- drivers/pci/hotplug/cpqphp_pci.c | 9 ++++++--- drivers/pci/hotplug/ibmphp_core.c | 8 ++++++-- drivers/pci/hotplug/pciehp_pci.c | 7 +++++-- drivers/pci/hotplug/shpchp_pci.c | 7 +++++-- drivers/pci/probe.c | 9 ++++++--- 6 files changed, 33 insertions(+), 14 deletions(-)