summaryrefslogtreecommitdiffstats
path: root/drivers/pci/remove.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-10-09 18:35:22 -0400
committerJ. Bruce Fields <bfields@redhat.com>2012-10-09 18:35:22 -0400
commitf474af7051212b4efc8267583fad9c4ebf33ccff (patch)
tree1aa46ebc8065a341f247c2a2d9af2f624ad1d4f8 /drivers/pci/remove.c
parent0d22f68f02c10d5d10ec5712917e5828b001a822 (diff)
parente3dd9a52cb5552c46c2a4ca7ccdfb4dab5c72457 (diff)
nfs: disintegrate UAPI for nfs
This is to complete part of the Userspace API (UAPI) disintegration for which the preparatory patches were pulled recently. After these patches, userspace headers will be segregated into: include/uapi/linux/.../foo.h for the userspace interface stuff, and: include/linux/.../foo.h for the strictly kernel internal stuff. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'drivers/pci/remove.c')
-rw-r--r--drivers/pci/remove.c156
1 files changed, 43 insertions, 113 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 04a4861b474..513972f3ed1 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -32,152 +32,82 @@ 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)
-{
- if (pci_dev_driver(dev))
- return -EBUSY;
- pci_destroy_dev(dev);
- return 0;
-}
-#endif /* 0 */
-
-void pci_remove_bus(struct pci_bus *pci_bus)
+void pci_remove_bus(struct pci_bus *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
- *
- * Remove a PCI device from the device lists, informing the drivers
- * that the device has been removed. We also remove any subordinate
- * buses and children in a depth-first manner.
- *
- * For each device we remove, delete the device structure from the
- * device lists, remove the /proc entry, and notify userspace
- * (/sbin/hotplug).
- */
-void __pci_remove_bus_device(struct pci_dev *dev)
+static void pci_stop_bus_device(struct pci_dev *dev)
{
- if (dev->subordinate) {
- struct pci_bus *b = dev->subordinate;
+ struct pci_bus *bus = dev->subordinate;
+ struct pci_dev *child, *tmp;
- __pci_remove_behind_bridge(dev);
- pci_remove_bus(b);
- dev->subordinate = NULL;
+ /*
+ * Stopping 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.
+ */
+ if (bus) {
+ list_for_each_entry_safe_reverse(child, tmp,
+ &bus->devices, bus_list)
+ pci_stop_bus_device(child);
}
- 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);
+ pci_stop_dev(dev);
}
-static void __pci_remove_behind_bridge(struct pci_dev *dev)
+static void pci_remove_bus_device(struct pci_dev *dev)
{
- struct list_head *l, *n;
+ struct pci_bus *bus = dev->subordinate;
+ struct pci_dev *child, *tmp;
- if (dev->subordinate)
- list_for_each_safe(l, n, &dev->subordinate->devices)
- __pci_remove_bus_device(pci_dev_b(l));
-}
+ if (bus) {
+ list_for_each_entry_safe(child, tmp,
+ &bus->devices, bus_list)
+ pci_remove_bus_device(child);
-static void pci_stop_behind_bridge(struct pci_dev *dev)
-{
- struct list_head *l, *n;
+ pci_remove_bus(bus);
+ dev->subordinate = NULL;
+ }
- if (dev->subordinate)
- list_for_each_safe(l, n, &dev->subordinate->devices)
- pci_stop_bus_device(pci_dev_b(l));
+ pci_destroy_dev(dev);
}
/**
- * pci_stop_and_remove_behind_bridge - stop and remove all devices behind
- * a PCI bridge
- * @dev: PCI bridge device
+ * pci_stop_and_remove_bus_device - remove a PCI device and any children
+ * @dev: the device to remove
*
- * 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;
-
- /*
- * 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.
- */
- list_for_each_prev_safe(l, n, &bus->devices) {
- struct pci_dev *dev = pci_dev_b(l);
- pci_stop_bus_device(dev);
- }
-}
-
-/**
- * pci_stop_bus_device - stop a PCI device and any children
- * @dev: the device to stop
+ * Remove a PCI device from the device lists, informing the drivers
+ * that the device has been removed. We also remove any subordinate
+ * buses and children in a depth-first manner.
*
- * 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.
+ * For each device we remove, delete the device structure from the
+ * device lists, remove the /proc entry, and notify userspace
+ * (/sbin/hotplug).
*/
-void pci_stop_bus_device(struct pci_dev *dev)
+void pci_stop_and_remove_bus_device(struct pci_dev *dev)
{
- if (dev->subordinate)
- pci_stop_bus_devices(dev->subordinate);
-
- pci_stop_dev(dev);
+ pci_stop_bus_device(dev);
+ pci_remove_bus_device(dev);
}
-
EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
-EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge);
-EXPORT_SYMBOL_GPL(pci_stop_bus_device);