| 457 | } |
| 458 | |
| 459 | int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen) |
| 460 | { |
| 461 | int pdepth = 0, p = 0; |
| 462 | int offset, depth, namelen; |
| 463 | const char *name; |
| 464 | |
| 465 | FDT_CHECK_HEADER(fdt); |
| 466 | |
| 467 | if (buflen < 2) |
| 468 | return -FDT_ERR_NOSPACE; |
| 469 | |
| 470 | for (offset = 0, depth = 0; |
| 471 | (offset >= 0) && (offset <= nodeoffset); |
| 472 | offset = fdt_next_node(fdt, offset, &depth)) { |
| 473 | while (pdepth > depth) { |
| 474 | do { |
| 475 | p--; |
| 476 | } while (buf[p-1] != '/'); |
| 477 | pdepth--; |
| 478 | } |
| 479 | |
| 480 | if (pdepth >= depth) { |
| 481 | name = fdt_get_name(fdt, offset, &namelen); |
| 482 | if (!name) |
| 483 | return namelen; |
| 484 | if ((p + namelen + 1) <= buflen) { |
| 485 | memcpy(buf + p, name, namelen); |
| 486 | p += namelen; |
| 487 | buf[p++] = '/'; |
| 488 | pdepth++; |
| 489 | } |
| 490 | } |
| 491 | |
| 492 | if (offset == nodeoffset) { |
| 493 | if (pdepth < (depth + 1)) |
| 494 | return -FDT_ERR_NOSPACE; |
| 495 | |
| 496 | if (p > 1) /* special case so that root path is "/", not "" */ |
| 497 | p--; |
| 498 | buf[p] = '\0'; |
| 499 | return 0; |
| 500 | } |
| 501 | } |
| 502 | |
| 503 | if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) |
| 504 | return -FDT_ERR_BADOFFSET; |
| 505 | else if (offset == -FDT_ERR_BADOFFSET) |
| 506 | return -FDT_ERR_BADSTRUCTURE; |
| 507 | |
| 508 | return offset; /* error from fdt_next_node() */ |
| 509 | } |
| 510 | |
| 511 | int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset, |
| 512 | int supernodedepth, int *nodedepth) |
no test coverage detected