Annotation of sys/arch/sparc64/sparc64/openprom.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: openprom.c,v 1.12 2007/08/10 14:25:08 fgsch Exp $ */
2: /* $NetBSD: openprom.c,v 1.4 2002/01/10 06:21:53 briggs Exp $ */
3:
4: /*
5: * Copyright (c) 1992, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * This software was developed by the Computer Systems Engineering group
9: * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
10: * contributed to Berkeley.
11: *
12: * All advertising materials mentioning features or use of this software
13: * must display the following acknowledgement:
14: * This product includes software developed by the University of
15: * California, Lawrence Berkeley Laboratory.
16: *
17: * Redistribution and use in source and binary forms, with or without
18: * modification, are permitted provided that the following conditions
19: * are met:
20: * 1. Redistributions of source code must retain the above copyright
21: * notice, this list of conditions and the following disclaimer.
22: * 2. Redistributions in binary form must reproduce the above copyright
23: * notice, this list of conditions and the following disclaimer in the
24: * documentation and/or other materials provided with the distribution.
25: * 3. Neither the name of the University nor the names of its contributors
26: * may be used to endorse or promote products derived from this software
27: * without specific prior written permission.
28: *
29: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39: * SUCH DAMAGE.
40: *
41: * @(#)openprom.c 8.1 (Berkeley) 6/11/93
42: */
43:
44: #include <sys/param.h>
45: #include <sys/systm.h>
46: #include <sys/errno.h>
47: #include <sys/fcntl.h>
48: #include <sys/ioctl.h>
49: #include <sys/malloc.h>
50: #include <sys/conf.h>
51: #include <sys/device.h>
52:
53: #include <machine/bsd_openprom.h>
54: #include <machine/openpromio.h>
55: #include <machine/autoconf.h>
56: #include <machine/conf.h>
57:
58: #include <dev/ofw/openfirm.h>
59:
60: #define OPROMMAXPARAM 32
61:
62: static int lastnode; /* speed hack */
63: extern int optionsnode; /* node ID of ROM's options */
64:
65: static int openpromcheckid(int, int);
66: static int openpromgetstr(int, char *, char **);
67:
68: int
69: openpromopen(dev, flags, mode, p)
70: dev_t dev;
71: int flags, mode;
72: struct proc *p;
73: {
74:
75: return (0);
76: }
77:
78: int
79: openpromclose(dev, flags, mode, p)
80: dev_t dev;
81: int flags, mode;
82: struct proc *p;
83: {
84:
85: return (0);
86: }
87:
88: /*
89: * Verify target ID is valid (exists in the OPENPROM tree), as
90: * listed from node ID sid forward.
91: */
92: static int
93: openpromcheckid(sid, tid)
94: int sid, tid;
95: {
96: for (; sid != 0; sid = OF_peer(sid))
97: if (sid == tid || openpromcheckid(OF_child(sid), tid))
98: return (1);
99:
100: return (0);
101: }
102:
103: static int
104: openpromgetstr(len, user, cpp)
105: int len;
106: char *user, **cpp;
107: {
108: int error;
109: char *cp;
110:
111: /* Reject obvious bogus requests */
112: if ((u_int)len > (8 * 1024) - 1)
113: return (ENAMETOOLONG);
114:
115: *cpp = cp = malloc(len + 1, M_TEMP, M_WAITOK);
116: error = copyin(user, cp, len);
117: cp[len] = '\0';
118: return (error);
119: }
120:
121: int
122: openpromioctl(dev, cmd, data, flags, p)
123: dev_t dev;
124: u_long cmd;
125: caddr_t data;
126: int flags;
127: struct proc *p;
128: {
129: struct opiocdesc *op;
130: int node, len, ok, error, s;
131: char *name, *value, *nextprop;
132:
133: /* All too easy... */
134: if (cmd == OPIOCGETOPTNODE) {
135: *(int *)data = optionsnode;
136: return (0);
137: }
138:
139: /* Verify node id */
140: op = (struct opiocdesc *)data;
141: node = op->op_nodeid;
142: if (node != 0 && node != lastnode && node != optionsnode) {
143: /* Not an easy one, must search for it */
144: s = splhigh();
145: ok = openpromcheckid(findroot(), node);
146: splx(s);
147: if (!ok)
148: return (EINVAL);
149: lastnode = node;
150: }
151:
152: name = value = NULL;
153: error = 0;
154: switch (cmd) {
155:
156: case OPIOCGET:
157: if ((flags & FREAD) == 0)
158: return (EBADF);
159: if (node == 0)
160: return (EINVAL);
161: error = openpromgetstr(op->op_namelen, op->op_name, &name);
162: if (error)
163: break;
164: s = splhigh();
165: len = getproplen(node, name);
166: splx(s);
167: if (len > op->op_buflen) {
168: error = ENOMEM;
169: break;
170: }
171: op->op_buflen = len;
172: /* -1 means no entry; 0 means no value */
173: if (len <= 0)
174: break;
175: value = malloc(len, M_TEMP, M_WAITOK);
176: s = splhigh();
177: error = getprop(node, name, 1, &len, (void **)&value);
178: splx(s);
179: if (error != 0)
180: break;
181: error = copyout(value, op->op_buf, len);
182: break;
183:
184: case OPIOCSET:
185: if ((flags & FWRITE) == 0)
186: return (EBADF);
187: if (node == 0)
188: return (EINVAL);
189: error = openpromgetstr(op->op_namelen, op->op_name, &name);
190: if (error)
191: break;
192: error = openpromgetstr(op->op_buflen, op->op_buf, &value);
193: if (error)
194: break;
195: s = splhigh();
196: len = OF_setprop(node, name, value, op->op_buflen + 1);
197: splx(s);
198: if (len != op->op_buflen)
199: error = EINVAL;
200: break;
201:
202: case OPIOCNEXTPROP:
203: if ((flags & FREAD) == 0)
204: return (EBADF);
205: if (node == 0)
206: return (EINVAL);
207: error = openpromgetstr(op->op_namelen, op->op_name, &name);
208: if (error)
209: break;
210: if (op->op_buflen <= 0) {
211: error = ENAMETOOLONG;
212: break;
213: }
214: value = nextprop = malloc(OPROMMAXPARAM, M_TEMP, M_WAITOK);
215: if (nextprop == NULL) {
216: error = ENOMEM;
217: break;
218: }
219: s = splhigh();
220: error = OF_nextprop(node, name, nextprop);
221: splx(s);
222: if (error == -1) {
223: error = EINVAL;
224: break;
225: }
226: if (error == 0) {
227: char nul = '\0';
228:
229: op->op_buflen = 0;
230: error = copyout(&nul, op->op_buf, sizeof(char));
231: break;
232: }
233: len = strlen(nextprop);
234: if (len > op->op_buflen)
235: len = op->op_buflen;
236: else
237: op->op_buflen = len;
238: error = copyout(nextprop, op->op_buf, len);
239: break;
240:
241: case OPIOCGETNEXT:
242: if ((flags & FREAD) == 0)
243: return (EBADF);
244: s = splhigh();
245: node = nextsibling(node);
246: splx(s);
247: *(int *)data = lastnode = node;
248: break;
249:
250: case OPIOCGETCHILD:
251: if ((flags & FREAD) == 0)
252: return (EBADF);
253: if (node == 0)
254: return (EINVAL);
255: s = splhigh();
256: node = firstchild(node);
257: splx(s);
258: *(int *)data = lastnode = node;
259: break;
260:
261: default:
262: return (ENOTTY);
263: }
264:
265: if (name)
266: free(name, M_TEMP);
267: if (value)
268: free(value, M_TEMP);
269:
270: return (error);
271: }
CVSweb