Commit 695794ae0c5bdd9bd06e35b118801e2e9be04f9e
1 parent
93562b5376
Exists in
master
and in
39 other branches
Driver Core: add ability for class_find_device to start in middle of list
This mirrors the functionality that driver_find_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>
Showing 8 changed files with 28 additions and 19 deletions Side-by-side Diff
drivers/base/class.c
... | ... | @@ -302,6 +302,7 @@ |
302 | 302 | /** |
303 | 303 | * class_find_device - device iterator for locating a particular device |
304 | 304 | * @class: the class we're iterating |
305 | + * @start: Device to begin with | |
305 | 306 | * @data: data for the match function |
306 | 307 | * @match: function to check device |
307 | 308 | * |
... | ... | @@ -319,8 +320,9 @@ |
319 | 320 | * re-acquired in @match, otherwise it will self-deadlocking. For |
320 | 321 | * example, calls to add or remove class members would be verboten. |
321 | 322 | */ |
322 | -struct device *class_find_device(struct class *class, void *data, | |
323 | - int (*match)(struct device *, void *)) | |
323 | +struct device *class_find_device(struct class *class, struct device *start, | |
324 | + void *data, | |
325 | + int (*match)(struct device *, void *)) | |
324 | 326 | { |
325 | 327 | struct device *dev; |
326 | 328 | int found = 0; |
327 | 329 | |
328 | 330 | |
... | ... | @@ -330,15 +332,17 @@ |
330 | 332 | |
331 | 333 | down(&class->sem); |
332 | 334 | list_for_each_entry(dev, &class->devices, node) { |
335 | + if (start) { | |
336 | + if (start == dev) | |
337 | + start = NULL; | |
338 | + continue; | |
339 | + } | |
333 | 340 | dev = get_device(dev); |
334 | - if (dev) { | |
335 | - if (match(dev, data)) { | |
336 | - found = 1; | |
337 | - break; | |
338 | - } else | |
339 | - put_device(dev); | |
340 | - } else | |
341 | + if (match(dev, data)) { | |
342 | + found = 1; | |
341 | 343 | break; |
344 | + } else | |
345 | + put_device(dev); | |
342 | 346 | } |
343 | 347 | up(&class->sem); |
344 | 348 |
drivers/base/core.c
drivers/ieee1394/nodemgr.c
... | ... | @@ -754,7 +754,8 @@ |
754 | 754 | */ |
755 | 755 | mutex_lock(&nodemgr_serialize_remove_uds); |
756 | 756 | for (;;) { |
757 | - dev = class_find_device(&nodemgr_ud_class, ne, __match_ne); | |
757 | + dev = class_find_device(&nodemgr_ud_class, NULL, ne, | |
758 | + __match_ne); | |
758 | 759 | if (!dev) |
759 | 760 | break; |
760 | 761 | ud = container_of(dev, struct unit_directory, unit_dev); |
... | ... | @@ -901,7 +902,8 @@ |
901 | 902 | struct device *dev; |
902 | 903 | struct node_entry *ne; |
903 | 904 | |
904 | - dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid); | |
905 | + dev = class_find_device(&nodemgr_ne_class, NULL, &guid, | |
906 | + __match_ne_guid); | |
905 | 907 | if (!dev) |
906 | 908 | return NULL; |
907 | 909 | ne = container_of(dev, struct node_entry, node_dev); |
... | ... | @@ -940,7 +942,8 @@ |
940 | 942 | param.host = host; |
941 | 943 | param.nodeid = nodeid; |
942 | 944 | |
943 | - dev = class_find_device(&nodemgr_ne_class, ¶m, __match_ne_nodeid); | |
945 | + dev = class_find_device(&nodemgr_ne_class, NULL, ¶m, | |
946 | + __match_ne_nodeid); | |
944 | 947 | if (!dev) |
945 | 948 | return NULL; |
946 | 949 | ne = container_of(dev, struct node_entry, node_dev); |
drivers/rtc/interface.c
drivers/scsi/hosts.c
... | ... | @@ -466,7 +466,8 @@ |
466 | 466 | struct device *cdev; |
467 | 467 | struct Scsi_Host *shost = ERR_PTR(-ENXIO); |
468 | 468 | |
469 | - cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match); | |
469 | + cdev = class_find_device(&shost_class, NULL, &hostnum, | |
470 | + __scsi_host_match); | |
470 | 471 | if (cdev) { |
471 | 472 | shost = scsi_host_get(class_to_shost(cdev)); |
472 | 473 | put_device(cdev); |
drivers/scsi/scsi_transport_iscsi.c
... | ... | @@ -170,7 +170,7 @@ |
170 | 170 | int err; |
171 | 171 | |
172 | 172 | for (id = 1; id < ISCSI_MAX_EPID; id++) { |
173 | - dev = class_find_device(&iscsi_endpoint_class, &id, | |
173 | + dev = class_find_device(&iscsi_endpoint_class, NULL, &id, | |
174 | 174 | iscsi_match_epid); |
175 | 175 | if (!dev) |
176 | 176 | break; |
... | ... | @@ -222,7 +222,7 @@ |
222 | 222 | struct iscsi_endpoint *ep; |
223 | 223 | struct device *dev; |
224 | 224 | |
225 | - dev = class_find_device(&iscsi_endpoint_class, &handle, | |
225 | + dev = class_find_device(&iscsi_endpoint_class, NULL, &handle, | |
226 | 226 | iscsi_match_epid); |
227 | 227 | if (!dev) |
228 | 228 | return NULL; |
drivers/spi/spi.c
... | ... | @@ -502,7 +502,7 @@ |
502 | 502 | struct device *dev; |
503 | 503 | struct spi_master *master = NULL; |
504 | 504 | |
505 | - dev = class_find_device(&spi_master_class, &bus_num, | |
505 | + dev = class_find_device(&spi_master_class, NULL, &bus_num, | |
506 | 506 | __spi_master_match); |
507 | 507 | if (dev) |
508 | 508 | master = container_of(dev, struct spi_master, dev); |
include/linux/device.h
... | ... | @@ -213,7 +213,8 @@ |
213 | 213 | extern int class_for_each_device(struct class *class, struct device *start, |
214 | 214 | void *data, |
215 | 215 | int (*fn)(struct device *dev, void *data)); |
216 | -extern struct device *class_find_device(struct class *class, void *data, | |
216 | +extern struct device *class_find_device(struct class *class, | |
217 | + struct device *start, void *data, | |
217 | 218 | int (*match)(struct device *, void *)); |
218 | 219 | |
219 | 220 | struct class_attribute { |