Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tree_64.c
Go to the documentation of this file.
1 /*
2  * tree.c: Basic device tree traversal/scanning for the Linux
3  * prom library.
4  *
5  * Copyright (C) 1995 David S. Miller ([email protected])
6  * Copyright (C) 1996,1997 Jakub Jelinek ([email protected])
7  */
8 
9 #include <linux/string.h>
10 #include <linux/types.h>
11 #include <linux/kernel.h>
12 #include <linux/sched.h>
13 #include <linux/module.h>
14 
15 #include <asm/openprom.h>
16 #include <asm/oplib.h>
17 #include <asm/ldc.h>
18 
19 static phandle prom_node_to_node(const char *type, phandle node)
20 {
21  unsigned long args[5];
22 
23  args[0] = (unsigned long) type;
24  args[1] = 1;
25  args[2] = 1;
26  args[3] = (unsigned int) node;
27  args[4] = (unsigned long) -1;
28 
29  p1275_cmd_direct(args);
30 
31  return (phandle) args[4];
32 }
33 
34 /* Return the child of node 'node' or zero if no this node has no
35  * direct descendent.
36  */
38 {
39  return prom_node_to_node("child", node);
40 }
41 
43 {
44  phandle cnode;
45 
46  if ((s32)node == -1)
47  return 0;
48  cnode = __prom_getchild(node);
49  if ((s32)cnode == -1)
50  return 0;
51  return cnode;
52 }
54 
56 {
57  phandle cnode;
58 
59  if ((s32)node == -1)
60  return 0;
61  cnode = prom_node_to_node("parent", node);
62  if ((s32)cnode == -1)
63  return 0;
64  return cnode;
65 }
66 
67 /* Return the next sibling of node 'node' or zero if no more siblings
68  * at this level of depth in the tree.
69  */
71 {
72  return prom_node_to_node(prom_peer_name, node);
73 }
74 
76 {
77  phandle sibnode;
78 
79  if ((s32)node == -1)
80  return 0;
81  sibnode = __prom_getsibling(node);
82  if ((s32)sibnode == -1)
83  return 0;
84 
85  return sibnode;
86 }
88 
89 /* Return the length in bytes of property 'prop' at node 'node'.
90  * Return -1 on error.
91  */
92 inline int prom_getproplen(phandle node, const char *prop)
93 {
94  unsigned long args[6];
95 
96  if (!node || !prop)
97  return -1;
98 
99  args[0] = (unsigned long) "getproplen";
100  args[1] = 2;
101  args[2] = 1;
102  args[3] = (unsigned int) node;
103  args[4] = (unsigned long) prop;
104  args[5] = (unsigned long) -1;
105 
106  p1275_cmd_direct(args);
107 
108  return (int) args[5];
109 }
111 
112 /* Acquire a property 'prop' at node 'node' and place it in
113  * 'buffer' which has a size of 'bufsize'. If the acquisition
114  * was successful the length will be returned, else -1 is returned.
115  */
116 inline int prom_getproperty(phandle node, const char *prop,
117  char *buffer, int bufsize)
118 {
119  unsigned long args[8];
120  int plen;
121 
122  plen = prom_getproplen(node, prop);
123  if ((plen > bufsize) || (plen == 0) || (plen == -1))
124  return -1;
125 
126  args[0] = (unsigned long) prom_getprop_name;
127  args[1] = 4;
128  args[2] = 1;
129  args[3] = (unsigned int) node;
130  args[4] = (unsigned long) prop;
131  args[5] = (unsigned long) buffer;
132  args[6] = bufsize;
133  args[7] = (unsigned long) -1;
134 
135  p1275_cmd_direct(args);
136 
137  return (int) args[7];
138 }
140 
141 /* Acquire an integer property and return its value. Returns -1
142  * on failure.
143  */
144 inline int prom_getint(phandle node, const char *prop)
145 {
146  int intprop;
147 
148  if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
149  return intprop;
150 
151  return -1;
152 }
154 
155 /* Acquire an integer property, upon error return the passed default
156  * integer.
157  */
158 
159 int prom_getintdefault(phandle node, const char *property, int deflt)
160 {
161  int retval;
162 
163  retval = prom_getint(node, property);
164  if (retval == -1)
165  return deflt;
166 
167  return retval;
168 }
170 
171 /* Acquire a boolean property, 1=TRUE 0=FALSE. */
172 int prom_getbool(phandle node, const char *prop)
173 {
174  int retval;
175 
176  retval = prom_getproplen(node, prop);
177  if (retval == -1)
178  return 0;
179  return 1;
180 }
182 
183 /* Acquire a property whose value is a string, returns a null
184  * string on error. The char pointer is the user supplied string
185  * buffer.
186  */
187 void prom_getstring(phandle node, const char *prop, char *user_buf,
188  int ubuf_size)
189 {
190  int len;
191 
192  len = prom_getproperty(node, prop, user_buf, ubuf_size);
193  if (len != -1)
194  return;
195  user_buf[0] = 0;
196 }
198 
199 /* Does the device at node 'node' have name 'name'?
200  * YES = 1 NO = 0
201  */
202 int prom_nodematch(phandle node, const char *name)
203 {
204  char namebuf[128];
205  prom_getproperty(node, "name", namebuf, sizeof(namebuf));
206  if (strcmp(namebuf, name) == 0)
207  return 1;
208  return 0;
209 }
210 
211 /* Search siblings at 'node_start' for a node with name
212  * 'nodename'. Return node if successful, zero if not.
213  */
214 phandle prom_searchsiblings(phandle node_start, const char *nodename)
215 {
216  phandle thisnode;
217  int error;
218  char promlib_buf[128];
219 
220  for(thisnode = node_start; thisnode;
221  thisnode=prom_getsibling(thisnode)) {
222  error = prom_getproperty(thisnode, "name", promlib_buf,
223  sizeof(promlib_buf));
224  /* Should this ever happen? */
225  if(error == -1) continue;
226  if(strcmp(nodename, promlib_buf)==0) return thisnode;
227  }
228 
229  return 0;
230 }
232 
233 static const char *prom_nextprop_name = "nextprop";
234 
235 /* Return the first property type for node 'node'.
236  * buffer should be at least 32B in length
237  */
238 inline char *prom_firstprop(phandle node, char *buffer)
239 {
240  unsigned long args[7];
241 
242  *buffer = 0;
243  if ((s32)node == -1)
244  return buffer;
245 
246  args[0] = (unsigned long) prom_nextprop_name;
247  args[1] = 3;
248  args[2] = 1;
249  args[3] = (unsigned int) node;
250  args[4] = 0;
251  args[5] = (unsigned long) buffer;
252  args[6] = (unsigned long) -1;
253 
254  p1275_cmd_direct(args);
255 
256  return buffer;
257 }
259 
260 /* Return the property type string after property type 'oprop'
261  * at node 'node' . Returns NULL string if no more
262  * property types for this node.
263  */
264 inline char *prom_nextprop(phandle node, const char *oprop, char *buffer)
265 {
266  unsigned long args[7];
267  char buf[32];
268 
269  if ((s32)node == -1) {
270  *buffer = 0;
271  return buffer;
272  }
273  if (oprop == buffer) {
274  strcpy (buf, oprop);
275  oprop = buf;
276  }
277 
278  args[0] = (unsigned long) prom_nextprop_name;
279  args[1] = 3;
280  args[2] = 1;
281  args[3] = (unsigned int) node;
282  args[4] = (unsigned long) oprop;
283  args[5] = (unsigned long) buffer;
284  args[6] = (unsigned long) -1;
285 
286  p1275_cmd_direct(args);
287 
288  return buffer;
289 }
291 
293 {
294  unsigned long args[5];
295 
296  if (!name)
297  return 0;
298  args[0] = (unsigned long) "finddevice";
299  args[1] = 1;
300  args[2] = 1;
301  args[3] = (unsigned long) name;
302  args[4] = (unsigned long) -1;
303 
304  p1275_cmd_direct(args);
305 
306  return (int) args[4];
307 }
309 
310 int prom_node_has_property(phandle node, const char *prop)
311 {
312  char buf [32];
313 
314  *buf = 0;
315  do {
316  prom_nextprop(node, buf, buf);
317  if (!strcmp(buf, prop))
318  return 1;
319  } while (*buf);
320  return 0;
321 }
323 
324 /* Set property 'pname' at node 'node' to value 'value' which has a length
325  * of 'size' bytes. Return the number of bytes the prom accepted.
326  */
327 int
328 prom_setprop(phandle node, const char *pname, char *value, int size)
329 {
330  unsigned long args[8];
331 
332  if (size == 0)
333  return 0;
334  if ((pname == 0) || (value == 0))
335  return 0;
336 
337 #ifdef CONFIG_SUN_LDOMS
339  ldom_set_var(pname, value);
340  return 0;
341  }
342 #endif
343  args[0] = (unsigned long) "setprop";
344  args[1] = 4;
345  args[2] = 1;
346  args[3] = (unsigned int) node;
347  args[4] = (unsigned long) pname;
348  args[5] = (unsigned long) value;
349  args[6] = size;
350  args[7] = (unsigned long) -1;
351 
352  p1275_cmd_direct(args);
353 
354  return (int) args[7];
355 }
357 
358 inline phandle prom_inst2pkg(int inst)
359 {
360  unsigned long args[5];
361  phandle node;
362 
363  args[0] = (unsigned long) "instance-to-package";
364  args[1] = 1;
365  args[2] = 1;
366  args[3] = (unsigned int) inst;
367  args[4] = (unsigned long) -1;
368 
369  p1275_cmd_direct(args);
370 
371  node = (int) args[4];
372  if ((s32)node == -1)
373  return 0;
374  return node;
375 }
376 
378 {
379  unsigned long args[7];
380 
381  args[0] = (unsigned long) "instance-to-path";
382  args[1] = 3;
383  args[2] = 1;
384  args[3] = (unsigned int) handle;
385  args[4] = (unsigned long) buffer;
386  args[5] = bufsize;
387  args[6] = (unsigned long) -1;
388 
389  p1275_cmd_direct(args);
390 
391  return (int) args[6];
392 }