Commit cdb38206 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

[PATCH] IBM PCI Hotplug: convert driver to use pci_bus_remove_device()

Also cleaned up a lot of unnecessary bus walking on device startup
and shutdown.
parent a7434f09
......@@ -781,141 +781,23 @@ static void free_slots (void)
debug ("%s -- exit\n", __FUNCTION__);
}
static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
{
struct pci_dev *dev = wrapped_dev->dev;
struct pci_func *temp_func;
int i = 0;
do {
temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
if (dev) {
if (pci_remove_device_safe(dev) == 0)
kfree (dev); /* Now, remove */
else
return -1;
}
if (temp_func)
temp_func->dev = NULL;
else
debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
return 0;
}
static int ibm_unconfigure_visit_pci_bus_phase2 (struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_dev)
{
struct pci_bus *bus = wrapped_bus->bus;
pci_proc_detach_bus (bus);
/* The cleanup code should live in the kernel... */
bus->self->subordinate = NULL;
/* unlink from parent bus */
list_del (&bus->node);
/* Now, remove */
if (bus)
kfree (bus);
return 0;
}
static int ibm_unconfigure_visit_pci_dev_phase1 (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
{
struct pci_dev *dev = wrapped_dev->dev;
debug ("attempting removal of driver for device (%x, %x, %x)\n", dev->bus->number, PCI_SLOT (dev->devfn), PCI_FUNC (dev->devfn));
/* Now, remove the Linux Driver Representation */
if (dev->driver) {
debug ("is there a driver?\n");
if (dev->driver->remove) {
dev->driver->remove (dev);
debug ("driver was properly removed\n");
}
dev->driver = NULL;
}
return (pci_dev_driver(dev) != NULL);
}
static struct pci_visit ibm_unconfigure_functions_phase1 = {
.post_visit_pci_dev = ibm_unconfigure_visit_pci_dev_phase1,
};
static struct pci_visit ibm_unconfigure_functions_phase2 = {
.post_visit_pci_bus = ibm_unconfigure_visit_pci_bus_phase2,
.post_visit_pci_dev = ibm_unconfigure_visit_pci_dev_phase2,
};
static int ibm_unconfigure_device (struct pci_func *func)
{
int rc = 0;
struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus;
struct pci_dev *temp;
u8 j;
memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
debug ("inside ibm_unconfigure_device\n");
debug ("inside %s\n", __FUNCTION__);
debug ("func->device = %x, func->function = %x\n", func->device, func->function);
debug ("func->device << 3 | 0x0 = %x\n", func->device << 3 | 0x0);
for (j = 0; j < 0x08; j++) {
temp = pci_find_slot (func->busno, (func->device << 3) | j);
if (temp) {
wrapped_dev.dev = temp;
wrapped_bus.bus = temp->bus;
rc = pci_visit_dev (&ibm_unconfigure_functions_phase1, &wrapped_dev, &wrapped_bus);
if (rc)
break;
rc = pci_visit_dev (&ibm_unconfigure_functions_phase2, &wrapped_dev, &wrapped_bus);
if (rc)
break;
if (temp)
pci_remove_bus_device(temp);
}
}
debug ("rc in ibm_unconfigure_device b4 returning is %d \n", rc);
return rc;
}
static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct pci_bus_wrapped *wrapped_bus)
{
// struct pci_bus *bus = wrapped_bus->bus; /* We don't need this, since we don't create in the else statement */
struct pci_dev *dev = wrapped_dev->dev;
struct pci_func *temp_func;
int i = 0;
do {
temp_func = ibm_slot_find (dev->bus->number, dev->devfn >> 3, i++);
} while (temp_func && (temp_func->function != (dev->devfn & 0x07)));
if (temp_func)
temp_func->dev = dev;
else {
/* This should not really happen, since we create functions
first and then call to configure */
debug (" We shouldn't come here \n");
}
if (temp_func->dev) {
// pci_proc_attach_device (temp_func->dev);
// pci_announce_device_to_drivers (temp_func->dev);
}
return 0;
}
static struct pci_visit configure_functions = {
.visit_pci_dev =configure_visit_pci_dev,
};
/*
* The following function is to fix kernel bug regarding
* getting bus entries, here we manually add those primary
......@@ -965,15 +847,9 @@ static int ibm_configure_device (struct pci_func *func)
unsigned char bus;
struct pci_dev dev0;
struct pci_bus *child;
struct pci_dev *temp;
int rc = 0;
int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */
struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus;
memset (&wrapped_dev, 0, sizeof (struct pci_dev_wrapped));
memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
memset (&dev0, 0, sizeof (struct pci_dev));
if (!(bus_structure_fixup (func->busno)))
......@@ -1001,12 +877,6 @@ static int ibm_configure_device (struct pci_func *func)
pci_do_scan_bus (child);
}
temp = func->dev;
if (temp) {
wrapped_dev.dev = temp;
wrapped_bus.bus = temp->bus;
rc = pci_visit_dev (&configure_functions, &wrapped_dev, &wrapped_bus);
}
return rc;
}
......
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