]> git.hungrycats.org Git - linux/commitdiff
Fix "bus_for_each_dev()" and "bus_for_each_drv()", which did not
authorLinus Torvalds <torvalds@home.osdl.org>
Thu, 12 Feb 2004 05:00:34 +0000 (21:00 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Thu, 12 Feb 2004 05:00:34 +0000 (21:00 -0800)
correctly handle the "restart from this device/driver" case, and
caused oopses with ieee1394.

This just uses "list_for_each_entry_continue()" instead.

Add helper macro to make usage of "list_for_each_entry_continue()"
a bit more readable.

drivers/base/bus.c
include/linux/list.h

index 28982a1c4371b334e9876dc49450082e6ab64dae..5a2b6b74daf1b01828ba2c61a123f7e164e2d37f 100644 (file)
@@ -158,17 +158,19 @@ decl_subsys(bus,&ktype_bus,NULL);
 int bus_for_each_dev(struct bus_type * bus, struct device * start, 
                     void * data, int (*fn)(struct device *, void *))
 {
-       struct list_head * head, * entry;
+       struct device *dev;
+       struct list_head * head;
        int error = 0;
 
        if (!(bus = get_bus(bus)))
                return -EINVAL;
 
-       head = start ? &start->bus_list : &bus->devices.list;
+       head = &bus->devices.list;
+       dev = list_prepare_entry(start, head, bus_list);
 
        down_read(&bus->subsys.rwsem);
-       list_for_each(entry,head) {
-               struct device * dev = get_device(to_dev(entry));
+       list_for_each_entry_continue(dev, head, bus_list) {
+               get_device(dev);
                error = fn(dev,data);
                put_device(dev);
                if (error)
@@ -202,17 +204,19 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start,
 int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
                     void * data, int (*fn)(struct device_driver *, void *))
 {
-       struct list_head * head, * entry;
+       struct list_head * head;
+       struct device_driver *drv;
        int error = 0;
 
        if(!(bus = get_bus(bus)))
                return -EINVAL;
 
-       head = start ? &start->kobj.entry : &bus->drivers.list;
+       head = &bus->drivers.list;
+       drv = list_prepare_entry(start, head, kobj.entry);
 
        down_read(&bus->subsys.rwsem);
-       list_for_each(entry,head) {
-               struct device_driver * drv = get_driver(to_drv(entry));
+       list_for_each_entry_continue(drv, head, kobj.entry) {
+               get_driver(drv);
                error = fn(drv,data);
                put_driver(drv);
                if(error)
index 9a5df31af22e678f258c8ca0a3e5c8701377bd9e..5388098449ccd82966faedf70a9eb0aae984219e 100644 (file)
@@ -343,6 +343,16 @@ static inline void list_splice_init(struct list_head *list,
             pos = list_entry(pos->member.prev, typeof(*pos), member),  \
                     prefetch(pos->member.prev))
 
+/**
+ * list_prepare_entry - prepare a pos entry for use as a start point in
+ *                     list_for_each_entry_continue
+ * @pos:       the type * to use as a start point
+ * @head:      the head of the list
+ * @member:    the name of the list_struct within the struct.
+ */
+#define list_prepare_entry(pos, head, member) \
+       ((pos) ? : list_entry(head, typeof(*pos), member))
+
 /**
  * list_for_each_entry_continue -      iterate over list of given type
  *                     continuing after existing point