[U-Boot] [RFC][PATCH] INIT_FUNC - List madness
Graeme Russ
graeme.russ at gmail.com
Thu Apr 12 14:43:28 CEST 2012
Hello All,
This patch is a little heads-up for my upcomming INIT_FUNC patch series
This is the INIT_FUNC 'engine' - It processes a file which consists of
entries created by the following macros:
#define INIT_FUNC(fn, init_name, man_reqs, pre_reqs, post_reqs) \
static const char __init_func_ ## fn[] __used \
__attribute__((__section__(".initfuncs"))) = \
"(f:" #fn ":" #init_name ":" #man_reqs " | " #pre_reqs " | " #post_reqs ")\n";
#define SKIP_INIT(init_name) \
static const char __skip_init_ ## req[] __used \
__attribute__((__section__(".initfuncs"))) = \
"(s:" #init_name ")\n";
#define REPLACE_INIT(old_func, new_func) \
static const char __replace_init_ ## old_func[] __used \
__attribute__((__section__(".initfuncs"))) = \
"(r:" #old_func ":" #new_func ")\n";
So an 'function' entry will look like
(f:function_name:init_step:mandatory_req_1 mandatory_req_2 | optional_req_1 optional_req_2 | post_req_1 post_req_2)
'init_step' allows multiple functions to be logically grouped (see below)
where:
mandatory_req_1 & mandatory_req_2 are functions or 'init steps' which MUST
exist and will be put in the init sequence before 'function_name'
optional_req_1 & optional_req_2 are functions or 'init steps' which might
exist and (if they do) will be put in the init sequence before
'function_name'
post_req_1 & post_req_2 are are functions or 'init steps' which might
exist and (if they do) will be put in the init sequence after
'function_name'
A 'skip' entry will look like:
(s:function_or_step_name)
The function named 'function_or_step_name' will not be included in the
init sequence. If 'function_or_step_name' is the name of a 'step' then
all functions which make up that step are skipped - This is to replace
a arch-level function (or set of functions) with board specific
alternatives.
A 'replace' entry will look like:
(r:old_name:new_name)
Any function named 'old_name' in the init sequence will be replaced with
'new_name' (this is like overriding a weak function without needing to
make the function weak)
So far this seems to work - It creates a list of functions with each
having a list of dependent functions (steps are expanded so the dependency
lists only have functions in them)
Now I just need to write the code that will order the function list
I think this single patch will more than double the use of struct list_head
in U-Boot. It took a while to get used to it's sematics, but the Linux
kernel list data structure is incredible
Regards,
Graeme
commit 1567e349f774d93e25b3ab2da01cab5e11632916
Author: Graeme Russ <graeme.russ at gmail.com>
Date: Sun Apr 8 22:09:42 2012 +1000
initcall: Some testing
diff --git a/tools/mkinitseq.c b/tools/mkinitseq.c
new file mode 100644
index 0000000..1e2bbb2
--- /dev/null
+++ b/tools/mkinitseq.c
@@ -0,0 +1,870 @@
+/*
+ * (C) Copyright 2012
+ * Graeme Russ <graeme.russ at gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+#include "os_support.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <linux/list.h>
+#include <malloc.h>
+
+#undef MKINITSEQ_DEBUG
+
+#ifdef MKINITSEQ_DEBUG
+#define debug(fmt,args...) printf (fmt ,##args)
+#else
+#define debug(fmt,args...)
+#endif /* MKINITSEQ_DEBUG */
+
+#include <version.h>
+
+struct init_id {
+ struct list_head list;
+ char *name;
+};
+
+struct replace_def {
+ struct list_head list;
+ char *old_name;
+ char *new_name;
+};
+
+struct init_function {
+ struct list_head list;
+
+ char *function_name;
+ char *init_step_name;
+
+ struct list_head mandatory_deps;
+ struct list_head pre_deps;
+ struct list_head post_deps;
+};
+
+struct init_step {
+ struct list_head list;
+
+ char *name;
+
+ struct list_head functions;
+};
+
+struct list_head init_functions;
+struct list_head mandatory_functions;
+struct list_head skip_list;
+struct list_head replace_list;
+struct list_head init_steps;
+
+/* These are the initialisation sequence placeholders */
+static char default_init_reset[] = "f:RESET:RESET: | | SDRAM";
+static char default_init_sdram[] = "f:SDRAM:SDRAM: RESET | | RELOC";
+static char default_init_reloc[] = "f:RELOC:RELOC: SDRAM | | ";
+
+static int add_function_to_init_step(struct init_step *init_step,
+ const char *function_name)
+{
+ struct init_id *init_id;
+
+ init_id = malloc(sizeof(struct init_id));
+
+ if (!init_id)
+ return ENOMEM;
+
+ init_id->name = strdup(function_name);
+
+ if (!init_id->name) {
+ free(init_id);
+ return ENOMEM;
+ }
+
+ list_add(&init_id->list, &init_step->functions);
+
+ return 0;
+}
+
+static int add_init_step_function(const char *init_step_name,
+ const char *function_name)
+{
+ int found = 0;
+ struct list_head *position = NULL ;
+ struct init_step *init_step = NULL ;
+
+
+ list_for_each(position, &init_steps)
+ {
+ init_step = list_entry(position, struct init_step, list);
+
+ if (!strcmp(init_step->name, init_step_name)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ init_step = malloc(sizeof(struct init_step));
+
+ if (!init_step)
+ return ENOMEM;
+
+ init_step->name = strdup(init_step_name);
+
+ if (!init_step->name) {
+ free(init_step);
+ return ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&init_step->functions);
+ list_add(&init_step->list, &init_steps);
+ }
+
+ return add_function_to_init_step(init_step, function_name);
+
+}
+
+static int add_mandatory_init(const char *name)
+{
+ struct list_head *position = NULL ;
+ struct init_id *init_id = NULL ;
+
+ list_for_each(position, &mandatory_functions)
+ {
+ init_id = list_entry(position, struct init_id, list);
+
+ if (!strcmp(init_id->name, name))
+ return 0;
+ }
+
+ init_id = malloc(sizeof(struct init_id));
+
+ if (!init_id)
+ return ENOMEM;
+
+ init_id->name = strdup(name);
+
+ if (!init_id->name) {
+ free(init_id);
+ return ENOMEM;
+ }
+
+ list_add(&init_id->list, &mandatory_functions);
+
+ return 0;
+}
+
+static int process_dep_list(struct list_head *dep_list, char *deps, int mandatory)
+{
+ int err = 0;
+ struct init_id *new_init_id;
+ char *save_ptr;
+
+ char *init_id;
+
+ init_id = strtok_r(deps, " ", &save_ptr);
+
+ while (init_id) {
+ new_init_id = malloc(sizeof(struct init_id));
+
+ if (!new_init_id)
+ return ENOMEM;
+
+ new_init_id->name = strdup(init_id);
+
+ if (!new_init_id->name) {
+ free(new_init_id);
+ return ENOMEM;
+ }
+
+ list_add(&new_init_id->list, dep_list);
+
+ if (mandatory)
+ if (add_mandatory_init(init_id))
+ err = 1;
+
+ init_id = strtok_r(NULL, " ", &save_ptr);
+ };
+
+ return err;
+}
+
+static int process_init_info(struct init_function *init_function, char *deps)
+{
+ char *mandatory_deps;
+ char *pre_deps;
+ char *post_deps;
+ char *save_ptr;
+
+ INIT_LIST_HEAD(&init_function->mandatory_deps);
+ INIT_LIST_HEAD(&init_function->pre_deps);
+ INIT_LIST_HEAD(&init_function->post_deps);
+
+ mandatory_deps = strtok_r(deps, "|", &save_ptr);
+ pre_deps = strtok_r(NULL, "|", &save_ptr);
+ post_deps = strtok_r(NULL, "|", &save_ptr);
+
+ process_dep_list(&init_function->mandatory_deps, mandatory_deps, 1);
+ process_dep_list(&init_function->pre_deps, pre_deps, 0);
+ process_dep_list(&init_function->post_deps, post_deps, 0);
+
+ return 0;
+}
+
+static int check_for_duplicate_function(const char *function_name)
+{
+ struct list_head *position = NULL;
+ struct init_function *init_func = NULL;
+
+ list_for_each(position , &init_functions)
+ {
+ init_func = list_entry(position, struct init_function, list);
+
+ if (!strcmp(function_name, init_func->function_name)) {
+ printf("Duplicate init function: %s\n", function_name);
+
+ return EEXIST;
+ }
+ }
+
+ return 0;
+}
+
+static int add_to_skip_list(const char *function_name)
+{
+ struct list_head *position = NULL;
+ struct init_id *init_id = NULL;
+
+ /* Duplicate skip definitions are OK, but we only want the fist one */
+ list_for_each(position , &skip_list)
+ {
+ init_id = list_entry(position, struct init_id, list);
+
+ if (!strcmp(function_name, init_id->name))
+ return 0;
+ }
+
+ init_id = malloc(sizeof(struct init_id));
+
+ if (!init_id)
+ return ENOMEM;
+
+ init_id->name = strdup(function_name);
+
+ if (!init_id->name) {
+ free(init_id);
+ return ENOMEM;
+ }
+
+ list_add(&init_id->list, &skip_list);
+
+ return 0;
+}
+
+static int add_to_replace_list(const char *old_name, const char *new_name)
+{
+ struct list_head *position = NULL;
+ struct replace_def *replace_def = NULL;
+
+ /* Duplicate replace definitions are not OK */
+ list_for_each(position , &replace_list)
+ {
+ replace_def = list_entry(position, struct replace_def, list);
+
+ if (!strcmp(old_name, replace_def->old_name) ||
+ !strcmp(old_name, replace_def->new_name) ||
+ !strcmp(new_name, replace_def->old_name) ||
+ !strcmp(new_name, replace_def->new_name)) {
+ printf("Multiple replace definitions for function: %s\n",
+ old_name);
+
+ return EEXIST;
+ }
+ }
+
+ replace_def = malloc(sizeof(struct replace_def));
+
+ if (!replace_def)
+ return ENOMEM;
+
+ replace_def->old_name = strdup(old_name);
+ replace_def->new_name = strdup(new_name);
+
+ if ((!replace_def->old_name) || (!replace_def->new_name)) {
+ free(replace_def->old_name);
+ free(replace_def->new_name);
+ free(replace_def);
+ return ENOMEM;
+ }
+
+ list_add(&replace_def->list, &replace_list);
+
+ return 0;
+}
+
+static int process_init_def(char *init_def)
+{
+ struct init_function *new_init_function;
+
+ char *save_ptr;
+ char *def_type;
+ char *function_name;
+ char *init_step_name;
+ char *old_name;
+ char *new_name;
+ char *deps;
+ int err;
+
+ def_type = strtok_r(init_def, ":", &save_ptr);
+
+ switch(def_type[0]) {
+ case 'f':
+ /* An init function definition - Get the function name */
+ function_name = strtok_r(NULL, ":", &save_ptr);
+ init_step_name = strtok_r(NULL, ":", &save_ptr);
+
+ /* Check that the function is not already included */
+ err = check_for_duplicate_function(function_name);
+
+ if (err)
+ return err;
+
+ err = add_init_step_function(init_step_name, function_name);
+
+ if (err)
+ return err;
+
+ /* Create a list node for the new init function */
+ new_init_function = malloc(sizeof(struct init_function));
+
+ if (!new_init_function)
+ return ENOMEM;
+
+ new_init_function->function_name = strdup(function_name);
+ new_init_function->init_step_name = strdup(init_step_name);
+
+ if ((!new_init_function->function_name) ||
+ (!new_init_function->init_step_name)) {
+ free(new_init_function->function_name);
+ free(new_init_function->init_step_name);
+ free(new_init_function);
+ return ENOMEM;
+ }
+
+ /* Add the new function to the init function list */
+ list_add(&new_init_function->list, &init_functions);
+
+ /* Process the new functions dependencies */
+ deps = strtok_r(NULL, ":", &save_ptr);
+ return process_init_info(new_init_function, deps);
+
+ break;
+
+ case 's':
+ function_name = strtok_r(NULL, ":", &save_ptr);
+ return add_to_skip_list(function_name);
+
+ break;
+
+ case 'r':
+ old_name = strtok_r(NULL, ":", &save_ptr);
+ new_name = strtok_r(NULL, ":", &save_ptr);
+ return add_to_replace_list(old_name, new_name);
+
+ break;
+
+ default:
+ printf("Unknown Init Type: %s", def_type);
+ break;
+ }
+
+ return 0;
+}
+
+static int build_function_list(char *buffer)
+{
+ int err = 0;
+
+ char *save_ptr;
+
+ char *init_def;
+
+ if (process_init_def(default_init_reset) ||
+ process_init_def(default_init_sdram) ||
+ process_init_def(default_init_reloc))
+ err = 1;
+
+ init_def = strtok_r(buffer, "()", &save_ptr);
+
+ while (init_def) {
+ if (process_init_def(init_def))
+ err = 1;
+
+ /* Skip the garbage between init definitions */
+ init_def = strtok_r(NULL, "(", &save_ptr);
+
+ /* Get the next init definition */
+ init_def = strtok_r(NULL, ")", &save_ptr);
+ };
+
+ return err;
+}
+
+
+static int open_file(const char *file, char **buffer, int *buf_size)
+{
+ struct stat sbuf;
+ int file_ptr;
+
+ char *ptr;
+
+ if ((file_ptr = open(file, O_RDONLY|O_BINARY)) < 0) {
+ fprintf (stderr, "Can't open %s: %s\n", file, strerror(errno));
+ return errno;
+ }
+
+ if (fstat(file_ptr, &sbuf) < 0) {
+ fprintf (stderr, "Can't stat %s: %s\n", file, strerror(errno));
+ return errno;
+ }
+
+ ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, file_ptr, 0);
+ if (ptr == MAP_FAILED) {
+ fprintf (stderr, "Can't read %s: %s\n", file, strerror(errno));
+ return errno;
+ }
+
+ *buffer = malloc(sbuf.st_size + 1);
+
+ if (!*buffer)
+ return ENOMEM;
+
+ *buf_size = sbuf.st_size;
+ memcpy(*buffer, ptr, sbuf.st_size);
+ (*buffer)[sbuf.st_size] = 0x00;
+
+ munmap((void *)ptr, sbuf.st_size);
+ close (file_ptr);
+
+ return 0;
+}
+
+static int check_mandatory_list(void)
+{
+ int err = 0;
+ struct list_head *position = NULL;
+ struct list_head *q = NULL;
+ struct list_head *sub_position = NULL;
+ struct init_function *init_func = NULL;
+ struct init_id *init_id = NULL;
+
+
+ /* Remove functions that exist from the mandatory functions list */
+ list_for_each_safe(position, q, &mandatory_functions)
+ {
+ init_id = list_entry(position, struct init_id, list);
+
+ list_for_each(sub_position , &init_functions)
+ {
+ init_func = list_entry(sub_position,
+ struct init_function,
+ list);
+
+ if (!strcmp(init_id->name, init_func->function_name) ||
+ !strcmp(init_id->name, init_func->init_step_name))
+ {
+ free(init_id->name);
+
+ list_del(position);
+ free(init_id);
+ }
+ }
+
+ }
+
+ list_for_each(position , &mandatory_functions)
+ {
+ init_id = list_entry(position, struct init_id, list);
+
+ printf("Missing mandatory function: %s\n", init_id->name);
+ err = 1;
+ }
+
+ return err;
+}
+
+static int crosscheck_skip_replace(void)
+{
+ int err = 0;
+
+ /*
+ * The same function cannot appear in both the skip list and the
+ * replace list (either as the new or old function name)
+ */
+ struct list_head *skip_pos = NULL;
+ struct list_head *replace_pos = NULL;
+
+ struct init_id *skip_def = NULL;
+ struct replace_def *replace_def = NULL;
+
+ list_for_each(skip_pos, &skip_list)
+ {
+ skip_def = list_entry(skip_pos, struct init_id, list);
+
+ list_for_each(replace_pos , &replace_list)
+ {
+ replace_def = list_entry(replace_pos,
+ struct replace_def,
+ list);
+
+ if (!strcmp(skip_def->name, replace_def->old_name) ||
+ !strcmp(skip_def->name, replace_def->new_name))
+ {
+ printf("Function %s in both skip and replace definitions\n",
+ skip_def->name);
+
+ err = 1;
+ }
+ }
+
+ }
+
+ return err;
+}
+
+static void free_dep_list(struct list_head *dep_list)
+{
+ struct init_id *tmp;
+
+ while(!list_empty(dep_list)) {
+
+ tmp = list_first_entry(dep_list, struct init_id, list);
+
+ printf("Deleting %s\n", tmp->name);
+
+ free(tmp->name);
+ list_del(&tmp->list);
+ }
+
+}
+
+static int process_skip_list(void)
+{
+ int err = 0;
+
+ /*
+ * The same function cannot appear in both the skip list and the
+ * replace list (either as the new or old function name)
+ */
+ struct list_head *skip_pos = NULL;
+ struct init_id *skip_def = NULL;
+
+ struct list_head *func_pos = NULL;
+ struct list_head *q = NULL;
+ struct init_function *func_def = NULL;
+
+ list_for_each(skip_pos, &skip_list)
+ {
+ skip_def = list_entry(skip_pos, struct init_id, list);
+
+ list_for_each_safe(func_pos, q, &init_functions) {
+ func_def = list_entry(func_pos,
+ struct init_function,
+ list);
+
+ if (!strcmp(func_def->function_name, skip_def->name) ||
+ !strcmp(func_def->init_step_name, skip_def->name))
+ {
+ free(func_def->function_name);
+ free(func_def->init_step_name);
+
+ free_dep_list(&func_def->mandatory_deps);
+ free_dep_list(&func_def->post_deps);
+ free_dep_list(&func_def->pre_deps);
+
+ list_del(func_pos);
+
+ free(func_def);
+ }
+ }
+ }
+
+ return err;
+}
+
+static int process_replace_list(void)
+{
+ int err = 0;
+
+ /*
+ * The same function cannot appear in both the skip list and the
+ * replace list (either as the new or old function name)
+ */
+ struct list_head *func_pos = NULL;
+ struct list_head *replace_pos = NULL;
+
+ struct init_function *func_def = NULL;
+ struct replace_def *replace_def = NULL;
+
+ int found;
+
+ list_for_each(replace_pos, &replace_list)
+ {
+ replace_def = list_entry(replace_pos, struct replace_def, list);
+
+ found = 0;
+
+ list_for_each(func_pos , &init_functions)
+ {
+ func_def = list_entry(func_pos,
+ struct init_function,
+ list);
+
+ if (!strcmp(func_def->function_name,
+ replace_def->old_name)) {
+ found = 1;
+ free(func_def->function_name);
+ func_def->function_name = strdup(replace_def->new_name);
+
+ if (!func_def->function_name) {
+ printf("strdup() failed!\n");
+ err = 1;
+ }
+ }
+ }
+ if (!found) {
+ printf("Replace function %s not in init list\n",
+ replace_def->old_name);
+ err = 1;
+ }
+ }
+
+ return err;
+}
+
+static int insert_into_dep_list(struct list_head *dep_list,
+ struct init_step *init_step)
+{
+ struct list_head *position = NULL ;
+ struct init_id *init_id = NULL ;
+ struct init_id *new_init_id;
+
+ list_for_each(position, &init_step->functions)
+ {
+ init_id = list_entry(position, struct init_id, list);
+
+ new_init_id = malloc(sizeof(struct init_id));
+
+ if (!new_init_id)
+ return ENOMEM;
+
+ new_init_id->name = strdup(init_id->name);
+
+ if (!new_init_id->name) {
+ free(new_init_id);
+ return ENOMEM;
+ }
+
+ list_add(&new_init_id->list, dep_list);
+ }
+
+ return 0;
+}
+
+static int expand_dep_list(struct list_head *dep_list)
+{
+ int err = 0;
+
+ struct list_head *position = NULL ;
+ struct init_id *init_id = NULL ;
+ struct list_head *q = NULL;
+
+ struct list_head *step_pos = NULL ;
+ struct init_step *init_step = NULL ;
+
+
+ list_for_each_safe(position, q, dep_list) {
+ init_id = list_entry(position, struct init_id, list);
+
+ /* Is this a 'step' rather than a 'function' */
+ list_for_each(step_pos, &init_steps)
+ {
+ init_step = list_entry(step_pos,
+ struct init_step,
+ list);
+
+ if (!strcmp(init_step->name, init_id->name)) {
+ /*
+ * Replace this init id (which is a 'step'
+ * with the list of step functions
+ */
+ free(init_id->name);
+
+ list_del(position);
+ free(init_id);
+
+ err = insert_into_dep_list(dep_list,
+ init_step);
+
+ if (err)
+ return err;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int expand_dep_lists(void)
+{
+ int err = 0;
+
+ struct list_head *position = NULL ;
+ struct init_function *init_func = NULL ;
+
+ list_for_each(position , &init_functions)
+ {
+ init_func = list_entry(position, struct init_function, list);
+
+ err = expand_dep_list(&init_func->mandatory_deps);
+
+ if (err)
+ return err;
+
+ err = expand_dep_list(&init_func->pre_deps);
+
+ if (err)
+ return err;
+
+ err = expand_dep_list(&init_func->post_deps);
+
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+int main(int argc, const char **argv)
+{
+ int err;
+ int buf_size;
+ char *local_buffer = NULL;
+ char *x;
+
+ INIT_LIST_HEAD(&init_functions);
+ INIT_LIST_HEAD(&mandatory_functions);
+ INIT_LIST_HEAD(&skip_list);
+ INIT_LIST_HEAD(&replace_list);
+ INIT_LIST_HEAD(&init_steps);
+
+ printf("Generating init sequence from %s\n", argv[1]);
+
+ /* Read the init function definitions into a local buffer */
+ err = open_file(argv[1], &local_buffer, &buf_size);
+
+ if(err || !local_buffer)
+ exit(EXIT_FAILURE);
+
+ /*
+ * Convert all the NULLs (except the last one) to non-NULL so
+ * the buffer can be processed using standard string functions
+ */
+ for(x=local_buffer; x != &local_buffer[buf_size]; x++) {
+ if(*x == 0x00)
+ *x = 0x01;
+ }
+
+ if (build_function_list(local_buffer))
+ exit(EXIT_FAILURE);
+
+ if (check_mandatory_list())
+ exit(EXIT_FAILURE);
+
+ if (crosscheck_skip_replace())
+ exit(EXIT_FAILURE);
+
+ if (process_skip_list())
+ exit(EXIT_FAILURE);
+
+ if (process_replace_list())
+ exit(EXIT_FAILURE);
+
+ if (expand_dep_lists())
+ exit(EXIT_FAILURE);
+
+ /* OK - Time to build the init sequence :) */
+
+
+ printf("*** Dumping Lists ***\n");
+
+
+ struct list_head *position = NULL ;
+ struct init_function *init_func = NULL ;
+
+ struct list_head *sub_position = NULL ;
+ struct init_id *init_id = NULL ;
+
+ list_for_each(position , &init_functions)
+ {
+ init_func = list_entry(position, struct init_function, list);
+
+ printf("Function Name = %s\n", init_func->function_name);
+ printf("Init Step Name = %s\n", init_func->init_step_name);
+
+ printf(" Mandatory Deps\n");
+ list_for_each(sub_position , &init_func->mandatory_deps)
+ {
+ init_id = list_entry(sub_position, struct init_id, list);
+ printf(" - %s\n", init_id->name);
+ }
+
+ printf(" Pre Deps\n");
+ list_for_each(sub_position , &init_func->pre_deps)
+ {
+ init_id = list_entry(sub_position, struct init_id, list);
+ printf(" - %s\n", init_id->name);
+ }
+
+ printf(" Post Deps\n");
+ list_for_each(sub_position , &init_func->post_deps)
+ {
+ init_id = list_entry(sub_position, struct init_id, list);
+ printf(" - %s\n", init_id->name);
+ }
+ }
+
+
+ free(local_buffer);
+ exit (EXIT_SUCCESS);
+}
More information about the U-Boot
mailing list