Commit 465c7a3a authored by mochel@digitalimplant.org's avatar mochel@digitalimplant.org Committed by Greg Kroah-Hartman

[PATCH] Add a klist to struct bus_type for its devices.

- Use it for bus_for_each_dev().
- Use the klist spinlock instead of the bus rwsem.
Signed-off-by: default avatarPatrick Mochel <mochel@digitalimplant.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9a19fea4
...@@ -134,28 +134,6 @@ static struct kobj_type ktype_bus = { ...@@ -134,28 +134,6 @@ static struct kobj_type ktype_bus = {
decl_subsys(bus, &ktype_bus, NULL); decl_subsys(bus, &ktype_bus, NULL);
static int __bus_for_each_dev(struct bus_type *bus, struct device *start,
void *data, int (*fn)(struct device *, void *))
{
struct list_head *head;
struct device *dev;
int error = 0;
if (!(bus = get_bus(bus)))
return -EINVAL;
head = &bus->devices.list;
dev = list_prepare_entry(start, head, bus_list);
list_for_each_entry_continue(dev, head, bus_list) {
get_device(dev);
error = fn(dev, data);
put_device(dev);
if (error)
break;
}
put_bus(bus);
return error;
}
static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start, static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
void * data, int (*fn)(struct device_driver *, void *)) void * data, int (*fn)(struct device_driver *, void *))
...@@ -180,6 +158,13 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start, ...@@ -180,6 +158,13 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
return error; return error;
} }
static struct device * next_device(struct klist_iter * i)
{
struct klist_node * n = klist_next(i);
return n ? container_of(n, struct device, knode_bus) : NULL;
}
/** /**
* bus_for_each_dev - device iterator. * bus_for_each_dev - device iterator.
* @bus: bus type. * @bus: bus type.
...@@ -203,12 +188,19 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start, ...@@ -203,12 +188,19 @@ static int __bus_for_each_drv(struct bus_type *bus, struct device_driver *start,
int bus_for_each_dev(struct bus_type * bus, struct device * start, int bus_for_each_dev(struct bus_type * bus, struct device * start,
void * data, int (*fn)(struct device *, void *)) void * data, int (*fn)(struct device *, void *))
{ {
int ret; struct klist_iter i;
struct device * dev;
int error = 0;
down_read(&bus->subsys.rwsem); if (!bus)
ret = __bus_for_each_dev(bus, start, data, fn); return -EINVAL;
up_read(&bus->subsys.rwsem);
return ret; klist_iter_init_node(&bus->klist_devices, &i,
(start ? &start->knode_bus : NULL));
while ((dev = next_device(&i)) && !error)
error = fn(dev, data);
klist_iter_exit(&i);
return error;
} }
/** /**
...@@ -293,6 +285,7 @@ int bus_add_device(struct device * dev) ...@@ -293,6 +285,7 @@ int bus_add_device(struct device * dev)
list_add_tail(&dev->bus_list, &dev->bus->devices.list); list_add_tail(&dev->bus_list, &dev->bus->devices.list);
device_attach(dev); device_attach(dev);
up_write(&dev->bus->subsys.rwsem); up_write(&dev->bus->subsys.rwsem);
klist_add_tail(&bus->klist_devices, &dev->knode_bus);
device_add_attrs(bus, dev); device_add_attrs(bus, dev);
sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id); sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus"); sysfs_create_link(&dev->kobj, &dev->bus->subsys.kset.kobj, "bus");
...@@ -315,6 +308,7 @@ void bus_remove_device(struct device * dev) ...@@ -315,6 +308,7 @@ void bus_remove_device(struct device * dev)
sysfs_remove_link(&dev->kobj, "bus"); sysfs_remove_link(&dev->kobj, "bus");
sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id); sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);
device_remove_attrs(dev->bus, dev); device_remove_attrs(dev->bus, dev);
klist_remove(&dev->knode_bus);
down_write(&dev->bus->subsys.rwsem); down_write(&dev->bus->subsys.rwsem);
pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id); pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);
device_release_driver(dev); device_release_driver(dev);
...@@ -439,9 +433,7 @@ int bus_rescan_devices(struct bus_type * bus) ...@@ -439,9 +433,7 @@ int bus_rescan_devices(struct bus_type * bus)
{ {
int count = 0; int count = 0;
down_write(&bus->subsys.rwsem); bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
__bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);
up_write(&bus->subsys.rwsem);
return count; return count;
} }
...@@ -542,6 +534,8 @@ int bus_register(struct bus_type * bus) ...@@ -542,6 +534,8 @@ int bus_register(struct bus_type * bus)
retval = kset_register(&bus->drivers); retval = kset_register(&bus->drivers);
if (retval) if (retval)
goto bus_drivers_fail; goto bus_drivers_fail;
klist_init(&bus->klist_devices);
bus_add_attrs(bus); bus_add_attrs(bus);
pr_debug("bus type '%s' registered\n", bus->name); pr_debug("bus type '%s' registered\n", bus->name);
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/ioport.h> #include <linux/ioport.h>
#include <linux/kobject.h> #include <linux/kobject.h>
#include <linux/klist.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/module.h> #include <linux/module.h>
...@@ -51,6 +52,7 @@ struct bus_type { ...@@ -51,6 +52,7 @@ struct bus_type {
struct subsystem subsys; struct subsystem subsys;
struct kset drivers; struct kset drivers;
struct kset devices; struct kset devices;
struct klist klist_devices;
struct bus_attribute * bus_attrs; struct bus_attribute * bus_attrs;
struct device_attribute * dev_attrs; struct device_attribute * dev_attrs;
...@@ -262,6 +264,7 @@ struct device { ...@@ -262,6 +264,7 @@ struct device {
struct list_head bus_list; /* node in bus's list */ struct list_head bus_list; /* node in bus's list */
struct list_head driver_list; struct list_head driver_list;
struct list_head children; struct list_head children;
struct klist_node knode_bus;
struct device * parent; struct device * parent;
struct kobject kobj; struct kobject kobj;
......
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