Skip to content

Commit

Permalink
Merge branch 'pci/bjorn-cleanup-remove' into next
Browse files Browse the repository at this point in the history
* pci/bjorn-cleanup-remove:
  PCI: Remove unused pci_dev_b()
  sgi-agp: Use list_for_each_entry() for bus->devices traversal
  parisc/PCI: Use list_for_each_entry() for bus->devices traversal
  parisc/PCI: Enable PERR/SERR on all devices
  frv/PCI: Use list_for_each_entry() for bus->devices traversal
  PCI: Leave normal LIST_POISON in deleted list entries
  PCI: Rename local variables to conventional names
  PCI: Remove unused, commented-out, code
  PCI: Stop and remove devices in one pass
  PCI: Fold stop and remove helpers into their callers
  PCI: Use list_for_each_entry() for bus->devices traversal
  PCI: Remove pci_stop_and_remove_behind_bridge()
  PCI: Don't export stop_bus_device and remove_bus_device interfaces
  pcmcia: Use common pci_stop_and_remove_bus_device()
  PCI: acpiphp: Use common pci_stop_and_remove_bus_device()
  PCI: acpiphp: Stop disabling bridges on remove
  • Loading branch information
bjorn-helgaas committed Aug 24, 2012
2 parents a28afda + c29aabe commit 7bf79d8
Show file tree
Hide file tree
Showing 11 changed files with 45 additions and 261 deletions.
4 changes: 1 addition & 3 deletions arch/frv/mb93090-mb00/pci-vdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,8 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
pci_read_bridge_bases(bus);

if (bus->number == 0) {
struct list_head *ln;
struct pci_dev *dev;
for (ln=bus->devices.next; ln != &bus->devices; ln=ln->next) {
dev = pci_dev_b(ln);
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->devfn == 0) {
dev->resource[0].start = 0;
dev->resource[0].end = 0;
Expand Down
5 changes: 2 additions & 3 deletions drivers/char/agp/sgi-agp.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,12 +289,11 @@ static int __devinit agp_sgi_init(void)

j = 0;
list_for_each_entry(info, &tioca_list, ca_list) {
struct list_head *tmp;
if (list_empty(info->ca_devices))
continue;
list_for_each(tmp, info->ca_devices) {
list_for_each_entry(pdev, info->ca_devices, bus_list) {
u8 cap_ptr;
pdev = pci_dev_b(tmp);

if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8))
continue;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
Expand Down
10 changes: 3 additions & 7 deletions drivers/parisc/dino.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,14 +477,12 @@ dino_card_setup(struct pci_bus *bus, void __iomem *base_addr)
if (ccio_allocate_resource(dino_dev->hba.dev, res, _8MB,
F_EXTEND(0xf0000000UL) | _8MB,
F_EXTEND(0xffffffffUL) &~ _8MB, _8MB) < 0) {
struct list_head *ln, *tmp_ln;
struct pci_dev *dev, *tmp;

printk(KERN_ERR "Dino: cannot attach bus %s\n",
dev_name(bus->bridge));
/* kill the bus, we can't do anything with it */
list_for_each_safe(ln, tmp_ln, &bus->devices) {
struct pci_dev *dev = pci_dev_b(ln);

list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
list_del(&dev->bus_list);
}

Expand Down Expand Up @@ -549,7 +547,6 @@ dino_card_fixup(struct pci_dev *dev)
static void __init
dino_fixup_bus(struct pci_bus *bus)
{
struct list_head *ln;
struct pci_dev *dev;
struct dino_device *dino_dev = DINO_DEV(parisc_walk_tree(bus->bridge));

Expand Down Expand Up @@ -596,8 +593,7 @@ dino_fixup_bus(struct pci_bus *bus)
}


list_for_each(ln, &bus->devices) {
dev = pci_dev_b(ln);
list_for_each_entry(dev, &bus->devices, bus_list) {
if (is_card_dino(&dino_dev->hba.dev->id))
dino_card_fixup(dev);

Expand Down
7 changes: 3 additions & 4 deletions drivers/parisc/lba_pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ truncate_pat_collision(struct resource *root, struct resource *new)
static void
lba_fixup_bus(struct pci_bus *bus)
{
struct list_head *ln;
struct pci_dev *dev;
#ifdef FBB_SUPPORT
u16 status;
#endif
Expand Down Expand Up @@ -710,9 +710,8 @@ lba_fixup_bus(struct pci_bus *bus)

}

list_for_each(ln, &bus->devices) {
list_for_each_entry(dev, &bus->devices, bus_list) {
int i;
struct pci_dev *dev = pci_dev_b(ln);

DBG("lba_fixup_bus() %s\n", pci_name(dev));

Expand Down Expand Up @@ -770,7 +769,7 @@ lba_fixup_bus(struct pci_bus *bus)
}

/* Lastly enable FBB/PERR/SERR on all devices too */
list_for_each(ln, &bus->devices) {
list_for_each_entry(dev, &bus->devices, bus_list) {
(void) pci_read_config_word(dev, PCI_COMMAND, &status);
status |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR | fbb_enable;
(void) pci_write_config_word(dev, PCI_COMMAND, status);
Expand Down
46 changes: 1 addition & 45 deletions drivers/pci/hotplug/acpiphp_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -869,17 +869,6 @@ static int __ref enable_device(struct acpiphp_slot *slot)
return retval;
}

static void disable_bridges(struct pci_bus *bus)
{
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
disable_bridges(dev->subordinate);
pci_disable_device(dev);
}
}
}

/* return first device in slot, acquiring a reference on it */
static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
{
Expand Down Expand Up @@ -931,12 +920,7 @@ static int disable_device(struct acpiphp_slot *slot)
* here.
*/
while ((pdev = dev_in_slot(slot))) {
pci_stop_bus_device(pdev);
if (pdev->subordinate) {
disable_bridges(pdev->subordinate);
pci_disable_device(pdev);
}
__pci_remove_bus_device(pdev);
pci_stop_and_remove_bus_device(pdev);
pci_dev_put(pdev);
}

Expand Down Expand Up @@ -1477,34 +1461,6 @@ int __init acpiphp_get_num_slots(void)
}


#if 0
/**
* acpiphp_for_each_slot - call function for each slot
* @fn: callback function
* @data: context to be passed to callback function
*/
static int acpiphp_for_each_slot(acpiphp_callback fn, void *data)
{
struct list_head *node;
struct acpiphp_bridge *bridge;
struct acpiphp_slot *slot;
int retval = 0;

list_for_each (node, &bridge_list) {
bridge = (struct acpiphp_bridge *)node;
for (slot = bridge->slots; slot; slot = slot->next) {
retval = fn(slot, data);
if (!retval)
goto err_exit;
}
}

err_exit:
return retval;
}
#endif


/**
* acpiphp_enable_slot - power on slot
* @slot: ACPI PHP slot
Expand Down
19 changes: 0 additions & 19 deletions drivers/pci/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,25 +434,6 @@ int pci_proc_detach_device(struct pci_dev *dev)
return 0;
}

#if 0
int pci_proc_attach_bus(struct pci_bus* bus)
{
struct proc_dir_entry *de = bus->procdir;

if (!proc_initialized)
return -EACCES;

if (!de) {
char name[16];
sprintf(name, "%02x", bus->number);
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
if (!de)
return -ENOMEM;
}
return 0;
}
#endif /* 0 */

int pci_proc_detach_bus(struct pci_bus* bus)
{
struct proc_dir_entry *de = bus->procdir;
Expand Down
131 changes: 21 additions & 110 deletions drivers/pci/remove.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,53 +32,30 @@ static void pci_stop_dev(struct pci_dev *dev)

static void pci_destroy_dev(struct pci_dev *dev)
{
/* Remove the device from the device lists, and prevent any further
* list accesses from this device */
down_write(&pci_bus_sem);
list_del(&dev->bus_list);
dev->bus_list.next = dev->bus_list.prev = NULL;
up_write(&pci_bus_sem);

pci_free_resources(dev);
pci_dev_put(dev);
}

/**
* pci_remove_device_safe - remove an unused hotplug device
* @dev: the device to remove
*
* Delete the device structure from the device lists and
* notify userspace (/sbin/hotplug), but only if the device
* in question is not being used by a driver.
* Returns 0 on success.
*/
#if 0
int pci_remove_device_safe(struct pci_dev *dev)
void pci_remove_bus(struct pci_bus *bus)
{
if (pci_dev_driver(dev))
return -EBUSY;
pci_destroy_dev(dev);
return 0;
}
#endif /* 0 */

void pci_remove_bus(struct pci_bus *pci_bus)
{
pci_proc_detach_bus(pci_bus);
pci_proc_detach_bus(bus);

down_write(&pci_bus_sem);
list_del(&pci_bus->node);
pci_bus_release_busn_res(pci_bus);
list_del(&bus->node);
pci_bus_release_busn_res(bus);
up_write(&pci_bus_sem);
if (!pci_bus->is_added)
if (!bus->is_added)
return;

pci_remove_legacy_files(pci_bus);
device_unregister(&pci_bus->dev);
pci_remove_legacy_files(bus);
device_unregister(&bus->dev);
}
EXPORT_SYMBOL(pci_remove_bus);

static void __pci_remove_behind_bridge(struct pci_dev *dev);
/**
* pci_stop_and_remove_bus_device - remove a PCI device and any children
* @dev: the device to remove
Expand All @@ -91,93 +68,27 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev);
* device lists, remove the /proc entry, and notify userspace
* (/sbin/hotplug).
*/
void __pci_remove_bus_device(struct pci_dev *dev)
{
if (dev->subordinate) {
struct pci_bus *b = dev->subordinate;

__pci_remove_behind_bridge(dev);
pci_remove_bus(b);
dev->subordinate = NULL;
}

pci_destroy_dev(dev);
}
EXPORT_SYMBOL(__pci_remove_bus_device);

void pci_stop_and_remove_bus_device(struct pci_dev *dev)
{
pci_stop_bus_device(dev);
__pci_remove_bus_device(dev);
}

static void __pci_remove_behind_bridge(struct pci_dev *dev)
{
struct list_head *l, *n;

if (dev->subordinate)
list_for_each_safe(l, n, &dev->subordinate->devices)
__pci_remove_bus_device(pci_dev_b(l));
}

static void pci_stop_behind_bridge(struct pci_dev *dev)
{
struct list_head *l, *n;

if (dev->subordinate)
list_for_each_safe(l, n, &dev->subordinate->devices)
pci_stop_bus_device(pci_dev_b(l));
}

/**
* pci_stop_and_remove_behind_bridge - stop and remove all devices behind
* a PCI bridge
* @dev: PCI bridge device
*
* Remove all devices on the bus, except for the parent bridge.
* This also removes any child buses, and any devices they may
* contain in a depth-first manner.
*/
void pci_stop_and_remove_behind_bridge(struct pci_dev *dev)
{
pci_stop_behind_bridge(dev);
__pci_remove_behind_bridge(dev);
}

static void pci_stop_bus_devices(struct pci_bus *bus)
{
struct list_head *l, *n;
struct pci_bus *bus = dev->subordinate;
struct pci_dev *child, *tmp;

/*
* VFs could be removed by pci_stop_and_remove_bus_device() in the
* pci_stop_bus_devices() code path for PF.
* aka, bus->devices get updated in the process.
* but VFs are inserted after PFs when SRIOV is enabled for PF,
* We can iterate the list backwards to get prev valid PF instead
* of removed VF.
* Removing an SR-IOV PF device removes all the associated VFs,
* which will update the bus->devices list and confuse the
* iterator. Therefore, iterate in reverse so we remove the VFs
* first, then the PF.
*/
list_for_each_prev_safe(l, n, &bus->devices) {
struct pci_dev *dev = pci_dev_b(l);
pci_stop_bus_device(dev);
}
}
if (bus) {
list_for_each_entry_safe_reverse(child, tmp,
&bus->devices, bus_list)
pci_stop_and_remove_bus_device(child);

/**
* pci_stop_bus_device - stop a PCI device and any children
* @dev: the device to stop
*
* Stop a PCI device (detach the driver, remove from the global list
* and so on). This also stop any subordinate buses and children in a
* depth-first manner.
*/
void pci_stop_bus_device(struct pci_dev *dev)
{
if (dev->subordinate)
pci_stop_bus_devices(dev->subordinate);
pci_remove_bus(bus);
dev->subordinate = NULL;
}

pci_stop_dev(dev);
pci_destroy_dev(dev);
}

EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge);
EXPORT_SYMBOL_GPL(pci_stop_bus_device);
Loading

0 comments on commit 7bf79d8

Please sign in to comment.