1 /* $NetBSD: ofw_subr.c,v 1.14 2009/03/14 21:04:21 dsl Exp $ */
5 * Digital Equipment Corporation. All rights reserved.
7 * This software is furnished under license and may be used and
8 * copied only in accordance with the following terms and conditions.
9 * Subject to these conditions, you may download, copy, install,
10 * use, modify and distribute this software in source and/or binary
11 * form. No title or ownership is transferred hereby.
13 * 1) Any source code used, modified or distributed must reproduce
14 * and retain this copyright notice and list of conditions as
15 * they appear in the source file.
17 * 2) No right is granted to use any trade name, trademark, or logo of
18 * Digital Equipment Corporation. Neither the "Digital Equipment
19 * Corporation" name nor any trademark or logo of Digital Equipment
20 * Corporation may be used to endorse or promote products derived
21 * from this software without the prior written permission of
22 * Digital Equipment Corporation.
24 * 3) This software is provided "AS-IS" and any express or implied
25 * warranties, including but not limited to, any implied warranties
26 * of merchantability, fitness for a particular purpose, or
27 * non-infringement are disclaimed. In no event shall DIGITAL be
28 * liable for any damages whatsoever, and in particular, DIGITAL
29 * shall not be liable for special, indirect, consequential, or
30 * incidental damages or damages for lost profits, loss of
31 * revenue or loss of use, whether such damages arise in contract,
32 * negligence, tort, under statute, in equity, at law or otherwise,
33 * even if advised of the possibility of such damage.
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: ofw_subr.c,v 1.14 2009/03/14 21:04:21 dsl Exp $");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <dev/ofw/openfirm.h>
44 #define OFW_MAX_STACK_BUF_SIZE 256
45 #define OFW_PATH_BUF_SIZE 512
48 * int of_decode_int(p)
50 * This routine converts OFW encoded-int datums
51 * into the integer format of the host machine.
53 * It is primarily used to convert integer properties
54 * returned by the OF_getprop routine.
57 * p pointer to unsigned char array which is an
58 * OFW-encoded integer.
61 * Decoded integer value of argument p.
67 of_decode_int(const unsigned char *p
)
69 unsigned int i
= *p
++ << 8;
76 * int of_compatible(phandle, strings)
78 * This routine checks an OFW node's "compatible" entry to see if
79 * it matches any of the provided strings.
81 * It should be used when determining whether a driver can drive
85 * phandle OFW phandle of device to be checked for
87 * strings Array of containing expected "compatibility"
88 * property values, presence of any of which
89 * indicates compatibility.
92 * -1 if none of the strings are found in phandle's "compatibility"
93 * property, or the index of the string in "strings" of the first
94 * string found in phandle's "compatibility" property.
100 of_compatible(int phandle
, const char * const *strings
)
102 int len
, allocated
, rv
;
104 const char *sp
, *nsp
;
106 len
= OF_getproplen(phandle
, "compatible");
110 if (len
> OFW_MAX_STACK_BUF_SIZE
) {
111 buf
= malloc(len
, M_TEMP
, M_WAITOK
);
118 /* 'compatible' size should not change. */
119 if (OF_getprop(phandle
, "compatible", buf
, len
) != len
) {
125 while (len
&& (nsp
= memchr(sp
, 0, len
)) != NULL
) {
126 /* look for a match among the strings provided */
127 for (rv
= 0; strings
[rv
] != NULL
; rv
++)
128 if (strcmp(sp
, strings
[rv
]) == 0)
131 nsp
++; /* skip over NUL char */
145 * int of_packagename(phandle, buf, bufsize)
147 * This routine places the last component of an OFW node's name
148 * into a user-provided buffer.
150 * It can be used during autoconfiguration to make printing of
151 * device names more informative.
154 * phandle OFW phandle of device whose name name is
156 * buf Buffer to contain device name, provided by
157 * caller. (For now, must be at least 4
159 * bufsize Length of buffer referenced by 'buf', in
163 * -1 if the device path name could not be obtained or would
164 * not fit in the allocated temporary buffer, or zero otherwise
165 * (meaning that the leaf node name was successfully extracted).
168 * If the leaf node name was successfully extracted, 'buf' is
169 * filled in with at most 'bufsize' bytes of the leaf node
170 * name. If the leaf node was not successfully extracted, a
171 * somewhat meaningful string is placed in the buffer. In
172 * either case, the contents of 'buf' will be NUL-terminated.
175 of_packagename(int phandle
, char *buf
, int bufsize
)
178 const char *lastslash
;
181 pbuf
= malloc(OFW_PATH_BUF_SIZE
, M_TEMP
, M_WAITOK
);
182 l
= OF_package_to_path(phandle
, pbuf
, OFW_PATH_BUF_SIZE
);
184 /* check that we could get the name, and that it's not too long. */
186 (l
== OFW_PATH_BUF_SIZE
&& pbuf
[OFW_PATH_BUF_SIZE
- 1] != '\0')) {
188 snprintf(buf
, bufsize
, "??? (phandle 0x%x)", phandle
);
189 else if (bufsize
>= 4)
190 strlcpy(buf
, "???", bufsize
);
192 panic("of_packagename: bufsize = %d is silly",
197 lastslash
= strrchr(pbuf
, '/');
198 strlcpy(buf
, (lastslash
== NULL
) ? pbuf
: (lastslash
+ 1),
208 * Find the first child of a given node that matches name. Does not recurse.
211 of_find_firstchild_byname(int node
, const char *name
)
216 for (nn
= OF_child(node
); nn
; nn
= OF_peer(nn
)) {
217 memset(namex
, 0, sizeof(namex
));
218 if (OF_getprop(nn
, "name", namex
, sizeof(namex
)) == -1)
220 if (strcmp(name
, namex
) == 0)
227 * Find a give node by name. Recurses, and seems to walk upwards too.
231 of_getnode_byname(int start
, const char *target
)
239 for (node
= start
; node
; node
= next
) {
240 memset(name
, 0, sizeof name
);
241 OF_getprop(node
, "name", name
, sizeof name
- 1);
242 if (strcmp(name
, target
) == 0)
245 if ((next
= OF_child(node
)) != 0)
249 if ((next
= OF_peer(node
)) != 0)
251 node
= OF_parent(node
);
255 /* XXX is this correct? */
260 * Create a uint32_t integer property from an OFW node property.
264 of_to_uint32_prop(prop_dictionary_t dict
, int node
, const char *ofname
,
265 const char *propname
)
269 if (OF_getprop(node
, ofname
, &prop
, sizeof(prop
)) != sizeof(prop
))
272 return(prop_dictionary_set_uint32(dict
, propname
, prop
));
276 * Create a data property from an OFW node property. Max size of 256bytes.
280 of_to_dataprop(prop_dictionary_t dict
, int node
, const char *ofname
,
281 const char *propname
)
287 len
= OF_getprop(node
, ofname
, prop
, 256);
291 data
= prop_data_create_data(prop
, len
);
292 return(prop_dictionary_set(dict
, propname
, data
));
296 * look at output-device, see if there's a Sun-typical video mode specifier as
297 * in screen:r1024x768x60 attached. If found copy it into *buffer, otherwise
302 of_get_mode_string(char *buffer
, int len
)
305 char *pos
, output_device
[256];
308 * finally, let's see if there's a video mode specified in
309 * output-device and pass it on so there's at least some way
310 * to program video modes
312 options
= OF_finddevice("/options");
313 if ((options
== 0) || (options
== -1))
315 if (OF_getprop(options
, "output-device", output_device
, 256) == 0)
318 /* find the mode string if there is one */
319 pos
= strstr(output_device
, ":r");
322 strncpy(buffer
, pos
+ 2, len
);