Commit 8aa48084 authored by Scott Murray's avatar Scott Murray

[CPCI] Fix potential deadlock on extract found by Rusty Lynch.

Removed cpci_find_slot function that created potential deadlock
condition from the CPCI hotplug API.
parent a1bafab5
...@@ -75,7 +75,6 @@ extern int cpci_hp_register_controller(struct cpci_hp_controller *controller); ...@@ -75,7 +75,6 @@ extern int cpci_hp_register_controller(struct cpci_hp_controller *controller);
extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller); extern int cpci_hp_unregister_controller(struct cpci_hp_controller *controller);
extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last); extern int cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last);
extern int cpci_hp_unregister_bus(struct pci_bus *bus); extern int cpci_hp_unregister_bus(struct pci_bus *bus);
extern struct slot *cpci_find_slot(struct pci_bus *bus, unsigned int devfn);
extern int cpci_hp_start(void); extern int cpci_hp_start(void);
extern int cpci_hp_stop(void); extern int cpci_hp_stop(void);
......
...@@ -427,34 +427,6 @@ cpci_hp_unregister_bus(struct pci_bus *bus) ...@@ -427,34 +427,6 @@ cpci_hp_unregister_bus(struct pci_bus *bus)
return 0; return 0;
} }
struct slot *
cpci_find_slot(struct pci_bus *bus, unsigned int devfn)
{
struct slot *slot;
struct slot *found;
struct list_head *tmp;
if(!bus) {
return NULL;
}
spin_lock(&list_lock);
if(!slots) {
spin_unlock(&list_lock);
return NULL;
}
found = NULL;
list_for_each(tmp, &slot_list) {
slot = list_entry(tmp, struct slot, slot_list);
if(slot->bus == bus && slot->devfn == devfn) {
found = slot;
break;
}
}
spin_unlock(&list_lock);
return found;
}
/* This is the interrupt mode interrupt handler */ /* This is the interrupt mode interrupt handler */
irqreturn_t irqreturn_t
cpci_hp_intr(int irq, void *data, struct pt_regs *regs) cpci_hp_intr(int irq, void *data, struct pt_regs *regs)
...@@ -924,6 +896,5 @@ EXPORT_SYMBOL_GPL(cpci_hp_register_controller); ...@@ -924,6 +896,5 @@ EXPORT_SYMBOL_GPL(cpci_hp_register_controller);
EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller); EXPORT_SYMBOL_GPL(cpci_hp_unregister_controller);
EXPORT_SYMBOL_GPL(cpci_hp_register_bus); EXPORT_SYMBOL_GPL(cpci_hp_register_bus);
EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus); EXPORT_SYMBOL_GPL(cpci_hp_unregister_bus);
EXPORT_SYMBOL_GPL(cpci_find_slot);
EXPORT_SYMBOL_GPL(cpci_hp_start); EXPORT_SYMBOL_GPL(cpci_hp_start);
EXPORT_SYMBOL_GPL(cpci_hp_stop); EXPORT_SYMBOL_GPL(cpci_hp_stop);
...@@ -448,7 +448,7 @@ static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev) ...@@ -448,7 +448,7 @@ static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev)
} }
static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev, static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_bus) struct pci_bus_wrapped *wrapped_bus)
{ {
int rc; int rc;
struct pci_dev *dev = wrapped_dev->dev; struct pci_dev *dev = wrapped_dev->dev;
...@@ -461,8 +461,8 @@ static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev, ...@@ -461,8 +461,8 @@ static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev,
* We need to fix up the hotplug representation with the Linux * We need to fix up the hotplug representation with the Linux
* representation. * representation.
*/ */
slot = cpci_find_slot(dev->bus, dev->devfn); if(wrapped_dev->data) {
if(slot) { slot = (struct slot*) wrapped_dev->data;
slot->dev = dev; slot->dev = dev;
} }
...@@ -504,8 +504,8 @@ static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev, ...@@ -504,8 +504,8 @@ static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev,
/* /*
* Now remove the hotplug representation. * Now remove the hotplug representation.
*/ */
slot = cpci_find_slot(dev->bus, dev->devfn); if(wrapped_dev->data) {
if(slot) { slot = (struct slot*) wrapped_dev->data;
slot->dev = NULL; slot->dev = NULL;
} else { } else {
dbg("No hotplug representation for %02x:%02x.%x", dbg("No hotplug representation for %02x:%02x.%x",
...@@ -603,6 +603,10 @@ int cpci_configure_slot(struct slot* slot) ...@@ -603,6 +603,10 @@ int cpci_configure_slot(struct slot* slot)
continue; continue;
wrapped_dev.dev = dev; wrapped_dev.dev = dev;
wrapped_bus.bus = slot->dev->bus; wrapped_bus.bus = slot->dev->bus;
if(i)
wrapped_dev.data = NULL;
else
wrapped_dev.data = (void*) slot;
rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus); rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus);
} }
} }
...@@ -635,9 +639,14 @@ int cpci_unconfigure_slot(struct slot* slot) ...@@ -635,9 +639,14 @@ int cpci_unconfigure_slot(struct slot* slot)
if(dev) { if(dev) {
wrapped_dev.dev = dev; wrapped_dev.dev = dev;
wrapped_bus.bus = dev->bus; wrapped_bus.bus = dev->bus;
if(i)
wrapped_dev.data = NULL;
else
wrapped_dev.data = (void*) slot;
dbg("%s - unconfigure phase 2", __FUNCTION__); dbg("%s - unconfigure phase 2", __FUNCTION__);
rc = pci_visit_dev(&unconfigure_functions_phase2, rc = pci_visit_dev(&unconfigure_functions_phase2,
&wrapped_dev, &wrapped_bus); &wrapped_dev,
&wrapped_bus);
if(rc) if(rc)
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment