1*41aa5859Sriastradh /* $NetBSD: sunos_ioctl.c,v 1.71 2021/09/07 11:43:05 riastradh Exp $ */
2cf92afd6Scgd
34588caefSderaadt /*
4ea61d920Sderaadt * Copyright (c) 1993 Markus Wild.
5ea61d920Sderaadt * All rights reserved.
64588caefSderaadt *
74588caefSderaadt * Redistribution and use in source and binary forms, with or without
84588caefSderaadt * modification, are permitted provided that the following conditions
94588caefSderaadt * are met:
104588caefSderaadt * 1. Redistributions of source code must retain the above copyright
114588caefSderaadt * notice, this list of conditions and the following disclaimer.
12ea61d920Sderaadt * 2. The name of the author may not be used to endorse or promote products
1352351800Sjtc * derived from this software without specific prior written permission
144588caefSderaadt *
15ea61d920Sderaadt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16ea61d920Sderaadt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17ea61d920Sderaadt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18ea61d920Sderaadt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19ea61d920Sderaadt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20ea61d920Sderaadt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21ea61d920Sderaadt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22ea61d920Sderaadt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23ea61d920Sderaadt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24ea61d920Sderaadt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
254588caefSderaadt *
26019f4833Sderaadt * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
274588caefSderaadt */
284588caefSderaadt
29dab6ef8bSlukem #include <sys/cdefs.h>
30*41aa5859Sriastradh __KERNEL_RCSID(0, "$NetBSD: sunos_ioctl.c,v 1.71 2021/09/07 11:43:05 riastradh Exp $");
31bdec6819Smrg
324588caefSderaadt #include <sys/param.h>
334588caefSderaadt #include <sys/proc.h>
34019f4833Sderaadt #include <sys/systm.h>
354588caefSderaadt #include <sys/file.h>
364588caefSderaadt #include <sys/filedesc.h>
374588caefSderaadt #include <sys/ioctl.h>
384588caefSderaadt #include <sys/termios.h>
394588caefSderaadt #include <sys/tty.h>
409d48733fSderaadt #include <sys/socket.h>
41a1cfb5b3Spk #include <sys/audioio.h>
4239dfdd06Spk #include <sys/vnode.h>
43019f4833Sderaadt #include <sys/mount.h>
44cbffcd18Smrg #include <sys/disklabel.h>
45cbffcd18Smrg #include <sys/syscallargs.h>
46019f4833Sderaadt
4739dfdd06Spk #include <miscfs/specfs/specdev.h>
4839dfdd06Spk
49cbffcd18Smrg #include <net/if.h>
50cbffcd18Smrg
518f77cc1cShe #include <compat/sys/sockio.h>
528f77cc1cShe
53cbffcd18Smrg #include <dev/sun/disklabel.h>
54cbffcd18Smrg
55019f4833Sderaadt #include <compat/sunos/sunos.h>
56019f4833Sderaadt #include <compat/sunos/sunos_syscallargs.h>
5701040d97Sjdolecek #include <compat/common/compat_util.h>
58019f4833Sderaadt
594588caefSderaadt /*
604588caefSderaadt * SunOS ioctl calls.
614588caefSderaadt * This file is something of a hodge-podge.
624588caefSderaadt * Support gets added as things turn up....
634588caefSderaadt */
644588caefSderaadt
6522120ad6Smatt static const struct speedtab sptab[] = {
66ea61d920Sderaadt { 0, 0 },
67ea61d920Sderaadt { 50, 1 },
68ea61d920Sderaadt { 75, 2 },
69ea61d920Sderaadt { 110, 3 },
70ea61d920Sderaadt { 134, 4 },
71ea61d920Sderaadt { 135, 4 },
72ea61d920Sderaadt { 150, 5 },
73ea61d920Sderaadt { 200, 6 },
74ea61d920Sderaadt { 300, 7 },
75ea61d920Sderaadt { 600, 8 },
76ea61d920Sderaadt { 1200, 9 },
77ea61d920Sderaadt { 1800, 10 },
78ea61d920Sderaadt { 2400, 11 },
79ea61d920Sderaadt { 4800, 12 },
80ea61d920Sderaadt { 9600, 13 },
81ea61d920Sderaadt { 19200, 14 },
82ea61d920Sderaadt { 38400, 15 },
83ea61d920Sderaadt { -1, -1 }
84ea61d920Sderaadt };
85ea61d920Sderaadt
8622120ad6Smatt static const u_long s2btab[] = {
87ea61d920Sderaadt 0,
88ea61d920Sderaadt 50,
89ea61d920Sderaadt 75,
90ea61d920Sderaadt 110,
91ea61d920Sderaadt 134,
92ea61d920Sderaadt 150,
93ea61d920Sderaadt 200,
94ea61d920Sderaadt 300,
95ea61d920Sderaadt 600,
96ea61d920Sderaadt 1200,
97ea61d920Sderaadt 1800,
98ea61d920Sderaadt 2400,
99ea61d920Sderaadt 4800,
100ea61d920Sderaadt 9600,
101ea61d920Sderaadt 19200,
102ea61d920Sderaadt 38400,
103ea61d920Sderaadt };
104ea61d920Sderaadt
105f2af9174Sdsl static void stios2btios(struct sunos_termios *, struct termios *);
106f2af9174Sdsl static void btios2stios(struct termios *, struct sunos_termios *);
107f2af9174Sdsl static void stios2stio(struct sunos_termios *, struct sunos_termio *);
108f2af9174Sdsl static void stio2stios(struct sunos_termio *, struct sunos_termios *);
109fc8b478bSchristos
110ea61d920Sderaadt /*
11139dfdd06Spk * These two conversion functions have mostly been done
11239dfdd06Spk * with some perl cut&paste, then hand-edited to comment
113ea61d920Sderaadt * out what doesn't exist under NetBSD.
114ea61d920Sderaadt * A note from Markus's code:
115ea61d920Sderaadt * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
116ea61d920Sderaadt * optimally by gcc m68k, much better than any ?: stuff.
117ea61d920Sderaadt * Code may vary with different architectures of course.
118ea61d920Sderaadt *
119ea61d920Sderaadt * I don't know what optimizer you used, but seeing divu's and
120ea61d920Sderaadt * bfextu's in the m68k assembly output did not encourage me...
12139dfdd06Spk * as well, gcc on the sparc definitely generates much better
12239dfdd06Spk * code with `?:'.
123ea61d920Sderaadt */
124ea61d920Sderaadt
125ea61d920Sderaadt static void
stios2btios(struct sunos_termios * st,struct termios * bt)12628bae79bSdsl stios2btios(struct sunos_termios *st, struct termios *bt)
127ea61d920Sderaadt {
128a82aeb55Saugustss u_long l, r;
129ea61d920Sderaadt
130*41aa5859Sriastradh memset(bt, 0, sizeof(*bt));
131*41aa5859Sriastradh
132ea61d920Sderaadt l = st->c_iflag;
133db97aa73Sderaadt r = ((l & 0x00000001) ? IGNBRK : 0);
134db97aa73Sderaadt r |= ((l & 0x00000002) ? BRKINT : 0);
135db97aa73Sderaadt r |= ((l & 0x00000004) ? IGNPAR : 0);
136db97aa73Sderaadt r |= ((l & 0x00000008) ? PARMRK : 0);
137db97aa73Sderaadt r |= ((l & 0x00000010) ? INPCK : 0);
138db97aa73Sderaadt r |= ((l & 0x00000020) ? ISTRIP : 0);
139db97aa73Sderaadt r |= ((l & 0x00000040) ? INLCR : 0);
140db97aa73Sderaadt r |= ((l & 0x00000080) ? IGNCR : 0);
141db97aa73Sderaadt r |= ((l & 0x00000100) ? ICRNL : 0);
142db97aa73Sderaadt /* ((l & 0x00000200) ? IUCLC : 0) */
143db97aa73Sderaadt r |= ((l & 0x00000400) ? IXON : 0);
144db97aa73Sderaadt r |= ((l & 0x00000800) ? IXANY : 0);
145db97aa73Sderaadt r |= ((l & 0x00001000) ? IXOFF : 0);
146db97aa73Sderaadt r |= ((l & 0x00002000) ? IMAXBEL : 0);
147ea61d920Sderaadt bt->c_iflag = r;
148ea61d920Sderaadt
149ea61d920Sderaadt l = st->c_oflag;
150db97aa73Sderaadt r = ((l & 0x00000001) ? OPOST : 0);
151db97aa73Sderaadt /* ((l & 0x00000002) ? OLCUC : 0) */
152db97aa73Sderaadt r |= ((l & 0x00000004) ? ONLCR : 0);
153db97aa73Sderaadt /* ((l & 0x00000008) ? OCRNL : 0) */
154db97aa73Sderaadt /* ((l & 0x00000010) ? ONOCR : 0) */
155db97aa73Sderaadt /* ((l & 0x00000020) ? ONLRET : 0) */
156db97aa73Sderaadt /* ((l & 0x00000040) ? OFILL : 0) */
157db97aa73Sderaadt /* ((l & 0x00000080) ? OFDEL : 0) */
158db97aa73Sderaadt /* ((l & 0x00000100) ? NLDLY : 0) */
159db97aa73Sderaadt /* ((l & 0x00000100) ? NL1 : 0) */
160db97aa73Sderaadt /* ((l & 0x00000600) ? CRDLY : 0) */
161db97aa73Sderaadt /* ((l & 0x00000200) ? CR1 : 0) */
162db97aa73Sderaadt /* ((l & 0x00000400) ? CR2 : 0) */
163db97aa73Sderaadt /* ((l & 0x00000600) ? CR3 : 0) */
164db97aa73Sderaadt /* ((l & 0x00001800) ? TABDLY : 0) */
165db97aa73Sderaadt /* ((l & 0x00000800) ? TAB1 : 0) */
166db97aa73Sderaadt /* ((l & 0x00001000) ? TAB2 : 0) */
167db97aa73Sderaadt r |= ((l & 0x00001800) ? OXTABS : 0);
168db97aa73Sderaadt /* ((l & 0x00002000) ? BSDLY : 0) */
169db97aa73Sderaadt /* ((l & 0x00002000) ? BS1 : 0) */
170db97aa73Sderaadt /* ((l & 0x00004000) ? VTDLY : 0) */
171db97aa73Sderaadt /* ((l & 0x00004000) ? VT1 : 0) */
172db97aa73Sderaadt /* ((l & 0x00008000) ? FFDLY : 0) */
173db97aa73Sderaadt /* ((l & 0x00008000) ? FF1 : 0) */
174db97aa73Sderaadt /* ((l & 0x00010000) ? PAGEOUT : 0) */
175db97aa73Sderaadt /* ((l & 0x00020000) ? WRAP : 0) */
176ea61d920Sderaadt bt->c_oflag = r;
177ea61d920Sderaadt
178ea61d920Sderaadt l = st->c_cflag;
179930c2dadSderaadt switch (l & 0x00000030) {
180930c2dadSderaadt case 0:
181930c2dadSderaadt r = CS5;
182930c2dadSderaadt break;
183930c2dadSderaadt case 0x00000010:
184930c2dadSderaadt r = CS6;
185930c2dadSderaadt break;
186930c2dadSderaadt case 0x00000020:
187930c2dadSderaadt r = CS7;
188930c2dadSderaadt break;
189930c2dadSderaadt case 0x00000030:
190930c2dadSderaadt r = CS8;
191930c2dadSderaadt break;
192930c2dadSderaadt }
193db97aa73Sderaadt r |= ((l & 0x00000040) ? CSTOPB : 0);
194db97aa73Sderaadt r |= ((l & 0x00000080) ? CREAD : 0);
195db97aa73Sderaadt r |= ((l & 0x00000100) ? PARENB : 0);
196db97aa73Sderaadt r |= ((l & 0x00000200) ? PARODD : 0);
197db97aa73Sderaadt r |= ((l & 0x00000400) ? HUPCL : 0);
198db97aa73Sderaadt r |= ((l & 0x00000800) ? CLOCAL : 0);
199db97aa73Sderaadt /* ((l & 0x00001000) ? LOBLK : 0) */
200db97aa73Sderaadt r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
201ea61d920Sderaadt bt->c_cflag = r;
202ea61d920Sderaadt
203ea61d920Sderaadt bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
204ea61d920Sderaadt
205ea61d920Sderaadt l = st->c_lflag;
206db97aa73Sderaadt r = ((l & 0x00000001) ? ISIG : 0);
207db97aa73Sderaadt r |= ((l & 0x00000002) ? ICANON : 0);
208db97aa73Sderaadt /* ((l & 0x00000004) ? XCASE : 0) */
209db97aa73Sderaadt r |= ((l & 0x00000008) ? ECHO : 0);
210db97aa73Sderaadt r |= ((l & 0x00000010) ? ECHOE : 0);
211db97aa73Sderaadt r |= ((l & 0x00000020) ? ECHOK : 0);
212db97aa73Sderaadt r |= ((l & 0x00000040) ? ECHONL : 0);
213db97aa73Sderaadt r |= ((l & 0x00000080) ? NOFLSH : 0);
214db97aa73Sderaadt r |= ((l & 0x00000100) ? TOSTOP : 0);
215db97aa73Sderaadt r |= ((l & 0x00000200) ? ECHOCTL : 0);
216db97aa73Sderaadt r |= ((l & 0x00000400) ? ECHOPRT : 0);
217db97aa73Sderaadt r |= ((l & 0x00000800) ? ECHOKE : 0);
218db97aa73Sderaadt /* ((l & 0x00001000) ? DEFECHO : 0) */
219db97aa73Sderaadt r |= ((l & 0x00002000) ? FLUSHO : 0);
220db97aa73Sderaadt r |= ((l & 0x00004000) ? PENDIN : 0);
221ea61d920Sderaadt bt->c_lflag = r;
222ea61d920Sderaadt
223ea61d920Sderaadt bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
224ea61d920Sderaadt bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
225ea61d920Sderaadt bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
226ea61d920Sderaadt bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
227ea61d920Sderaadt bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
228ea61d920Sderaadt bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
229ea61d920Sderaadt bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
230ea61d920Sderaadt /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
231ea61d920Sderaadt bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
232ea61d920Sderaadt bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
233ea61d920Sderaadt bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
234ea61d920Sderaadt bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
235ea61d920Sderaadt bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
236ea61d920Sderaadt bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
237ea61d920Sderaadt bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
238ea61d920Sderaadt bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
239ea61d920Sderaadt bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
2402e57b94fSderaadt
2412e57b94fSderaadt /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
2422e57b94fSderaadt bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
2432e57b94fSderaadt bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
244ea61d920Sderaadt }
245ea61d920Sderaadt
246ea61d920Sderaadt
247ea61d920Sderaadt static void
btios2stios(struct termios * bt,struct sunos_termios * st)24828bae79bSdsl btios2stios(struct termios *bt, struct sunos_termios *st)
249ea61d920Sderaadt {
250a82aeb55Saugustss u_long l, r;
251fc8b478bSchristos int s;
252ea61d920Sderaadt
253*41aa5859Sriastradh memset(st, 0, sizeof(*st));
254*41aa5859Sriastradh
255ea61d920Sderaadt l = bt->c_iflag;
256db97aa73Sderaadt r = ((l & IGNBRK) ? 0x00000001 : 0);
257db97aa73Sderaadt r |= ((l & BRKINT) ? 0x00000002 : 0);
258db97aa73Sderaadt r |= ((l & IGNPAR) ? 0x00000004 : 0);
259db97aa73Sderaadt r |= ((l & PARMRK) ? 0x00000008 : 0);
260db97aa73Sderaadt r |= ((l & INPCK) ? 0x00000010 : 0);
261db97aa73Sderaadt r |= ((l & ISTRIP) ? 0x00000020 : 0);
262db97aa73Sderaadt r |= ((l & INLCR) ? 0x00000040 : 0);
263db97aa73Sderaadt r |= ((l & IGNCR) ? 0x00000080 : 0);
264db97aa73Sderaadt r |= ((l & ICRNL) ? 0x00000100 : 0);
265db97aa73Sderaadt /* ((l & IUCLC) ? 0x00000200 : 0) */
266db97aa73Sderaadt r |= ((l & IXON) ? 0x00000400 : 0);
267db97aa73Sderaadt r |= ((l & IXANY) ? 0x00000800 : 0);
268db97aa73Sderaadt r |= ((l & IXOFF) ? 0x00001000 : 0);
269db97aa73Sderaadt r |= ((l & IMAXBEL) ? 0x00002000 : 0);
270ea61d920Sderaadt st->c_iflag = r;
271ea61d920Sderaadt
272ea61d920Sderaadt l = bt->c_oflag;
273db97aa73Sderaadt r = ((l & OPOST) ? 0x00000001 : 0);
274db97aa73Sderaadt /* ((l & OLCUC) ? 0x00000002 : 0) */
275db97aa73Sderaadt r |= ((l & ONLCR) ? 0x00000004 : 0);
276db97aa73Sderaadt /* ((l & OCRNL) ? 0x00000008 : 0) */
277db97aa73Sderaadt /* ((l & ONOCR) ? 0x00000010 : 0) */
278db97aa73Sderaadt /* ((l & ONLRET) ? 0x00000020 : 0) */
279db97aa73Sderaadt /* ((l & OFILL) ? 0x00000040 : 0) */
280db97aa73Sderaadt /* ((l & OFDEL) ? 0x00000080 : 0) */
281db97aa73Sderaadt /* ((l & NLDLY) ? 0x00000100 : 0) */
282db97aa73Sderaadt /* ((l & NL1) ? 0x00000100 : 0) */
283db97aa73Sderaadt /* ((l & CRDLY) ? 0x00000600 : 0) */
284db97aa73Sderaadt /* ((l & CR1) ? 0x00000200 : 0) */
285db97aa73Sderaadt /* ((l & CR2) ? 0x00000400 : 0) */
286db97aa73Sderaadt /* ((l & CR3) ? 0x00000600 : 0) */
287db97aa73Sderaadt /* ((l & TABDLY) ? 0x00001800 : 0) */
288db97aa73Sderaadt /* ((l & TAB1) ? 0x00000800 : 0) */
289db97aa73Sderaadt /* ((l & TAB2) ? 0x00001000 : 0) */
290db97aa73Sderaadt r |= ((l & OXTABS) ? 0x00001800 : 0);
291db97aa73Sderaadt /* ((l & BSDLY) ? 0x00002000 : 0) */
292db97aa73Sderaadt /* ((l & BS1) ? 0x00002000 : 0) */
293db97aa73Sderaadt /* ((l & VTDLY) ? 0x00004000 : 0) */
294db97aa73Sderaadt /* ((l & VT1) ? 0x00004000 : 0) */
295db97aa73Sderaadt /* ((l & FFDLY) ? 0x00008000 : 0) */
296db97aa73Sderaadt /* ((l & FF1) ? 0x00008000 : 0) */
297db97aa73Sderaadt /* ((l & PAGEOUT) ? 0x00010000 : 0) */
298db97aa73Sderaadt /* ((l & WRAP) ? 0x00020000 : 0) */
299ea61d920Sderaadt st->c_oflag = r;
300ea61d920Sderaadt
301ea61d920Sderaadt l = bt->c_cflag;
302930c2dadSderaadt switch (l & CSIZE) {
303930c2dadSderaadt case CS5:
304930c2dadSderaadt r = 0;
305930c2dadSderaadt break;
306930c2dadSderaadt case CS6:
307930c2dadSderaadt r = 0x00000010;
308930c2dadSderaadt break;
309930c2dadSderaadt case CS7:
310930c2dadSderaadt r = 0x00000020;
311930c2dadSderaadt break;
312930c2dadSderaadt case CS8:
313930c2dadSderaadt r = 0x00000030;
314930c2dadSderaadt break;
315930c2dadSderaadt }
316db97aa73Sderaadt r |= ((l & CSTOPB) ? 0x00000040 : 0);
317db97aa73Sderaadt r |= ((l & CREAD) ? 0x00000080 : 0);
318db97aa73Sderaadt r |= ((l & PARENB) ? 0x00000100 : 0);
319db97aa73Sderaadt r |= ((l & PARODD) ? 0x00000200 : 0);
320db97aa73Sderaadt r |= ((l & HUPCL) ? 0x00000400 : 0);
321db97aa73Sderaadt r |= ((l & CLOCAL) ? 0x00000800 : 0);
322db97aa73Sderaadt /* ((l & LOBLK) ? 0x00001000 : 0) */
323db97aa73Sderaadt r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
324ea61d920Sderaadt st->c_cflag = r;
325ea61d920Sderaadt
326ea61d920Sderaadt l = bt->c_lflag;
327db97aa73Sderaadt r = ((l & ISIG) ? 0x00000001 : 0);
328db97aa73Sderaadt r |= ((l & ICANON) ? 0x00000002 : 0);
329db97aa73Sderaadt /* ((l & XCASE) ? 0x00000004 : 0) */
330db97aa73Sderaadt r |= ((l & ECHO) ? 0x00000008 : 0);
331db97aa73Sderaadt r |= ((l & ECHOE) ? 0x00000010 : 0);
332db97aa73Sderaadt r |= ((l & ECHOK) ? 0x00000020 : 0);
333db97aa73Sderaadt r |= ((l & ECHONL) ? 0x00000040 : 0);
334db97aa73Sderaadt r |= ((l & NOFLSH) ? 0x00000080 : 0);
335db97aa73Sderaadt r |= ((l & TOSTOP) ? 0x00000100 : 0);
336db97aa73Sderaadt r |= ((l & ECHOCTL) ? 0x00000200 : 0);
337db97aa73Sderaadt r |= ((l & ECHOPRT) ? 0x00000400 : 0);
338db97aa73Sderaadt r |= ((l & ECHOKE) ? 0x00000800 : 0);
339db97aa73Sderaadt /* ((l & DEFECHO) ? 0x00001000 : 0) */
340db97aa73Sderaadt r |= ((l & FLUSHO) ? 0x00002000 : 0);
341db97aa73Sderaadt r |= ((l & PENDIN) ? 0x00004000 : 0);
342ea61d920Sderaadt st->c_lflag = r;
343ea61d920Sderaadt
344fc8b478bSchristos s = ttspeedtab(bt->c_ospeed, sptab);
345fc8b478bSchristos if (s >= 0)
346fc8b478bSchristos st->c_cflag |= s;
347ea61d920Sderaadt
348ea61d920Sderaadt st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
349ea61d920Sderaadt st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
350ea61d920Sderaadt st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
351ea61d920Sderaadt st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
352ea61d920Sderaadt st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
353ea61d920Sderaadt st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
354ea61d920Sderaadt st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
355ea61d920Sderaadt st->c_cc[7] = 0;
356ea61d920Sderaadt /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
357ea61d920Sderaadt st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
358ea61d920Sderaadt st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
359ea61d920Sderaadt st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
360ea61d920Sderaadt st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
361ea61d920Sderaadt st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
362ea61d920Sderaadt st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
363ea61d920Sderaadt st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
364ea61d920Sderaadt st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
365ea61d920Sderaadt st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
366ea61d920Sderaadt
3671dd6d8a8Spk if (!(bt->c_lflag & ICANON)) {
3681dd6d8a8Spk /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
3691dd6d8a8Spk st->c_cc[4] = bt->c_cc[VMIN];
3701dd6d8a8Spk st->c_cc[5] = bt->c_cc[VTIME];
3711dd6d8a8Spk }
3721dd6d8a8Spk
373ea61d920Sderaadt st->c_line = 0;
374ea61d920Sderaadt }
375ea61d920Sderaadt
376ea61d920Sderaadt static void
stios2stio(struct sunos_termios * ts,struct sunos_termio * t)37728bae79bSdsl stios2stio(struct sunos_termios *ts, struct sunos_termio *t)
378ea61d920Sderaadt {
379*41aa5859Sriastradh
380*41aa5859Sriastradh memset(t, 0, sizeof(*t));
381ea61d920Sderaadt t->c_iflag = ts->c_iflag;
382ea61d920Sderaadt t->c_oflag = ts->c_oflag;
383ea61d920Sderaadt t->c_cflag = ts->c_cflag;
384ea61d920Sderaadt t->c_lflag = ts->c_lflag;
385ea61d920Sderaadt t->c_line = ts->c_line;
386e1601dc2Sperry memcpy(t->c_cc, ts->c_cc, 8);
387ea61d920Sderaadt }
388ea61d920Sderaadt
389ea61d920Sderaadt static void
stio2stios(struct sunos_termio * t,struct sunos_termios * ts)39028bae79bSdsl stio2stios(struct sunos_termio *t, struct sunos_termios *ts)
391ea61d920Sderaadt {
392*41aa5859Sriastradh
393*41aa5859Sriastradh memset(ts, 0, sizeof(*ts));
394ea61d920Sderaadt ts->c_iflag = t->c_iflag;
395ea61d920Sderaadt ts->c_oflag = t->c_oflag;
396ea61d920Sderaadt ts->c_cflag = t->c_cflag;
397ea61d920Sderaadt ts->c_lflag = t->c_lflag;
398ea61d920Sderaadt ts->c_line = t->c_line;
399e1601dc2Sperry memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */
400ea61d920Sderaadt }
4014588caefSderaadt
402ea61d920Sderaadt int
sunos_sys_ioctl(struct lwp * l,const struct sunos_sys_ioctl_args * uap,register_t * retval)403e19818fbSmsaitoh sunos_sys_ioctl(struct lwp *l, const struct sunos_sys_ioctl_args *uap,
404e19818fbSmsaitoh register_t *retval)
4054588caefSderaadt {
4067e2790cfSdsl /* {
407cbffcd18Smrg int fd;
408cbffcd18Smrg u_long com;
40953524e44Schristos void * data;
4107e2790cfSdsl } */
411a9ca7a37Sad file_t *fp;
412a9ca7a37Sad int (*ctl)(struct file *, u_long, void *);
4137e2790cfSdsl struct sys_ioctl_args pass_ua;
4144588caefSderaadt int error;
4154588caefSderaadt
416a9ca7a37Sad if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
417ea61d920Sderaadt return EBADF;
418ea61d920Sderaadt
4192931081aSpk if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
420c6c77837Spk error = EBADF;
421c6c77837Spk goto out;
4222931081aSpk }
423ea61d920Sderaadt
424c6c77837Spk error = EPASSTHROUGH;
4257e2790cfSdsl SCARG(&pass_ua, com) = SCARG(uap, com);
4264588caefSderaadt ctl = fp->f_ops->fo_ioctl;
4274588caefSderaadt
428019f4833Sderaadt switch (SCARG(uap, com)) {
4294588caefSderaadt case _IOR('t', 0, int):
4307e2790cfSdsl SCARG(&pass_ua, com) = TIOCGETD;
4314588caefSderaadt break;
4324588caefSderaadt case _IOW('t', 1, int):
433ea61d920Sderaadt {
434ea61d920Sderaadt int disc;
4354588caefSderaadt
43653524e44Schristos if ((error = copyin(SCARG(uap, data), (void *)&disc,
437ea61d920Sderaadt sizeof disc)) != 0)
438c6c77837Spk break;
439ea61d920Sderaadt
440ea61d920Sderaadt /* map SunOS NTTYDISC into our termios discipline */
441ea61d920Sderaadt if (disc == 2)
442ea61d920Sderaadt disc = 0;
443ea61d920Sderaadt /* all other disciplines are not supported by NetBSD */
444c6c77837Spk if (disc) {
445c6c77837Spk error = ENXIO;
446c6c77837Spk break;
447c6c77837Spk }
448ea61d920Sderaadt
449a9ca7a37Sad error = (*ctl)(fp, TIOCSETD, &disc);
4504640ae90Schristos break;
4514588caefSderaadt }
452019f4833Sderaadt case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
453ac4a9763Sderaadt {
454ac4a9763Sderaadt int x; /* unused */
455ac4a9763Sderaadt
4565107c4e2Smaxv error = copyin(SCARG(uap, data), (void *)&x, sizeof x);
457c6c77837Spk break;
458ac4a9763Sderaadt }
459019f4833Sderaadt case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
460ac4a9763Sderaadt {
461ac4a9763Sderaadt int x = 0;
462ac4a9763Sderaadt
46353524e44Schristos error = copyout((void *)&x, SCARG(uap, data), sizeof x);
464c6c77837Spk break;
465ac4a9763Sderaadt }
466ea61d920Sderaadt case _IO('t', 36): /* sun TIOCCONS, no parameters */
467ea61d920Sderaadt {
468ea61d920Sderaadt int on = 1;
469a9ca7a37Sad error = (*ctl)(fp, TIOCCONS, &on);
470c6c77837Spk break;
471ea61d920Sderaadt }
472019f4833Sderaadt case _IOW('t', 37, struct sunos_ttysize):
473ea61d920Sderaadt {
4744588caefSderaadt struct winsize ws;
475019f4833Sderaadt struct sunos_ttysize ss;
476ea61d920Sderaadt
477a9ca7a37Sad if ((error = (*ctl)(fp, TIOCGWINSZ, &ws)) != 0)
478c6c77837Spk break;
479ea61d920Sderaadt
480019f4833Sderaadt if ((error = copyin(SCARG(uap, data), &ss, sizeof(ss))) != 0)
481c6c77837Spk break;
482ea61d920Sderaadt
483ea61d920Sderaadt ws.ws_row = ss.ts_row;
484ea61d920Sderaadt ws.ws_col = ss.ts_col;
485ea61d920Sderaadt
486a9ca7a37Sad error = (*ctl)(fp, TIOCSWINSZ, &ws);
487c6c77837Spk break;
4884588caefSderaadt }
489019f4833Sderaadt case _IOW('t', 38, struct sunos_ttysize):
490ea61d920Sderaadt {
4914588caefSderaadt struct winsize ws;
492019f4833Sderaadt struct sunos_ttysize ss;
493ea61d920Sderaadt
494a9ca7a37Sad if ((error = (*ctl)(fp, TIOCGWINSZ, &ws)) != 0)
495c6c77837Spk break;
4964588caefSderaadt
497*41aa5859Sriastradh memset(&ss, 0, sizeof(ss));
498ea61d920Sderaadt ss.ts_row = ws.ws_row;
499ea61d920Sderaadt ss.ts_col = ws.ws_col;
500ea61d920Sderaadt
50153524e44Schristos error = copyout((void *)&ss, SCARG(uap, data), sizeof(ss));
502c6c77837Spk break;
503ea61d920Sderaadt }
504d3b3f3e5Smrg case _IOR('t', 119, int): /* TIOCGPGRP */
505d3b3f3e5Smrg {
506d3b3f3e5Smrg int pgrp;
507d3b3f3e5Smrg
508a9ca7a37Sad error = (*ctl)(fp, TIOCGPGRP, &pgrp);
509d3b3f3e5Smrg if (error == 0 && pgrp == 0)
510c6c77837Spk error = EIO;
511d3b3f3e5Smrg if (error)
512c6c77837Spk break;
51353524e44Schristos error = copyout((void *)&pgrp, SCARG(uap, data), sizeof(pgrp));
514c6c77837Spk break;
515d3b3f3e5Smrg }
51639dfdd06Spk case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
5177e2790cfSdsl SCARG(&pass_ua, com) = TIOCSPGRP;
5184588caefSderaadt break;
51939dfdd06Spk case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
52039dfdd06Spk {
52139dfdd06Spk /*
522d3b3f3e5Smrg * sigh, must do error translation on pty devices. if the pgrp
523d3b3f3e5Smrg * returned is 0 (and no error), we convert this to EIO, if it
524d3b3f3e5Smrg * is on a pty.
52539dfdd06Spk */
52639dfdd06Spk int pgrp;
52745b1ec74Smatt struct vnode *vp = NULL;
528d3b3f3e5Smrg
529a9ca7a37Sad error = (*ctl)(fp, TIOCGPGRP, &pgrp);
53039dfdd06Spk if (error) {
53145b1ec74Smatt if (fp->f_type == DTYPE_VNODE)
53245b1ec74Smatt vp = fp->f_vnode;
533d3b3f3e5Smrg if ((error == EIO || (error == 0 && pgrp == 0)) &&
534d3b3f3e5Smrg vp != NULL &&
535d3b3f3e5Smrg vp->v_type == VCHR &&
536d3b3f3e5Smrg major(vp->v_rdev) == 21)
53739dfdd06Spk error = ENOTTY;
538c6c77837Spk break;
53939dfdd06Spk }
54053524e44Schristos error = copyout((void *)&pgrp, SCARG(uap, data), sizeof(pgrp));
541c6c77837Spk break;
54239dfdd06Spk }
5434588caefSderaadt case _IO('t', 132):
5447e2790cfSdsl SCARG(&pass_ua, com) = TIOCSCTTY;
5454588caefSderaadt break;
546019f4833Sderaadt case SUNOS_TCGETA:
547019f4833Sderaadt case SUNOS_TCGETS:
548ea61d920Sderaadt {
549ea61d920Sderaadt struct termios bts;
550019f4833Sderaadt struct sunos_termios sts;
551019f4833Sderaadt struct sunos_termio st;
5524588caefSderaadt
553a9ca7a37Sad if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0)
554c6c77837Spk break;
555ea61d920Sderaadt
556ea61d920Sderaadt btios2stios (&bts, &sts);
557019f4833Sderaadt if (SCARG(uap, com) == SUNOS_TCGETA) {
558ea61d920Sderaadt stios2stio (&sts, &st);
55953524e44Schristos error = copyout((void *)&st, SCARG(uap, data),
560019f4833Sderaadt sizeof(st));
561ea61d920Sderaadt } else
56253524e44Schristos error = copyout((void *)&sts, SCARG(uap, data),
563019f4833Sderaadt sizeof(sts));
564c6c77837Spk break;
565ea61d920Sderaadt }
566019f4833Sderaadt case SUNOS_TCSETA:
567019f4833Sderaadt case SUNOS_TCSETAW:
568019f4833Sderaadt case SUNOS_TCSETAF:
569ea61d920Sderaadt {
570ea61d920Sderaadt struct termios bts;
571019f4833Sderaadt struct sunos_termios sts;
572019f4833Sderaadt struct sunos_termio st;
573ea61d920Sderaadt
574a9ca7a37Sad if ((error = copyin(SCARG(uap, data), &st, sizeof(st))) != 0)
575c6c77837Spk break;
576ea61d920Sderaadt
577ea61d920Sderaadt /* get full BSD termios so we don't lose information */
578a9ca7a37Sad if ((error = (*ctl)(fp, TIOCGETA, &bts)) != 0)
579c6c77837Spk break;
580ea61d920Sderaadt
581ea61d920Sderaadt /*
582ea61d920Sderaadt * convert to sun termios, copy in information from
583ea61d920Sderaadt * termio, and convert back, then set new values.
584ea61d920Sderaadt */
585ea61d920Sderaadt btios2stios(&bts, &sts);
586ea61d920Sderaadt stio2stios(&st, &sts);
587ea61d920Sderaadt stios2btios(&sts, &bts);
588ea61d920Sderaadt
589c6c77837Spk error = (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA,
590a9ca7a37Sad &bts);
591c6c77837Spk break;
592ea61d920Sderaadt }
593019f4833Sderaadt case SUNOS_TCSETS:
594019f4833Sderaadt case SUNOS_TCSETSW:
595019f4833Sderaadt case SUNOS_TCSETSF:
596ea61d920Sderaadt {
597ea61d920Sderaadt struct termios bts;
598019f4833Sderaadt struct sunos_termios sts;
599ea61d920Sderaadt
60053524e44Schristos if ((error = copyin(SCARG(uap, data), (void *)&sts,
601ea61d920Sderaadt sizeof(sts))) != 0)
602c6c77837Spk break;
603ea61d920Sderaadt stios2btios (&sts, &bts);
604c6c77837Spk error = (*ctl)(fp, SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA,
605a9ca7a37Sad &bts);
606c6c77837Spk break;
6074588caefSderaadt }
6089d48733fSderaadt /*
6099d48733fSderaadt * Pseudo-tty ioctl translations.
6109d48733fSderaadt */
61121099f34Spk case _IOW('t', 32, int): { /* TIOCTCNTL */
612189e1218Stsutsui int on;
61321099f34Spk
61453524e44Schristos error = copyin(SCARG(uap, data), (void *)&on, sizeof(on));
615fc8b478bSchristos if (error)
616c6c77837Spk break;
617a9ca7a37Sad error = (*ctl)(fp, TIOCUCNTL, &on);
618c6c77837Spk break;
61921099f34Spk }
6209d48733fSderaadt case _IOW('t', 33, int): { /* TIOCSIGNAL */
621189e1218Stsutsui int sig;
6229d48733fSderaadt
62353524e44Schristos error = copyin(SCARG(uap, data), (void *)&sig, sizeof(sig));
624fc8b478bSchristos if (error)
625c6c77837Spk break;
626a9ca7a37Sad error = (*ctl)(fp, TIOCSIG, &sig);
627c6c77837Spk break;
6289d48733fSderaadt }
6299d48733fSderaadt
6309d48733fSderaadt /*
6319d48733fSderaadt * Socket ioctl translations.
6329d48733fSderaadt */
6339d48733fSderaadt #define IFREQ_IN(a) { \
63420bfd989Schristos struct oifreq ifreq; \
63553524e44Schristos error = copyin(SCARG(uap, data), (void *)&ifreq, sizeof(ifreq)); \
636fc8b478bSchristos if (error) \
637c6c77837Spk break; \
638a9ca7a37Sad error = (*ctl)(fp, a, &ifreq); \
639c6c77837Spk break; \
6409d48733fSderaadt }
6419d48733fSderaadt #define IFREQ_INOUT(a) { \
64220bfd989Schristos struct oifreq ifreq; \
64353524e44Schristos error = copyin(SCARG(uap, data), (void *)&ifreq, sizeof(ifreq)); \
644fc8b478bSchristos if (error) \
645c6c77837Spk break; \
646a9ca7a37Sad if ((error = (*ctl)(fp, a, &ifreq)) != 0) \
647c6c77837Spk break; \
64853524e44Schristos error = copyout((void *)&ifreq, SCARG(uap, data), sizeof(ifreq)); \
649c6c77837Spk break; \
6509d48733fSderaadt }
6519d48733fSderaadt
65220bfd989Schristos case _IOW('i', 12, struct oifreq): /* SIOCSIFADDR */
65320bfd989Schristos case _IOW('i', 14, struct oifreq): /* SIOCSIFDSTADDR */
65420bfd989Schristos case _IOW('i', 16, struct oifreq): /* SIOCSIFFLAGS */
65520bfd989Schristos case _IOWR('i', 17, struct oifreq): /* SIOCGIFFLAGS */
656c6c77837Spk case _IOW('i', 30, struct arpreq): /* SIOCSARP */
657c6c77837Spk case _IOWR('i', 31, struct arpreq): /* SIOCGARP */
658c6c77837Spk case _IOW('i', 32, struct arpreq): /* SIOCDARP */
6599d48733fSderaadt break;
6609d48733fSderaadt
66120bfd989Schristos case _IOWR('i', 13, struct oifreq):
6628f77cc1cShe IFREQ_INOUT(OOSIOCGIFADDR);
6639d48733fSderaadt
66420bfd989Schristos case _IOWR('i', 15, struct oifreq):
6658f77cc1cShe IFREQ_INOUT(OOSIOCGIFDSTADDR);
6669d48733fSderaadt
66720bfd989Schristos case _IOW('i', 21, struct oifreq):
6689d48733fSderaadt IFREQ_IN(SIOCSIFMTU);
6699d48733fSderaadt
67020bfd989Schristos case _IOWR('i', 22, struct oifreq):
6719d48733fSderaadt IFREQ_INOUT(SIOCGIFMTU);
6729d48733fSderaadt
67320bfd989Schristos case _IOWR('i', 23, struct oifreq):
6749d48733fSderaadt IFREQ_INOUT(SIOCGIFBRDADDR);
6759d48733fSderaadt
67620bfd989Schristos case _IOW('i', 24, struct oifreq):
6779d48733fSderaadt IFREQ_IN(SIOCSIFBRDADDR);
6789d48733fSderaadt
67920bfd989Schristos case _IOWR('i', 25, struct oifreq):
6808f77cc1cShe IFREQ_INOUT(OOSIOCGIFNETMASK);
6819d48733fSderaadt
68220bfd989Schristos case _IOW('i', 26, struct oifreq):
6839d48733fSderaadt IFREQ_IN(SIOCSIFNETMASK);
6849d48733fSderaadt
68520bfd989Schristos case _IOWR('i', 27, struct oifreq):
6869d48733fSderaadt IFREQ_INOUT(SIOCGIFMETRIC);
6879d48733fSderaadt
68820bfd989Schristos case _IOWR('i', 28, struct oifreq):
6899d48733fSderaadt IFREQ_IN(SIOCSIFMETRIC);
6909d48733fSderaadt
69120bfd989Schristos case _IOW('i', 18, struct oifreq): /* SIOCSIFMEM */
69220bfd989Schristos case _IOWR('i', 19, struct oifreq): /* SIOCGIFMEM */
69320bfd989Schristos case _IOW('i', 40, struct oifreq): /* SIOCUPPER */
69420bfd989Schristos case _IOW('i', 41, struct oifreq): /* SIOCLOWER */
69520bfd989Schristos case _IOW('i', 44, struct oifreq): /* SIOCSETSYNC */
69620bfd989Schristos case _IOWR('i', 45, struct oifreq): /* SIOCGETSYNC */
69720bfd989Schristos case _IOWR('i', 46, struct oifreq): /* SIOCSDSTATS */
69820bfd989Schristos case _IOWR('i', 47, struct oifreq): /* SIOCSESTATS */
6999d48733fSderaadt case _IOW('i', 48, int): /* SIOCSPROMISC */
70020bfd989Schristos case _IOW('i', 49, struct oifreq): /* SIOCADDMULTI */
70120bfd989Schristos case _IOW('i', 50, struct oifreq): /* SIOCDELMULTI */
702c6c77837Spk error = EOPNOTSUPP;
703c6c77837Spk break;
7049d48733fSderaadt
70520bfd989Schristos case _IOWR('i', 20, struct oifconf): /* SIOCGIFCONF */
7069d48733fSderaadt {
70720bfd989Schristos struct oifconf ifc;
7089d48733fSderaadt
7099d48733fSderaadt /*
7109d48733fSderaadt * XXX: two more problems
711e19818fbSmsaitoh * 1. our sockaddr's are variable length, not always
712e19818fbSmsaitoh * sizeof(sockaddr)
713e19818fbSmsaitoh * 2. this returns a name per protocol, ie. it returns two
714e19818fbSmsaitoh * "lo0"'s
7159d48733fSderaadt */
716a9ca7a37Sad error = copyin(SCARG(uap, data), &ifc, sizeof(ifc));
717fc8b478bSchristos if (error)
718c6c77837Spk break;
719a9ca7a37Sad error = (*ctl)(fp, OOSIOCGIFCONF, &ifc);
720fc8b478bSchristos if (error)
721c6c77837Spk break;
722e19818fbSmsaitoh error = copyout((void *)&ifc, SCARG(uap, data), sizeof(ifc));
723c6c77837Spk break;
7249d48733fSderaadt }
725a1cfb5b3Spk
726a1cfb5b3Spk /*
727a1cfb5b3Spk * Audio ioctl translations.
728a1cfb5b3Spk */
729a1cfb5b3Spk case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */
7301dd6d8a8Spk sunos_au_getinfo:
731a1cfb5b3Spk {
732a1cfb5b3Spk struct audio_info aui;
733a1cfb5b3Spk struct sunos_audio_info sunos_aui;
734a1cfb5b3Spk
735a9ca7a37Sad error = (*ctl)(fp, AUDIO_GETINFO, &aui);
736fc8b478bSchristos if (error)
737c6c77837Spk break;
738a1cfb5b3Spk
739*41aa5859Sriastradh memset(&sunos_aui, 0, sizeof(sunos_aui));
740a1cfb5b3Spk sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
741a1cfb5b3Spk sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
742a1cfb5b3Spk
743a1cfb5b3Spk /* `avail_ports' is `seek' in BSD */
744a1cfb5b3Spk sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
745a1cfb5b3Spk sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
746a1cfb5b3Spk
747a1cfb5b3Spk sunos_aui.play.waiting = 0;
748a1cfb5b3Spk sunos_aui.record.waiting = 0;
749a1cfb5b3Spk sunos_aui.play.eof = 0;
750a1cfb5b3Spk sunos_aui.record.eof = 0;
7513d6483abSjeremy sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
7521e070197Spk /*XXXsunos_aui.output_muted = 0;*/
7531e070197Spk /*XXX*/sunos_aui.reserved[0] = 0;
7541e070197Spk /*XXX*/sunos_aui.reserved[1] = 0;
7551e070197Spk /*XXX*/sunos_aui.reserved[2] = 0;
7561e070197Spk /*XXX*/sunos_aui.reserved[3] = 0;
757a1cfb5b3Spk
75853524e44Schristos error = copyout((void *)&sunos_aui, SCARG(uap, data),
759a1cfb5b3Spk sizeof(sunos_aui));
760c6c77837Spk break;
761a1cfb5b3Spk }
762a1cfb5b3Spk
763a1cfb5b3Spk case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */
764a1cfb5b3Spk {
765a1cfb5b3Spk struct audio_info aui;
766a1cfb5b3Spk struct sunos_audio_info sunos_aui;
767a1cfb5b3Spk
76853524e44Schristos error = copyin(SCARG(uap, data), (void *)&sunos_aui,
769fc8b478bSchristos sizeof(sunos_aui));
770fc8b478bSchristos if (error)
771c6c77837Spk break;
772a1cfb5b3Spk
773a1cfb5b3Spk aui.play = *(struct audio_prinfo *)&sunos_aui.play;
774a1cfb5b3Spk aui.record = *(struct audio_prinfo *)&sunos_aui.record;
7753d6483abSjeremy /* aui.__spare = sunos_aui.monitor_gain; */
776a1cfb5b3Spk aui.blocksize = ~0;
777a1cfb5b3Spk aui.hiwat = ~0;
778a1cfb5b3Spk aui.lowat = ~0;
779c7f92376Sis /* XXX somebody check this please. - is: aui.backlog = ~0; */
7804c8828e7Spk aui.mode = ~0;
781a1cfb5b3Spk /*
782a1cfb5b3Spk * The bsd driver does not distinguish between paused and
783a1cfb5b3Spk * active. (In the sun driver, not active means samples are
784617b132aSwiz * not output at all, but paused means the last streams buffer
785a1cfb5b3Spk * is drained and then output stops.) If either are 0, then
786a1cfb5b3Spk * when stop output. Otherwise, if either are non-zero,
787a1cfb5b3Spk * we resume.
788a1cfb5b3Spk */
789a1cfb5b3Spk if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
790a1cfb5b3Spk aui.play.pause = 0;
791a1cfb5b3Spk else if (sunos_aui.play.pause != (u_char)~0 ||
792a1cfb5b3Spk sunos_aui.play.active != (u_char)~0)
793a1cfb5b3Spk aui.play.pause = 1;
794a1cfb5b3Spk if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
795a1cfb5b3Spk aui.record.pause = 0;
796a1cfb5b3Spk else if (sunos_aui.record.pause != (u_char)~0 ||
797a1cfb5b3Spk sunos_aui.record.active != (u_char)~0)
798a1cfb5b3Spk aui.record.pause = 1;
799a1cfb5b3Spk
800a9ca7a37Sad error = (*ctl)(fp, AUDIO_SETINFO, &aui);
801fc8b478bSchristos if (error)
802c6c77837Spk break;
8031dd6d8a8Spk /* Return new state */
8041dd6d8a8Spk goto sunos_au_getinfo;
805a1cfb5b3Spk }
806a1cfb5b3Spk case _IO('A', 3): /* AUDIO_DRAIN */
807a9ca7a37Sad error = (*ctl)(fp, AUDIO_DRAIN, NULL);
808c6c77837Spk break;
809a1cfb5b3Spk case _IOR('A', 4, int): /* AUDIO_GETDEV */
810a1cfb5b3Spk {
811a1cfb5b3Spk int devtype = SUNOS_AUDIO_DEV_AMD;
81253524e44Schristos error = copyout((void *)&devtype, SCARG(uap, data),
813a1cfb5b3Spk sizeof(devtype));
814c6c77837Spk break;
815a1cfb5b3Spk }
8161dd6d8a8Spk
8171dd6d8a8Spk /*
8181dd6d8a8Spk * Selected streams ioctls.
8191dd6d8a8Spk */
8201dd6d8a8Spk #define SUNOS_S_FLUSHR 1
8211dd6d8a8Spk #define SUNOS_S_FLUSHW 2
8221dd6d8a8Spk #define SUNOS_S_FLUSHRW 3
8231dd6d8a8Spk
8241dd6d8a8Spk #define SUNOS_S_INPUT 1
8251dd6d8a8Spk #define SUNOS_S_HIPRI 2
8261dd6d8a8Spk #define SUNOS_S_OUTPUT 4
8271dd6d8a8Spk #define SUNOS_S_MSG 8
8281dd6d8a8Spk
8291dd6d8a8Spk case _IO('S', 5): /* I_FLUSH */
8301dd6d8a8Spk {
8311dd6d8a8Spk int tmp = 0;
832705b50bfSmrg switch ((int)(u_long)SCARG(uap, data)) {
83305c35a4eSmlelstv case SUNOS_S_FLUSHR: tmp = FREAD; break;
83405c35a4eSmlelstv case SUNOS_S_FLUSHW: tmp = FWRITE; break;
83505c35a4eSmlelstv case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE; break;
8361dd6d8a8Spk }
837a9ca7a37Sad error = (*ctl)(fp, TIOCFLUSH, &tmp);
838c6c77837Spk break;
8391dd6d8a8Spk }
840ec587073Spk case _IO('S', 9): /* I_SETSIG */
8411dd6d8a8Spk {
8421dd6d8a8Spk int on = 1;
843705b50bfSmrg if (((int)(u_long)SCARG(uap, data) &
844c6c77837Spk (SUNOS_S_HIPRI|SUNOS_S_INPUT)) == SUNOS_S_HIPRI) {
845c6c77837Spk error = EOPNOTSUPP;
846c6c77837Spk break;
847c6c77837Spk }
848a9ca7a37Sad error = (*ctl)(fp, FIOASYNC, &on);
849c6c77837Spk break;
8501dd6d8a8Spk }
851cbffcd18Smrg /*
852cbffcd18Smrg * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
853cbffcd18Smrg * (which was from the old sparc/scsi/sun_disklabel.c), and
854cbffcd18Smrg * modified to suite.
855cbffcd18Smrg */
856ec9d9246Schristos case SUN_DKIOCGGEOM:
857cbffcd18Smrg {
858cbffcd18Smrg struct disklabel dl;
859cbffcd18Smrg
860a9ca7a37Sad error = (*ctl)(fp, DIOCGDINFO, &dl);
861cbffcd18Smrg if (error)
862c6c77837Spk break;
863cbffcd18Smrg
864cbffcd18Smrg #define datageom ((struct sun_dkgeom *)SCARG(uap, data))
865e1601dc2Sperry memset(SCARG(uap, data), 0, sizeof(*datageom));
866cbffcd18Smrg
867cbffcd18Smrg datageom->sdkc_ncylinders = dl.d_ncylinders;
868cbffcd18Smrg datageom->sdkc_acylinders = dl.d_acylinders;
869cbffcd18Smrg datageom->sdkc_ntracks = dl.d_ntracks;
870cbffcd18Smrg datageom->sdkc_nsectors = dl.d_nsectors;
871cbffcd18Smrg datageom->sdkc_interleave = dl.d_interleave;
872cbffcd18Smrg datageom->sdkc_sparespercyl = dl.d_sparespercyl;
873cbffcd18Smrg datageom->sdkc_rpm = dl.d_rpm;
874cbffcd18Smrg datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders;
875cbffcd18Smrg #undef datageom
876cbffcd18Smrg break;
877cbffcd18Smrg }
878cbffcd18Smrg
879ec9d9246Schristos case SUN_DKIOCINFO:
880cbffcd18Smrg /* Homey don't do DKIOCINFO */
881e1601dc2Sperry memset(SCARG(uap, data), 0, sizeof(struct sun_dkctlr));
882cbffcd18Smrg break;
883cbffcd18Smrg
884ec9d9246Schristos case SUN_DKIOCGPART:
885cbffcd18Smrg {
886cbffcd18Smrg struct partinfo pi;
8878d10f962Schristos struct disklabel label;
888cbffcd18Smrg
8898d10f962Schristos error = (*ctl)(fp, DIOCGDINFO, &label);
8908d10f962Schristos if (error)
8918d10f962Schristos break;
8928d10f962Schristos error = (*ctl)(fp, DIOCGPARTINFO, &pi);
893cbffcd18Smrg if (error)
894c6c77837Spk break;
895cbffcd18Smrg
896a5e9d486Snakayama if (label.d_secpercyl == 0) {
897a5e9d486Snakayama error = ERANGE; /* XXX */
898a5e9d486Snakayama break;
899a5e9d486Snakayama }
9008d10f962Schristos if (pi.pi_offset % label.d_secpercyl != 0) {
901c6c77837Spk error = ERANGE; /* XXX */
902c6c77837Spk break;
903c6c77837Spk }
904c6c77837Spk
905cbffcd18Smrg #define datapart ((struct sun_dkpart *)SCARG(uap, data))
9068d10f962Schristos datapart->sdkp_cyloffset = pi.pi_offset / label.d_secpercyl;
9078d10f962Schristos datapart->sdkp_nsectors = pi.pi_size;
908cbffcd18Smrg #undef datapart
909c6c77837Spk break;
910cbffcd18Smrg }
911cbffcd18Smrg
9124588caefSderaadt }
913c6c77837Spk
914c6c77837Spk out:
915a9ca7a37Sad fd_putfile(SCARG(uap, fd));
9167e2790cfSdsl if (error == EPASSTHROUGH) {
9177e2790cfSdsl SCARG(&pass_ua, fd) = SCARG(uap, fd);
9187e2790cfSdsl SCARG(&pass_ua, data) = SCARG(uap, data);
9197e2790cfSdsl error = sys_ioctl(l, &pass_ua, retval);
9207e2790cfSdsl }
921e19818fbSmsaitoh return error;
9224588caefSderaadt }
923636580a3Spk
924636580a3Spk /* SunOS fcntl(2) cmds not implemented */
925636580a3Spk #define SUN_F_RGETLK 10
926636580a3Spk #define SUN_F_RSETLK 11
927636580a3Spk #define SUN_F_CNVT 12
928636580a3Spk #define SUN_F_RSETLKW 13
929636580a3Spk
9305641a30aSpk /* SunOS flock translation */
9315641a30aSpk struct sunos_flock {
9325641a30aSpk short l_type;
9335641a30aSpk short l_whence;
9345641a30aSpk long l_start;
9355641a30aSpk long l_len;
9365641a30aSpk short l_pid;
9375641a30aSpk short l_xxx;
9385641a30aSpk };
9395641a30aSpk
940f2af9174Sdsl static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *);
941f2af9174Sdsl static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *);
9425641a30aSpk
9435641a30aSpk #define SUNOS_F_RDLCK 1
9445641a30aSpk #define SUNOS_F_WRLCK 2
9455641a30aSpk #define SUNOS_F_UNLCK 3
9465641a30aSpk
9475641a30aSpk static void
bsd_to_sunos_flock(struct flock * iflp,struct sunos_flock * oflp)94828bae79bSdsl bsd_to_sunos_flock(struct flock *iflp, struct sunos_flock *oflp)
9495641a30aSpk {
950*41aa5859Sriastradh
951*41aa5859Sriastradh memset(oflp, 0, sizeof(*oflp));
952*41aa5859Sriastradh
9535641a30aSpk switch (iflp->l_type) {
9545641a30aSpk case F_RDLCK:
9555641a30aSpk oflp->l_type = SUNOS_F_RDLCK;
9565641a30aSpk break;
9575641a30aSpk case F_WRLCK:
9585641a30aSpk oflp->l_type = SUNOS_F_WRLCK;
9595641a30aSpk break;
9605641a30aSpk case F_UNLCK:
9615641a30aSpk oflp->l_type = SUNOS_F_UNLCK;
9625641a30aSpk break;
9635641a30aSpk default:
9645641a30aSpk oflp->l_type = -1;
9655641a30aSpk break;
9665641a30aSpk }
9675641a30aSpk
9685641a30aSpk oflp->l_whence = (short) iflp->l_whence;
9695641a30aSpk oflp->l_start = (long) iflp->l_start;
9705641a30aSpk oflp->l_len = (long) iflp->l_len;
9715641a30aSpk oflp->l_pid = (short) iflp->l_pid;
9725641a30aSpk oflp->l_xxx = 0;
9735641a30aSpk }
9745641a30aSpk
9755641a30aSpk
9765641a30aSpk static void
sunos_to_bsd_flock(struct sunos_flock * iflp,struct flock * oflp)97728bae79bSdsl sunos_to_bsd_flock(struct sunos_flock *iflp, struct flock *oflp)
9785641a30aSpk {
979*41aa5859Sriastradh
980*41aa5859Sriastradh memset(oflp, 0, sizeof(*oflp));
981*41aa5859Sriastradh
9825641a30aSpk switch (iflp->l_type) {
9835641a30aSpk case SUNOS_F_RDLCK:
9845641a30aSpk oflp->l_type = F_RDLCK;
9855641a30aSpk break;
9865641a30aSpk case SUNOS_F_WRLCK:
9875641a30aSpk oflp->l_type = F_WRLCK;
9885641a30aSpk break;
9895641a30aSpk case SUNOS_F_UNLCK:
9905641a30aSpk oflp->l_type = F_UNLCK;
9915641a30aSpk break;
9925641a30aSpk default:
9935641a30aSpk oflp->l_type = -1;
9945641a30aSpk break;
9955641a30aSpk }
9965641a30aSpk
9975641a30aSpk oflp->l_whence = iflp->l_whence;
9985641a30aSpk oflp->l_start = (off_t) iflp->l_start;
9995641a30aSpk oflp->l_len = (off_t) iflp->l_len;
10005641a30aSpk oflp->l_pid = (pid_t) iflp->l_pid;
10015641a30aSpk
10025641a30aSpk }
1003636580a3Spk static struct {
1004636580a3Spk long sun_flg;
1005636580a3Spk long bsd_flg;
1006636580a3Spk } sunfcntl_flgtab[] = {
1007636580a3Spk /* F_[GS]ETFLags that differ: */
1008636580a3Spk #define SUN_FSETBLK 0x0010
1009636580a3Spk #define SUN_SHLOCK 0x0080
1010636580a3Spk #define SUN_EXLOCK 0x0100
1011636580a3Spk #define SUN_FNBIO 0x1000
1012636580a3Spk #define SUN_FSYNC 0x2000
1013636580a3Spk #define SUN_NONBLOCK 0x4000
1014636580a3Spk #define SUN_FNOCTTY 0x8000
1015636580a3Spk { SUN_NONBLOCK, O_NONBLOCK },
1016636580a3Spk { SUN_FNBIO, O_NONBLOCK },
1017636580a3Spk { SUN_SHLOCK, O_SHLOCK },
1018636580a3Spk { SUN_EXLOCK, O_EXLOCK },
1019636580a3Spk { SUN_FSYNC, O_FSYNC },
1020636580a3Spk { SUN_FSETBLK, 0 },
1021636580a3Spk { SUN_FNOCTTY, 0 }
1022636580a3Spk };
1023636580a3Spk
1024636580a3Spk int
sunos_sys_fcntl(struct lwp * l,const struct sunos_sys_fcntl_args * uap,register_t * retval)1025e19818fbSmsaitoh sunos_sys_fcntl(struct lwp *l, const struct sunos_sys_fcntl_args *uap,
1026e19818fbSmsaitoh register_t *retval)
1027636580a3Spk {
1028636580a3Spk long flg;
1029636580a3Spk int n, ret;
10307e2790cfSdsl struct sys_fcntl_args bsd_ua;
10317e2790cfSdsl
10327e2790cfSdsl SCARG(&bsd_ua, fd) = SCARG(uap, fd);
10337e2790cfSdsl SCARG(&bsd_ua, cmd) = SCARG(uap, cmd);
10347e2790cfSdsl SCARG(&bsd_ua, arg) = SCARG(uap, arg);
1035636580a3Spk
1036636580a3Spk
1037636580a3Spk switch (SCARG(uap, cmd)) {
1038636580a3Spk case F_SETFL:
1039636580a3Spk flg = (long)SCARG(uap, arg);
1040636580a3Spk n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1041636580a3Spk while (--n >= 0) {
1042636580a3Spk if (flg & sunfcntl_flgtab[n].sun_flg) {
1043636580a3Spk flg &= ~sunfcntl_flgtab[n].sun_flg;
1044636580a3Spk flg |= sunfcntl_flgtab[n].bsd_flg;
1045636580a3Spk }
1046636580a3Spk }
10477e2790cfSdsl SCARG(&bsd_ua, arg) = (void *)flg;
1048636580a3Spk break;
1049636580a3Spk
10505641a30aSpk case F_GETLK:
10515641a30aSpk case F_SETLK:
10525641a30aSpk case F_SETLKW:
10535641a30aSpk {
10545641a30aSpk int error;
10555641a30aSpk struct sunos_flock ifl;
1056701496b5Sdsl struct flock fl;
10575641a30aSpk
10585641a30aSpk error = copyin(SCARG(uap, arg), &ifl, sizeof ifl);
10595641a30aSpk if (error)
10605641a30aSpk return error;
10615641a30aSpk sunos_to_bsd_flock(&ifl, &fl);
10625641a30aSpk
1063e19818fbSmsaitoh error = do_fcntl_lock(SCARG(uap, fd), SCARG(uap, cmd),
1064e19818fbSmsaitoh &fl);
10655641a30aSpk if (error)
10665641a30aSpk return error;
10675641a30aSpk
1068701496b5Sdsl if (error || SCARG(uap, cmd) != F_GETLK)
10695641a30aSpk return error;
10705641a30aSpk
10715641a30aSpk bsd_to_sunos_flock(&fl, &ifl);
10725641a30aSpk
10735641a30aSpk return copyout(&ifl, SCARG(uap, arg), sizeof ifl);
10745641a30aSpk }
10755641a30aSpk break;
1076636580a3Spk case SUN_F_RGETLK:
1077636580a3Spk case SUN_F_RSETLK:
1078636580a3Spk case SUN_F_CNVT:
1079636580a3Spk case SUN_F_RSETLKW:
1080e19818fbSmsaitoh return EOPNOTSUPP;
1081636580a3Spk
1082636580a3Spk default:
10838bf2751bSthorpej break;
1084636580a3Spk }
1085636580a3Spk
10867e2790cfSdsl ret = sys_fcntl(l, &bsd_ua, retval);
1087636580a3Spk
10887e2790cfSdsl switch (SCARG(&bsd_ua, cmd)) {
1089636580a3Spk case F_GETFL:
1090636580a3Spk n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
1091636580a3Spk while (--n >= 0) {
1092636580a3Spk if (ret & sunfcntl_flgtab[n].bsd_flg) {
1093636580a3Spk ret &= ~sunfcntl_flgtab[n].bsd_flg;
1094636580a3Spk ret |= sunfcntl_flgtab[n].sun_flg;
1095636580a3Spk }
1096636580a3Spk }
1097636580a3Spk break;
1098636580a3Spk default:
10998bf2751bSthorpej break;
1100636580a3Spk }
1101636580a3Spk
1102e19818fbSmsaitoh return ret;
1103636580a3Spk }
1104