summaryrefslogtreecommitdiff
path: root/drivers/base
diff options
context:
space:
mode:
authorPatrick Mochel <mochel@osdl.org>2002-10-16 21:13:28 -0700
committerPatrick Mochel <mochel@osdl.org>2002-10-16 21:13:28 -0700
commitec0a28d2ce23c7118ca42b7ab0f5017e709eceea (patch)
treec41e0cfc5cb6e39cc9b2735e6b540652cc593b80 /drivers/base
parent557aebd24f59a1e90093661233f8e79e78a563f9 (diff)
driver model: clean up bus_for_each_{dev,drv}
- make sure we check what we get back from get_bus() - do down_read() instead of down_write(), so multiple people can do iterations concurrently. - Note that devices and drivers are removed from these while doing a down_write(), so all removals will be stalled until the iterators are done.
Diffstat (limited to 'drivers/base')
-rw-r--r--drivers/base/bus.c59
1 files changed, 26 insertions, 33 deletions
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 1f3b6471a582..7ef3111f0091 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -43,26 +43,23 @@ int bus_for_each_dev(struct bus_type * bus, void * data,
int (*callback)(struct device * dev, void * data))
{
struct list_head * node;
- struct device * prev = NULL;
int error = 0;
- get_bus(bus);
- down_write(&bus->rwsem);
- list_for_each(node,&bus->devices) {
- struct device * dev = get_device(to_dev(node));
- if (dev) {
- error = callback(dev,data);
- if (prev)
- put_device(prev);
- prev = dev;
- if (error)
- break;
+ bus = get_bus(bus);
+ if (bus) {
+ down_read(&bus->rwsem);
+ list_for_each(node,&bus->devices) {
+ struct device * dev = get_device(to_dev(node));
+ if (dev) {
+ error = callback(dev,data);
+ put_device(dev);
+ if (error)
+ break;
+ }
}
+ up_read(&bus->rwsem);
+ put_bus(bus);
}
- if (prev)
- put_device(prev);
- up_write(&bus->rwsem);
- put_bus(bus);
return error;
}
@@ -70,27 +67,23 @@ int bus_for_each_drv(struct bus_type * bus, void * data,
int (*callback)(struct device_driver * drv, void * data))
{
struct list_head * node;
- struct device_driver * prev = NULL;
int error = 0;
- /* pin bus in memory */
- get_bus(bus);
- down_write(&bus->rwsem);
- list_for_each(node,&bus->drivers) {
- struct device_driver * drv = get_driver(to_drv(node));
- if (drv) {
- error = callback(drv,data);
- if (prev)
- put_driver(prev);
- prev = drv;
- if (error)
- break;
+ bus = get_bus(bus);
+ if (bus) {
+ down_read(&bus->rwsem);
+ list_for_each(node,&bus->drivers) {
+ struct device_driver * drv = get_driver(to_drv(node));
+ if (drv) {
+ error = callback(drv,data);
+ put_driver(drv);
+ if (error)
+ break;
+ }
}
+ up_read(&bus->rwsem);
+ put_bus(bus);
}
- if (prev)
- put_driver(prev);
- up_write(&bus->rwsem);
- put_bus(bus);
return error;
}