243
243
NODE_CHECK(duplicate_property_names, NULL, ERROR);
245
#define LOWERCASE "abcdefghijklmnopqrstuvwxyz"
246
#define UPPERCASE "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
247
#define DIGITS "0123456789"
248
#define PROPNODECHARS LOWERCASE UPPERCASE DIGITS ",._+*#?-"
250
static void check_node_name_chars(struct check *c, struct node *dt,
253
int n = strspn(node->name, c->data);
255
if (n < strlen(node->name))
256
FAIL(c, "Bad character '%c' in node %s",
257
node->name[n], node->fullpath);
259
NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
261
static void check_node_name_format(struct check *c, struct node *dt,
264
if (strchr(get_unitname(node), '@'))
265
FAIL(c, "Node %s has multiple '@' characters in name",
268
NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
270
static void check_property_name_chars(struct check *c, struct node *dt,
271
struct node *node, struct property *prop)
273
int n = strspn(prop->name, c->data);
275
if (n < strlen(prop->name))
276
FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
277
prop->name[n], prop->name, node->fullpath);
279
PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
281
#define DESCLABEL_FMT "%s%s%s%s%s"
282
#define DESCLABEL_ARGS(node,prop,mark) \
283
((mark) ? "value of " : ""), \
284
((prop) ? "'" : ""), \
285
((prop) ? (prop)->name : ""), \
286
((prop) ? "' in " : ""), (node)->fullpath
288
static void check_duplicate_label(struct check *c, struct node *dt,
289
const char *label, struct node *node,
290
struct property *prop, struct marker *mark)
292
struct node *othernode = NULL;
293
struct property *otherprop = NULL;
294
struct marker *othermark = NULL;
296
othernode = get_node_by_label(dt, label);
299
otherprop = get_property_by_label(dt, label, &othernode);
301
othermark = get_marker_label(dt, label, &othernode,
307
if ((othernode != node) || (otherprop != prop) || (othermark != mark))
308
FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
309
" and " DESCLABEL_FMT,
310
label, DESCLABEL_ARGS(node, prop, mark),
311
DESCLABEL_ARGS(othernode, otherprop, othermark));
314
static void check_duplicate_label_node(struct check *c, struct node *dt,
319
for_each_label(node->labels, l)
320
check_duplicate_label(c, dt, l->label, node, NULL, NULL);
322
static void check_duplicate_label_prop(struct check *c, struct node *dt,
323
struct node *node, struct property *prop)
325
struct marker *m = prop->val.markers;
328
for_each_label(prop->labels, l)
329
check_duplicate_label(c, dt, l->label, node, prop, NULL);
331
for_each_marker_of_type(m, LABEL)
332
check_duplicate_label(c, dt, m->ref, node, prop, m);
334
CHECK(duplicate_label, NULL, check_duplicate_label_node,
335
check_duplicate_label_prop, NULL, ERROR);
245
337
static void check_explicit_phandles(struct check *c, struct node *root,
338
struct node *node, struct property *prop)
248
struct property *prop;
249
341
struct node *other;
252
prop = get_property(node, "linux,phandle");
254
return; /* No phandle, that's fine */
344
if (!streq(prop->name, "phandle")
345
&& !streq(prop->name, "linux,phandle"))
256
348
if (prop->val.len != sizeof(cell_t)) {
257
FAIL(c, "%s has bad length (%d) linux,phandle property",
258
node->fullpath, prop->val.len);
349
FAIL(c, "%s has bad length (%d) %s property",
350
node->fullpath, prop->val.len, prop->name);
354
m = prop->val.markers;
355
for_each_marker_of_type(m, REF_PHANDLE) {
356
assert(m->offset == 0);
357
if (node != get_node_by_ref(root, m->ref))
358
/* "Set this node's phandle equal to some
359
* other node's phandle". That's nonsensical
360
* by construction. */ {
361
FAIL(c, "%s in %s is a reference to another node",
362
prop->name, node->fullpath);
365
/* But setting this node's phandle equal to its own
366
* phandle is allowed - that means allocate a unique
367
* phandle for this node, even if it's not otherwise
368
* referenced. The value will be filled in later, so
369
* no further checking for now. */
262
373
phandle = propval_cell(prop);
263
375
if ((phandle == 0) || (phandle == -1)) {
264
FAIL(c, "%s has invalid linux,phandle value 0x%x",
265
node->fullpath, phandle);
376
FAIL(c, "%s has bad value (0x%x) in %s property",
377
node->fullpath, phandle, prop->name);
381
if (node->phandle && (node->phandle != phandle))
382
FAIL(c, "%s has %s property which replaces existing phandle information",
383
node->fullpath, prop->name);
269
385
other = get_node_by_phandle(root, phandle);
386
if (other && (other != node)) {
271
387
FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
272
388
node->fullpath, phandle, other->fullpath);
276
392
node->phandle = phandle;
278
NODE_CHECK(explicit_phandles, NULL, ERROR);
394
PROP_CHECK(explicit_phandles, NULL, ERROR);
280
396
static void check_name_properties(struct check *c, struct node *root,
281
397
struct node *node)
283
struct property *prop;
285
prop = get_property(node, "name");
399
struct property **pp, *prop = NULL;
401
for (pp = &node->proplist; *pp; pp = &((*pp)->next))
402
if (streq((*pp)->name, "name")) {
287
408
return; /* No name property, that's fine */
289
410
if ((prop->val.len != node->basenamelen+1)
290
|| (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
411
|| (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
291
412
FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
292
413
" of base node name)", node->fullpath, prop->val.val);
415
/* The name property is correct, and therefore redundant.
419
data_free(prop->val);
294
423
CHECK_IS_STRING(name_is_string, "name", ERROR);
295
424
NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
301
430
static void fixup_phandle_references(struct check *c, struct node *dt,
302
431
struct node *node, struct property *prop)
304
struct marker *m = prop->val.markers;
305
struct node *refnode;
308
for_each_marker_of_type(m, REF_PHANDLE) {
309
assert(m->offset + sizeof(cell_t) <= prop->val.len);
311
refnode = get_node_by_ref(dt, m->ref);
313
FAIL(c, "Reference to non-existent node or label \"%s\"\n",
318
phandle = get_node_phandle(dt, refnode);
319
*((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
433
struct marker *m = prop->val.markers;
434
struct node *refnode;
437
for_each_marker_of_type(m, REF_PHANDLE) {
438
assert(m->offset + sizeof(cell_t) <= prop->val.len);
440
refnode = get_node_by_ref(dt, m->ref);
442
FAIL(c, "Reference to non-existent node or label \"%s\"\n",
447
phandle = get_node_phandle(dt, refnode);
448
*((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
322
451
CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
323
452
&duplicate_node_names, &explicit_phandles);