diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2008-05-22 17:21:08 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-07-21 21:54:47 -0700 |
commit | 93562b537659fc0f63920fd4d9d24f54e434f4c4 (patch) | |
tree | 6b7678f91af838f0c1fb85105b68b6c7f7e027e0 /drivers/base | |
parent | 4e10673944a5c386378ff9d692ae37e19993f9d5 (diff) | |
download | linux-93562b537659fc0f63920fd4d9d24f54e434f4c4.tar.gz linux-93562b537659fc0f63920fd4d9d24f54e434f4c4.tar.bz2 linux-93562b537659fc0f63920fd4d9d24f54e434f4c4.zip |
Driver Core: add ability for class_for_each_device to start in middle of list
This mirrors the functionality that driver_for_each_device has as well.
We add a start variable, and all callers of the function are fixed up at
the same time.
The block layer will be using this new functionality in a follow-on
patch.
Cc: Kay Sievers <kay.sievers@vrfy.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/base')
-rw-r--r-- | drivers/base/class.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/base/class.c b/drivers/base/class.c index 71ce3ff6bdf5..2eb7048003a8 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -256,11 +256,14 @@ char *make_class_name(const char *name, struct kobject *kobj) /** * class_for_each_device - device iterator * @class: the class we're iterating + * @start: the device to start with in the list, if any. * @data: data for the callback * @fn: function to be called for each device * * Iterate over @class's list of devices, and call @fn for each, - * passing it @data. + * passing it @data. If @start is set, the list iteration will start + * there, otherwise if it is NULL, the iteration starts at the + * beginning of the list. * * We check the return of @fn each time. If it returns anything * other than 0, we break out and return that value. @@ -269,8 +272,8 @@ char *make_class_name(const char *name, struct kobject *kobj) * re-acquired in @fn, otherwise it will self-deadlocking. For * example, calls to add or remove class members would be verboten. */ -int class_for_each_device(struct class *class, void *data, - int (*fn)(struct device *, void *)) +int class_for_each_device(struct class *class, struct device *start, + void *data, int (*fn)(struct device *, void *)) { struct device *dev; int error = 0; @@ -279,12 +282,14 @@ int class_for_each_device(struct class *class, void *data, return -EINVAL; down(&class->sem); list_for_each_entry(dev, &class->devices, node) { + if (start) { + if (start == dev) + start = NULL; + continue; + } dev = get_device(dev); - if (dev) { - error = fn(dev, data); - put_device(dev); - } else - error = -ENODEV; + error = fn(dev, data); + put_device(dev); if (error) break; } |