From: Kenn H. <ke...@us...> - 2003-01-14 23:55:21
|
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); |