4 * Copyright (c) Intel Corporation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "spdk_internal/event.h"
40 static TAILQ_HEAD(spdk_subsystem_list
, spdk_subsystem
) g_subsystems
=
41 TAILQ_HEAD_INITIALIZER(g_subsystems
);
42 static TAILQ_HEAD(subsystem_depend
, spdk_subsystem_depend
) g_depends
=
43 TAILQ_HEAD_INITIALIZER(g_depends
);
46 spdk_add_subsystem(struct spdk_subsystem
*subsystem
)
48 TAILQ_INSERT_TAIL(&g_subsystems
, subsystem
, tailq
);
52 spdk_add_subsystem_depend(struct spdk_subsystem_depend
*depend
)
54 TAILQ_INSERT_TAIL(&g_depends
, depend
, tailq
);
57 static struct spdk_subsystem
*
58 spdk_subsystem_find(struct spdk_subsystem_list
*list
, const char *name
)
60 struct spdk_subsystem
*iter
;
62 TAILQ_FOREACH(iter
, list
, tailq
) {
63 if (strcmp(name
, iter
->name
) == 0) {
74 bool depends_on
, depends_on_sorted
;
75 struct spdk_subsystem
*subsystem
, *subsystem_tmp
;
76 struct spdk_subsystem_depend
*subsystem_dep
;
78 struct spdk_subsystem_list subsystems_list
= TAILQ_HEAD_INITIALIZER(subsystems_list
);
80 while (!TAILQ_EMPTY(&g_subsystems
)) {
81 TAILQ_FOREACH_SAFE(subsystem
, &g_subsystems
, tailq
, subsystem_tmp
) {
83 TAILQ_FOREACH(subsystem_dep
, &g_depends
, tailq
) {
84 if (strcmp(subsystem
->name
, subsystem_dep
->name
) == 0) {
86 depends_on_sorted
= !!spdk_subsystem_find(&subsystems_list
, subsystem_dep
->depends_on
);
87 if (depends_on_sorted
)
93 if (depends_on
== false) {
94 TAILQ_REMOVE(&g_subsystems
, subsystem
, tailq
);
95 TAILQ_INSERT_TAIL(&subsystems_list
, subsystem
, tailq
);
97 if (depends_on_sorted
== true) {
98 TAILQ_REMOVE(&g_subsystems
, subsystem
, tailq
);
99 TAILQ_INSERT_TAIL(&subsystems_list
, subsystem
, tailq
);
105 TAILQ_FOREACH_SAFE(subsystem
, &subsystems_list
, tailq
, subsystem_tmp
) {
106 TAILQ_REMOVE(&subsystems_list
, subsystem
, tailq
);
107 TAILQ_INSERT_TAIL(&g_subsystems
, subsystem
, tailq
);
112 spdk_subsystem_init(void)
115 struct spdk_subsystem
*subsystem
;
116 struct spdk_subsystem_depend
*dep
;
118 /* Verify that all dependency name and depends_on subsystems are registered */
119 TAILQ_FOREACH(dep
, &g_depends
, tailq
) {
120 if (!spdk_subsystem_find(&g_subsystems
, dep
->name
)) {
121 fprintf(stderr
, "subsystem %s is missing\n", dep
->name
);
124 if (!spdk_subsystem_find(&g_subsystems
, dep
->depends_on
)) {
125 fprintf(stderr
, "subsystem %s dependency %s is missing\n",
126 dep
->name
, dep
->depends_on
);
133 TAILQ_FOREACH(subsystem
, &g_subsystems
, tailq
) {
134 if (subsystem
->init
) {
135 rc
= subsystem
->init();
144 spdk_subsystem_fini(void)
147 struct spdk_subsystem
*cur
;
149 cur
= TAILQ_LAST(&g_subsystems
, spdk_subsystem_list
);
157 cur
= TAILQ_PREV(cur
, spdk_subsystem_list
, tailq
);
164 spdk_subsystem_config(FILE *fp
)
166 struct spdk_subsystem
*subsystem
;
168 TAILQ_FOREACH(subsystem
, &g_subsystems
, tailq
) {
169 if (subsystem
->config
)
170 subsystem
->config(fp
);