source: rtems/cpukit/libdrvmgr/drvmgr_for_each_dev.c @ 7075fb11

5
Last change on this file since 7075fb11 was bb2f220, checked in by Daniel Hellstrom <daniel@…>, on 04/13/15 at 08:49:47

DRVMGR: renamed private drv_mgr and its struct name

  • Property mode set to 100644
File size: 2.1 KB
Line 
1/* Iterate over device tree topology, breadth or depth-first
2 *
3 * COPYRIGHT (c) 2009 Cobham Gaisler AB.
4 *
5 * The license and distribution terms for this file may be
6 * found in the file LICENSE in this distribution or at
7 * http://www.rtems.org/license/LICENSE.
8 */
9
10#include <string.h>
11#include <drvmgr/drvmgr.h>
12#include <drvmgr/drvmgr_list.h>
13#include "drvmgr_internal.h"
14
15/* Traverse device tree breadth-first. Supports up to 31 buses */
16static int drvmgr_for_each_dev_breadth(
17        int (*func)(struct drvmgr_dev *dev, void *arg),
18        void *arg
19        )
20{
21        int ret = 0, i, pos;
22        struct drvmgr_bus *bus, *buses[32];
23        struct drvmgr_dev *dev;
24
25        pos = 0;
26        memset(&buses[0], 0, sizeof(buses));
27        buses[pos++] = drvmgr.root_dev.bus;     /* Get root bus */
28
29        for (i = 0, bus = buses[0]; buses[i]; i++, bus = buses[i]) {
30                dev = bus->children;
31                while (dev) {
32                        ret = func(dev, arg);
33                        if (ret != 0)
34                                break;
35                        if (dev->bus && pos < 31)
36                                buses[pos++] = dev->bus;
37
38                        dev = dev->next_in_bus;
39                }
40        }
41
42        return ret;
43}
44
45/* Traverse device tree depth-first. */
46static int drvmgr_for_each_dev_depth(
47        int (*func)(struct drvmgr_dev *dev, void *arg),
48        void *arg
49        )
50{
51        int ret = 0;
52        struct drvmgr_dev *dev;
53
54        /* Get first device */
55        dev = drvmgr.root_dev.bus->children;
56
57        while (dev) {
58                ret = func(dev, arg);
59                if (ret != 0)
60                        break;
61                if (dev->bus && dev->bus->children) {
62                        dev = dev->bus->children;
63                } else {
64next_dev:
65                        if (dev->next_in_bus == NULL) {
66                                /* Step up one level... back to parent bus */
67                                dev = dev->parent->dev;
68                                if (dev == &drvmgr.root_dev)
69                                        break;
70                                goto next_dev;
71                        } else {
72                                dev = dev->next_in_bus;
73                        }
74                }
75        }
76
77        return ret;
78}
79
80/* Traverse device tree depth-first or breadth-first */
81int drvmgr_for_each_dev(
82        int (*func)(struct drvmgr_dev *dev, void *arg),
83        void *arg,
84        int options
85        )
86{
87        int ret;
88
89        DRVMGR_LOCK_READ();
90
91        /* Get Root Device */
92        if (drvmgr.root_dev.bus->children != NULL) {
93                if (options & DRVMGR_FED_BF)
94                        ret = drvmgr_for_each_dev_breadth(func, arg);
95                else
96                        ret = drvmgr_for_each_dev_depth(func, arg);
97        } else
98                ret = 0;
99
100        DRVMGR_UNLOCK();
101
102        return ret;
103}
Note: See TracBrowser for help on using the repository browser.