checks.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356
  1. /*
  2. * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
  3. *
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  18. * USA
  19. */
  20. #include "dtc.h"
  21. #ifdef TRACE_CHECKS
  22. #define TRACE(c, ...) \
  23. do { \
  24. fprintf(stderr, "=== %s: ", (c)->name); \
  25. fprintf(stderr, __VA_ARGS__); \
  26. fprintf(stderr, "\n"); \
  27. } while (0)
  28. #else
  29. #define TRACE(c, fmt, ...) do { } while (0)
  30. #endif
  31. enum checkstatus {
  32. UNCHECKED = 0,
  33. PREREQ,
  34. PASSED,
  35. FAILED,
  36. };
  37. struct check;
  38. typedef void (*check_fn)(struct check *c, struct dt_info *dti, struct node *node);
  39. struct check {
  40. const char *name;
  41. check_fn fn;
  42. void *data;
  43. bool warn, error;
  44. enum checkstatus status;
  45. bool inprogress;
  46. int num_prereqs;
  47. struct check **prereq;
  48. };
  49. #define CHECK_ENTRY(_nm, _fn, _d, _w, _e, ...) \
  50. static struct check *_nm##_prereqs[] = { __VA_ARGS__ }; \
  51. static struct check _nm = { \
  52. .name = #_nm, \
  53. .fn = (_fn), \
  54. .data = (_d), \
  55. .warn = (_w), \
  56. .error = (_e), \
  57. .status = UNCHECKED, \
  58. .num_prereqs = ARRAY_SIZE(_nm##_prereqs), \
  59. .prereq = _nm##_prereqs, \
  60. };
  61. #define WARNING(_nm, _fn, _d, ...) \
  62. CHECK_ENTRY(_nm, _fn, _d, true, false, __VA_ARGS__)
  63. #define ERROR(_nm, _fn, _d, ...) \
  64. CHECK_ENTRY(_nm, _fn, _d, false, true, __VA_ARGS__)
  65. #define CHECK(_nm, _fn, _d, ...) \
  66. CHECK_ENTRY(_nm, _fn, _d, false, false, __VA_ARGS__)
  67. static inline void PRINTF(3, 4) check_msg(struct check *c, struct dt_info *dti,
  68. const char *fmt, ...)
  69. {
  70. va_list ap;
  71. va_start(ap, fmt);
  72. if ((c->warn && (quiet < 1))
  73. || (c->error && (quiet < 2))) {
  74. fprintf(stderr, "%s: %s (%s): ",
  75. strcmp(dti->outname, "-") ? dti->outname : "<stdout>",
  76. (c->error) ? "ERROR" : "Warning", c->name);
  77. vfprintf(stderr, fmt, ap);
  78. fprintf(stderr, "\n");
  79. }
  80. va_end(ap);
  81. }
  82. #define FAIL(c, dti, ...) \
  83. do { \
  84. TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
  85. (c)->status = FAILED; \
  86. check_msg((c), dti, __VA_ARGS__); \
  87. } while (0)
  88. static void check_nodes_props(struct check *c, struct dt_info *dti, struct node *node)
  89. {
  90. struct node *child;
  91. TRACE(c, "%s", node->fullpath);
  92. if (c->fn)
  93. c->fn(c, dti, node);
  94. for_each_child(node, child)
  95. check_nodes_props(c, dti, child);
  96. }
  97. static bool run_check(struct check *c, struct dt_info *dti)
  98. {
  99. struct node *dt = dti->dt;
  100. bool error = false;
  101. int i;
  102. assert(!c->inprogress);
  103. if (c->status != UNCHECKED)
  104. goto out;
  105. c->inprogress = true;
  106. for (i = 0; i < c->num_prereqs; i++) {
  107. struct check *prq = c->prereq[i];
  108. error = error || run_check(prq, dti);
  109. if (prq->status != PASSED) {
  110. c->status = PREREQ;
  111. check_msg(c, dti, "Failed prerequisite '%s'",
  112. c->prereq[i]->name);
  113. }
  114. }
  115. if (c->status != UNCHECKED)
  116. goto out;
  117. check_nodes_props(c, dti, dt);
  118. if (c->status == UNCHECKED)
  119. c->status = PASSED;
  120. TRACE(c, "\tCompleted, status %d", c->status);
  121. out:
  122. c->inprogress = false;
  123. if ((c->status != PASSED) && (c->error))
  124. error = true;
  125. return error;
  126. }
  127. /*
  128. * Utility check functions
  129. */
  130. /* A check which always fails, for testing purposes only */
  131. static inline void check_always_fail(struct check *c, struct dt_info *dti,
  132. struct node *node)
  133. {
  134. FAIL(c, dti, "always_fail check");
  135. }
  136. CHECK(always_fail, check_always_fail, NULL);
  137. static void check_is_string(struct check *c, struct dt_info *dti,
  138. struct node *node)
  139. {
  140. struct property *prop;
  141. char *propname = c->data;
  142. prop = get_property(node, propname);
  143. if (!prop)
  144. return; /* Not present, assumed ok */
  145. if (!data_is_one_string(prop->val))
  146. FAIL(c, dti, "\"%s\" property in %s is not a string",
  147. propname, node->fullpath);
  148. }
  149. #define WARNING_IF_NOT_STRING(nm, propname) \
  150. WARNING(nm, check_is_string, (propname))
  151. #define ERROR_IF_NOT_STRING(nm, propname) \
  152. ERROR(nm, check_is_string, (propname))
  153. static void check_is_cell(struct check *c, struct dt_info *dti,
  154. struct node *node)
  155. {
  156. struct property *prop;
  157. char *propname = c->data;
  158. prop = get_property(node, propname);
  159. if (!prop)
  160. return; /* Not present, assumed ok */
  161. if (prop->val.len != sizeof(cell_t))
  162. FAIL(c, dti, "\"%s\" property in %s is not a single cell",
  163. propname, node->fullpath);
  164. }
  165. #define WARNING_IF_NOT_CELL(nm, propname) \
  166. WARNING(nm, check_is_cell, (propname))
  167. #define ERROR_IF_NOT_CELL(nm, propname) \
  168. ERROR(nm, check_is_cell, (propname))
  169. /*
  170. * Structural check functions
  171. */
  172. static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
  173. struct node *node)
  174. {
  175. struct node *child, *child2;
  176. for_each_child(node, child)
  177. for (child2 = child->next_sibling;
  178. child2;
  179. child2 = child2->next_sibling)
  180. if (streq(child->name, child2->name))
  181. FAIL(c, dti, "Duplicate node name %s",
  182. child->fullpath);
  183. }
  184. ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
  185. static void check_duplicate_property_names(struct check *c, struct dt_info *dti,
  186. struct node *node)
  187. {
  188. struct property *prop, *prop2;
  189. for_each_property(node, prop) {
  190. for (prop2 = prop->next; prop2; prop2 = prop2->next) {
  191. if (prop2->deleted)
  192. continue;
  193. if (streq(prop->name, prop2->name))
  194. FAIL(c, dti, "Duplicate property name %s in %s",
  195. prop->name, node->fullpath);
  196. }
  197. }
  198. }
  199. ERROR(duplicate_property_names, check_duplicate_property_names, NULL);
  200. #define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
  201. #define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  202. #define DIGITS "0123456789"
  203. #define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
  204. #define PROPNODECHARSSTRICT LOWERCASE UPPERCASE DIGITS ",-"
  205. static void check_node_name_chars(struct check *c, struct dt_info *dti,
  206. struct node *node)
  207. {
  208. int n = strspn(node->name, c->data);
  209. if (n < strlen(node->name))
  210. FAIL(c, dti, "Bad character '%c' in node %s",
  211. node->name[n], node->fullpath);
  212. }
  213. ERROR(node_name_chars, check_node_name_chars, PROPNODECHARS "@");
  214. static void check_node_name_chars_strict(struct check *c, struct dt_info *dti,
  215. struct node *node)
  216. {
  217. int n = strspn(node->name, c->data);
  218. if (n < node->basenamelen)
  219. FAIL(c, dti, "Character '%c' not recommended in node %s",
  220. node->name[n], node->fullpath);
  221. }
  222. CHECK(node_name_chars_strict, check_node_name_chars_strict, PROPNODECHARSSTRICT);
  223. static void check_node_name_format(struct check *c, struct dt_info *dti,
  224. struct node *node)
  225. {
  226. if (strchr(get_unitname(node), '@'))
  227. FAIL(c, dti, "Node %s has multiple '@' characters in name",
  228. node->fullpath);
  229. }
  230. ERROR(node_name_format, check_node_name_format, NULL, &node_name_chars);
  231. static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
  232. struct node *node)
  233. {
  234. const char *unitname = get_unitname(node);
  235. struct property *prop = get_property(node, "reg");
  236. if (!prop) {
  237. prop = get_property(node, "ranges");
  238. if (prop && !prop->val.len)
  239. prop = NULL;
  240. }
  241. if (prop) {
  242. if (!unitname[0])
  243. FAIL(c, dti, "Node %s has a reg or ranges property, but no unit name",
  244. node->fullpath);
  245. } else {
  246. if (unitname[0])
  247. FAIL(c, dti, "Node %s has a unit name, but no reg property",
  248. node->fullpath);
  249. }
  250. }
  251. WARNING(unit_address_vs_reg, check_unit_address_vs_reg, NULL);
  252. static void check_property_name_chars(struct check *c, struct dt_info *dti,
  253. struct node *node)
  254. {
  255. struct property *prop;
  256. for_each_property(node, prop) {
  257. int n = strspn(prop->name, c->data);
  258. if (n < strlen(prop->name))
  259. FAIL(c, dti, "Bad character '%c' in property name \"%s\", node %s",
  260. prop->name[n], prop->name, node->fullpath);
  261. }
  262. }
  263. ERROR(property_name_chars, check_property_name_chars, PROPNODECHARS);
  264. static void check_property_name_chars_strict(struct check *c,
  265. struct dt_info *dti,
  266. struct node *node)
  267. {
  268. struct property *prop;
  269. for_each_property(node, prop) {
  270. const char *name = prop->name;
  271. int n = strspn(name, c->data);
  272. if (n == strlen(prop->name))
  273. continue;
  274. /* Certain names are whitelisted */
  275. if (streq(name, "device_type"))
  276. continue;
  277. /*
  278. * # is only allowed at the beginning of property names not counting
  279. * the vendor prefix.
  280. */
  281. if (name[n] == '#' && ((n == 0) || (name[n-1] == ','))) {
  282. name += n + 1;
  283. n = strspn(name, c->data);
  284. }
  285. if (n < strlen(name))
  286. FAIL(c, dti, "Character '%c' not recommended in property name \"%s\", node %s",
  287. name[n], prop->name, node->fullpath);
  288. }
  289. }
  290. CHECK(property_name_chars_strict, check_property_name_chars_strict, PROPNODECHARSSTRICT);
  291. #define DESCLABEL_FMT "%s%s%s%s%s"
  292. #define DESCLABEL_ARGS(node,prop,mark) \
  293. ((mark) ? "value of " : ""), \
  294. ((prop) ? "'" : ""), \
  295. ((prop) ? (prop)->name : ""), \
  296. ((prop) ? "' in " : ""), (node)->fullpath
  297. static void check_duplicate_label(struct check *c, struct dt_info *dti,
  298. const char *label, struct node *node,
  299. struct property *prop, struct marker *mark)
  300. {
  301. struct node *dt = dti->dt;
  302. struct node *othernode = NULL;
  303. struct property *otherprop = NULL;
  304. struct marker *othermark = NULL;
  305. othernode = get_node_by_label(dt, label);
  306. if (!othernode)
  307. otherprop = get_property_by_label(dt, label, &othernode);
  308. if (!othernode)
  309. othermark = get_marker_label(dt, label, &othernode,
  310. &otherprop);
  311. if (!othernode)
  312. return;
  313. if ((othernode != node) || (otherprop != prop) || (othermark != mark))
  314. FAIL(c, dti, "Duplicate label '%s' on " DESCLABEL_FMT
  315. " and " DESCLABEL_FMT,
  316. label, DESCLABEL_ARGS(node, prop, mark),
  317. DESCLABEL_ARGS(othernode, otherprop, othermark));
  318. }
  319. static void check_duplicate_label_node(struct check *c, struct dt_info *dti,
  320. struct node *node)
  321. {
  322. struct label *l;
  323. struct property *prop;
  324. for_each_label(node->labels, l)
  325. check_duplicate_label(c, dti, l->label, node, NULL, NULL);
  326. for_each_property(node, prop) {
  327. struct marker *m = prop->val.markers;
  328. for_each_label(prop->labels, l)
  329. check_duplicate_label(c, dti, l->label, node, prop, NULL);
  330. for_each_marker_of_type(m, LABEL)
  331. check_duplicate_label(c, dti, m->ref, node, prop, m);
  332. }
  333. }
  334. ERROR(duplicate_label, check_duplicate_label_node, NULL);
  335. static cell_t check_phandle_prop(struct check *c, struct dt_info *dti,
  336. struct node *node, const char *propname)
  337. {
  338. struct node *root = dti->dt;
  339. struct property *prop;
  340. struct marker *m;
  341. cell_t phandle;
  342. prop = get_property(node, propname);
  343. if (!prop)
  344. return 0;
  345. if (prop->val.len != sizeof(cell_t)) {
  346. FAIL(c, dti, "%s has bad length (%d) %s property",
  347. node->fullpath, prop->val.len, prop->name);
  348. return 0;
  349. }
  350. m = prop->val.markers;
  351. for_each_marker_of_type(m, REF_PHANDLE) {
  352. assert(m->offset == 0);
  353. if (node != get_node_by_ref(root, m->ref))
  354. /* "Set this node's phandle equal to some
  355. * other node's phandle". That's nonsensical
  356. * by construction. */ {
  357. FAIL(c, dti, "%s in %s is a reference to another node",
  358. prop->name, node->fullpath);
  359. }
  360. /* But setting this node's phandle equal to its own
  361. * phandle is allowed - that means allocate a unique
  362. * phandle for this node, even if it's not otherwise
  363. * referenced. The value will be filled in later, so
  364. * we treat it as having no phandle data for now. */
  365. return 0;
  366. }
  367. phandle = propval_cell(prop);
  368. if ((phandle == 0) || (phandle == -1)) {
  369. FAIL(c, dti, "%s has bad value (0x%x) in %s property",
  370. node->fullpath, phandle, prop->name);
  371. return 0;
  372. }
  373. return phandle;
  374. }
  375. static void check_explicit_phandles(struct check *c, struct dt_info *dti,
  376. struct node *node)
  377. {
  378. struct node *root = dti->dt;
  379. struct node *other;
  380. cell_t phandle, linux_phandle;
  381. /* Nothing should have assigned phandles yet */
  382. assert(!node->phandle);
  383. phandle = check_phandle_prop(c, dti, node, "phandle");
  384. linux_phandle = check_phandle_prop(c, dti, node, "linux,phandle");
  385. if (!phandle && !linux_phandle)
  386. /* No valid phandles; nothing further to check */
  387. return;
  388. if (linux_phandle && phandle && (phandle != linux_phandle))
  389. FAIL(c, dti, "%s has mismatching 'phandle' and 'linux,phandle'"
  390. " properties", node->fullpath);
  391. if (linux_phandle && !phandle)
  392. phandle = linux_phandle;
  393. other = get_node_by_phandle(root, phandle);
  394. if (other && (other != node)) {
  395. FAIL(c, dti, "%s has duplicated phandle 0x%x (seen before at %s)",
  396. node->fullpath, phandle, other->fullpath);
  397. return;
  398. }
  399. node->phandle = phandle;
  400. }
  401. ERROR(explicit_phandles, check_explicit_phandles, NULL);
  402. static void check_name_properties(struct check *c, struct dt_info *dti,
  403. struct node *node)
  404. {
  405. struct property **pp, *prop = NULL;
  406. for (pp = &node->proplist; *pp; pp = &((*pp)->next))
  407. if (streq((*pp)->name, "name")) {
  408. prop = *pp;
  409. break;
  410. }
  411. if (!prop)
  412. return; /* No name property, that's fine */
  413. if ((prop->val.len != node->basenamelen+1)
  414. || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
  415. FAIL(c, dti, "\"name\" property in %s is incorrect (\"%s\" instead"
  416. " of base node name)", node->fullpath, prop->val.val);
  417. } else {
  418. /* The name property is correct, and therefore redundant.
  419. * Delete it */
  420. *pp = prop->next;
  421. free(prop->name);
  422. data_free(prop->val);
  423. free(prop);
  424. }
  425. }
  426. ERROR_IF_NOT_STRING(name_is_string, "name");
  427. ERROR(name_properties, check_name_properties, NULL, &name_is_string);
  428. /*
  429. * Reference fixup functions
  430. */
  431. static void fixup_phandle_references(struct check *c, struct dt_info *dti,
  432. struct node *node)
  433. {
  434. struct node *dt = dti->dt;
  435. struct property *prop;
  436. for_each_property(node, prop) {
  437. struct marker *m = prop->val.markers;
  438. struct node *refnode;
  439. cell_t phandle;
  440. for_each_marker_of_type(m, REF_PHANDLE) {
  441. assert(m->offset + sizeof(cell_t) <= prop->val.len);
  442. refnode = get_node_by_ref(dt, m->ref);
  443. if (! refnode) {
  444. if (!(dti->dtsflags & DTSF_PLUGIN))
  445. FAIL(c, dti, "Reference to non-existent node or "
  446. "label \"%s\"\n", m->ref);
  447. else /* mark the entry as unresolved */
  448. *((fdt32_t *)(prop->val.val + m->offset)) =
  449. cpu_to_fdt32(0xffffffff);
  450. continue;
  451. }
  452. phandle = get_node_phandle(dt, refnode);
  453. *((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
  454. }
  455. }
  456. }
  457. ERROR(phandle_references, fixup_phandle_references, NULL,
  458. &duplicate_node_names, &explicit_phandles);
  459. static void fixup_path_references(struct check *c, struct dt_info *dti,
  460. struct node *node)
  461. {
  462. struct node *dt = dti->dt;
  463. struct property *prop;
  464. for_each_property(node, prop) {
  465. struct marker *m = prop->val.markers;
  466. struct node *refnode;
  467. char *path;
  468. for_each_marker_of_type(m, REF_PATH) {
  469. assert(m->offset <= prop->val.len);
  470. refnode = get_node_by_ref(dt, m->ref);
  471. if (!refnode) {
  472. FAIL(c, dti, "Reference to non-existent node or label \"%s\"\n",
  473. m->ref);
  474. continue;
  475. }
  476. path = refnode->fullpath;
  477. prop->val = data_insert_at_marker(prop->val, m, path,
  478. strlen(path) + 1);
  479. }
  480. }
  481. }
  482. ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
  483. /*
  484. * Semantic checks
  485. */
  486. WARNING_IF_NOT_CELL(address_cells_is_cell, "#address-cells");
  487. WARNING_IF_NOT_CELL(size_cells_is_cell, "#size-cells");
  488. WARNING_IF_NOT_CELL(interrupt_cells_is_cell, "#interrupt-cells");
  489. WARNING_IF_NOT_STRING(device_type_is_string, "device_type");
  490. WARNING_IF_NOT_STRING(model_is_string, "model");
  491. WARNING_IF_NOT_STRING(status_is_string, "status");
  492. static void fixup_addr_size_cells(struct check *c, struct dt_info *dti,
  493. struct node *node)
  494. {
  495. struct property *prop;
  496. node->addr_cells = -1;
  497. node->size_cells = -1;
  498. prop = get_property(node, "#address-cells");
  499. if (prop)
  500. node->addr_cells = propval_cell(prop);
  501. prop = get_property(node, "#size-cells");
  502. if (prop)
  503. node->size_cells = propval_cell(prop);
  504. }
  505. WARNING(addr_size_cells, fixup_addr_size_cells, NULL,
  506. &address_cells_is_cell, &size_cells_is_cell);
  507. #define node_addr_cells(n) \
  508. (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
  509. #define node_size_cells(n) \
  510. (((n)->size_cells == -1) ? 1 : (n)->size_cells)
  511. static void check_reg_format(struct check *c, struct dt_info *dti,
  512. struct node *node)
  513. {
  514. struct property *prop;
  515. int addr_cells, size_cells, entrylen;
  516. prop = get_property(node, "reg");
  517. if (!prop)
  518. return; /* No "reg", that's fine */
  519. if (!node->parent) {
  520. FAIL(c, dti, "Root node has a \"reg\" property");
  521. return;
  522. }
  523. if (prop->val.len == 0)
  524. FAIL(c, dti, "\"reg\" property in %s is empty", node->fullpath);
  525. addr_cells = node_addr_cells(node->parent);
  526. size_cells = node_size_cells(node->parent);
  527. entrylen = (addr_cells + size_cells) * sizeof(cell_t);
  528. if (!entrylen || (prop->val.len % entrylen) != 0)
  529. FAIL(c, dti, "\"reg\" property in %s has invalid length (%d bytes) "
  530. "(#address-cells == %d, #size-cells == %d)",
  531. node->fullpath, prop->val.len, addr_cells, size_cells);
  532. }
  533. WARNING(reg_format, check_reg_format, NULL, &addr_size_cells);
  534. static void check_ranges_format(struct check *c, struct dt_info *dti,
  535. struct node *node)
  536. {
  537. struct property *prop;
  538. int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
  539. prop = get_property(node, "ranges");
  540. if (!prop)
  541. return;
  542. if (!node->parent) {
  543. FAIL(c, dti, "Root node has a \"ranges\" property");
  544. return;
  545. }
  546. p_addr_cells = node_addr_cells(node->parent);
  547. p_size_cells = node_size_cells(node->parent);
  548. c_addr_cells = node_addr_cells(node);
  549. c_size_cells = node_size_cells(node);
  550. entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
  551. if (prop->val.len == 0) {
  552. if (p_addr_cells != c_addr_cells)
  553. FAIL(c, dti, "%s has empty \"ranges\" property but its "
  554. "#address-cells (%d) differs from %s (%d)",
  555. node->fullpath, c_addr_cells, node->parent->fullpath,
  556. p_addr_cells);
  557. if (p_size_cells != c_size_cells)
  558. FAIL(c, dti, "%s has empty \"ranges\" property but its "
  559. "#size-cells (%d) differs from %s (%d)",
  560. node->fullpath, c_size_cells, node->parent->fullpath,
  561. p_size_cells);
  562. } else if ((prop->val.len % entrylen) != 0) {
  563. FAIL(c, dti, "\"ranges\" property in %s has invalid length (%d bytes) "
  564. "(parent #address-cells == %d, child #address-cells == %d, "
  565. "#size-cells == %d)", node->fullpath, prop->val.len,
  566. p_addr_cells, c_addr_cells, c_size_cells);
  567. }
  568. }
  569. WARNING(ranges_format, check_ranges_format, NULL, &addr_size_cells);
  570. static const struct bus_type pci_bus = {
  571. .name = "PCI",
  572. };
  573. static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *node)
  574. {
  575. struct property *prop;
  576. cell_t *cells;
  577. prop = get_property(node, "device_type");
  578. if (!prop || !streq(prop->val.val, "pci"))
  579. return;
  580. node->bus = &pci_bus;
  581. if (!strneq(node->name, "pci", node->basenamelen) &&
  582. !strneq(node->name, "pcie", node->basenamelen))
  583. FAIL(c, dti, "Node %s node name is not \"pci\" or \"pcie\"",
  584. node->fullpath);
  585. prop = get_property(node, "ranges");
  586. if (!prop)
  587. FAIL(c, dti, "Node %s missing ranges for PCI bridge (or not a bridge)",
  588. node->fullpath);
  589. if (node_addr_cells(node) != 3)
  590. FAIL(c, dti, "Node %s incorrect #address-cells for PCI bridge",
  591. node->fullpath);
  592. if (node_size_cells(node) != 2)
  593. FAIL(c, dti, "Node %s incorrect #size-cells for PCI bridge",
  594. node->fullpath);
  595. prop = get_property(node, "bus-range");
  596. if (!prop) {
  597. FAIL(c, dti, "Node %s missing bus-range for PCI bridge",
  598. node->fullpath);
  599. return;
  600. }
  601. if (prop->val.len != (sizeof(cell_t) * 2)) {
  602. FAIL(c, dti, "Node %s bus-range must be 2 cells",
  603. node->fullpath);
  604. return;
  605. }
  606. cells = (cell_t *)prop->val.val;
  607. if (fdt32_to_cpu(cells[0]) > fdt32_to_cpu(cells[1]))
  608. FAIL(c, dti, "Node %s bus-range 1st cell must be less than or equal to 2nd cell",
  609. node->fullpath);
  610. if (fdt32_to_cpu(cells[1]) > 0xff)
  611. FAIL(c, dti, "Node %s bus-range maximum bus number must be less than 256",
  612. node->fullpath);
  613. }
  614. WARNING(pci_bridge, check_pci_bridge, NULL,
  615. &device_type_is_string, &addr_size_cells);
  616. static void check_pci_device_bus_num(struct check *c, struct dt_info *dti, struct node *node)
  617. {
  618. struct property *prop;
  619. unsigned int bus_num, min_bus, max_bus;
  620. cell_t *cells;
  621. if (!node->parent || (node->parent->bus != &pci_bus))
  622. return;
  623. prop = get_property(node, "reg");
  624. if (!prop)
  625. return;
  626. cells = (cell_t *)prop->val.val;
  627. bus_num = (fdt32_to_cpu(cells[0]) & 0x00ff0000) >> 16;
  628. prop = get_property(node->parent, "bus-range");
  629. if (!prop) {
  630. min_bus = max_bus = 0;
  631. } else {
  632. cells = (cell_t *)prop->val.val;
  633. min_bus = fdt32_to_cpu(cells[0]);
  634. max_bus = fdt32_to_cpu(cells[0]);
  635. }
  636. if ((bus_num < min_bus) || (bus_num > max_bus))
  637. FAIL(c, dti, "Node %s PCI bus number %d out of range, expected (%d - %d)",
  638. node->fullpath, bus_num, min_bus, max_bus);
  639. }
  640. WARNING(pci_device_bus_num, check_pci_device_bus_num, NULL, &reg_format, &pci_bridge);
  641. static void check_pci_device_reg(struct check *c, struct dt_info *dti, struct node *node)
  642. {
  643. struct property *prop;
  644. const char *unitname = get_unitname(node);
  645. char unit_addr[5];
  646. unsigned int dev, func, reg;
  647. cell_t *cells;
  648. if (!node->parent || (node->parent->bus != &pci_bus))
  649. return;
  650. prop = get_property(node, "reg");
  651. if (!prop) {
  652. FAIL(c, dti, "Node %s missing PCI reg property", node->fullpath);
  653. return;
  654. }
  655. cells = (cell_t *)prop->val.val;
  656. if (cells[1] || cells[2])
  657. FAIL(c, dti, "Node %s PCI reg config space address cells 2 and 3 must be 0",
  658. node->fullpath);
  659. reg = fdt32_to_cpu(cells[0]);
  660. dev = (reg & 0xf800) >> 11;
  661. func = (reg & 0x700) >> 8;
  662. if (reg & 0xff000000)
  663. FAIL(c, dti, "Node %s PCI reg address is not configuration space",
  664. node->fullpath);
  665. if (reg & 0x000000ff)
  666. FAIL(c, dti, "Node %s PCI reg config space address register number must be 0",
  667. node->fullpath);
  668. if (func == 0) {
  669. snprintf(unit_addr, sizeof(unit_addr), "%x", dev);
  670. if (streq(unitname, unit_addr))
  671. return;
  672. }
  673. snprintf(unit_addr, sizeof(unit_addr), "%x,%x", dev, func);
  674. if (streq(unitname, unit_addr))
  675. return;
  676. FAIL(c, dti, "Node %s PCI unit address format error, expected \"%s\"",
  677. node->fullpath, unit_addr);
  678. }
  679. WARNING(pci_device_reg, check_pci_device_reg, NULL, &reg_format, &pci_bridge);
  680. static const struct bus_type simple_bus = {
  681. .name = "simple-bus",
  682. };
  683. static bool node_is_compatible(struct node *node, const char *compat)
  684. {
  685. struct property *prop;
  686. const char *str, *end;
  687. prop = get_property(node, "compatible");
  688. if (!prop)
  689. return false;
  690. for (str = prop->val.val, end = str + prop->val.len; str < end;
  691. str += strnlen(str, end - str) + 1) {
  692. if (strneq(str, compat, end - str))
  693. return true;
  694. }
  695. return false;
  696. }
  697. static void check_simple_bus_bridge(struct check *c, struct dt_info *dti, struct node *node)
  698. {
  699. if (node_is_compatible(node, "simple-bus"))
  700. node->bus = &simple_bus;
  701. }
  702. WARNING(simple_bus_bridge, check_simple_bus_bridge, NULL, &addr_size_cells);
  703. static void check_simple_bus_reg(struct check *c, struct dt_info *dti, struct node *node)
  704. {
  705. struct property *prop;
  706. const char *unitname = get_unitname(node);
  707. char unit_addr[17];
  708. unsigned int size;
  709. uint64_t reg = 0;
  710. cell_t *cells = NULL;
  711. if (!node->parent || (node->parent->bus != &simple_bus))
  712. return;
  713. prop = get_property(node, "reg");
  714. if (prop)
  715. cells = (cell_t *)prop->val.val;
  716. else {
  717. prop = get_property(node, "ranges");
  718. if (prop && prop->val.len)
  719. /* skip of child address */
  720. cells = ((cell_t *)prop->val.val) + node_addr_cells(node);
  721. }
  722. if (!cells) {
  723. if (node->parent->parent && !(node->bus == &simple_bus))
  724. FAIL(c, dti, "Node %s missing or empty reg/ranges property", node->fullpath);
  725. return;
  726. }
  727. size = node_addr_cells(node->parent);
  728. while (size--)
  729. reg = (reg << 32) | fdt32_to_cpu(*(cells++));
  730. snprintf(unit_addr, sizeof(unit_addr), "%"PRIx64, reg);
  731. if (!streq(unitname, unit_addr))
  732. FAIL(c, dti, "Node %s simple-bus unit address format error, expected \"%s\"",
  733. node->fullpath, unit_addr);
  734. }
  735. WARNING(simple_bus_reg, check_simple_bus_reg, NULL, &reg_format, &simple_bus_bridge);
  736. static void check_unit_address_format(struct check *c, struct dt_info *dti,
  737. struct node *node)
  738. {
  739. const char *unitname = get_unitname(node);
  740. if (node->parent && node->parent->bus)
  741. return;
  742. if (!unitname[0])
  743. return;
  744. if (!strncmp(unitname, "0x", 2)) {
  745. FAIL(c, dti, "Node %s unit name should not have leading \"0x\"",
  746. node->fullpath);
  747. /* skip over 0x for next test */
  748. unitname += 2;
  749. }
  750. if (unitname[0] == '0' && isxdigit(unitname[1]))
  751. FAIL(c, dti, "Node %s unit name should not have leading 0s",
  752. node->fullpath);
  753. }
  754. WARNING(unit_address_format, check_unit_address_format, NULL,
  755. &node_name_format, &pci_bridge, &simple_bus_bridge);
  756. /*
  757. * Style checks
  758. */
  759. static void check_avoid_default_addr_size(struct check *c, struct dt_info *dti,
  760. struct node *node)
  761. {
  762. struct property *reg, *ranges;
  763. if (!node->parent)
  764. return; /* Ignore root node */
  765. reg = get_property(node, "reg");
  766. ranges = get_property(node, "ranges");
  767. if (!reg && !ranges)
  768. return;
  769. if (node->parent->addr_cells == -1)
  770. FAIL(c, dti, "Relying on default #address-cells value for %s",
  771. node->fullpath);
  772. if (node->parent->size_cells == -1)
  773. FAIL(c, dti, "Relying on default #size-cells value for %s",
  774. node->fullpath);
  775. }
  776. WARNING(avoid_default_addr_size, check_avoid_default_addr_size, NULL,
  777. &addr_size_cells);
  778. static void check_obsolete_chosen_interrupt_controller(struct check *c,
  779. struct dt_info *dti,
  780. struct node *node)
  781. {
  782. struct node *dt = dti->dt;
  783. struct node *chosen;
  784. struct property *prop;
  785. if (node != dt)
  786. return;
  787. chosen = get_node_by_path(dt, "/chosen");
  788. if (!chosen)
  789. return;
  790. prop = get_property(chosen, "interrupt-controller");
  791. if (prop)
  792. FAIL(c, dti, "/chosen has obsolete \"interrupt-controller\" "
  793. "property");
  794. }
  795. WARNING(obsolete_chosen_interrupt_controller,
  796. check_obsolete_chosen_interrupt_controller, NULL);
  797. struct provider {
  798. const char *prop_name;
  799. const char *cell_name;
  800. bool optional;
  801. };
  802. static void check_property_phandle_args(struct check *c,
  803. struct dt_info *dti,
  804. struct node *node,
  805. struct property *prop,
  806. const struct provider *provider)
  807. {
  808. struct node *root = dti->dt;
  809. int cell, cellsize = 0;
  810. if (prop->val.len % sizeof(cell_t)) {
  811. FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
  812. prop->name, prop->val.len, sizeof(cell_t), node->fullpath);
  813. return;
  814. }
  815. for (cell = 0; cell < prop->val.len / sizeof(cell_t); cell += cellsize + 1) {
  816. struct node *provider_node;
  817. struct property *cellprop;
  818. int phandle;
  819. phandle = propval_cell_n(prop, cell);
  820. /*
  821. * Some bindings use a cell value 0 or -1 to skip over optional
  822. * entries when each index position has a specific definition.
  823. */
  824. if (phandle == 0 || phandle == -1) {
  825. cellsize = 0;
  826. continue;
  827. }
  828. /* If we have markers, verify the current cell is a phandle */
  829. if (prop->val.markers) {
  830. struct marker *m = prop->val.markers;
  831. for_each_marker_of_type(m, REF_PHANDLE) {
  832. if (m->offset == (cell * sizeof(cell_t)))
  833. break;
  834. }
  835. if (!m)
  836. FAIL(c, dti, "Property '%s', cell %d is not a phandle reference in %s",
  837. prop->name, cell, node->fullpath);
  838. }
  839. provider_node = get_node_by_phandle(root, phandle);
  840. if (!provider_node) {
  841. FAIL(c, dti, "Could not get phandle node for %s:%s(cell %d)",
  842. node->fullpath, prop->name, cell);
  843. break;
  844. }
  845. cellprop = get_property(provider_node, provider->cell_name);
  846. if (cellprop) {
  847. cellsize = propval_cell(cellprop);
  848. } else if (provider->optional) {
  849. cellsize = 0;
  850. } else {
  851. FAIL(c, dti, "Missing property '%s' in node %s or bad phandle (referred from %s:%s[%d])",
  852. provider->cell_name,
  853. provider_node->fullpath,
  854. node->fullpath, prop->name, cell);
  855. break;
  856. }
  857. if (prop->val.len < ((cell + cellsize + 1) * sizeof(cell_t))) {
  858. FAIL(c, dti, "%s property size (%d) too small for cell size %d in %s",
  859. prop->name, prop->val.len, cellsize, node->fullpath);
  860. }
  861. }
  862. }
  863. static void check_provider_cells_property(struct check *c,
  864. struct dt_info *dti,
  865. struct node *node)
  866. {
  867. struct provider *provider = c->data;
  868. struct property *prop;
  869. prop = get_property(node, provider->prop_name);
  870. if (!prop)
  871. return;
  872. check_property_phandle_args(c, dti, node, prop, provider);
  873. }
  874. #define WARNING_PROPERTY_PHANDLE_CELLS(nm, propname, cells_name, ...) \
  875. static struct provider nm##_provider = { (propname), (cells_name), __VA_ARGS__ }; \
  876. WARNING(nm##_property, check_provider_cells_property, &nm##_provider, &phandle_references);
  877. WARNING_PROPERTY_PHANDLE_CELLS(clocks, "clocks", "#clock-cells");
  878. WARNING_PROPERTY_PHANDLE_CELLS(cooling_device, "cooling-device", "#cooling-cells");
  879. WARNING_PROPERTY_PHANDLE_CELLS(dmas, "dmas", "#dma-cells");
  880. WARNING_PROPERTY_PHANDLE_CELLS(hwlocks, "hwlocks", "#hwlock-cells");
  881. WARNING_PROPERTY_PHANDLE_CELLS(interrupts_extended, "interrupts-extended", "#interrupt-cells");
  882. WARNING_PROPERTY_PHANDLE_CELLS(io_channels, "io-channels", "#io-channel-cells");
  883. WARNING_PROPERTY_PHANDLE_CELLS(iommus, "iommus", "#iommu-cells");
  884. WARNING_PROPERTY_PHANDLE_CELLS(mboxes, "mboxes", "#mbox-cells");
  885. WARNING_PROPERTY_PHANDLE_CELLS(msi_parent, "msi-parent", "#msi-cells", true);
  886. WARNING_PROPERTY_PHANDLE_CELLS(mux_controls, "mux-controls", "#mux-control-cells");
  887. WARNING_PROPERTY_PHANDLE_CELLS(phys, "phys", "#phy-cells");
  888. WARNING_PROPERTY_PHANDLE_CELLS(power_domains, "power-domains", "#power-domain-cells");
  889. WARNING_PROPERTY_PHANDLE_CELLS(pwms, "pwms", "#pwm-cells");
  890. WARNING_PROPERTY_PHANDLE_CELLS(resets, "resets", "#reset-cells");
  891. WARNING_PROPERTY_PHANDLE_CELLS(sound_dais, "sound-dais", "#sound-dai-cells");
  892. WARNING_PROPERTY_PHANDLE_CELLS(thermal_sensors, "thermal-sensors", "#thermal-sensor-cells");
  893. static bool prop_is_gpio(struct property *prop)
  894. {
  895. char *str;
  896. /*
  897. * *-gpios and *-gpio can appear in property names,
  898. * so skip over any false matches (only one known ATM)
  899. */
  900. if (strstr(prop->name, "nr-gpio"))
  901. return false;
  902. str = strrchr(prop->name, '-');
  903. if (str)
  904. str++;
  905. else
  906. str = prop->name;
  907. if (!(streq(str, "gpios") || streq(str, "gpio")))
  908. return false;
  909. return true;
  910. }
  911. static void check_gpios_property(struct check *c,
  912. struct dt_info *dti,
  913. struct node *node)
  914. {
  915. struct property *prop;
  916. /* Skip GPIO hog nodes which have 'gpios' property */
  917. if (get_property(node, "gpio-hog"))
  918. return;
  919. for_each_property(node, prop) {
  920. struct provider provider;
  921. if (!prop_is_gpio(prop))
  922. continue;
  923. provider.prop_name = prop->name;
  924. provider.cell_name = "#gpio-cells";
  925. provider.optional = false;
  926. check_property_phandle_args(c, dti, node, prop, &provider);
  927. }
  928. }
  929. WARNING(gpios_property, check_gpios_property, NULL, &phandle_references);
  930. static void check_deprecated_gpio_property(struct check *c,
  931. struct dt_info *dti,
  932. struct node *node)
  933. {
  934. struct property *prop;
  935. for_each_property(node, prop) {
  936. char *str;
  937. if (!prop_is_gpio(prop))
  938. continue;
  939. str = strstr(prop->name, "gpio");
  940. if (!streq(str, "gpio"))
  941. continue;
  942. FAIL(c, dti, "'[*-]gpio' is deprecated, use '[*-]gpios' instead for %s:%s",
  943. node->fullpath, prop->name);
  944. }
  945. }
  946. CHECK(deprecated_gpio_property, check_deprecated_gpio_property, NULL);
  947. static bool node_is_interrupt_provider(struct node *node)
  948. {
  949. struct property *prop;
  950. prop = get_property(node, "interrupt-controller");
  951. if (prop)
  952. return true;
  953. prop = get_property(node, "interrupt-map");
  954. if (prop)
  955. return true;
  956. return false;
  957. }
  958. static void check_interrupts_property(struct check *c,
  959. struct dt_info *dti,
  960. struct node *node)
  961. {
  962. struct node *root = dti->dt;
  963. struct node *irq_node = NULL, *parent = node;
  964. struct property *irq_prop, *prop = NULL;
  965. int irq_cells, phandle;
  966. irq_prop = get_property(node, "interrupts");
  967. if (!irq_prop)
  968. return;
  969. if (irq_prop->val.len % sizeof(cell_t))
  970. FAIL(c, dti, "property '%s' size (%d) is invalid, expected multiple of %zu in node %s",
  971. irq_prop->name, irq_prop->val.len, sizeof(cell_t),
  972. node->fullpath);
  973. while (parent && !prop) {
  974. if (parent != node && node_is_interrupt_provider(parent)) {
  975. irq_node = parent;
  976. break;
  977. }
  978. prop = get_property(parent, "interrupt-parent");
  979. if (prop) {
  980. phandle = propval_cell(prop);
  981. irq_node = get_node_by_phandle(root, phandle);
  982. if (!irq_node) {
  983. FAIL(c, dti, "Bad interrupt-parent phandle for %s",
  984. node->fullpath);
  985. return;
  986. }
  987. if (!node_is_interrupt_provider(irq_node))
  988. FAIL(c, dti,
  989. "Missing interrupt-controller or interrupt-map property in %s",
  990. irq_node->fullpath);
  991. break;
  992. }
  993. parent = parent->parent;
  994. }
  995. if (!irq_node) {
  996. FAIL(c, dti, "Missing interrupt-parent for %s", node->fullpath);
  997. return;
  998. }
  999. prop = get_property(irq_node, "#interrupt-cells");
  1000. if (!prop) {
  1001. FAIL(c, dti, "Missing #interrupt-cells in interrupt-parent %s",
  1002. irq_node->fullpath);
  1003. return;
  1004. }
  1005. irq_cells = propval_cell(prop);
  1006. if (irq_prop->val.len % (irq_cells * sizeof(cell_t))) {
  1007. FAIL(c, dti,
  1008. "interrupts size is (%d), expected multiple of %d in %s",
  1009. irq_prop->val.len, (int)(irq_cells * sizeof(cell_t)),
  1010. node->fullpath);
  1011. }
  1012. }
  1013. WARNING(interrupts_property, check_interrupts_property, &phandle_references);
  1014. static struct check *check_table[] = {
  1015. &duplicate_node_names, &duplicate_property_names,
  1016. &node_name_chars, &node_name_format, &property_name_chars,
  1017. &name_is_string, &name_properties,
  1018. &duplicate_label,
  1019. &explicit_phandles,
  1020. &phandle_references, &path_references,
  1021. &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
  1022. &device_type_is_string, &model_is_string, &status_is_string,
  1023. &property_name_chars_strict,
  1024. &node_name_chars_strict,
  1025. &addr_size_cells, &reg_format, &ranges_format,
  1026. &unit_address_vs_reg,
  1027. &unit_address_format,
  1028. &pci_bridge,
  1029. &pci_device_reg,
  1030. &pci_device_bus_num,
  1031. &simple_bus_bridge,
  1032. &simple_bus_reg,
  1033. &avoid_default_addr_size,
  1034. &obsolete_chosen_interrupt_controller,
  1035. &clocks_property,
  1036. &cooling_device_property,
  1037. &dmas_property,
  1038. &hwlocks_property,
  1039. &interrupts_extended_property,
  1040. &io_channels_property,
  1041. &iommus_property,
  1042. &mboxes_property,
  1043. &msi_parent_property,
  1044. &mux_controls_property,
  1045. &phys_property,
  1046. &power_domains_property,
  1047. &pwms_property,
  1048. &resets_property,
  1049. &sound_dais_property,
  1050. &thermal_sensors_property,
  1051. &deprecated_gpio_property,
  1052. &gpios_property,
  1053. &interrupts_property,
  1054. &always_fail,
  1055. };
  1056. static void enable_warning_error(struct check *c, bool warn, bool error)
  1057. {
  1058. int i;
  1059. /* Raising level, also raise it for prereqs */
  1060. if ((warn && !c->warn) || (error && !c->error))
  1061. for (i = 0; i < c->num_prereqs; i++)
  1062. enable_warning_error(c->prereq[i], warn, error);
  1063. c->warn = c->warn || warn;
  1064. c->error = c->error || error;
  1065. }
  1066. static void disable_warning_error(struct check *c, bool warn, bool error)
  1067. {
  1068. int i;
  1069. /* Lowering level, also lower it for things this is the prereq
  1070. * for */
  1071. if ((warn && c->warn) || (error && c->error)) {
  1072. for (i = 0; i < ARRAY_SIZE(check_table); i++) {
  1073. struct check *cc = check_table[i];
  1074. int j;
  1075. for (j = 0; j < cc->num_prereqs; j++)
  1076. if (cc->prereq[j] == c)
  1077. disable_warning_error(cc, warn, error);
  1078. }
  1079. }
  1080. c->warn = c->warn && !warn;
  1081. c->error = c->error && !error;
  1082. }
  1083. void parse_checks_option(bool warn, bool error, const char *arg)
  1084. {
  1085. int i;
  1086. const char *name = arg;
  1087. bool enable = true;
  1088. if ((strncmp(arg, "no-", 3) == 0)
  1089. || (strncmp(arg, "no_", 3) == 0)) {
  1090. name = arg + 3;
  1091. enable = false;
  1092. }
  1093. for (i = 0; i < ARRAY_SIZE(check_table); i++) {
  1094. struct check *c = check_table[i];
  1095. if (streq(c->name, name)) {
  1096. if (enable)
  1097. enable_warning_error(c, warn, error);
  1098. else
  1099. disable_warning_error(c, warn, error);
  1100. return;
  1101. }
  1102. }
  1103. die("Unrecognized check name \"%s\"\n", name);
  1104. }
  1105. void process_checks(bool force, struct dt_info *dti)
  1106. {
  1107. int i;
  1108. int error = 0;
  1109. for (i = 0; i < ARRAY_SIZE(check_table); i++) {
  1110. struct check *c = check_table[i];
  1111. if (c->warn || c->error)
  1112. error = error || run_check(c, dti);
  1113. }
  1114. if (error) {
  1115. if (!force) {
  1116. fprintf(stderr, "ERROR: Input tree has errors, aborting "
  1117. "(use -f to force output)\n");
  1118. exit(2);
  1119. } else if (quiet < 3) {
  1120. fprintf(stderr, "Warning: Input tree has errors, "
  1121. "output forced\n");
  1122. }
  1123. }
  1124. }