Annotation of sys/arch/sparc/sparc/openprom.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: openprom.c,v 1.5 2003/06/02 23:27:55 millert Exp $ */
2: /* $NetBSD: openprom.c,v 1.8 1996/03/31 23:45:34 pk 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:
52: #include <machine/bsd_openprom.h>
53: #include <machine/openpromio.h>
54: #include <machine/autoconf.h>
55: #include <machine/conf.h>
56:
57: static int lastnode; /* speed hack */
58: extern int optionsnode; /* node ID of ROM's options */
59: extern struct promvec *promvec;
60:
61: static int openpromcheckid(int, int);
62: static int openpromgetstr(int, char *, char **);
63:
64: int
65: openpromopen(dev, flags, mode, p)
66: dev_t dev;
67: int flags, mode;
68: struct proc *p;
69: {
70: #if defined(SUN4)
71: if (cputyp==CPU_SUN4)
72: return (ENODEV);
73: #endif
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: register int sid, tid;
95: {
96: register struct nodeops *no;
97:
98: no = promvec->pv_nodeops;
99: for (; sid != 0; sid = no->no_nextnode(sid))
100: if (sid == tid || openpromcheckid(no->no_child(sid), tid))
101: return (1);
102:
103: return (0);
104: }
105:
106: static int
107: openpromgetstr(len, user, cpp)
108: int len;
109: char *user, **cpp;
110: {
111: register int error;
112: register char *cp;
113:
114: /* Reject obvious bogus requests */
115: if ((u_int)len > (8 * 1024) - 1)
116: return (ENAMETOOLONG);
117:
118: *cpp = cp = malloc(len + 1, M_TEMP, M_WAITOK);
119: error = copyin(user, cp, len);
120: cp[len] = '\0';
121: return (error);
122: }
123:
124: int
125: openpromioctl(dev, cmd, data, flags, p)
126: dev_t dev;
127: u_long cmd;
128: caddr_t data;
129: int flags;
130: struct proc *p;
131: {
132: register struct opiocdesc *op;
133: register int node, len, ok, error, s;
134: char *name, *value, *nextprop;
135: register struct nodeops *no;
136:
137: /* All too easy... */
138: if (cmd == OPIOCGETOPTNODE) {
139: *(int *)data = optionsnode;
140: return (0);
141: }
142:
143: /* Verify node id */
144: op = (struct opiocdesc *)data;
145: node = op->op_nodeid;
146: if (node != 0 && node != lastnode && node != optionsnode) {
147: /* Not an easy one, must search for it */
148: s = splhigh();
149: ok = openpromcheckid(findroot(), node);
150: splx(s);
151: if (!ok)
152: return (EINVAL);
153: lastnode = node;
154: }
155:
156: name = value = NULL;
157: no = promvec->pv_nodeops;
158: error = 0;
159: switch (cmd) {
160:
161: case OPIOCGET:
162: if ((flags & FREAD) == 0)
163: return (EBADF);
164: if (node == 0)
165: return (EINVAL);
166: error = openpromgetstr(op->op_namelen, op->op_name, &name);
167: if (error)
168: break;
169: s = splhigh();
170: len = no->no_proplen(node, name);
171: splx(s);
172: if (len > op->op_buflen) {
173: error = ENOMEM;
174: break;
175: }
176: op->op_buflen = len;
177: /* -1 means no entry; 0 means no value */
178: if (len <= 0)
179: break;
180: value = malloc(len, M_TEMP, M_WAITOK);
181: s = splhigh();
182: (void)no->no_getprop(node, name, value);
183: splx(s);
184: error = copyout(value, op->op_buf, len);
185: break;
186:
187: case OPIOCSET:
188: if ((flags & FWRITE) == 0)
189: return (EBADF);
190: if (node == 0)
191: return (EINVAL);
192: error = openpromgetstr(op->op_namelen, op->op_name, &name);
193: if (error)
194: break;
195: error = openpromgetstr(op->op_buflen, op->op_buf, &value);
196: if (error)
197: break;
198: s = splhigh();
199: len = no->no_setprop(node, name, value, op->op_buflen + 1);
200: splx(s);
201: if (len != op->op_buflen)
202: error = EINVAL;
203: break;
204:
205: case OPIOCNEXTPROP:
206: if ((flags & FREAD) == 0)
207: return (EBADF);
208: if (node == 0)
209: return (EINVAL);
210: error = openpromgetstr(op->op_namelen, op->op_name, &name);
211: if (error)
212: break;
213: s = splhigh();
214: nextprop = no->no_nextprop(node, name);
215: splx(s);
216: len = strlen(nextprop);
217: if (len > op->op_buflen)
218: len = op->op_buflen;
219: else
220: op->op_buflen = len;
221: error = copyout(nextprop, op->op_buf, len);
222: break;
223:
224: case OPIOCGETNEXT:
225: if ((flags & FREAD) == 0)
226: return (EBADF);
227: s = splhigh();
228: node = no->no_nextnode(node);
229: splx(s);
230: *(int *)data = lastnode = node;
231: break;
232:
233: case OPIOCGETCHILD:
234: if ((flags & FREAD) == 0)
235: return (EBADF);
236: if (node == 0)
237: return (EINVAL);
238: s = splhigh();
239: node = no->no_child(node);
240: splx(s);
241: *(int *)data = lastnode = node;
242: break;
243:
244: default:
245: return (ENOTTY);
246: }
247:
248: if (name)
249: free(name, M_TEMP);
250: if (value)
251: free(value, M_TEMP);
252:
253: return (error);
254: }
CVSweb