1 /* $NetBSD: ofhandlers.c,v 1.3 2007/01/16 17:32:04 hubertf Exp $ */
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/ioctl.h>
41 #include <dev/ofw/openfirmio.h>
45 extern char *path_openfirm
;
49 static char err_str
[BUFSIZE
];
51 static void of_notsupp (struct extabent
*, struct ofiocdesc
*, char *);
52 static void of_uint32h (struct extabent
*, struct ofiocdesc
*, char *);
53 static void of_uint32d (struct extabent
*, struct ofiocdesc
*, char *);
56 * There are several known fields that I either don't know how to
57 * deal with or require special treatment.
59 static struct extabent ofextab
[] = {
60 { "security-password", of_notsupp
},
61 { "security-mode", of_notsupp
},
62 { "oem-logo", of_notsupp
},
63 { "oem-banner", of_notsupp
},
64 { "real-base", of_uint32h
},
65 { "real-size", of_uint32h
},
66 { "load-base", of_uint32h
},
67 { "virt-base", of_uint32h
},
68 { "virt-size", of_uint32h
},
69 { "screen-#columns", of_uint32d
},
70 { "screen-#rows", of_uint32d
},
71 { "selftest-#megs", of_uint32d
},
75 #define BARF(str1, str2) { \
76 snprintf(err_str, sizeof err_str, "%s: %s", (str1), (str2)); \
82 of_action(keyword
, arg
)
87 if ((cp
= of_handler(keyword
, arg
)) != NULL
)
93 of_handler(keyword
, arg
)
96 struct ofiocdesc ofio
;
98 char ofio_buf
[BUFSIZE
];
101 if ((fd
= open(path_openfirm
, arg
? O_RDWR
: O_RDONLY
, 0640)) < 0)
102 BARF(path_openfirm
, strerror(errno
));
104 /* Check to see if it's a special-case keyword. */
105 for (ex
= ofextab
; ex
->ex_keyword
!= NULL
; ++ex
)
106 if (strcmp(ex
->ex_keyword
, keyword
) == 0)
109 if (ioctl(fd
, OFIOCGETOPTNODE
, (char *)&optnode
) < 0)
110 BARF("OFIOCGETOPTNODE", strerror(errno
));
112 memset(&ofio_buf
[0], 0, sizeof(ofio_buf
));
113 memset(&ofio
, 0, sizeof(ofio
));
114 ofio
.of_nodeid
= optnode
;
115 ofio
.of_name
= keyword
;
116 ofio
.of_namelen
= strlen(ofio
.of_name
);
122 ofio
.of_buf
= &ofio_buf
[0];
123 ofio
.of_buflen
= sizeof(ofio_buf
);
124 if (ioctl(fd
, OFIOCGET
, (char *)&ofio
) < 0)
125 BARF("OFIOCGET", strerror(errno
));
127 if (ofio
.of_buflen
<= 0) {
128 printf("nothing available for %s\n", keyword
);
132 if (ex
->ex_keyword
!= NULL
)
133 (*ex
->ex_handler
)(ex
, &ofio
, NULL
);
135 printf("%s\n", ofio
.of_buf
);
138 if (ex
->ex_keyword
!= NULL
)
139 (*ex
->ex_handler
)(ex
, &ofio
, arg
);
142 ofio
.of_buflen
= strlen(arg
);
145 if (ioctl(fd
, OFIOCSET
, (char *)&ofio
) < 0)
146 BARF("invalid keyword", keyword
);
150 if (ex
->ex_keyword
!= NULL
)
151 (*ex
->ex_handler
)(ex
, &ofio
, NULL
);
153 printf("%s\n", ofio
.of_buf
);
156 ofio
.of_buf
= &ofio_buf
[0];
157 ofio
.of_buflen
= sizeof(ofio_buf
);
158 if (ioctl(fd
, OFIOCGET
, (char *)&ofio
) < 0)
159 BARF("OFIOCGET", strerror(errno
));
161 if (ofio
.of_buflen
<= 0) {
162 (void)snprintf(err_str
, sizeof err_str
,
163 "nothing available for %s", keyword
);
167 if (ex
->ex_keyword
!= NULL
)
168 (*ex
->ex_handler
)(ex
, &ofio
, NULL
);
170 printf("%s=%s\n", keyword
, ofio
.of_buf
);
179 of_notsupp(exent
, ofiop
, arg
)
180 struct extabent
*exent
;
181 struct ofiocdesc
*ofiop
;
185 warnx("property `%s' not yet supported", exent
->ex_keyword
);
189 of_uint32h(exent
, ofiop
, arg
)
190 struct extabent
*exent
;
191 struct ofiocdesc
*ofiop
;
195 printf("%s=0x%08x\n", exent
->ex_keyword
, *(uint32_t *)ofiop
->of_buf
);
199 of_uint32d(exent
, ofiop
, arg
)
200 struct extabent
*exent
;
201 struct ofiocdesc
*ofiop
;
205 printf("%s=%d\n", exent
->ex_keyword
, *(uint32_t *)ofiop
->of_buf
);
209 * XXX: This code is quite ugly. You have been warned.
210 * (Really! This is the only way I could get it to work!)
215 struct ofiocdesc ofio1
, ofio2
;
217 char buf1
[BUFSIZE
], buf2
[BUFSIZE
], buf3
[BUFSIZE
], buf4
[BUFSIZE
];
220 if ((fd
= open(path_openfirm
, O_RDONLY
, 0640)) < 0)
221 err(1, "open: %s", path_openfirm
);
223 if (ioctl(fd
, OFIOCGETOPTNODE
, (char *)&optnode
) < 0)
224 err(1, "OFIOCGETOPTNODE");
226 memset(&ofio1
, 0, sizeof(ofio1
));
228 /* This will grab the first property name from OPIOCNEXTPROP. */
229 memset(buf1
, 0, sizeof(buf1
));
230 memset(buf2
, 0, sizeof(buf2
));
232 ofio1
.of_nodeid
= ofio2
.of_nodeid
= optnode
;
234 ofio1
.of_name
= buf1
;
237 ofio2
.of_name
= buf3
;
241 * For reference: ofio1 is for obtaining the name. Pass the
242 * name of the last property read in of_name, and the next one
243 * will be returned in of_buf. To get the first name, pass
244 * an empty string. There are no more properties when an
245 * empty string is returned.
247 * ofio2 is for obtaining the value associated with that name.
248 * For some crazy reason, it seems as if we need to do all
249 * of that gratuitious zapping and copying. *sigh*
252 ofio1
.of_namelen
= strlen(ofio1
.of_name
);
253 ofio1
.of_buflen
= sizeof(buf2
);
255 if (ioctl(fd
, OFIOCNEXTPROP
, (char *)&ofio1
) < 0) {
258 /* err(1, "ioctl: OFIOCNEXTPROP"); */
262 * The name of the property we wish to get the
263 * value for has been stored in the value field
264 * of ofio1. If the length of the name is 0, there
265 * are no more properties left.
267 strcpy(ofio2
.of_name
, ofio1
.of_buf
); /* XXX strcpy is safe */
268 ofio2
.of_namelen
= strlen(ofio2
.of_name
);
270 if (ofio2
.of_namelen
== 0) {
275 memset(ofio2
.of_buf
, 0, sizeof(buf4
));
276 ofio2
.of_buflen
= sizeof(buf4
);
278 if (ioctl(fd
, OFIOCGET
, (char *)&ofio2
) < 0)
279 err(1, "ioctl: OFIOCGET");
281 for (ex
= ofextab
; ex
->ex_keyword
!= NULL
; ++ex
)
282 if (strcmp(ex
->ex_keyword
, ofio2
.of_name
) == 0)
285 if (ex
->ex_keyword
!= NULL
)
286 (*ex
->ex_handler
)(ex
, &ofio2
, NULL
);
288 printf("%s=%s\n", ofio2
.of_name
, ofio2
.of_buf
);
291 * Place the name of the last read value back into
292 * ofio1 so that we may obtain the next name.
294 memset(ofio1
.of_name
, 0, sizeof(buf1
));
295 memset(ofio1
.of_buf
, 0, sizeof(buf2
));
296 strcpy(ofio1
.of_name
, ofio2
.of_name
); /* XXX strcpy is safe */