sunos32_ioctl.c revision 1.4 1 1.4 mrg /* $NetBSD: sunos32_ioctl.c,v 1.4 2001/05/30 11:37:31 mrg Exp $ */
2 1.2 mrg /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */
3 1.1 mrg
4 1.1 mrg /*
5 1.1 mrg * Copyright (c) 2001 Matthew R. Green
6 1.1 mrg * All rights reserved.
7 1.1 mrg *
8 1.1 mrg * Redistribution and use in source and binary forms, with or without
9 1.1 mrg * modification, are permitted provided that the following conditions
10 1.1 mrg * are met:
11 1.1 mrg * 1. Redistributions of source code must retain the above copyright
12 1.1 mrg * notice, this list of conditions and the following disclaimer.
13 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 mrg * notice, this list of conditions and the following disclaimer in the
15 1.1 mrg * documentation and/or other materials provided with the distribution.
16 1.1 mrg * 3. The name of the author may not be used to endorse or promote products
17 1.1 mrg * derived from this software without specific prior written permission.
18 1.1 mrg *
19 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 1.1 mrg * SUCH DAMAGE.
30 1.1 mrg */
31 1.1 mrg
32 1.2 mrg /*
33 1.2 mrg * Copyright (c) 1993 Markus Wild.
34 1.2 mrg * All rights reserved.
35 1.2 mrg *
36 1.2 mrg * Redistribution and use in source and binary forms, with or without
37 1.2 mrg * modification, are permitted provided that the following conditions
38 1.2 mrg * are met:
39 1.2 mrg * 1. Redistributions of source code must retain the above copyright
40 1.2 mrg * notice, this list of conditions and the following disclaimer.
41 1.2 mrg * 2. The name of the author may not be used to endorse or promote products
42 1.2 mrg * derived from this software without specific prior written permission
43 1.2 mrg *
44 1.2 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
45 1.2 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 1.2 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 1.2 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
48 1.2 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
49 1.2 mrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
50 1.2 mrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
51 1.2 mrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
52 1.2 mrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
53 1.2 mrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 1.2 mrg *
55 1.2 mrg * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
56 1.2 mrg */
57 1.2 mrg
58 1.4 mrg #if defined(_KERNEL_OPT)
59 1.2 mrg #include "opt_compat_netbsd32.h"
60 1.2 mrg #include "opt_execfmt.h"
61 1.2 mrg #endif
62 1.2 mrg
63 1.2 mrg #include <sys/param.h>
64 1.2 mrg #include <sys/proc.h>
65 1.2 mrg #include <sys/systm.h>
66 1.2 mrg #include <sys/file.h>
67 1.2 mrg #include <sys/filedesc.h>
68 1.2 mrg #include <sys/ioctl.h>
69 1.2 mrg #include <sys/termios.h>
70 1.2 mrg #include <sys/tty.h>
71 1.2 mrg #include <sys/socket.h>
72 1.2 mrg #include <sys/audioio.h>
73 1.2 mrg #include <sys/vnode.h>
74 1.2 mrg #include <sys/mount.h>
75 1.2 mrg #include <sys/disklabel.h>
76 1.2 mrg #include <sys/syscallargs.h>
77 1.2 mrg
78 1.2 mrg #include <miscfs/specfs/specdev.h>
79 1.2 mrg
80 1.2 mrg #include <net/if.h>
81 1.2 mrg
82 1.2 mrg #include <dev/sun/disklabel.h>
83 1.2 mrg
84 1.2 mrg #include <compat/sunos/sunos.h>
85 1.2 mrg #include <compat/sunos/sunos_syscallargs.h>
86 1.2 mrg #include <compat/netbsd32/netbsd32.h>
87 1.2 mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
88 1.2 mrg #include <compat/sunos32/sunos32.h>
89 1.2 mrg #include <compat/sunos32/sunos32_syscallargs.h>
90 1.2 mrg #include <compat/common/compat_util.h>
91 1.2 mrg
92 1.2 mrg /*
93 1.2 mrg * SunOS ioctl calls.
94 1.2 mrg * This file is something of a hodge-podge.
95 1.2 mrg * Support gets added as things turn up....
96 1.2 mrg */
97 1.2 mrg
98 1.2 mrg static struct speedtab sptab[] = {
99 1.2 mrg { 0, 0 },
100 1.2 mrg { 50, 1 },
101 1.2 mrg { 75, 2 },
102 1.2 mrg { 110, 3 },
103 1.2 mrg { 134, 4 },
104 1.2 mrg { 135, 4 },
105 1.2 mrg { 150, 5 },
106 1.2 mrg { 200, 6 },
107 1.2 mrg { 300, 7 },
108 1.2 mrg { 600, 8 },
109 1.2 mrg { 1200, 9 },
110 1.2 mrg { 1800, 10 },
111 1.2 mrg { 2400, 11 },
112 1.2 mrg { 4800, 12 },
113 1.2 mrg { 9600, 13 },
114 1.2 mrg { 19200, 14 },
115 1.2 mrg { 38400, 15 },
116 1.2 mrg { -1, -1 }
117 1.2 mrg };
118 1.2 mrg
119 1.3 mrg static netbsd32_u_long s2btab[] = {
120 1.2 mrg 0,
121 1.2 mrg 50,
122 1.2 mrg 75,
123 1.2 mrg 110,
124 1.2 mrg 134,
125 1.2 mrg 150,
126 1.2 mrg 200,
127 1.2 mrg 300,
128 1.2 mrg 600,
129 1.2 mrg 1200,
130 1.2 mrg 1800,
131 1.2 mrg 2400,
132 1.2 mrg 4800,
133 1.2 mrg 9600,
134 1.2 mrg 19200,
135 1.2 mrg 38400,
136 1.2 mrg };
137 1.2 mrg
138 1.2 mrg static void stios2btios __P((struct sunos_termios *, struct termios *));
139 1.2 mrg static void btios2stios __P((struct termios *, struct sunos_termios *));
140 1.2 mrg static void stios2stio __P((struct sunos_termios *, struct sunos_termio *));
141 1.2 mrg static void stio2stios __P((struct sunos_termio *, struct sunos_termios *));
142 1.2 mrg
143 1.2 mrg /*
144 1.2 mrg * These two conversion functions have mostly been done
145 1.2 mrg * with some perl cut&paste, then hand-edited to comment
146 1.2 mrg * out what doesn't exist under NetBSD.
147 1.2 mrg * A note from Markus's code:
148 1.2 mrg * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
149 1.2 mrg * optimally by gcc m68k, much better than any ?: stuff.
150 1.2 mrg * Code may vary with different architectures of course.
151 1.2 mrg *
152 1.2 mrg * I don't know what optimizer you used, but seeing divu's and
153 1.2 mrg * bfextu's in the m68k assembly output did not encourage me...
154 1.2 mrg * as well, gcc on the sparc definitely generates much better
155 1.2 mrg * code with `?:'.
156 1.2 mrg */
157 1.2 mrg
158 1.2 mrg static void
159 1.2 mrg stios2btios(st, bt)
160 1.2 mrg struct sunos_termios *st;
161 1.2 mrg struct termios *bt;
162 1.2 mrg {
163 1.3 mrg netbsd32_u_long l, r;
164 1.2 mrg
165 1.2 mrg l = st->c_iflag;
166 1.2 mrg r = ((l & 0x00000001) ? IGNBRK : 0);
167 1.2 mrg r |= ((l & 0x00000002) ? BRKINT : 0);
168 1.2 mrg r |= ((l & 0x00000004) ? IGNPAR : 0);
169 1.2 mrg r |= ((l & 0x00000008) ? PARMRK : 0);
170 1.2 mrg r |= ((l & 0x00000010) ? INPCK : 0);
171 1.2 mrg r |= ((l & 0x00000020) ? ISTRIP : 0);
172 1.2 mrg r |= ((l & 0x00000040) ? INLCR : 0);
173 1.2 mrg r |= ((l & 0x00000080) ? IGNCR : 0);
174 1.2 mrg r |= ((l & 0x00000100) ? ICRNL : 0);
175 1.2 mrg /* ((l & 0x00000200) ? IUCLC : 0) */
176 1.2 mrg r |= ((l & 0x00000400) ? IXON : 0);
177 1.2 mrg r |= ((l & 0x00000800) ? IXANY : 0);
178 1.2 mrg r |= ((l & 0x00001000) ? IXOFF : 0);
179 1.2 mrg r |= ((l & 0x00002000) ? IMAXBEL : 0);
180 1.2 mrg bt->c_iflag = r;
181 1.2 mrg
182 1.2 mrg l = st->c_oflag;
183 1.2 mrg r = ((l & 0x00000001) ? OPOST : 0);
184 1.2 mrg /* ((l & 0x00000002) ? OLCUC : 0) */
185 1.2 mrg r |= ((l & 0x00000004) ? ONLCR : 0);
186 1.2 mrg /* ((l & 0x00000008) ? OCRNL : 0) */
187 1.2 mrg /* ((l & 0x00000010) ? ONOCR : 0) */
188 1.2 mrg /* ((l & 0x00000020) ? ONLRET : 0) */
189 1.2 mrg /* ((l & 0x00000040) ? OFILL : 0) */
190 1.2 mrg /* ((l & 0x00000080) ? OFDEL : 0) */
191 1.2 mrg /* ((l & 0x00000100) ? NLDLY : 0) */
192 1.2 mrg /* ((l & 0x00000100) ? NL1 : 0) */
193 1.2 mrg /* ((l & 0x00000600) ? CRDLY : 0) */
194 1.2 mrg /* ((l & 0x00000200) ? CR1 : 0) */
195 1.2 mrg /* ((l & 0x00000400) ? CR2 : 0) */
196 1.2 mrg /* ((l & 0x00000600) ? CR3 : 0) */
197 1.2 mrg /* ((l & 0x00001800) ? TABDLY : 0) */
198 1.2 mrg /* ((l & 0x00000800) ? TAB1 : 0) */
199 1.2 mrg /* ((l & 0x00001000) ? TAB2 : 0) */
200 1.2 mrg r |= ((l & 0x00001800) ? OXTABS : 0);
201 1.2 mrg /* ((l & 0x00002000) ? BSDLY : 0) */
202 1.2 mrg /* ((l & 0x00002000) ? BS1 : 0) */
203 1.2 mrg /* ((l & 0x00004000) ? VTDLY : 0) */
204 1.2 mrg /* ((l & 0x00004000) ? VT1 : 0) */
205 1.2 mrg /* ((l & 0x00008000) ? FFDLY : 0) */
206 1.2 mrg /* ((l & 0x00008000) ? FF1 : 0) */
207 1.2 mrg /* ((l & 0x00010000) ? PAGEOUT : 0) */
208 1.2 mrg /* ((l & 0x00020000) ? WRAP : 0) */
209 1.2 mrg bt->c_oflag = r;
210 1.2 mrg
211 1.2 mrg l = st->c_cflag;
212 1.2 mrg switch (l & 0x00000030) {
213 1.2 mrg case 0:
214 1.2 mrg r = CS5;
215 1.2 mrg break;
216 1.2 mrg case 0x00000010:
217 1.2 mrg r = CS6;
218 1.2 mrg break;
219 1.2 mrg case 0x00000020:
220 1.2 mrg r = CS7;
221 1.2 mrg break;
222 1.2 mrg case 0x00000030:
223 1.2 mrg r = CS8;
224 1.2 mrg break;
225 1.2 mrg }
226 1.2 mrg r |= ((l & 0x00000040) ? CSTOPB : 0);
227 1.2 mrg r |= ((l & 0x00000080) ? CREAD : 0);
228 1.2 mrg r |= ((l & 0x00000100) ? PARENB : 0);
229 1.2 mrg r |= ((l & 0x00000200) ? PARODD : 0);
230 1.2 mrg r |= ((l & 0x00000400) ? HUPCL : 0);
231 1.2 mrg r |= ((l & 0x00000800) ? CLOCAL : 0);
232 1.2 mrg /* ((l & 0x00001000) ? LOBLK : 0) */
233 1.2 mrg r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
234 1.2 mrg bt->c_cflag = r;
235 1.2 mrg
236 1.2 mrg bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
237 1.2 mrg
238 1.2 mrg l = st->c_lflag;
239 1.2 mrg r = ((l & 0x00000001) ? ISIG : 0);
240 1.2 mrg r |= ((l & 0x00000002) ? ICANON : 0);
241 1.2 mrg /* ((l & 0x00000004) ? XCASE : 0) */
242 1.2 mrg r |= ((l & 0x00000008) ? ECHO : 0);
243 1.2 mrg r |= ((l & 0x00000010) ? ECHOE : 0);
244 1.2 mrg r |= ((l & 0x00000020) ? ECHOK : 0);
245 1.2 mrg r |= ((l & 0x00000040) ? ECHONL : 0);
246 1.2 mrg r |= ((l & 0x00000080) ? NOFLSH : 0);
247 1.2 mrg r |= ((l & 0x00000100) ? TOSTOP : 0);
248 1.2 mrg r |= ((l & 0x00000200) ? ECHOCTL : 0);
249 1.2 mrg r |= ((l & 0x00000400) ? ECHOPRT : 0);
250 1.2 mrg r |= ((l & 0x00000800) ? ECHOKE : 0);
251 1.2 mrg /* ((l & 0x00001000) ? DEFECHO : 0) */
252 1.2 mrg r |= ((l & 0x00002000) ? FLUSHO : 0);
253 1.2 mrg r |= ((l & 0x00004000) ? PENDIN : 0);
254 1.2 mrg bt->c_lflag = r;
255 1.2 mrg
256 1.2 mrg bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
257 1.2 mrg bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
258 1.2 mrg bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
259 1.2 mrg bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
260 1.2 mrg bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
261 1.2 mrg bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
262 1.2 mrg bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
263 1.2 mrg /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
264 1.2 mrg bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
265 1.2 mrg bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
266 1.2 mrg bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
267 1.2 mrg bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
268 1.2 mrg bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
269 1.2 mrg bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
270 1.2 mrg bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
271 1.2 mrg bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
272 1.2 mrg bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
273 1.2 mrg
274 1.2 mrg /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
275 1.2 mrg bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
276 1.2 mrg bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
277 1.2 mrg }
278 1.2 mrg
279 1.2 mrg
280 1.2 mrg static void
281 1.2 mrg btios2stios(bt, st)
282 1.2 mrg struct termios *bt;
283 1.2 mrg struct sunos_termios *st;
284 1.2 mrg {
285 1.3 mrg netbsd32_u_long l, r;
286 1.2 mrg int s;
287 1.2 mrg
288 1.2 mrg l = bt->c_iflag;
289 1.2 mrg r = ((l & IGNBRK) ? 0x00000001 : 0);
290 1.2 mrg r |= ((l & BRKINT) ? 0x00000002 : 0);
291 1.2 mrg r |= ((l & IGNPAR) ? 0x00000004 : 0);
292 1.2 mrg r |= ((l & PARMRK) ? 0x00000008 : 0);
293 1.2 mrg r |= ((l & INPCK) ? 0x00000010 : 0);
294 1.2 mrg r |= ((l & ISTRIP) ? 0x00000020 : 0);
295 1.2 mrg r |= ((l & INLCR) ? 0x00000040 : 0);
296 1.2 mrg r |= ((l & IGNCR) ? 0x00000080 : 0);
297 1.2 mrg r |= ((l & ICRNL) ? 0x00000100 : 0);
298 1.2 mrg /* ((l & IUCLC) ? 0x00000200 : 0) */
299 1.2 mrg r |= ((l & IXON) ? 0x00000400 : 0);
300 1.2 mrg r |= ((l & IXANY) ? 0x00000800 : 0);
301 1.2 mrg r |= ((l & IXOFF) ? 0x00001000 : 0);
302 1.2 mrg r |= ((l & IMAXBEL) ? 0x00002000 : 0);
303 1.2 mrg st->c_iflag = r;
304 1.2 mrg
305 1.2 mrg l = bt->c_oflag;
306 1.2 mrg r = ((l & OPOST) ? 0x00000001 : 0);
307 1.2 mrg /* ((l & OLCUC) ? 0x00000002 : 0) */
308 1.2 mrg r |= ((l & ONLCR) ? 0x00000004 : 0);
309 1.2 mrg /* ((l & OCRNL) ? 0x00000008 : 0) */
310 1.2 mrg /* ((l & ONOCR) ? 0x00000010 : 0) */
311 1.2 mrg /* ((l & ONLRET) ? 0x00000020 : 0) */
312 1.2 mrg /* ((l & OFILL) ? 0x00000040 : 0) */
313 1.2 mrg /* ((l & OFDEL) ? 0x00000080 : 0) */
314 1.2 mrg /* ((l & NLDLY) ? 0x00000100 : 0) */
315 1.2 mrg /* ((l & NL1) ? 0x00000100 : 0) */
316 1.2 mrg /* ((l & CRDLY) ? 0x00000600 : 0) */
317 1.2 mrg /* ((l & CR1) ? 0x00000200 : 0) */
318 1.2 mrg /* ((l & CR2) ? 0x00000400 : 0) */
319 1.2 mrg /* ((l & CR3) ? 0x00000600 : 0) */
320 1.2 mrg /* ((l & TABDLY) ? 0x00001800 : 0) */
321 1.2 mrg /* ((l & TAB1) ? 0x00000800 : 0) */
322 1.2 mrg /* ((l & TAB2) ? 0x00001000 : 0) */
323 1.2 mrg r |= ((l & OXTABS) ? 0x00001800 : 0);
324 1.2 mrg /* ((l & BSDLY) ? 0x00002000 : 0) */
325 1.2 mrg /* ((l & BS1) ? 0x00002000 : 0) */
326 1.2 mrg /* ((l & VTDLY) ? 0x00004000 : 0) */
327 1.2 mrg /* ((l & VT1) ? 0x00004000 : 0) */
328 1.2 mrg /* ((l & FFDLY) ? 0x00008000 : 0) */
329 1.2 mrg /* ((l & FF1) ? 0x00008000 : 0) */
330 1.2 mrg /* ((l & PAGEOUT) ? 0x00010000 : 0) */
331 1.2 mrg /* ((l & WRAP) ? 0x00020000 : 0) */
332 1.2 mrg st->c_oflag = r;
333 1.2 mrg
334 1.2 mrg l = bt->c_cflag;
335 1.2 mrg switch (l & CSIZE) {
336 1.2 mrg case CS5:
337 1.2 mrg r = 0;
338 1.2 mrg break;
339 1.2 mrg case CS6:
340 1.2 mrg r = 0x00000010;
341 1.2 mrg break;
342 1.2 mrg case CS7:
343 1.2 mrg r = 0x00000020;
344 1.2 mrg break;
345 1.2 mrg case CS8:
346 1.2 mrg r = 0x00000030;
347 1.2 mrg break;
348 1.2 mrg }
349 1.2 mrg r |= ((l & CSTOPB) ? 0x00000040 : 0);
350 1.2 mrg r |= ((l & CREAD) ? 0x00000080 : 0);
351 1.2 mrg r |= ((l & PARENB) ? 0x00000100 : 0);
352 1.2 mrg r |= ((l & PARODD) ? 0x00000200 : 0);
353 1.2 mrg r |= ((l & HUPCL) ? 0x00000400 : 0);
354 1.2 mrg r |= ((l & CLOCAL) ? 0x00000800 : 0);
355 1.2 mrg /* ((l & LOBLK) ? 0x00001000 : 0) */
356 1.2 mrg r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
357 1.2 mrg st->c_cflag = r;
358 1.2 mrg
359 1.2 mrg l = bt->c_lflag;
360 1.2 mrg r = ((l & ISIG) ? 0x00000001 : 0);
361 1.2 mrg r |= ((l & ICANON) ? 0x00000002 : 0);
362 1.2 mrg /* ((l & XCASE) ? 0x00000004 : 0) */
363 1.2 mrg r |= ((l & ECHO) ? 0x00000008 : 0);
364 1.2 mrg r |= ((l & ECHOE) ? 0x00000010 : 0);
365 1.2 mrg r |= ((l & ECHOK) ? 0x00000020 : 0);
366 1.2 mrg r |= ((l & ECHONL) ? 0x00000040 : 0);
367 1.2 mrg r |= ((l & NOFLSH) ? 0x00000080 : 0);
368 1.2 mrg r |= ((l & TOSTOP) ? 0x00000100 : 0);
369 1.2 mrg r |= ((l & ECHOCTL) ? 0x00000200 : 0);
370 1.2 mrg r |= ((l & ECHOPRT) ? 0x00000400 : 0);
371 1.2 mrg r |= ((l & ECHOKE) ? 0x00000800 : 0);
372 1.2 mrg /* ((l & DEFECHO) ? 0x00001000 : 0) */
373 1.2 mrg r |= ((l & FLUSHO) ? 0x00002000 : 0);
374 1.2 mrg r |= ((l & PENDIN) ? 0x00004000 : 0);
375 1.2 mrg st->c_lflag = r;
376 1.2 mrg
377 1.2 mrg s = ttspeedtab(bt->c_ospeed, sptab);
378 1.2 mrg if (s >= 0)
379 1.2 mrg st->c_cflag |= s;
380 1.2 mrg
381 1.2 mrg st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
382 1.2 mrg st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
383 1.2 mrg st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
384 1.2 mrg st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
385 1.2 mrg st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
386 1.2 mrg st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
387 1.2 mrg st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
388 1.2 mrg st->c_cc[7] = 0;
389 1.2 mrg /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
390 1.2 mrg st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
391 1.2 mrg st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
392 1.2 mrg st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
393 1.2 mrg st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
394 1.2 mrg st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
395 1.2 mrg st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
396 1.2 mrg st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
397 1.2 mrg st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
398 1.2 mrg st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
399 1.2 mrg
400 1.2 mrg if (!(bt->c_lflag & ICANON)) {
401 1.2 mrg /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
402 1.2 mrg st->c_cc[4] = bt->c_cc[VMIN];
403 1.2 mrg st->c_cc[5] = bt->c_cc[VTIME];
404 1.2 mrg }
405 1.2 mrg
406 1.2 mrg st->c_line = 0;
407 1.2 mrg }
408 1.2 mrg
409 1.2 mrg static void
410 1.2 mrg stios2stio(ts, t)
411 1.2 mrg struct sunos_termios *ts;
412 1.2 mrg struct sunos_termio *t;
413 1.2 mrg {
414 1.2 mrg t->c_iflag = ts->c_iflag;
415 1.2 mrg t->c_oflag = ts->c_oflag;
416 1.2 mrg t->c_cflag = ts->c_cflag;
417 1.2 mrg t->c_lflag = ts->c_lflag;
418 1.2 mrg t->c_line = ts->c_line;
419 1.2 mrg memcpy(t->c_cc, ts->c_cc, 8);
420 1.2 mrg }
421 1.2 mrg
422 1.2 mrg static void
423 1.2 mrg stio2stios(t, ts)
424 1.2 mrg struct sunos_termio *t;
425 1.2 mrg struct sunos_termios *ts;
426 1.2 mrg {
427 1.2 mrg ts->c_iflag = t->c_iflag;
428 1.2 mrg ts->c_oflag = t->c_oflag;
429 1.2 mrg ts->c_cflag = t->c_cflag;
430 1.2 mrg ts->c_lflag = t->c_lflag;
431 1.2 mrg ts->c_line = t->c_line;
432 1.2 mrg memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */
433 1.2 mrg }
434 1.2 mrg
435 1.2 mrg int
436 1.2 mrg sunos32_sys_ioctl(p, v, retval)
437 1.2 mrg struct proc *p;
438 1.2 mrg void *v;
439 1.2 mrg register_t *retval;
440 1.2 mrg {
441 1.2 mrg struct sunos32_sys_ioctl_args /* {
442 1.2 mrg int fd;
443 1.2 mrg netbsd32_u_long com;
444 1.2 mrg netbsd32_caddr_t data;
445 1.2 mrg } */ *uap = v;
446 1.2 mrg struct filedesc *fdp = p->p_fd;
447 1.2 mrg struct file *fp;
448 1.2 mrg int (*ctl) __P((struct file *, u_long, caddr_t, struct proc *));
449 1.2 mrg int error;
450 1.2 mrg
451 1.2 mrg if ((unsigned)SCARG(uap, fd) >= fdp->fd_nfiles ||
452 1.2 mrg (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)
453 1.2 mrg return EBADF;
454 1.2 mrg
455 1.2 mrg if ((fp->f_flag & (FREAD|FWRITE)) == 0)
456 1.2 mrg return EBADF;
457 1.2 mrg
458 1.2 mrg ctl = fp->f_ops->fo_ioctl;
459 1.2 mrg
460 1.2 mrg switch (SCARG(uap, com)) {
461 1.2 mrg case _IOR('t', 0, int):
462 1.2 mrg SCARG(uap, com) = TIOCGETD;
463 1.2 mrg break;
464 1.2 mrg case _IOW('t', 1, int):
465 1.2 mrg {
466 1.2 mrg int disc;
467 1.2 mrg
468 1.2 mrg if ((error = copyin((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&disc,
469 1.2 mrg sizeof disc)) != 0)
470 1.2 mrg return error;
471 1.2 mrg
472 1.2 mrg /* map SunOS NTTYDISC into our termios discipline */
473 1.2 mrg if (disc == 2)
474 1.2 mrg disc = 0;
475 1.2 mrg /* all other disciplines are not supported by NetBSD */
476 1.2 mrg if (disc)
477 1.2 mrg return ENXIO;
478 1.2 mrg
479 1.2 mrg return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
480 1.2 mrg }
481 1.2 mrg case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
482 1.2 mrg {
483 1.2 mrg int x; /* unused */
484 1.2 mrg
485 1.2 mrg return copyin((caddr_t)&x, (caddr_t)(u_long)SCARG(uap, data), sizeof x);
486 1.2 mrg }
487 1.2 mrg case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
488 1.2 mrg {
489 1.2 mrg int x = 0;
490 1.2 mrg
491 1.2 mrg return copyout((caddr_t)&x, (caddr_t)(u_long)SCARG(uap, data), sizeof x);
492 1.2 mrg }
493 1.2 mrg case _IO('t', 36): /* sun TIOCCONS, no parameters */
494 1.2 mrg {
495 1.2 mrg int on = 1;
496 1.2 mrg return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
497 1.2 mrg }
498 1.2 mrg case _IOW('t', 37, struct sunos_ttysize):
499 1.2 mrg {
500 1.2 mrg struct winsize ws;
501 1.2 mrg struct sunos_ttysize ss;
502 1.2 mrg
503 1.2 mrg if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
504 1.2 mrg return (error);
505 1.2 mrg
506 1.2 mrg if ((error = copyin ((caddr_t)(u_long)SCARG(uap, data), &ss, sizeof (ss))) != 0)
507 1.2 mrg return error;
508 1.2 mrg
509 1.2 mrg ws.ws_row = ss.ts_row;
510 1.2 mrg ws.ws_col = ss.ts_col;
511 1.2 mrg
512 1.2 mrg return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
513 1.2 mrg }
514 1.2 mrg case _IOW('t', 38, struct sunos_ttysize):
515 1.2 mrg {
516 1.2 mrg struct winsize ws;
517 1.2 mrg struct sunos_ttysize ss;
518 1.2 mrg
519 1.2 mrg if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
520 1.2 mrg return (error);
521 1.2 mrg
522 1.2 mrg ss.ts_row = ws.ws_row;
523 1.2 mrg ss.ts_col = ws.ws_col;
524 1.2 mrg
525 1.2 mrg return copyout ((caddr_t)&ss, (caddr_t)(u_long)SCARG(uap, data), sizeof (ss));
526 1.2 mrg }
527 1.2 mrg case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
528 1.2 mrg SCARG(uap, com) = TIOCSPGRP;
529 1.2 mrg break;
530 1.2 mrg case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
531 1.2 mrg {
532 1.2 mrg /*
533 1.2 mrg * sigh, must do error translation on pty devices
534 1.2 mrg * (see also kern/tty_pty.c)
535 1.2 mrg */
536 1.2 mrg int pgrp;
537 1.2 mrg struct vnode *vp;
538 1.2 mrg error = (*ctl)(fp, TIOCGPGRP, (caddr_t)&pgrp, p);
539 1.2 mrg if (error) {
540 1.2 mrg vp = (struct vnode *)fp->f_data;
541 1.2 mrg if (error == EIO && vp != NULL &&
542 1.2 mrg vp->v_type == VCHR && major(vp->v_rdev) == 21)
543 1.2 mrg error = ENOTTY;
544 1.2 mrg return (error);
545 1.2 mrg }
546 1.2 mrg return copyout((caddr_t)&pgrp, (caddr_t)(u_long)SCARG(uap, data), sizeof(pgrp));
547 1.2 mrg }
548 1.2 mrg case _IO('t', 132):
549 1.2 mrg SCARG(uap, com) = TIOCSCTTY;
550 1.2 mrg break;
551 1.2 mrg case SUNOS_TCGETA:
552 1.2 mrg case SUNOS_TCGETS:
553 1.2 mrg {
554 1.2 mrg struct termios bts;
555 1.2 mrg struct sunos_termios sts;
556 1.2 mrg struct sunos_termio st;
557 1.2 mrg
558 1.2 mrg if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
559 1.2 mrg return error;
560 1.2 mrg
561 1.2 mrg btios2stios (&bts, &sts);
562 1.2 mrg if (SCARG(uap, com) == SUNOS_TCGETA) {
563 1.2 mrg stios2stio (&sts, &st);
564 1.2 mrg return copyout((caddr_t)&st, (caddr_t)(u_long)SCARG(uap, data),
565 1.2 mrg sizeof (st));
566 1.2 mrg } else
567 1.2 mrg return copyout((caddr_t)&sts, (caddr_t)(u_long)SCARG(uap, data),
568 1.2 mrg sizeof (sts));
569 1.2 mrg /*NOTREACHED*/
570 1.2 mrg }
571 1.2 mrg case SUNOS_TCSETA:
572 1.2 mrg case SUNOS_TCSETAW:
573 1.2 mrg case SUNOS_TCSETAF:
574 1.2 mrg {
575 1.2 mrg struct termios bts;
576 1.2 mrg struct sunos_termios sts;
577 1.2 mrg struct sunos_termio st;
578 1.2 mrg
579 1.2 mrg if ((error = copyin((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&st,
580 1.2 mrg sizeof (st))) != 0)
581 1.2 mrg return error;
582 1.2 mrg
583 1.2 mrg /* get full BSD termios so we don't lose information */
584 1.2 mrg if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
585 1.2 mrg return error;
586 1.2 mrg
587 1.2 mrg /*
588 1.2 mrg * convert to sun termios, copy in information from
589 1.2 mrg * termio, and convert back, then set new values.
590 1.2 mrg */
591 1.2 mrg btios2stios(&bts, &sts);
592 1.2 mrg stio2stios(&st, &sts);
593 1.2 mrg stios2btios(&sts, &bts);
594 1.2 mrg
595 1.2 mrg return (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA,
596 1.2 mrg (caddr_t)&bts, p);
597 1.2 mrg }
598 1.2 mrg case SUNOS_TCSETS:
599 1.2 mrg case SUNOS_TCSETSW:
600 1.2 mrg case SUNOS_TCSETSF:
601 1.2 mrg {
602 1.2 mrg struct termios bts;
603 1.2 mrg struct sunos_termios sts;
604 1.2 mrg
605 1.2 mrg if ((error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sts,
606 1.2 mrg sizeof (sts))) != 0)
607 1.2 mrg return error;
608 1.2 mrg stios2btios (&sts, &bts);
609 1.2 mrg return (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA,
610 1.2 mrg (caddr_t)&bts, p);
611 1.2 mrg }
612 1.2 mrg /*
613 1.2 mrg * Pseudo-tty ioctl translations.
614 1.2 mrg */
615 1.2 mrg case _IOW('t', 32, int): { /* TIOCTCNTL */
616 1.2 mrg int error, on;
617 1.2 mrg
618 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&on, sizeof (on));
619 1.2 mrg if (error)
620 1.2 mrg return error;
621 1.2 mrg return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
622 1.2 mrg }
623 1.2 mrg case _IOW('t', 33, int): { /* TIOCSIGNAL */
624 1.2 mrg int error, sig;
625 1.2 mrg
626 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sig, sizeof (sig));
627 1.2 mrg if (error)
628 1.2 mrg return error;
629 1.2 mrg return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
630 1.2 mrg }
631 1.2 mrg
632 1.2 mrg /*
633 1.2 mrg * Socket ioctl translations.
634 1.2 mrg */
635 1.2 mrg #define IFREQ_IN(a) { \
636 1.2 mrg struct ifreq ifreq; \
637 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \
638 1.2 mrg if (error) \
639 1.2 mrg return error; \
640 1.2 mrg return (*ctl)(fp, a, (caddr_t)&ifreq, p); \
641 1.2 mrg }
642 1.2 mrg #define IFREQ_INOUT(a) { \
643 1.2 mrg struct ifreq ifreq; \
644 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq)); \
645 1.2 mrg if (error) \
646 1.2 mrg return error; \
647 1.2 mrg if ((error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) != 0) \
648 1.2 mrg return error; \
649 1.2 mrg return copyout ((caddr_t)&ifreq, (caddr_t)(u_long)SCARG(uap, data), sizeof (ifreq)); \
650 1.2 mrg }
651 1.2 mrg
652 1.2 mrg case _IOW('i', 12, struct ifreq):
653 1.2 mrg /* SIOCSIFADDR */
654 1.2 mrg break;
655 1.2 mrg
656 1.2 mrg case _IOWR('i', 13, struct ifreq):
657 1.2 mrg IFREQ_INOUT(OSIOCGIFADDR);
658 1.2 mrg
659 1.2 mrg case _IOW('i', 14, struct ifreq):
660 1.2 mrg /* SIOCSIFDSTADDR */
661 1.2 mrg break;
662 1.2 mrg
663 1.2 mrg case _IOWR('i', 15, struct ifreq):
664 1.2 mrg IFREQ_INOUT(OSIOCGIFDSTADDR);
665 1.2 mrg
666 1.2 mrg case _IOW('i', 16, struct ifreq):
667 1.2 mrg /* SIOCSIFFLAGS */
668 1.2 mrg break;
669 1.2 mrg
670 1.2 mrg case _IOWR('i', 17, struct ifreq):
671 1.2 mrg /* SIOCGIFFLAGS */
672 1.2 mrg break;
673 1.2 mrg
674 1.2 mrg case _IOW('i', 21, struct ifreq):
675 1.2 mrg IFREQ_IN(SIOCSIFMTU);
676 1.2 mrg
677 1.2 mrg case _IOWR('i', 22, struct ifreq):
678 1.2 mrg IFREQ_INOUT(SIOCGIFMTU);
679 1.2 mrg
680 1.2 mrg case _IOWR('i', 23, struct ifreq):
681 1.2 mrg IFREQ_INOUT(SIOCGIFBRDADDR);
682 1.2 mrg
683 1.2 mrg case _IOW('i', 24, struct ifreq):
684 1.2 mrg IFREQ_IN(SIOCSIFBRDADDR);
685 1.2 mrg
686 1.2 mrg case _IOWR('i', 25, struct ifreq):
687 1.2 mrg IFREQ_INOUT(OSIOCGIFNETMASK);
688 1.2 mrg
689 1.2 mrg case _IOW('i', 26, struct ifreq):
690 1.2 mrg IFREQ_IN(SIOCSIFNETMASK);
691 1.2 mrg
692 1.2 mrg case _IOWR('i', 27, struct ifreq):
693 1.2 mrg IFREQ_INOUT(SIOCGIFMETRIC);
694 1.2 mrg
695 1.2 mrg case _IOWR('i', 28, struct ifreq):
696 1.2 mrg IFREQ_IN(SIOCSIFMETRIC);
697 1.2 mrg
698 1.2 mrg case _IOW('i', 30, struct arpreq):
699 1.2 mrg /* SIOCSARP */
700 1.2 mrg break;
701 1.2 mrg
702 1.2 mrg case _IOWR('i', 31, struct arpreq):
703 1.2 mrg /* SIOCGARP */
704 1.2 mrg break;
705 1.2 mrg
706 1.2 mrg case _IOW('i', 32, struct arpreq):
707 1.2 mrg /* SIOCDARP */
708 1.2 mrg break;
709 1.2 mrg
710 1.2 mrg case _IOW('i', 18, struct ifreq): /* SIOCSIFMEM */
711 1.2 mrg case _IOWR('i', 19, struct ifreq): /* SIOCGIFMEM */
712 1.2 mrg case _IOW('i', 40, struct ifreq): /* SIOCUPPER */
713 1.2 mrg case _IOW('i', 41, struct ifreq): /* SIOCLOWER */
714 1.2 mrg case _IOW('i', 44, struct ifreq): /* SIOCSETSYNC */
715 1.2 mrg case _IOWR('i', 45, struct ifreq): /* SIOCGETSYNC */
716 1.2 mrg case _IOWR('i', 46, struct ifreq): /* SIOCSDSTATS */
717 1.2 mrg case _IOWR('i', 47, struct ifreq): /* SIOCSESTATS */
718 1.2 mrg case _IOW('i', 48, int): /* SIOCSPROMISC */
719 1.2 mrg case _IOW('i', 49, struct ifreq): /* SIOCADDMULTI */
720 1.2 mrg case _IOW('i', 50, struct ifreq): /* SIOCDELMULTI */
721 1.2 mrg return EOPNOTSUPP;
722 1.2 mrg
723 1.2 mrg case _IOWR('i', 20, struct ifconf): /* SIOCGIFCONF */
724 1.2 mrg {
725 1.2 mrg struct ifconf ifconf;
726 1.2 mrg
727 1.2 mrg /*
728 1.2 mrg * XXX: two more problems
729 1.2 mrg * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
730 1.2 mrg * 2. this returns a name per protocol, ie. it returns two "lo0"'s
731 1.2 mrg */
732 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&ifconf,
733 1.2 mrg sizeof (ifconf));
734 1.2 mrg if (error)
735 1.2 mrg return error;
736 1.2 mrg error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p);
737 1.2 mrg if (error)
738 1.2 mrg return error;
739 1.2 mrg return copyout ((caddr_t)&ifconf, (caddr_t)(u_long)SCARG(uap, data),
740 1.2 mrg sizeof (ifconf));
741 1.2 mrg }
742 1.2 mrg
743 1.2 mrg /*
744 1.2 mrg * Audio ioctl translations.
745 1.2 mrg */
746 1.2 mrg case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */
747 1.2 mrg sunos_au_getinfo:
748 1.2 mrg {
749 1.2 mrg struct audio_info aui;
750 1.2 mrg struct sunos_audio_info sunos_aui;
751 1.2 mrg
752 1.2 mrg error = (*ctl)(fp, AUDIO_GETINFO, (caddr_t)&aui, p);
753 1.2 mrg if (error)
754 1.2 mrg return error;
755 1.2 mrg
756 1.2 mrg sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
757 1.2 mrg sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
758 1.2 mrg
759 1.2 mrg /* `avail_ports' is `seek' in BSD */
760 1.2 mrg sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
761 1.2 mrg sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
762 1.2 mrg
763 1.2 mrg sunos_aui.play.waiting = 0;
764 1.2 mrg sunos_aui.record.waiting = 0;
765 1.2 mrg sunos_aui.play.eof = 0;
766 1.2 mrg sunos_aui.record.eof = 0;
767 1.2 mrg sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
768 1.2 mrg /*XXXsunos_aui.output_muted = 0;*/
769 1.2 mrg /*XXX*/sunos_aui.reserved[0] = 0;
770 1.2 mrg /*XXX*/sunos_aui.reserved[1] = 0;
771 1.2 mrg /*XXX*/sunos_aui.reserved[2] = 0;
772 1.2 mrg /*XXX*/sunos_aui.reserved[3] = 0;
773 1.2 mrg
774 1.2 mrg return copyout ((caddr_t)&sunos_aui, (caddr_t)(u_long)SCARG(uap, data),
775 1.2 mrg sizeof (sunos_aui));
776 1.2 mrg }
777 1.2 mrg
778 1.2 mrg case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */
779 1.2 mrg {
780 1.2 mrg struct audio_info aui;
781 1.2 mrg struct sunos_audio_info sunos_aui;
782 1.2 mrg
783 1.2 mrg error = copyin ((caddr_t)(u_long)SCARG(uap, data), (caddr_t)&sunos_aui,
784 1.2 mrg sizeof (sunos_aui));
785 1.2 mrg if (error)
786 1.2 mrg return error;
787 1.2 mrg
788 1.2 mrg aui.play = *(struct audio_prinfo *)&sunos_aui.play;
789 1.2 mrg aui.record = *(struct audio_prinfo *)&sunos_aui.record;
790 1.2 mrg /* aui.__spare = sunos_aui.monitor_gain; */
791 1.2 mrg aui.blocksize = ~0;
792 1.2 mrg aui.hiwat = ~0;
793 1.2 mrg aui.lowat = ~0;
794 1.2 mrg /* XXX somebody check this please. - is: aui.backlog = ~0; */
795 1.2 mrg aui.mode = ~0;
796 1.2 mrg /*
797 1.2 mrg * The bsd driver does not distinguish between paused and
798 1.2 mrg * active. (In the sun driver, not active means samples are
799 1.2 mrg * not ouput at all, but paused means the last streams buffer
800 1.2 mrg * is drained and then output stops.) If either are 0, then
801 1.2 mrg * when stop output. Otherwise, if either are non-zero,
802 1.2 mrg * we resume.
803 1.2 mrg */
804 1.2 mrg if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
805 1.2 mrg aui.play.pause = 0;
806 1.2 mrg else if (sunos_aui.play.pause != (u_char)~0 ||
807 1.2 mrg sunos_aui.play.active != (u_char)~0)
808 1.2 mrg aui.play.pause = 1;
809 1.2 mrg if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
810 1.2 mrg aui.record.pause = 0;
811 1.2 mrg else if (sunos_aui.record.pause != (u_char)~0 ||
812 1.2 mrg sunos_aui.record.active != (u_char)~0)
813 1.2 mrg aui.record.pause = 1;
814 1.2 mrg
815 1.2 mrg error = (*ctl)(fp, AUDIO_SETINFO, (caddr_t)&aui, p);
816 1.2 mrg if (error)
817 1.2 mrg return error;
818 1.2 mrg /* Return new state */
819 1.2 mrg goto sunos_au_getinfo;
820 1.2 mrg }
821 1.2 mrg case _IO('A', 3): /* AUDIO_DRAIN */
822 1.2 mrg return (*ctl)(fp, AUDIO_DRAIN, (void *)0, p);
823 1.2 mrg case _IOR('A', 4, int): /* AUDIO_GETDEV */
824 1.2 mrg {
825 1.2 mrg int devtype = SUNOS_AUDIO_DEV_AMD;
826 1.2 mrg return copyout ((caddr_t)&devtype, (caddr_t)(u_long)SCARG(uap, data),
827 1.2 mrg sizeof (devtype));
828 1.2 mrg }
829 1.2 mrg
830 1.2 mrg /*
831 1.2 mrg * Selected streams ioctls.
832 1.2 mrg */
833 1.2 mrg #define SUNOS_S_FLUSHR 1
834 1.2 mrg #define SUNOS_S_FLUSHW 2
835 1.2 mrg #define SUNOS_S_FLUSHRW 3
836 1.2 mrg
837 1.2 mrg #define SUNOS_S_INPUT 1
838 1.2 mrg #define SUNOS_S_HIPRI 2
839 1.2 mrg #define SUNOS_S_OUTPUT 4
840 1.2 mrg #define SUNOS_S_MSG 8
841 1.2 mrg
842 1.2 mrg case _IO('S', 5): /* I_FLUSH */
843 1.2 mrg {
844 1.2 mrg int tmp = 0;
845 1.2 mrg switch ((int)(u_long)SCARG(uap, data)) {
846 1.2 mrg case SUNOS_S_FLUSHR: tmp = FREAD;
847 1.2 mrg case SUNOS_S_FLUSHW: tmp = FWRITE;
848 1.2 mrg case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE;
849 1.2 mrg }
850 1.2 mrg return (*ctl)(fp, TIOCFLUSH, (caddr_t)&tmp, p);
851 1.2 mrg }
852 1.2 mrg case _IO('S', 9): /* I_SETSIG */
853 1.2 mrg {
854 1.2 mrg int on = 1;
855 1.2 mrg if (((int)(u_long)SCARG(uap, data) &
856 1.2 mrg (SUNOS_S_HIPRI|SUNOS_S_INPUT)) ==
857 1.2 mrg SUNOS_S_HIPRI)
858 1.2 mrg return EOPNOTSUPP;
859 1.2 mrg return (*ctl)(fp, FIOASYNC, (caddr_t)&on, p);
860 1.2 mrg }
861 1.2 mrg /*
862 1.2 mrg * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
863 1.2 mrg * (which was from the old sparc/scsi/sun_disklabel.c), and
864 1.2 mrg * modified to suite.
865 1.2 mrg */
866 1.2 mrg case DKIOCGGEOM:
867 1.2 mrg {
868 1.2 mrg struct disklabel dl;
869 1.2 mrg
870 1.2 mrg error = (*ctl)(fp, DIOCGDINFO, (caddr_t)&dl, p);
871 1.2 mrg if (error)
872 1.2 mrg return (error);
873 1.2 mrg
874 1.2 mrg #define datageom ((struct sun_dkgeom *)(u_long)SCARG(uap, data))
875 1.2 mrg memset((caddr_t)(u_long)SCARG(uap, data), 0, sizeof(*datageom));
876 1.2 mrg
877 1.2 mrg datageom->sdkc_ncylinders = dl.d_ncylinders;
878 1.2 mrg datageom->sdkc_acylinders = dl.d_acylinders;
879 1.2 mrg datageom->sdkc_ntracks = dl.d_ntracks;
880 1.2 mrg datageom->sdkc_nsectors = dl.d_nsectors;
881 1.2 mrg datageom->sdkc_interleave = dl.d_interleave;
882 1.2 mrg datageom->sdkc_sparespercyl = dl.d_sparespercyl;
883 1.2 mrg datageom->sdkc_rpm = dl.d_rpm;
884 1.2 mrg datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders;
885 1.2 mrg #undef datageom
886 1.2 mrg break;
887 1.2 mrg }
888 1.2 mrg
889 1.2 mrg case DKIOCINFO:
890 1.2 mrg /* Homey don't do DKIOCINFO */
891 1.2 mrg memset((caddr_t)(u_long)SCARG(uap, data), 0, sizeof(struct sun_dkctlr));
892 1.2 mrg break;
893 1.2 mrg
894 1.2 mrg case DKIOCGPART:
895 1.2 mrg {
896 1.2 mrg struct partinfo pi;
897 1.2 mrg
898 1.2 mrg error = (*ctl)(fp, DIOCGPART, (caddr_t)&pi, p);
899 1.2 mrg if (error)
900 1.2 mrg return (error);
901 1.2 mrg
902 1.2 mrg if (pi.disklab->d_secpercyl == 0)
903 1.2 mrg return (ERANGE); /* XXX */
904 1.2 mrg if (pi.part->p_offset % pi.disklab->d_secpercyl != 0)
905 1.2 mrg return (ERANGE); /* XXX */
906 1.2 mrg #define datapart ((struct sun_dkpart *)(u_long)SCARG(uap, data))
907 1.2 mrg datapart->sdkp_cyloffset = pi.part->p_offset / pi.disklab->d_secpercyl;
908 1.2 mrg datapart->sdkp_nsectors = pi.part->p_size;
909 1.2 mrg #undef datapart
910 1.2 mrg }
911 1.2 mrg
912 1.2 mrg }
913 1.2 mrg return (netbsd32_ioctl(p, uap, retval));
914 1.2 mrg }
915 1.2 mrg
916 1.2 mrg /* SunOS fcntl(2) cmds not implemented */
917 1.2 mrg #define SUN_F_RGETLK 10
918 1.2 mrg #define SUN_F_RSETLK 11
919 1.2 mrg #define SUN_F_CNVT 12
920 1.2 mrg #define SUN_F_RSETLKW 13
921 1.2 mrg
922 1.2 mrg /* SunOS flock translation */
923 1.2 mrg struct sunos_flock {
924 1.2 mrg short l_type;
925 1.2 mrg short l_whence;
926 1.3 mrg netbsd32_long l_start;
927 1.3 mrg netbsd32_long l_len;
928 1.2 mrg short l_pid;
929 1.2 mrg short l_xxx;
930 1.2 mrg };
931 1.2 mrg
932 1.2 mrg static void bsd_to_sunos_flock __P((struct flock *, struct sunos_flock *));
933 1.2 mrg static void sunos_to_bsd_flock __P((struct sunos_flock *, struct flock *));
934 1.2 mrg
935 1.2 mrg #define SUNOS_F_RDLCK 1
936 1.2 mrg #define SUNOS_F_WRLCK 2
937 1.2 mrg #define SUNOS_F_UNLCK 3
938 1.2 mrg
939 1.2 mrg static void
940 1.2 mrg bsd_to_sunos_flock(iflp, oflp)
941 1.2 mrg struct flock *iflp;
942 1.2 mrg struct sunos_flock *oflp;
943 1.2 mrg {
944 1.2 mrg switch (iflp->l_type) {
945 1.2 mrg case F_RDLCK:
946 1.2 mrg oflp->l_type = SUNOS_F_RDLCK;
947 1.2 mrg break;
948 1.2 mrg case F_WRLCK:
949 1.2 mrg oflp->l_type = SUNOS_F_WRLCK;
950 1.2 mrg break;
951 1.2 mrg case F_UNLCK:
952 1.2 mrg oflp->l_type = SUNOS_F_UNLCK;
953 1.2 mrg break;
954 1.2 mrg default:
955 1.2 mrg oflp->l_type = -1;
956 1.2 mrg break;
957 1.2 mrg }
958 1.2 mrg
959 1.2 mrg oflp->l_whence = (short) iflp->l_whence;
960 1.3 mrg oflp->l_start = (netbsd32_long) iflp->l_start;
961 1.3 mrg oflp->l_len = (netbsd32_long) iflp->l_len;
962 1.2 mrg oflp->l_pid = (short) iflp->l_pid;
963 1.2 mrg oflp->l_xxx = 0;
964 1.2 mrg }
965 1.2 mrg
966 1.2 mrg
967 1.2 mrg static void
968 1.2 mrg sunos_to_bsd_flock(iflp, oflp)
969 1.2 mrg struct sunos_flock *iflp;
970 1.2 mrg struct flock *oflp;
971 1.2 mrg {
972 1.2 mrg switch (iflp->l_type) {
973 1.2 mrg case SUNOS_F_RDLCK:
974 1.2 mrg oflp->l_type = F_RDLCK;
975 1.2 mrg break;
976 1.2 mrg case SUNOS_F_WRLCK:
977 1.2 mrg oflp->l_type = F_WRLCK;
978 1.2 mrg break;
979 1.2 mrg case SUNOS_F_UNLCK:
980 1.2 mrg oflp->l_type = F_UNLCK;
981 1.2 mrg break;
982 1.2 mrg default:
983 1.2 mrg oflp->l_type = -1;
984 1.2 mrg break;
985 1.2 mrg }
986 1.2 mrg
987 1.2 mrg oflp->l_whence = iflp->l_whence;
988 1.2 mrg oflp->l_start = (off_t) iflp->l_start;
989 1.2 mrg oflp->l_len = (off_t) iflp->l_len;
990 1.2 mrg oflp->l_pid = (pid_t) iflp->l_pid;
991 1.2 mrg
992 1.2 mrg }
993 1.2 mrg static struct {
994 1.3 mrg netbsd32_long sun_flg;
995 1.3 mrg netbsd32_long bsd_flg;
996 1.2 mrg } sunfcntl_flgtab[] = {
997 1.2 mrg /* F_[GS]ETFLags that differ: */
998 1.2 mrg #define SUN_FSETBLK 0x0010
999 1.2 mrg #define SUN_SHLOCK 0x0080
1000 1.2 mrg #define SUN_EXLOCK 0x0100
1001 1.2 mrg #define SUN_FNBIO 0x1000
1002 1.2 mrg #define SUN_FSYNC 0x2000
1003 1.2 mrg #define SUN_NONBLOCK 0x4000
1004 1.2 mrg #define SUN_FNOCTTY 0x8000
1005 1.2 mrg { SUN_NONBLOCK, O_NONBLOCK },
1006 1.2 mrg { SUN_FNBIO, O_NONBLOCK },
1007 1.2 mrg { SUN_SHLOCK, O_SHLOCK },
1008 1.2 mrg { SUN_EXLOCK, O_EXLOCK },
1009 1.2 mrg { SUN_FSYNC, O_FSYNC },
1010 1.2 mrg { SUN_FSETBLK, 0 },
1011 1.2 mrg { SUN_FNOCTTY, 0 }
1012 1.2 mrg };
1013 1.2 mrg
1014 1.2 mrg int
1015 1.2 mrg sunos32_sys_fcntl(p, v, retval)
1016 1.2 mrg struct proc *p;
1017 1.2 mrg void *v;
1018 1.2 mrg register_t *retval;
1019 1.2 mrg {
1020 1.3 mrg struct sunos32_sys_fcntl_args /* {
1021 1.3 mrg syscallarg(int) fd;
1022 1.3 mrg syscallarg(int) cmd;
1023 1.3 mrg syscallarg(netbsd32_voidp) arg;
1024 1.3 mrg } */ *uap = v;
1025 1.3 mrg netbsd32_long flg;
1026 1.2 mrg int n, ret;
1027 1.2 mrg
1028 1.2 mrg switch (SCARG(uap, cmd)) {
1029 1.2 mrg case F_SETFL:
1030 1.3 mrg flg = (netbsd32_long)SCARG(uap, arg);
1031 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1032 1.2 mrg while (--n >= 0) {
1033 1.2 mrg if (flg & sunfcntl_flgtab[n].sun_flg) {
1034 1.2 mrg flg &= ~sunfcntl_flgtab[n].sun_flg;
1035 1.2 mrg flg |= sunfcntl_flgtab[n].bsd_flg;
1036 1.2 mrg }
1037 1.2 mrg }
1038 1.3 mrg SCARG(uap, arg) = (netbsd32_voidp)flg;
1039 1.2 mrg break;
1040 1.2 mrg
1041 1.2 mrg case F_GETLK:
1042 1.2 mrg case F_SETLK:
1043 1.2 mrg case F_SETLKW:
1044 1.2 mrg {
1045 1.2 mrg int error;
1046 1.2 mrg struct sunos_flock ifl;
1047 1.2 mrg struct flock *flp, fl;
1048 1.2 mrg caddr_t sg = stackgap_init(p->p_emul);
1049 1.2 mrg struct sys_fcntl_args fa;
1050 1.2 mrg
1051 1.2 mrg SCARG(&fa, fd) = SCARG(uap, fd);
1052 1.2 mrg SCARG(&fa, cmd) = SCARG(uap, cmd);
1053 1.2 mrg
1054 1.2 mrg flp = stackgap_alloc(&sg, sizeof(struct flock));
1055 1.2 mrg SCARG(&fa, arg) = (void *) flp;
1056 1.2 mrg
1057 1.2 mrg error = copyin((caddr_t)(u_long)SCARG(uap, arg), &ifl, sizeof ifl);
1058 1.2 mrg if (error)
1059 1.2 mrg return error;
1060 1.2 mrg
1061 1.2 mrg sunos_to_bsd_flock(&ifl, &fl);
1062 1.2 mrg
1063 1.2 mrg error = copyout(&fl, flp, sizeof fl);
1064 1.2 mrg if (error)
1065 1.2 mrg return error;
1066 1.2 mrg
1067 1.2 mrg error = sys_fcntl(p, &fa, retval);
1068 1.2 mrg if (error || SCARG(&fa, cmd) != F_GETLK)
1069 1.2 mrg return error;
1070 1.2 mrg
1071 1.2 mrg error = copyin(flp, &fl, sizeof fl);
1072 1.2 mrg if (error)
1073 1.2 mrg return error;
1074 1.2 mrg
1075 1.2 mrg bsd_to_sunos_flock(&fl, &ifl);
1076 1.2 mrg
1077 1.2 mrg return copyout(&ifl, (caddr_t)(u_long)SCARG(uap, arg), sizeof ifl);
1078 1.2 mrg }
1079 1.2 mrg break;
1080 1.2 mrg case SUN_F_RGETLK:
1081 1.2 mrg case SUN_F_RSETLK:
1082 1.2 mrg case SUN_F_CNVT:
1083 1.2 mrg case SUN_F_RSETLKW:
1084 1.2 mrg return (EOPNOTSUPP);
1085 1.2 mrg
1086 1.2 mrg default:
1087 1.2 mrg }
1088 1.2 mrg
1089 1.3 mrg ret = netbsd32_fcntl(p, uap, retval);
1090 1.2 mrg
1091 1.2 mrg switch (SCARG(uap, cmd)) {
1092 1.2 mrg case F_GETFL:
1093 1.2 mrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1094 1.2 mrg while (--n >= 0) {
1095 1.2 mrg if (ret & sunfcntl_flgtab[n].bsd_flg) {
1096 1.2 mrg ret &= ~sunfcntl_flgtab[n].bsd_flg;
1097 1.2 mrg ret |= sunfcntl_flgtab[n].sun_flg;
1098 1.2 mrg }
1099 1.2 mrg }
1100 1.2 mrg break;
1101 1.2 mrg default:
1102 1.2 mrg }
1103 1.1 mrg
1104 1.2 mrg return (ret);
1105 1.2 mrg }
1106