24 #define TRACE(c, ...) \
26 fprintf(stderr, "=== %s: ", (c)->name); \
27 fprintf(stderr, __VA_ARGS__); \
28 fprintf(stderr, "\n"); \
31 #define TRACE(c, fmt, ...) do { } while (0)
61 #define CHECK_ENTRY(nm, tfn, nfn, pfn, d, w, e, ...) \
62 static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
63 static struct check nm = { \
71 .status = UNCHECKED, \
72 .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
73 .prereq = nm##_prereqs, \
75 #define WARNING(nm, tfn, nfn, pfn, d, ...) \
76 CHECK_ENTRY(nm, tfn, nfn, pfn, d, true, false, __VA_ARGS__)
77 #define ERROR(nm, tfn, nfn, pfn, d, ...) \
78 CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, true, __VA_ARGS__)
79 #define CHECK(nm, tfn, nfn, pfn, d, ...) \
80 CHECK_ENTRY(nm, tfn, nfn, pfn, d, false, false, __VA_ARGS__)
82 #define TREE_WARNING(nm, d, ...) \
83 WARNING(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
84 #define TREE_ERROR(nm, d, ...) \
85 ERROR(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
86 #define TREE_CHECK(nm, d, ...) \
87 CHECK(nm, check_##nm, NULL, NULL, d, __VA_ARGS__)
88 #define NODE_WARNING(nm, d, ...) \
89 WARNING(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
90 #define NODE_ERROR(nm, d, ...) \
91 ERROR(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
92 #define NODE_CHECK(nm, d, ...) \
93 CHECK(nm, NULL, check_##nm, NULL, d, __VA_ARGS__)
94 #define PROP_WARNING(nm, d, ...) \
95 WARNING(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
96 #define PROP_ERROR(nm, d, ...) \
97 ERROR(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
98 #define PROP_CHECK(nm, d, ...) \
99 CHECK(nm, NULL, NULL, check_##nm, d, __VA_ARGS__)
104 static inline void check_msg(
struct check *c,
const char *fmt, ...)
112 (c->
error) ?
"ERROR" :
"Warning", c->
name);
118 #define FAIL(c, ...) \
120 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
121 (c)->status = FAILED; \
122 check_msg((c), __VA_ARGS__); \
125 static void check_nodes_props(
struct check *c,
struct node *dt,
struct node *node)
141 check_nodes_props(c, dt, child);
144 static int run_check(
struct check *c,
struct node *dt)
158 error |= run_check(prq, dt);
161 check_msg(c,
"Failed prerequisite '%s'",
170 check_nodes_props(c, dt, dt);
191 static inline void check_always_fail(
struct check *c,
struct node *dt)
193 FAIL(c,
"always_fail check");
197 static void check_is_string(
struct check *c,
struct node *root,
201 char *propname = c->
data;
208 FAIL(c,
"\"%s\" property in %s is not a string",
211 #define WARNING_IF_NOT_STRING(nm, propname) \
212 WARNING(nm, NULL, check_is_string, NULL, (propname))
213 #define ERROR_IF_NOT_STRING(nm, propname) \
214 ERROR(nm, NULL, check_is_string, NULL, (propname))
216 static void check_is_cell(
struct check *c,
struct node *root,
220 char *propname = c->
data;
227 FAIL(c,
"\"%s\" property in %s is not a single cell",
230 #define WARNING_IF_NOT_CELL(nm, propname) \
231 WARNING(nm, NULL, check_is_cell, NULL, (propname))
232 #define ERROR_IF_NOT_CELL(nm, propname) \
233 ERROR(nm, NULL, check_is_cell, NULL, (propname))
239 static void check_duplicate_node_names(
struct check *c,
struct node *dt,
242 struct node *
child, *child2;
249 FAIL(c,
"Duplicate node name %s",
254 static void check_duplicate_property_names(
struct check *c,
struct node *dt,
260 for (prop2 = prop->
next; prop2; prop2 = prop2->
next) {
264 FAIL(c,
"Duplicate property name %s in %s",
271 #define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
272 #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
273 #define DIGITS "0123456789"
274 #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
276 static void check_node_name_chars(
struct check *c,
struct node *dt,
282 FAIL(c,
"Bad character '%c' in node %s",
287 static void check_node_name_format(
struct check *c,
struct node *dt,
291 FAIL(c,
"Node %s has multiple '@' characters in name",
296 static void check_property_name_chars(
struct check *c,
struct node *dt,
297 struct node *node,
struct property *prop)
302 FAIL(c,
"Bad character '%c' in property name \"%s\", node %s",
307 #define DESCLABEL_FMT "%s%s%s%s%s"
308 #define DESCLABEL_ARGS(node,prop,mark) \
309 ((mark) ? "value of " : ""), \
310 ((prop) ? "'" : ""), \
311 ((prop) ? (prop)->name : ""), \
312 ((prop) ? "' in " : ""), (node)->fullpath
314 static void check_duplicate_label(
struct check *c,
struct node *dt,
315 const char *
label,
struct node *node,
318 struct node *othernode =
NULL;
333 if ((othernode != node) || (otherprop != prop) || (othermark != mark))
340 static void check_duplicate_label_node(
struct check *c,
struct node *dt,
346 check_duplicate_label(c, dt, l->
label, node,
NULL, NULL);
351 struct marker *
m = prop->val.markers;
355 check_duplicate_label(c, dt, l->label, node, prop, NULL);
358 check_duplicate_label(c, dt, m->ref, node, prop, m);
360 ERROR(duplicate_label, NULL, check_duplicate_label_node,
361 check_duplicate_label_prop, NULL);
370 if (!
streq(prop->name,
"phandle")
371 && !
streq(prop->name,
"linux,phandle"))
374 if (prop->val.len !=
sizeof(
cell_t)) {
375 FAIL(c,
"%s has bad length (%d) %s property",
376 node->fullpath, prop->val.len, prop->name);
380 m = prop->val.markers;
387 FAIL(c,
"%s in %s is a reference to another node",
388 prop->name, node->fullpath);
401 if ((phandle == 0) || (phandle == -1)) {
402 FAIL(c,
"%s has bad value (0x%x) in %s property",
403 node->fullpath, phandle, prop->name);
407 if (node->phandle && (node->phandle != phandle))
408 FAIL(c,
"%s has %s property which replaces existing phandle information",
409 node->fullpath, prop->name);
412 if (other && (other != node)) {
413 FAIL(c,
"%s has duplicated phandle 0x%x (seen before at %s)",
414 node->fullpath, phandle, other->
fullpath);
422 static void check_name_properties(
struct check *c,
struct node *root,
427 for (pp = &node->
proplist; *pp; pp = &((*pp)->next))
428 if (
streq((*pp)->name,
"name")) {
438 FAIL(c,
"\"name\" property in %s is incorrect (\"%s\" instead"
439 " of base node name)", node->
fullpath, prop->
val.val);
450 NODE_ERROR(name_properties, NULL, &name_is_string);
456 static void fixup_phandle_references(
struct check *c,
struct node *dt,
457 struct node *node,
struct property *prop)
460 struct node *refnode;
468 FAIL(c,
"Reference to non-existent node or label \"%s\"\n",
477 ERROR(phandle_references, NULL, NULL, fixup_phandle_references, NULL,
478 &duplicate_node_names, &explicit_phandles);
480 static void fixup_path_references(
struct check *c,
struct node *dt,
481 struct node *node,
struct property *prop)
484 struct node *refnode;
492 FAIL(c,
"Reference to non-existent node or label \"%s\"\n",
502 ERROR(path_references, NULL, NULL, fixup_path_references, NULL,
503 &duplicate_node_names);
516 static void fixup_addr_size_cells(
struct check *c,
struct node *dt,
532 WARNING(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL,
533 &address_cells_is_cell, &size_cells_is_cell);
535 #define node_addr_cells(n) \
536 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
537 #define node_size_cells(n) \
538 (((n)->size_cells == -1) ? 1 : (n)->size_cells)
540 static void check_reg_format(
struct check *c,
struct node *dt,
544 int addr_cells, size_cells, entrylen;
551 FAIL(c,
"Root node has a \"reg\" property");
555 if (prop->
val.len == 0)
556 FAIL(c,
"\"reg\" property in %s is empty", node->
fullpath);
560 entrylen = (addr_cells + size_cells) *
sizeof(
cell_t);
562 if ((prop->
val.len % entrylen) != 0)
563 FAIL(c,
"\"reg\" property in %s has invalid length (%d bytes) "
564 "(#address-cells == %d, #size-cells == %d)",
565 node->
fullpath, prop->
val.len, addr_cells, size_cells);
569 static void check_ranges_format(
struct check *c,
struct node *dt,
573 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
580 FAIL(c,
"Root node has a \"ranges\" property");
588 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) *
sizeof(
cell_t);
590 if (prop->
val.len == 0) {
591 if (p_addr_cells != c_addr_cells)
592 FAIL(c,
"%s has empty \"ranges\" property but its "
593 "#address-cells (%d) differs from %s (%d)",
596 if (p_size_cells != c_size_cells)
597 FAIL(c,
"%s has empty \"ranges\" property but its "
598 "#size-cells (%d) differs from %s (%d)",
601 }
else if ((prop->
val.len % entrylen) != 0) {
602 FAIL(c,
"\"ranges\" property in %s has invalid length (%d bytes) "
603 "(parent #address-cells == %d, child #address-cells == %d, "
604 "#size-cells == %d)", node->
fullpath, prop->
val.len,
605 p_addr_cells, c_addr_cells, c_size_cells);
613 static void check_avoid_default_addr_size(
struct check *c,
struct node *dt,
627 if ((node->
parent->addr_cells == -1))
628 FAIL(c,
"Relying on default #address-cells value for %s",
631 if ((node->
parent->size_cells == -1))
632 FAIL(c,
"Relying on default #size-cells value for %s",
635 NODE_WARNING(avoid_default_addr_size, NULL, &addr_size_cells);
637 static void check_obsolete_chosen_interrupt_controller(
struct check *c,
649 FAIL(c,
"/chosen has obsolete \"interrupt-controller\" "
652 TREE_WARNING(obsolete_chosen_interrupt_controller, NULL);
654 static struct check *check_table[] = {
655 &duplicate_node_names, &duplicate_property_names,
656 &node_name_chars, &node_name_format, &property_name_chars,
657 &name_is_string, &name_properties,
662 &phandle_references, &path_references,
664 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
665 &device_type_is_string, &model_is_string, &status_is_string,
667 &addr_size_cells, ®_format, &ranges_format,
669 &avoid_default_addr_size,
670 &obsolete_chosen_interrupt_controller,
675 static void enable_warning_error(
struct check *c,
bool warn,
bool error)
680 if ((warn && !c->
warn) || (error && !c->
error))
682 enable_warning_error(c->
prereq[i], warn, error);
688 static void disable_warning_error(
struct check *c,
bool warn,
bool error)
694 if ((warn && c->
warn) || (error && c->
error)) {
695 for (i = 0; i <
ARRAY_SIZE(check_table); i++) {
701 disable_warning_error(cc, warn, error);
712 const char *
name = optarg;
715 if ((
strncmp(optarg,
"no-", 3) == 0)
716 || (
strncmp(optarg,
"no_", 3) == 0)) {
721 for (i = 0; i <
ARRAY_SIZE(check_table); i++) {
722 struct check *c = check_table[
i];
726 enable_warning_error(c, warn, error);
728 disable_warning_error(c, warn, error);
733 die(
"Unrecognized check name \"%s\"\n", name);
738 struct node *dt = bi->
dt;
742 for (i = 0; i <
ARRAY_SIZE(check_table); i++) {
743 struct check *c = check_table[
i];
746 error = error || run_check(c, dt);
751 fprintf(stderr,
"ERROR: Input tree has errors, aborting "
752 "(use -f to force output)\n");
754 }
else if (
quiet < 3) {
755 fprintf(stderr,
"Warning: Input tree has errors, "