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