Commit ec0a28d2 authored by Patrick Mochel's avatar Patrick Mochel

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.
 
parent 557aebd2
......@@ -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);
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);
if (prev)
put_device(prev);
prev = dev;
put_device(dev);
if (error)
break;
}
}
if (prev)
put_device(prev);
up_write(&bus->rwsem);
up_read(&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);
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);
if (prev)
put_driver(prev);
prev = drv;
put_driver(drv);
if (error)
break;
}
}
if (prev)
put_driver(prev);
up_write(&bus->rwsem);
up_read(&bus->rwsem);
put_bus(bus);
}
return error;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment