Update of /cvsroot/linux-vax/kernel-2.5/drivers/base
In directory sc8-pr-cvs1:/tmp/cvs-serv1632/drivers/base
Modified Files:
bus.c
Log Message:
Merge with 2.5.20. Also catch up on some file deletions in 2.5.17 to
2.5.19 that I missed earlier.
Index: bus.c
===================================================================
RCS file: /cvsroot/linux-vax/kernel-2.5/drivers/base/bus.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- bus.c 12 Jan 2003 22:46:40 -0000 1.2
+++ bus.c 14 Jan 2003 23:55:17 -0000 1.3
@@ -24,6 +24,91 @@
};
/**
+ * bus_for_each_dev - walk list of devices and do something to each
+ * @bus: bus in question
+ * @data: data for the callback
+ * @callback: caller-defined action to perform on each device
+ *
+ * Why do we do this? So we can guarantee proper locking and reference
+ * counting on devices as we touch each one.
+ *
+ * Algorithm:
+ * Take the bus lock and get the first node in the list. We increment
+ * the reference count and unlock the bus. If we have a device from a
+ * previous iteration, we decrement the reference count.
+ * After we call the callback, we get the next node in the list and loop.
+ * At the end, if @dev is not null, we still have it pinned, so we need
+ * to let it go.
+ */
+int bus_for_each_dev(struct bus_type * bus, void * data,
+ int (*callback)(struct device * dev, void * data))
+{
+ struct device * next;
+ struct device * dev = NULL;
+ struct list_head * node;
+ int error = 0;
+
+ get_bus(bus);
+ read_lock(&bus->lock);
+ node = bus->devices.next;
+ while (node != &bus->devices) {
+ next = list_entry(node,struct device,bus_list);
+ get_device(next);
+ read_unlock(&bus->lock);
+
+ if (dev)
+ put_device(dev);
+ dev = next;
+ if ((error = callback(dev,data))) {
+ put_device(dev);
+ break;
+ }
+ read_lock(&bus->lock);
+ node = dev->bus_list.next;
+ }
+ read_unlock(&bus->lock);
+ if (dev)
+ put_device(dev);
+ put_bus(bus);
+ return error;
+}
+
+int bus_for_each_drv(struct bus_type * bus, void * data,
+ int (*callback)(struct device_driver * drv, void * data))
+{
+ struct device_driver * next;
+ struct device_driver * drv = NULL;
+ struct list_head * node;
+ int error = 0;
+
+ /* pin bus in memory */
+ get_bus(bus);
+
+ read_lock(&bus->lock);
+ node = bus->drivers.next;
+ while (node != &bus->drivers) {
+ next = list_entry(node,struct device_driver,bus_list);
+ get_driver(next);
+ read_unlock(&bus->lock);
+
+ if (drv)
+ put_driver(drv);
+ drv = next;
+ if ((error = callback(drv,data))) {
+ put_driver(drv);
+ break;
+ }
+ read_lock(&bus->lock);
+ node = drv->bus_list.next;
+ }
+ read_unlock(&bus->lock);
+ if (drv)
+ put_driver(drv);
+ put_bus(bus);
+ return error;
+}
+
+/**
* bus_add_device - add device to bus
* @dev: device being added
*
@@ -120,6 +205,8 @@
core_initcall(bus_init);
+EXPORT_SYMBOL(bus_for_each_dev);
+EXPORT_SYMBOL(bus_for_each_drv);
EXPORT_SYMBOL(bus_add_device);
EXPORT_SYMBOL(bus_remove_device);
EXPORT_SYMBOL(bus_register);
|