proc_devtree.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /*
  2. * proc_devtree.c - handles /proc/device-tree
  3. *
  4. * Copyright 1997 Paul Mackerras
  5. */
  6. #include <linux/errno.h>
  7. #include <linux/init.h>
  8. #include <linux/time.h>
  9. #include <linux/proc_fs.h>
  10. #include <linux/stat.h>
  11. #include <linux/string.h>
  12. #include <asm/prom.h>
  13. #include <asm/uaccess.h>
  14. #ifndef HAVE_ARCH_DEVTREE_FIXUPS
  15. static inline void set_node_proc_entry(struct device_node *np,
  16. struct proc_dir_entry *de)
  17. {
  18. }
  19. #endif
  20. static struct proc_dir_entry *proc_device_tree;
  21. /*
  22. * Supply data on a read from /proc/device-tree/node/property.
  23. */
  24. static int property_read_proc(char *page, char **start, off_t off,
  25. int count, int *eof, void *data)
  26. {
  27. struct property *pp = data;
  28. int n;
  29. if (off >= pp->length) {
  30. *eof = 1;
  31. return 0;
  32. }
  33. n = pp->length - off;
  34. if (n > count)
  35. n = count;
  36. else
  37. *eof = 1;
  38. memcpy(page, (char *)pp->value + off, n);
  39. *start = page;
  40. return n;
  41. }
  42. /*
  43. * For a node with a name like "gc@10", we make symlinks called "gc"
  44. * and "@10" to it.
  45. */
  46. /*
  47. * Add a property to a node
  48. */
  49. static struct proc_dir_entry *
  50. __proc_device_tree_add_prop(struct proc_dir_entry *de, struct property *pp,
  51. const char *name)
  52. {
  53. struct proc_dir_entry *ent;
  54. /*
  55. * Unfortunately proc_register puts each new entry
  56. * at the beginning of the list. So we rearrange them.
  57. */
  58. ent = create_proc_read_entry(name,
  59. strncmp(name, "security-", 9)
  60. ? S_IRUGO : S_IRUSR, de,
  61. property_read_proc, pp);
  62. if (ent == NULL)
  63. return NULL;
  64. if (!strncmp(name, "security-", 9))
  65. ent->size = 0; /* don't leak number of password chars */
  66. else
  67. ent->size = pp->length;
  68. return ent;
  69. }
  70. void proc_device_tree_add_prop(struct proc_dir_entry *pde, struct property *prop)
  71. {
  72. __proc_device_tree_add_prop(pde, prop, prop->name);
  73. }
  74. void proc_device_tree_remove_prop(struct proc_dir_entry *pde,
  75. struct property *prop)
  76. {
  77. remove_proc_entry(prop->name, pde);
  78. }
  79. void proc_device_tree_update_prop(struct proc_dir_entry *pde,
  80. struct property *newprop,
  81. struct property *oldprop)
  82. {
  83. struct proc_dir_entry *ent;
  84. for (ent = pde->subdir; ent != NULL; ent = ent->next)
  85. if (ent->data == oldprop)
  86. break;
  87. if (ent == NULL) {
  88. printk(KERN_WARNING "device-tree: property \"%s\" "
  89. " does not exist\n", oldprop->name);
  90. } else {
  91. ent->data = newprop;
  92. ent->size = newprop->length;
  93. }
  94. }
  95. /*
  96. * Various dodgy firmware might give us nodes and/or properties with
  97. * conflicting names. That's generally ok, except for exporting via /proc,
  98. * so munge names here to ensure they're unique.
  99. */
  100. static int duplicate_name(struct proc_dir_entry *de, const char *name)
  101. {
  102. struct proc_dir_entry *ent;
  103. int found = 0;
  104. spin_lock(&proc_subdir_lock);
  105. for (ent = de->subdir; ent != NULL; ent = ent->next) {
  106. if (strcmp(ent->name, name) == 0) {
  107. found = 1;
  108. break;
  109. }
  110. }
  111. spin_unlock(&proc_subdir_lock);
  112. return found;
  113. }
  114. static const char *fixup_name(struct device_node *np, struct proc_dir_entry *de,
  115. const char *name)
  116. {
  117. char *fixed_name;
  118. int fixup_len = strlen(name) + 2 + 1; /* name + #x + \0 */
  119. int i = 1, size;
  120. realloc:
  121. fixed_name = kmalloc(fixup_len, GFP_KERNEL);
  122. if (fixed_name == NULL) {
  123. printk(KERN_ERR "device-tree: Out of memory trying to fixup "
  124. "name \"%s\"\n", name);
  125. return name;
  126. }
  127. retry:
  128. size = snprintf(fixed_name, fixup_len, "%s#%d", name, i);
  129. size++; /* account for NULL */
  130. if (size > fixup_len) {
  131. /* We ran out of space, free and reallocate. */
  132. kfree(fixed_name);
  133. fixup_len = size;
  134. goto realloc;
  135. }
  136. if (duplicate_name(de, fixed_name)) {
  137. /* Multiple duplicates. Retry with a different offset. */
  138. i++;
  139. goto retry;
  140. }
  141. printk(KERN_WARNING "device-tree: Duplicate name in %s, "
  142. "renamed to \"%s\"\n", np->full_name, fixed_name);
  143. return fixed_name;
  144. }
  145. /*
  146. * Process a node, adding entries for its children and its properties.
  147. */
  148. void proc_device_tree_add_node(struct device_node *np,
  149. struct proc_dir_entry *de)
  150. {
  151. struct property *pp;
  152. struct proc_dir_entry *ent;
  153. struct device_node *child;
  154. const char *p;
  155. set_node_proc_entry(np, de);
  156. for (child = NULL; (child = of_get_next_child(np, child));) {
  157. /* Use everything after the last slash, or the full name */
  158. p = strrchr(child->full_name, '/');
  159. if (!p)
  160. p = child->full_name;
  161. else
  162. ++p;
  163. if (duplicate_name(de, p))
  164. p = fixup_name(np, de, p);
  165. ent = proc_mkdir(p, de);
  166. if (ent == 0)
  167. break;
  168. proc_device_tree_add_node(child, ent);
  169. }
  170. of_node_put(child);
  171. for (pp = np->properties; pp != 0; pp = pp->next) {
  172. p = pp->name;
  173. if (duplicate_name(de, p))
  174. p = fixup_name(np, de, p);
  175. ent = __proc_device_tree_add_prop(de, pp, p);
  176. if (ent == 0)
  177. break;
  178. }
  179. }
  180. /*
  181. * Called on initialization to set up the /proc/device-tree subtree
  182. */
  183. void __init proc_device_tree_init(void)
  184. {
  185. struct device_node *root;
  186. proc_device_tree = proc_mkdir("device-tree", NULL);
  187. if (proc_device_tree == 0)
  188. return;
  189. root = of_find_node_by_path("/");
  190. if (root == 0) {
  191. printk(KERN_ERR "/proc/device-tree: can't find root\n");
  192. return;
  193. }
  194. proc_device_tree_add_node(root, proc_device_tree);
  195. of_node_put(root);
  196. }