From 657c2077a2dab228fcf28a708df1b1bcf4195803 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Aug 2012 10:07:00 -0600 Subject: PCI: Don't export stop_bus_device and remove_bus_device interfaces The acpiphp hotplug driver was the only user of pci_stop_bus_device() and __pci_remove_bus_device(), and it now uses pci_stop_and_remove_bus_device() instead, so stop exposing these interfaces. This removes these exported symbols: __pci_remove_bus_device pci_stop_bus_device Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 04a4861..534377f 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -79,6 +79,8 @@ void pci_remove_bus(struct pci_bus *pci_bus) EXPORT_SYMBOL(pci_remove_bus); static void __pci_remove_behind_bridge(struct pci_dev *dev); +static void pci_stop_bus_device(struct pci_dev *dev); + /** * pci_stop_and_remove_bus_device - remove a PCI device and any children * @dev: the device to remove @@ -91,7 +93,7 @@ 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) +static void __pci_remove_bus_device(struct pci_dev *dev) { if (dev->subordinate) { struct pci_bus *b = dev->subordinate; @@ -103,7 +105,6 @@ void __pci_remove_bus_device(struct pci_dev *dev) pci_destroy_dev(dev); } -EXPORT_SYMBOL(__pci_remove_bus_device); void pci_stop_and_remove_bus_device(struct pci_dev *dev) { @@ -170,7 +171,7 @@ static void pci_stop_bus_devices(struct pci_bus *bus) * 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) +static void pci_stop_bus_device(struct pci_dev *dev) { if (dev->subordinate) pci_stop_bus_devices(dev->subordinate); @@ -180,4 +181,3 @@ void pci_stop_bus_device(struct pci_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); -- cgit v1.1 From 125e14bb35e65b1ddfb7252fa8f6e3c50dbb6db2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Aug 2012 11:07:49 -0600 Subject: PCI: Remove pci_stop_and_remove_behind_bridge() The PCMCIA CardBus driver was the only user of pci_stop_and_remove_behind_bridge(), and it now uses pci_stop_and_remove_bus_device() instead, so remove this interface. This removes exported symbol pci_stop_and_remove_behind_bridge. Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 534377f..b18dc2e 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -121,30 +121,6 @@ static void __pci_remove_behind_bridge(struct pci_dev *dev) __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; @@ -180,4 +156,3 @@ static void pci_stop_bus_device(struct pci_dev *dev) } EXPORT_SYMBOL(pci_stop_and_remove_bus_device); -EXPORT_SYMBOL(pci_stop_and_remove_behind_bridge); -- cgit v1.1 From 66455f5472383df3632140e04f0852215e5c9ce8 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Aug 2012 15:53:27 -0600 Subject: PCI: Use list_for_each_entry() for bus->devices traversal Replace list_for_each() + pci_dev_b() with the simpler list_for_each_entry(). Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index b18dc2e..f17a027 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -114,16 +114,17 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) static void __pci_remove_behind_bridge(struct pci_dev *dev) { - struct list_head *l, *n; + 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)); + list_for_each_entry_safe(child, tmp, + &dev->subordinate->devices, bus_list) + __pci_remove_bus_device(child); } static void pci_stop_bus_devices(struct pci_bus *bus) { - struct list_head *l, *n; + struct pci_dev *dev, *tmp; /* * VFs could be removed by pci_stop_and_remove_bus_device() in the @@ -133,10 +134,8 @@ static void pci_stop_bus_devices(struct pci_bus *bus) * 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); + list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) pci_stop_bus_device(dev); - } } /** -- cgit v1.1 From 2ed168eeb3edec029aa0eca5cb981d6376f931f9 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Aug 2012 11:25:01 -0600 Subject: PCI: Fold stop and remove helpers into their callers pci_stop_bus_devices() is only two lines of code and is only called by pci_stop_bus_device(), so I think it's easier to read if we just fold it into the caller. Similarly for __pci_remove_behind_bridge(). Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 53 ++++++++++++++++++++-------------------------------- 1 file changed, 20 insertions(+), 33 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index f17a027..30d002e 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -78,7 +78,6 @@ void pci_remove_bus(struct pci_bus *pci_bus) } EXPORT_SYMBOL(pci_remove_bus); -static void __pci_remove_behind_bridge(struct pci_dev *dev); static void pci_stop_bus_device(struct pci_dev *dev); /** @@ -95,11 +94,14 @@ static void pci_stop_bus_device(struct pci_dev *dev); */ static void __pci_remove_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; + + if (bus) { + list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) + __pci_remove_bus_device(child); - __pci_remove_behind_bridge(dev); - pci_remove_bus(b); + pci_remove_bus(bus); dev->subordinate = NULL; } @@ -112,32 +114,6 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) __pci_remove_bus_device(dev); } -static void __pci_remove_behind_bridge(struct pci_dev *dev) -{ - struct pci_dev *child, *tmp; - - if (dev->subordinate) - list_for_each_entry_safe(child, tmp, - &dev->subordinate->devices, bus_list) - __pci_remove_bus_device(child); -} - -static void pci_stop_bus_devices(struct pci_bus *bus) -{ - struct pci_dev *dev, *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. - */ - list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) - pci_stop_bus_device(dev); -} - /** * pci_stop_bus_device - stop a PCI device and any children * @dev: the device to stop @@ -148,8 +124,19 @@ static void pci_stop_bus_devices(struct pci_bus *bus) */ static void pci_stop_bus_device(struct pci_dev *dev) { - if (dev->subordinate) - pci_stop_bus_devices(dev->subordinate); + struct pci_bus *bus = dev->subordinate; + struct pci_dev *child, *tmp; + + /* + * 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. + */ + if (bus) + list_for_each_entry_safe_reverse(child, tmp, + &bus->devices, bus_list) + pci_stop_bus_device(child); pci_stop_dev(dev); } -- cgit v1.1 From 282e1d655fe7c7c2e6b0dd8166c4c6b7c2a1219b Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 17 Aug 2012 11:57:48 -0600 Subject: PCI: Stop and remove devices in one pass Previously, when we removed a PCI device, we made two passes over the hierarchy rooted at the device. In the first pass, we stopped all the devices, and in the second, we removed them. This patch combines the two passes into one so that we remove a device as soon as it and all its children have been stopped. Note that we previously stopped devices in reverse order and removed them in forward order. Now we stop and remove them in reverse order. Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 42 +++++++----------------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 30d002e..3828104 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -78,8 +78,6 @@ void pci_remove_bus(struct pci_bus *pci_bus) } EXPORT_SYMBOL(pci_remove_bus); -static void pci_stop_bus_device(struct pci_dev *dev); - /** * pci_stop_and_remove_bus_device - remove a PCI device and any children * @dev: the device to remove @@ -92,38 +90,8 @@ static void pci_stop_bus_device(struct pci_dev *dev); * device lists, remove the /proc entry, and notify userspace * (/sbin/hotplug). */ -static void __pci_remove_bus_device(struct pci_dev *dev) -{ - struct pci_bus *bus = dev->subordinate; - struct pci_dev *child, *tmp; - - if (bus) { - list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) - __pci_remove_bus_device(child); - - pci_remove_bus(bus); - dev->subordinate = NULL; - } - - pci_destroy_dev(dev); -} - void pci_stop_and_remove_bus_device(struct pci_dev *dev) { - pci_stop_bus_device(dev); - __pci_remove_bus_device(dev); -} - -/** - * 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. - */ -static void pci_stop_bus_device(struct pci_dev *dev) -{ struct pci_bus *bus = dev->subordinate; struct pci_dev *child, *tmp; @@ -133,12 +101,16 @@ static void pci_stop_bus_device(struct pci_dev *dev) * iterator. Therefore, iterate in reverse so we remove the VFs * first, then the PF. */ - if (bus) + if (bus) { list_for_each_entry_safe_reverse(child, tmp, &bus->devices, bus_list) - pci_stop_bus_device(child); + pci_stop_and_remove_bus_device(child); + + pci_remove_bus(bus); + dev->subordinate = NULL; + } pci_stop_dev(dev); + pci_destroy_dev(dev); } - EXPORT_SYMBOL(pci_stop_and_remove_bus_device); -- cgit v1.1 From 7990681ad8215977b27ac855520720193de2c98f Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 16 Aug 2012 20:38:50 -0600 Subject: PCI: Remove unused, commented-out, code This removes unused code that was already commented out. Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 3828104..44f479f 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -43,25 +43,6 @@ static void pci_destroy_dev(struct pci_dev *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) { pci_proc_detach_bus(pci_bus); -- cgit v1.1 From d563e2ccc8adb1385da42e6077736ba6854117bb Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 16 Aug 2012 20:43:11 -0600 Subject: PCI: Rename local variables to conventional names "bus" is the conventional name for a "struct pci_bus *" variable. Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 44f479f..c01baca 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -43,19 +43,19 @@ static void pci_destroy_dev(struct pci_dev *dev) pci_dev_put(dev); } -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); -- cgit v1.1 From a7479d74460a4873b73534aa89cb82ab70ff8a32 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Thu, 16 Aug 2012 21:12:38 -0600 Subject: PCI: Leave normal LIST_POISON in deleted list entries list_del() already sets next/prev to LIST_POISON1/LIST_POISON2, so we don't need to do anything special here to prevent further list accesses. Tested-by: Yijing Wang Signed-off-by: Bjorn Helgaas Acked-by: Yinghai Lu --- drivers/pci/remove.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index c01baca..4f9ca91 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -32,11 +32,8 @@ 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); -- cgit v1.1 From 3891b6acb4f443cbe2e99367ee5e67c6bc29d446 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 19 Sep 2012 11:54:20 -0700 Subject: PCI: Stop all children first, before removing all children This restores the previous behavior of stopping all child devices before removing any of them. The current SR-IOV design, where removing the PF also drops references on all the VFs, depends on having the VFs continue to exist after having been stopped. [bhelgaas: changelog] Signed-off-by: Yinghai Lu Signed-off-by: Bjorn Helgaas --- drivers/pci/remove.c | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) (limited to 'drivers/pci/remove.c') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 4f9ca91..513972f 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -56,25 +56,13 @@ void pci_remove_bus(struct pci_bus *bus) } EXPORT_SYMBOL(pci_remove_bus); -/** - * 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_stop_and_remove_bus_device(struct pci_dev *dev) +static void pci_stop_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; struct pci_dev *child, *tmp; /* - * Removing an SR-IOV PF device removes all the associated VFs, + * 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. @@ -82,13 +70,44 @@ void pci_stop_and_remove_bus_device(struct pci_dev *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(child); + } + + pci_stop_dev(dev); +} + +static void pci_remove_bus_device(struct pci_dev *dev) +{ + struct pci_bus *bus = dev->subordinate; + struct pci_dev *child, *tmp; + + if (bus) { + list_for_each_entry_safe(child, tmp, + &bus->devices, bus_list) + pci_remove_bus_device(child); pci_remove_bus(bus); dev->subordinate = NULL; } - pci_stop_dev(dev); pci_destroy_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_stop_and_remove_bus_device(struct pci_dev *dev) +{ + pci_stop_bus_device(dev); + pci_remove_bus_device(dev); +} EXPORT_SYMBOL(pci_stop_and_remove_bus_device); -- cgit v1.1