aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/bus.c48
-rw-r--r--include/linux/pci.h3
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index a83ee0b85394..eed67d9e73bc 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -151,6 +151,54 @@ void pci_enable_bridges(struct pci_bus *bus)
151 } 151 }
152} 152}
153 153
154/** pci_walk_bus - walk devices on/under bus, calling callback.
155 * @top bus whose devices should be walked
156 * @cb callback to be called for each device found
157 * @userdata arbitrary pointer to be passed to callback.
158 *
159 * Walk the given bus, including any bridged devices
160 * on buses under this bus. Call the provided callback
161 * on each device found.
162 */
163void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
164 void *userdata)
165{
166 struct pci_dev *dev;
167 struct pci_bus *bus;
168 struct list_head *next;
169
170 bus = top;
171 spin_lock(&pci_bus_lock);
172 next = top->devices.next;
173 for (;;) {
174 if (next == &bus->devices) {
175 /* end of this bus, go up or finish */
176 if (bus == top)
177 break;
178 next = bus->self->bus_list.next;
179 bus = bus->self->bus;
180 continue;
181 }
182 dev = list_entry(next, struct pci_dev, bus_list);
183 pci_dev_get(dev);
184 if (dev->subordinate) {
185 /* this is a pci-pci bridge, do its devices next */
186 next = dev->subordinate->devices.next;
187 bus = dev->subordinate;
188 } else
189 next = dev->bus_list.next;
190 spin_unlock(&pci_bus_lock);
191
192 /* Run device routines with the bus unlocked */
193 cb(dev, userdata);
194
195 spin_lock(&pci_bus_lock);
196 pci_dev_put(dev);
197 }
198 spin_unlock(&pci_bus_lock);
199}
200EXPORT_SYMBOL_GPL(pci_walk_bus);
201
154EXPORT_SYMBOL(pci_bus_alloc_resource); 202EXPORT_SYMBOL(pci_bus_alloc_resource);
155EXPORT_SYMBOL_GPL(pci_bus_add_device); 203EXPORT_SYMBOL_GPL(pci_bus_add_device);
156EXPORT_SYMBOL(pci_bus_add_devices); 204EXPORT_SYMBOL(pci_bus_add_devices);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8878ccff9e3c..b0e244713281 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -434,6 +434,9 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_
434const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); 434const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
435int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); 435int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
436 436
437void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
438 void *userdata);
439
437/* kmem_cache style wrapper around pci_alloc_consistent() */ 440/* kmem_cache style wrapper around pci_alloc_consistent() */
438 441
439#include <linux/dmapool.h> 442#include <linux/dmapool.h>