aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/remove.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/remove.c')
-rw-r--r--drivers/pci/remove.c42
1 files changed, 7 insertions, 35 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 30d002e83e2d..38281042c31c 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -78,8 +78,6 @@ void pci_remove_bus(struct pci_bus *pci_bus)
78} 78}
79EXPORT_SYMBOL(pci_remove_bus); 79EXPORT_SYMBOL(pci_remove_bus);
80 80
81static void pci_stop_bus_device(struct pci_dev *dev);
82
83/** 81/**
84 * pci_stop_and_remove_bus_device - remove a PCI device and any children 82 * pci_stop_and_remove_bus_device - remove a PCI device and any children
85 * @dev: the device to remove 83 * @dev: the device to remove
@@ -92,38 +90,8 @@ static void pci_stop_bus_device(struct pci_dev *dev);
92 * device lists, remove the /proc entry, and notify userspace 90 * device lists, remove the /proc entry, and notify userspace
93 * (/sbin/hotplug). 91 * (/sbin/hotplug).
94 */ 92 */
95static void __pci_remove_bus_device(struct pci_dev *dev)
96{
97 struct pci_bus *bus = dev->subordinate;
98 struct pci_dev *child, *tmp;
99
100 if (bus) {
101 list_for_each_entry_safe(child, tmp, &bus->devices, bus_list)
102 __pci_remove_bus_device(child);
103
104 pci_remove_bus(bus);
105 dev->subordinate = NULL;
106 }
107
108 pci_destroy_dev(dev);
109}
110
111void pci_stop_and_remove_bus_device(struct pci_dev *dev) 93void pci_stop_and_remove_bus_device(struct pci_dev *dev)
112{ 94{
113 pci_stop_bus_device(dev);
114 __pci_remove_bus_device(dev);
115}
116
117/**
118 * pci_stop_bus_device - stop a PCI device and any children
119 * @dev: the device to stop
120 *
121 * Stop a PCI device (detach the driver, remove from the global list
122 * and so on). This also stop any subordinate buses and children in a
123 * depth-first manner.
124 */
125static void pci_stop_bus_device(struct pci_dev *dev)
126{
127 struct pci_bus *bus = dev->subordinate; 95 struct pci_bus *bus = dev->subordinate;
128 struct pci_dev *child, *tmp; 96 struct pci_dev *child, *tmp;
129 97
@@ -133,12 +101,16 @@ static void pci_stop_bus_device(struct pci_dev *dev)
133 * iterator. Therefore, iterate in reverse so we remove the VFs 101 * iterator. Therefore, iterate in reverse so we remove the VFs
134 * first, then the PF. 102 * first, then the PF.
135 */ 103 */
136 if (bus) 104 if (bus) {
137 list_for_each_entry_safe_reverse(child, tmp, 105 list_for_each_entry_safe_reverse(child, tmp,
138 &bus->devices, bus_list) 106 &bus->devices, bus_list)
139 pci_stop_bus_device(child); 107 pci_stop_and_remove_bus_device(child);
108
109 pci_remove_bus(bus);
110 dev->subordinate = NULL;
111 }
140 112
141 pci_stop_dev(dev); 113 pci_stop_dev(dev);
114 pci_destroy_dev(dev);
142} 115}
143
144EXPORT_SYMBOL(pci_stop_and_remove_bus_device); 116EXPORT_SYMBOL(pci_stop_and_remove_bus_device);