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