diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2012-08-17 13:25:01 -0400 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2012-08-22 13:31:42 -0400 |
commit | 2ed168eeb3edec029aa0eca5cb981d6376f931f9 (patch) | |
tree | 015c0c9f116b9e8f246784b7f0ba71970df81e58 | |
parent | 66455f5472383df3632140e04f0852215e5c9ce8 (diff) |
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 <wangyijing@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Yinghai Lu <yinghai@kernel.org>
-rw-r--r-- | drivers/pci/remove.c | 53 |
1 files changed, 20 insertions, 33 deletions
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index f17a02781e67..30d002e83e2d 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c | |||
@@ -78,7 +78,6 @@ void pci_remove_bus(struct pci_bus *pci_bus) | |||
78 | } | 78 | } |
79 | EXPORT_SYMBOL(pci_remove_bus); | 79 | EXPORT_SYMBOL(pci_remove_bus); |
80 | 80 | ||
81 | static void __pci_remove_behind_bridge(struct pci_dev *dev); | ||
82 | static void pci_stop_bus_device(struct pci_dev *dev); | 81 | static void pci_stop_bus_device(struct pci_dev *dev); |
83 | 82 | ||
84 | /** | 83 | /** |
@@ -95,11 +94,14 @@ static void pci_stop_bus_device(struct pci_dev *dev); | |||
95 | */ | 94 | */ |
96 | static void __pci_remove_bus_device(struct pci_dev *dev) | 95 | static void __pci_remove_bus_device(struct pci_dev *dev) |
97 | { | 96 | { |
98 | if (dev->subordinate) { | 97 | struct pci_bus *bus = dev->subordinate; |
99 | struct pci_bus *b = 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); | ||
100 | 103 | ||
101 | __pci_remove_behind_bridge(dev); | 104 | pci_remove_bus(bus); |
102 | pci_remove_bus(b); | ||
103 | dev->subordinate = NULL; | 105 | dev->subordinate = NULL; |
104 | } | 106 | } |
105 | 107 | ||
@@ -112,32 +114,6 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) | |||
112 | __pci_remove_bus_device(dev); | 114 | __pci_remove_bus_device(dev); |
113 | } | 115 | } |
114 | 116 | ||
115 | static void __pci_remove_behind_bridge(struct pci_dev *dev) | ||
116 | { | ||
117 | struct pci_dev *child, *tmp; | ||
118 | |||
119 | if (dev->subordinate) | ||
120 | list_for_each_entry_safe(child, tmp, | ||
121 | &dev->subordinate->devices, bus_list) | ||
122 | __pci_remove_bus_device(child); | ||
123 | } | ||
124 | |||
125 | static void pci_stop_bus_devices(struct pci_bus *bus) | ||
126 | { | ||
127 | struct pci_dev *dev, *tmp; | ||
128 | |||
129 | /* | ||
130 | * VFs could be removed by pci_stop_and_remove_bus_device() in the | ||
131 | * pci_stop_bus_devices() code path for PF. | ||
132 | * aka, bus->devices get updated in the process. | ||
133 | * but VFs are inserted after PFs when SRIOV is enabled for PF, | ||
134 | * We can iterate the list backwards to get prev valid PF instead | ||
135 | * of removed VF. | ||
136 | */ | ||
137 | list_for_each_entry_safe_reverse(dev, tmp, &bus->devices, bus_list) | ||
138 | pci_stop_bus_device(dev); | ||
139 | } | ||
140 | |||
141 | /** | 117 | /** |
142 | * pci_stop_bus_device - stop a PCI device and any children | 118 | * pci_stop_bus_device - stop a PCI device and any children |
143 | * @dev: the device to stop | 119 | * @dev: the device to stop |
@@ -148,8 +124,19 @@ static void pci_stop_bus_devices(struct pci_bus *bus) | |||
148 | */ | 124 | */ |
149 | static void pci_stop_bus_device(struct pci_dev *dev) | 125 | static void pci_stop_bus_device(struct pci_dev *dev) |
150 | { | 126 | { |
151 | if (dev->subordinate) | 127 | struct pci_bus *bus = dev->subordinate; |
152 | pci_stop_bus_devices(dev->subordinate); | 128 | struct pci_dev *child, *tmp; |
129 | |||
130 | /* | ||
131 | * Removing an SR-IOV PF device removes all the associated VFs, | ||
132 | * which will update the bus->devices list and confuse the | ||
133 | * iterator. Therefore, iterate in reverse so we remove the VFs | ||
134 | * first, then the PF. | ||
135 | */ | ||
136 | if (bus) | ||
137 | list_for_each_entry_safe_reverse(child, tmp, | ||
138 | &bus->devices, bus_list) | ||
139 | pci_stop_bus_device(child); | ||
153 | 140 | ||
154 | pci_stop_dev(dev); | 141 | pci_stop_dev(dev); |
155 | } | 142 | } |