1*41aa5859Sriastradh /* $NetBSD: sunos32_ioctl.c,v 1.36 2021/09/07 11:43:05 riastradh Exp $ */
22343525dSmrg /* from: NetBSD: sunos_ioctl.c,v 1.35 2001/02/03 22:20:02 mrg Exp */
33fbaadb8Smrg
43fbaadb8Smrg /*
53fbaadb8Smrg * Copyright (c) 2001 Matthew R. Green
63fbaadb8Smrg * All rights reserved.
73fbaadb8Smrg *
83fbaadb8Smrg * Redistribution and use in source and binary forms, with or without
93fbaadb8Smrg * modification, are permitted provided that the following conditions
103fbaadb8Smrg * are met:
113fbaadb8Smrg * 1. Redistributions of source code must retain the above copyright
123fbaadb8Smrg * notice, this list of conditions and the following disclaimer.
133fbaadb8Smrg * 2. Redistributions in binary form must reproduce the above copyright
143fbaadb8Smrg * notice, this list of conditions and the following disclaimer in the
153fbaadb8Smrg * documentation and/or other materials provided with the distribution.
163fbaadb8Smrg *
173fbaadb8Smrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
183fbaadb8Smrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
193fbaadb8Smrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
203fbaadb8Smrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
213fbaadb8Smrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
223fbaadb8Smrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
233fbaadb8Smrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
243fbaadb8Smrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
253fbaadb8Smrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
263fbaadb8Smrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
273fbaadb8Smrg * SUCH DAMAGE.
283fbaadb8Smrg */
293fbaadb8Smrg
302343525dSmrg /*
312343525dSmrg * Copyright (c) 1993 Markus Wild.
322343525dSmrg * All rights reserved.
332343525dSmrg *
342343525dSmrg * Redistribution and use in source and binary forms, with or without
352343525dSmrg * modification, are permitted provided that the following conditions
362343525dSmrg * are met:
372343525dSmrg * 1. Redistributions of source code must retain the above copyright
382343525dSmrg * notice, this list of conditions and the following disclaimer.
392343525dSmrg * 2. The name of the author may not be used to endorse or promote products
402343525dSmrg * derived from this software without specific prior written permission
412343525dSmrg *
422343525dSmrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
432343525dSmrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
442343525dSmrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
452343525dSmrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
462343525dSmrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
472343525dSmrg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
482343525dSmrg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
492343525dSmrg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
502343525dSmrg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
512343525dSmrg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
522343525dSmrg *
532343525dSmrg * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
542343525dSmrg */
553fbaadb8Smrg
56dab6ef8bSlukem #include <sys/cdefs.h>
57*41aa5859Sriastradh __KERNEL_RCSID(0, "$NetBSD: sunos32_ioctl.c,v 1.36 2021/09/07 11:43:05 riastradh Exp $");
58dab6ef8bSlukem
596a89288aSmrg #if defined(_KERNEL_OPT)
602343525dSmrg #include "opt_compat_netbsd32.h"
612343525dSmrg #include "opt_execfmt.h"
622343525dSmrg #endif
632343525dSmrg
642343525dSmrg #include <sys/param.h>
652343525dSmrg #include <sys/proc.h>
662343525dSmrg #include <sys/systm.h>
672343525dSmrg #include <sys/file.h>
682343525dSmrg #include <sys/filedesc.h>
692343525dSmrg #include <sys/ioctl.h>
702343525dSmrg #include <sys/termios.h>
712343525dSmrg #include <sys/tty.h>
722343525dSmrg #include <sys/socket.h>
732343525dSmrg #include <sys/audioio.h>
742343525dSmrg #include <sys/vnode.h>
752343525dSmrg #include <sys/mount.h>
762343525dSmrg #include <sys/disklabel.h>
772343525dSmrg #include <sys/syscallargs.h>
782343525dSmrg
792343525dSmrg #include <miscfs/specfs/specdev.h>
802343525dSmrg
812343525dSmrg #include <net/if.h>
822343525dSmrg
832343525dSmrg #include <dev/sun/disklabel.h>
842343525dSmrg
8520bfd989Schristos #include <compat/sys/sockio.h>
8620bfd989Schristos
872343525dSmrg #include <compat/sunos/sunos.h>
882343525dSmrg #include <compat/sunos/sunos_syscallargs.h>
892343525dSmrg #include <compat/netbsd32/netbsd32.h>
902343525dSmrg #include <compat/netbsd32/netbsd32_syscallargs.h>
912343525dSmrg #include <compat/sunos32/sunos32.h>
922343525dSmrg #include <compat/sunos32/sunos32_syscallargs.h>
932343525dSmrg #include <compat/common/compat_util.h>
942343525dSmrg
952343525dSmrg /*
962343525dSmrg * SunOS ioctl calls.
972343525dSmrg * This file is something of a hodge-podge.
982343525dSmrg * Support gets added as things turn up....
992343525dSmrg */
1002343525dSmrg
10122120ad6Smatt static const struct speedtab sptab[] = {
1022343525dSmrg { 0, 0 },
1032343525dSmrg { 50, 1 },
1042343525dSmrg { 75, 2 },
1052343525dSmrg { 110, 3 },
1062343525dSmrg { 134, 4 },
1072343525dSmrg { 135, 4 },
1082343525dSmrg { 150, 5 },
1092343525dSmrg { 200, 6 },
1102343525dSmrg { 300, 7 },
1112343525dSmrg { 600, 8 },
1122343525dSmrg { 1200, 9 },
1132343525dSmrg { 1800, 10 },
1142343525dSmrg { 2400, 11 },
1152343525dSmrg { 4800, 12 },
1162343525dSmrg { 9600, 13 },
1172343525dSmrg { 19200, 14 },
1182343525dSmrg { 38400, 15 },
1192343525dSmrg { -1, -1 }
1202343525dSmrg };
1212343525dSmrg
12222120ad6Smatt static const netbsd32_u_long s2btab[] = {
1232343525dSmrg 0,
1242343525dSmrg 50,
1252343525dSmrg 75,
1262343525dSmrg 110,
1272343525dSmrg 134,
1282343525dSmrg 150,
1292343525dSmrg 200,
1302343525dSmrg 300,
1312343525dSmrg 600,
1322343525dSmrg 1200,
1332343525dSmrg 1800,
1342343525dSmrg 2400,
1352343525dSmrg 4800,
1362343525dSmrg 9600,
1372343525dSmrg 19200,
1382343525dSmrg 38400,
1392343525dSmrg };
1402343525dSmrg
141f2af9174Sdsl static void stios2btios(struct sunos_termios *, struct termios *);
142f2af9174Sdsl static void btios2stios(struct termios *, struct sunos_termios *);
143f2af9174Sdsl static void stios2stio(struct sunos_termios *, struct sunos_termio *);
144f2af9174Sdsl static void stio2stios(struct sunos_termio *, struct sunos_termios *);
1452343525dSmrg
1462343525dSmrg /*
1472343525dSmrg * These two conversion functions have mostly been done
1482343525dSmrg * with some perl cut&paste, then hand-edited to comment
1492343525dSmrg * out what doesn't exist under NetBSD.
1502343525dSmrg * A note from Markus's code:
1512343525dSmrg * (l & BITMASK1) / BITMASK1 * BITMASK2 is translated
1522343525dSmrg * optimally by gcc m68k, much better than any ?: stuff.
1532343525dSmrg * Code may vary with different architectures of course.
1542343525dSmrg *
1552343525dSmrg * I don't know what optimizer you used, but seeing divu's and
1562343525dSmrg * bfextu's in the m68k assembly output did not encourage me...
1572343525dSmrg * as well, gcc on the sparc definitely generates much better
1582343525dSmrg * code with `?:'.
1592343525dSmrg */
1602343525dSmrg
1612343525dSmrg static void
stios2btios(struct sunos_termios * st,struct termios * bt)16228bae79bSdsl stios2btios(struct sunos_termios *st, struct termios *bt)
1632343525dSmrg {
164973fe837Smrg netbsd32_u_long l, r;
1652343525dSmrg
166*41aa5859Sriastradh memset(bt, 0, sizeof(*bt));
167*41aa5859Sriastradh
1682343525dSmrg l = st->c_iflag;
1692343525dSmrg r = ((l & 0x00000001) ? IGNBRK : 0);
1702343525dSmrg r |= ((l & 0x00000002) ? BRKINT : 0);
1712343525dSmrg r |= ((l & 0x00000004) ? IGNPAR : 0);
1722343525dSmrg r |= ((l & 0x00000008) ? PARMRK : 0);
1732343525dSmrg r |= ((l & 0x00000010) ? INPCK : 0);
1742343525dSmrg r |= ((l & 0x00000020) ? ISTRIP : 0);
1752343525dSmrg r |= ((l & 0x00000040) ? INLCR : 0);
1762343525dSmrg r |= ((l & 0x00000080) ? IGNCR : 0);
1772343525dSmrg r |= ((l & 0x00000100) ? ICRNL : 0);
1782343525dSmrg /* ((l & 0x00000200) ? IUCLC : 0) */
1792343525dSmrg r |= ((l & 0x00000400) ? IXON : 0);
1802343525dSmrg r |= ((l & 0x00000800) ? IXANY : 0);
1812343525dSmrg r |= ((l & 0x00001000) ? IXOFF : 0);
1822343525dSmrg r |= ((l & 0x00002000) ? IMAXBEL : 0);
1832343525dSmrg bt->c_iflag = r;
1842343525dSmrg
1852343525dSmrg l = st->c_oflag;
1862343525dSmrg r = ((l & 0x00000001) ? OPOST : 0);
1872343525dSmrg /* ((l & 0x00000002) ? OLCUC : 0) */
1882343525dSmrg r |= ((l & 0x00000004) ? ONLCR : 0);
1892343525dSmrg /* ((l & 0x00000008) ? OCRNL : 0) */
1902343525dSmrg /* ((l & 0x00000010) ? ONOCR : 0) */
1912343525dSmrg /* ((l & 0x00000020) ? ONLRET : 0) */
1922343525dSmrg /* ((l & 0x00000040) ? OFILL : 0) */
1932343525dSmrg /* ((l & 0x00000080) ? OFDEL : 0) */
1942343525dSmrg /* ((l & 0x00000100) ? NLDLY : 0) */
1952343525dSmrg /* ((l & 0x00000100) ? NL1 : 0) */
1962343525dSmrg /* ((l & 0x00000600) ? CRDLY : 0) */
1972343525dSmrg /* ((l & 0x00000200) ? CR1 : 0) */
1982343525dSmrg /* ((l & 0x00000400) ? CR2 : 0) */
1992343525dSmrg /* ((l & 0x00000600) ? CR3 : 0) */
2002343525dSmrg /* ((l & 0x00001800) ? TABDLY : 0) */
2012343525dSmrg /* ((l & 0x00000800) ? TAB1 : 0) */
2022343525dSmrg /* ((l & 0x00001000) ? TAB2 : 0) */
2032343525dSmrg r |= ((l & 0x00001800) ? OXTABS : 0);
2042343525dSmrg /* ((l & 0x00002000) ? BSDLY : 0) */
2052343525dSmrg /* ((l & 0x00002000) ? BS1 : 0) */
2062343525dSmrg /* ((l & 0x00004000) ? VTDLY : 0) */
2072343525dSmrg /* ((l & 0x00004000) ? VT1 : 0) */
2082343525dSmrg /* ((l & 0x00008000) ? FFDLY : 0) */
2092343525dSmrg /* ((l & 0x00008000) ? FF1 : 0) */
2102343525dSmrg /* ((l & 0x00010000) ? PAGEOUT : 0) */
2112343525dSmrg /* ((l & 0x00020000) ? WRAP : 0) */
2122343525dSmrg bt->c_oflag = r;
2132343525dSmrg
2142343525dSmrg l = st->c_cflag;
2152343525dSmrg switch (l & 0x00000030) {
2162343525dSmrg case 0:
2172343525dSmrg r = CS5;
2182343525dSmrg break;
2192343525dSmrg case 0x00000010:
2202343525dSmrg r = CS6;
2212343525dSmrg break;
2222343525dSmrg case 0x00000020:
2232343525dSmrg r = CS7;
2242343525dSmrg break;
2252343525dSmrg case 0x00000030:
2262343525dSmrg r = CS8;
2272343525dSmrg break;
2282343525dSmrg }
2292343525dSmrg r |= ((l & 0x00000040) ? CSTOPB : 0);
2302343525dSmrg r |= ((l & 0x00000080) ? CREAD : 0);
2312343525dSmrg r |= ((l & 0x00000100) ? PARENB : 0);
2322343525dSmrg r |= ((l & 0x00000200) ? PARODD : 0);
2332343525dSmrg r |= ((l & 0x00000400) ? HUPCL : 0);
2342343525dSmrg r |= ((l & 0x00000800) ? CLOCAL : 0);
2352343525dSmrg /* ((l & 0x00001000) ? LOBLK : 0) */
2362343525dSmrg r |= ((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
2372343525dSmrg bt->c_cflag = r;
2382343525dSmrg
2392343525dSmrg bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
2402343525dSmrg
2412343525dSmrg l = st->c_lflag;
2422343525dSmrg r = ((l & 0x00000001) ? ISIG : 0);
2432343525dSmrg r |= ((l & 0x00000002) ? ICANON : 0);
2442343525dSmrg /* ((l & 0x00000004) ? XCASE : 0) */
2452343525dSmrg r |= ((l & 0x00000008) ? ECHO : 0);
2462343525dSmrg r |= ((l & 0x00000010) ? ECHOE : 0);
2472343525dSmrg r |= ((l & 0x00000020) ? ECHOK : 0);
2482343525dSmrg r |= ((l & 0x00000040) ? ECHONL : 0);
2492343525dSmrg r |= ((l & 0x00000080) ? NOFLSH : 0);
2502343525dSmrg r |= ((l & 0x00000100) ? TOSTOP : 0);
2512343525dSmrg r |= ((l & 0x00000200) ? ECHOCTL : 0);
2522343525dSmrg r |= ((l & 0x00000400) ? ECHOPRT : 0);
2532343525dSmrg r |= ((l & 0x00000800) ? ECHOKE : 0);
2542343525dSmrg /* ((l & 0x00001000) ? DEFECHO : 0) */
2552343525dSmrg r |= ((l & 0x00002000) ? FLUSHO : 0);
2562343525dSmrg r |= ((l & 0x00004000) ? PENDIN : 0);
2572343525dSmrg bt->c_lflag = r;
2582343525dSmrg
2592343525dSmrg bt->c_cc[VINTR] = st->c_cc[0] ? st->c_cc[0] : _POSIX_VDISABLE;
2602343525dSmrg bt->c_cc[VQUIT] = st->c_cc[1] ? st->c_cc[1] : _POSIX_VDISABLE;
2612343525dSmrg bt->c_cc[VERASE] = st->c_cc[2] ? st->c_cc[2] : _POSIX_VDISABLE;
2622343525dSmrg bt->c_cc[VKILL] = st->c_cc[3] ? st->c_cc[3] : _POSIX_VDISABLE;
2632343525dSmrg bt->c_cc[VEOF] = st->c_cc[4] ? st->c_cc[4] : _POSIX_VDISABLE;
2642343525dSmrg bt->c_cc[VEOL] = st->c_cc[5] ? st->c_cc[5] : _POSIX_VDISABLE;
2652343525dSmrg bt->c_cc[VEOL2] = st->c_cc[6] ? st->c_cc[6] : _POSIX_VDISABLE;
2662343525dSmrg /* bt->c_cc[VSWTCH] = st->c_cc[7] ? st->c_cc[7] : _POSIX_VDISABLE; */
2672343525dSmrg bt->c_cc[VSTART] = st->c_cc[8] ? st->c_cc[8] : _POSIX_VDISABLE;
2682343525dSmrg bt->c_cc[VSTOP] = st->c_cc[9] ? st->c_cc[9] : _POSIX_VDISABLE;
2692343525dSmrg bt->c_cc[VSUSP] = st->c_cc[10] ? st->c_cc[10] : _POSIX_VDISABLE;
2702343525dSmrg bt->c_cc[VDSUSP] = st->c_cc[11] ? st->c_cc[11] : _POSIX_VDISABLE;
2712343525dSmrg bt->c_cc[VREPRINT] = st->c_cc[12] ? st->c_cc[12] : _POSIX_VDISABLE;
2722343525dSmrg bt->c_cc[VDISCARD] = st->c_cc[13] ? st->c_cc[13] : _POSIX_VDISABLE;
2732343525dSmrg bt->c_cc[VWERASE] = st->c_cc[14] ? st->c_cc[14] : _POSIX_VDISABLE;
2742343525dSmrg bt->c_cc[VLNEXT] = st->c_cc[15] ? st->c_cc[15] : _POSIX_VDISABLE;
2752343525dSmrg bt->c_cc[VSTATUS] = st->c_cc[16] ? st->c_cc[16] : _POSIX_VDISABLE;
2762343525dSmrg
2772343525dSmrg /* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
2782343525dSmrg bt->c_cc[VMIN] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
2792343525dSmrg bt->c_cc[VTIME] = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
2802343525dSmrg }
2812343525dSmrg
2822343525dSmrg
2832343525dSmrg static void
btios2stios(struct termios * bt,struct sunos_termios * st)28428bae79bSdsl btios2stios(struct termios *bt, struct sunos_termios *st)
2852343525dSmrg {
286973fe837Smrg netbsd32_u_long l, r;
2872343525dSmrg int s;
2882343525dSmrg
289*41aa5859Sriastradh memset(st, 0, sizeof(*st));
290*41aa5859Sriastradh
2912343525dSmrg l = bt->c_iflag;
2922343525dSmrg r = ((l & IGNBRK) ? 0x00000001 : 0);
2932343525dSmrg r |= ((l & BRKINT) ? 0x00000002 : 0);
2942343525dSmrg r |= ((l & IGNPAR) ? 0x00000004 : 0);
2952343525dSmrg r |= ((l & PARMRK) ? 0x00000008 : 0);
2962343525dSmrg r |= ((l & INPCK) ? 0x00000010 : 0);
2972343525dSmrg r |= ((l & ISTRIP) ? 0x00000020 : 0);
2982343525dSmrg r |= ((l & INLCR) ? 0x00000040 : 0);
2992343525dSmrg r |= ((l & IGNCR) ? 0x00000080 : 0);
3002343525dSmrg r |= ((l & ICRNL) ? 0x00000100 : 0);
3012343525dSmrg /* ((l & IUCLC) ? 0x00000200 : 0) */
3022343525dSmrg r |= ((l & IXON) ? 0x00000400 : 0);
3032343525dSmrg r |= ((l & IXANY) ? 0x00000800 : 0);
3042343525dSmrg r |= ((l & IXOFF) ? 0x00001000 : 0);
3052343525dSmrg r |= ((l & IMAXBEL) ? 0x00002000 : 0);
3062343525dSmrg st->c_iflag = r;
3072343525dSmrg
3082343525dSmrg l = bt->c_oflag;
3092343525dSmrg r = ((l & OPOST) ? 0x00000001 : 0);
3102343525dSmrg /* ((l & OLCUC) ? 0x00000002 : 0) */
3112343525dSmrg r |= ((l & ONLCR) ? 0x00000004 : 0);
3122343525dSmrg /* ((l & OCRNL) ? 0x00000008 : 0) */
3132343525dSmrg /* ((l & ONOCR) ? 0x00000010 : 0) */
3142343525dSmrg /* ((l & ONLRET) ? 0x00000020 : 0) */
3152343525dSmrg /* ((l & OFILL) ? 0x00000040 : 0) */
3162343525dSmrg /* ((l & OFDEL) ? 0x00000080 : 0) */
3172343525dSmrg /* ((l & NLDLY) ? 0x00000100 : 0) */
3182343525dSmrg /* ((l & NL1) ? 0x00000100 : 0) */
3192343525dSmrg /* ((l & CRDLY) ? 0x00000600 : 0) */
3202343525dSmrg /* ((l & CR1) ? 0x00000200 : 0) */
3212343525dSmrg /* ((l & CR2) ? 0x00000400 : 0) */
3222343525dSmrg /* ((l & CR3) ? 0x00000600 : 0) */
3232343525dSmrg /* ((l & TABDLY) ? 0x00001800 : 0) */
3242343525dSmrg /* ((l & TAB1) ? 0x00000800 : 0) */
3252343525dSmrg /* ((l & TAB2) ? 0x00001000 : 0) */
3262343525dSmrg r |= ((l & OXTABS) ? 0x00001800 : 0);
3272343525dSmrg /* ((l & BSDLY) ? 0x00002000 : 0) */
3282343525dSmrg /* ((l & BS1) ? 0x00002000 : 0) */
3292343525dSmrg /* ((l & VTDLY) ? 0x00004000 : 0) */
3302343525dSmrg /* ((l & VT1) ? 0x00004000 : 0) */
3312343525dSmrg /* ((l & FFDLY) ? 0x00008000 : 0) */
3322343525dSmrg /* ((l & FF1) ? 0x00008000 : 0) */
3332343525dSmrg /* ((l & PAGEOUT) ? 0x00010000 : 0) */
3342343525dSmrg /* ((l & WRAP) ? 0x00020000 : 0) */
3352343525dSmrg st->c_oflag = r;
3362343525dSmrg
3372343525dSmrg l = bt->c_cflag;
3382343525dSmrg switch (l & CSIZE) {
3392343525dSmrg case CS5:
3402343525dSmrg r = 0;
3412343525dSmrg break;
3422343525dSmrg case CS6:
3432343525dSmrg r = 0x00000010;
3442343525dSmrg break;
3452343525dSmrg case CS7:
3462343525dSmrg r = 0x00000020;
3472343525dSmrg break;
3482343525dSmrg case CS8:
3492343525dSmrg r = 0x00000030;
3502343525dSmrg break;
3512343525dSmrg }
3522343525dSmrg r |= ((l & CSTOPB) ? 0x00000040 : 0);
3532343525dSmrg r |= ((l & CREAD) ? 0x00000080 : 0);
3542343525dSmrg r |= ((l & PARENB) ? 0x00000100 : 0);
3552343525dSmrg r |= ((l & PARODD) ? 0x00000200 : 0);
3562343525dSmrg r |= ((l & HUPCL) ? 0x00000400 : 0);
3572343525dSmrg r |= ((l & CLOCAL) ? 0x00000800 : 0);
3582343525dSmrg /* ((l & LOBLK) ? 0x00001000 : 0) */
3592343525dSmrg r |= ((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
3602343525dSmrg st->c_cflag = r;
3612343525dSmrg
3622343525dSmrg l = bt->c_lflag;
3632343525dSmrg r = ((l & ISIG) ? 0x00000001 : 0);
3642343525dSmrg r |= ((l & ICANON) ? 0x00000002 : 0);
3652343525dSmrg /* ((l & XCASE) ? 0x00000004 : 0) */
3662343525dSmrg r |= ((l & ECHO) ? 0x00000008 : 0);
3672343525dSmrg r |= ((l & ECHOE) ? 0x00000010 : 0);
3682343525dSmrg r |= ((l & ECHOK) ? 0x00000020 : 0);
3692343525dSmrg r |= ((l & ECHONL) ? 0x00000040 : 0);
3702343525dSmrg r |= ((l & NOFLSH) ? 0x00000080 : 0);
3712343525dSmrg r |= ((l & TOSTOP) ? 0x00000100 : 0);
3722343525dSmrg r |= ((l & ECHOCTL) ? 0x00000200 : 0);
3732343525dSmrg r |= ((l & ECHOPRT) ? 0x00000400 : 0);
3742343525dSmrg r |= ((l & ECHOKE) ? 0x00000800 : 0);
3752343525dSmrg /* ((l & DEFECHO) ? 0x00001000 : 0) */
3762343525dSmrg r |= ((l & FLUSHO) ? 0x00002000 : 0);
3772343525dSmrg r |= ((l & PENDIN) ? 0x00004000 : 0);
3782343525dSmrg st->c_lflag = r;
3792343525dSmrg
3802343525dSmrg s = ttspeedtab(bt->c_ospeed, sptab);
3812343525dSmrg if (s >= 0)
3822343525dSmrg st->c_cflag |= s;
3832343525dSmrg
3842343525dSmrg st->c_cc[0] = bt->c_cc[VINTR] != _POSIX_VDISABLE? bt->c_cc[VINTR]:0;
3852343525dSmrg st->c_cc[1] = bt->c_cc[VQUIT] != _POSIX_VDISABLE? bt->c_cc[VQUIT]:0;
3862343525dSmrg st->c_cc[2] = bt->c_cc[VERASE] != _POSIX_VDISABLE? bt->c_cc[VERASE]:0;
3872343525dSmrg st->c_cc[3] = bt->c_cc[VKILL] != _POSIX_VDISABLE? bt->c_cc[VKILL]:0;
3882343525dSmrg st->c_cc[4] = bt->c_cc[VEOF] != _POSIX_VDISABLE? bt->c_cc[VEOF]:0;
3892343525dSmrg st->c_cc[5] = bt->c_cc[VEOL] != _POSIX_VDISABLE? bt->c_cc[VEOL]:0;
3902343525dSmrg st->c_cc[6] = bt->c_cc[VEOL2] != _POSIX_VDISABLE? bt->c_cc[VEOL2]:0;
3912343525dSmrg st->c_cc[7] = 0;
3922343525dSmrg /* bt->c_cc[VSWTCH] != _POSIX_VDISABLE? bt->c_cc[VSWTCH]: */
3932343525dSmrg st->c_cc[8] = bt->c_cc[VSTART] != _POSIX_VDISABLE? bt->c_cc[VSTART]:0;
3942343525dSmrg st->c_cc[9] = bt->c_cc[VSTOP] != _POSIX_VDISABLE? bt->c_cc[VSTOP]:0;
3952343525dSmrg st->c_cc[10]= bt->c_cc[VSUSP] != _POSIX_VDISABLE? bt->c_cc[VSUSP]:0;
3962343525dSmrg st->c_cc[11]= bt->c_cc[VDSUSP] != _POSIX_VDISABLE? bt->c_cc[VDSUSP]:0;
3972343525dSmrg st->c_cc[12]= bt->c_cc[VREPRINT]!= _POSIX_VDISABLE? bt->c_cc[VREPRINT]:0;
3982343525dSmrg st->c_cc[13]= bt->c_cc[VDISCARD]!= _POSIX_VDISABLE? bt->c_cc[VDISCARD]:0;
3992343525dSmrg st->c_cc[14]= bt->c_cc[VWERASE] != _POSIX_VDISABLE? bt->c_cc[VWERASE]:0;
4002343525dSmrg st->c_cc[15]= bt->c_cc[VLNEXT] != _POSIX_VDISABLE? bt->c_cc[VLNEXT]:0;
4012343525dSmrg st->c_cc[16]= bt->c_cc[VSTATUS] != _POSIX_VDISABLE? bt->c_cc[VSTATUS]:0;
4022343525dSmrg
4032343525dSmrg if (!(bt->c_lflag & ICANON)) {
4042343525dSmrg /* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
4052343525dSmrg st->c_cc[4] = bt->c_cc[VMIN];
4062343525dSmrg st->c_cc[5] = bt->c_cc[VTIME];
4072343525dSmrg }
4082343525dSmrg
4092343525dSmrg st->c_line = 0;
4102343525dSmrg }
4112343525dSmrg
4122343525dSmrg static void
stios2stio(struct sunos_termios * ts,struct sunos_termio * t)41328bae79bSdsl stios2stio(struct sunos_termios *ts, struct sunos_termio *t)
4142343525dSmrg {
415*41aa5859Sriastradh
416*41aa5859Sriastradh memset(t, 0, sizeof(*t));
4172343525dSmrg t->c_iflag = ts->c_iflag;
4182343525dSmrg t->c_oflag = ts->c_oflag;
4192343525dSmrg t->c_cflag = ts->c_cflag;
4202343525dSmrg t->c_lflag = ts->c_lflag;
4212343525dSmrg t->c_line = ts->c_line;
4222343525dSmrg memcpy(t->c_cc, ts->c_cc, 8);
4232343525dSmrg }
4242343525dSmrg
4252343525dSmrg static void
stio2stios(struct sunos_termio * t,struct sunos_termios * ts)42628bae79bSdsl stio2stios(struct sunos_termio *t, struct sunos_termios *ts)
4272343525dSmrg {
428*41aa5859Sriastradh
429*41aa5859Sriastradh memset(ts, 0, sizeof(*ts));
4302343525dSmrg ts->c_iflag = t->c_iflag;
4312343525dSmrg ts->c_oflag = t->c_oflag;
4322343525dSmrg ts->c_cflag = t->c_cflag;
4332343525dSmrg ts->c_lflag = t->c_lflag;
4342343525dSmrg ts->c_line = t->c_line;
4352343525dSmrg memcpy(ts->c_cc, t->c_cc, 8); /* don't touch the upper fields! */
4362343525dSmrg }
4372343525dSmrg
43895a19579Sdsl
43995a19579Sdsl static int
sunos32_do_ioctl(int fd,int cmd,void * arg,struct lwp * l)44095a19579Sdsl sunos32_do_ioctl(int fd, int cmd, void *arg, struct lwp *l)
44195a19579Sdsl {
442a9ca7a37Sad file_t *fp;
44395a19579Sdsl struct vnode *vp;
44495a19579Sdsl int error;
44595a19579Sdsl
446599e52f8Snakayama if ((error = fd_getvnode(fd, &fp)) != 0)
44745b1ec74Smatt return error;
44895a19579Sdsl if ((fp->f_flag & (FREAD|FWRITE)) == 0) {
449a9ca7a37Sad fd_putfile(fd);
45095a19579Sdsl return EBADF;
45195a19579Sdsl }
452a9ca7a37Sad error = fp->f_ops->fo_ioctl(fp, cmd, arg);
45395a19579Sdsl if (error == EIO && cmd == TIOCGPGRP) {
45445b1ec74Smatt vp = fp->f_vnode;
45595a19579Sdsl if (vp != NULL && vp->v_type == VCHR && major(vp->v_rdev) == 21)
45695a19579Sdsl error = ENOTTY;
45795a19579Sdsl }
458a9ca7a37Sad fd_putfile(fd);
45995a19579Sdsl return error;
46095a19579Sdsl }
46195a19579Sdsl
4622343525dSmrg int
sunos32_sys_ioctl(struct lwp * l,const struct sunos32_sys_ioctl_args * uap,register_t * retval)463e19818fbSmsaitoh sunos32_sys_ioctl(struct lwp *l, const struct sunos32_sys_ioctl_args *uap,
464e19818fbSmsaitoh register_t *retval)
4652343525dSmrg {
4667e2790cfSdsl /* {
4672343525dSmrg int fd;
4682343525dSmrg netbsd32_u_long com;
469fffc9c66Schristos netbsd32_caddr_t data;
4707e2790cfSdsl } */
4717e2790cfSdsl struct netbsd32_ioctl_args bsd_ua;
4722343525dSmrg int error;
4732343525dSmrg
4747e2790cfSdsl SCARG(&bsd_ua, fd) = SCARG(uap, fd);
4757e2790cfSdsl SCARG(&bsd_ua, com) = SCARG(uap, com);
4767e2790cfSdsl SCARG(&bsd_ua, data) = SCARG(uap, data);
4777e2790cfSdsl
4782343525dSmrg switch (SCARG(uap, com)) {
4792343525dSmrg case _IOR('t', 0, int):
4807e2790cfSdsl SCARG(&bsd_ua, com) = TIOCGETD;
4812343525dSmrg break;
4822343525dSmrg case _IOW('t', 1, int):
4832343525dSmrg {
4842343525dSmrg int disc;
4852343525dSmrg
486a065e516Sdsl if ((error = copyin(SCARG_P32(uap, data), &disc,
4872343525dSmrg sizeof disc)) != 0)
4882343525dSmrg return error;
4892343525dSmrg
4902343525dSmrg /* map SunOS NTTYDISC into our termios discipline */
4912343525dSmrg if (disc == 2)
4922343525dSmrg disc = 0;
4932343525dSmrg /* all other disciplines are not supported by NetBSD */
4942343525dSmrg if (disc)
4952343525dSmrg return ENXIO;
4962343525dSmrg
49795a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSETD, &disc, l);
4982343525dSmrg }
4992343525dSmrg case _IOW('t', 101, int): /* sun SUNOS_TIOCSSOFTCAR */
5002343525dSmrg {
5012343525dSmrg int x; /* unused */
5022343525dSmrg
503a065e516Sdsl return copyin(SCARG_P32(uap, data), &x, sizeof x);
5042343525dSmrg }
5052343525dSmrg case _IOR('t', 100, int): /* sun SUNOS_TIOCSSOFTCAR */
5062343525dSmrg {
5072343525dSmrg int x = 0;
5082343525dSmrg
509a065e516Sdsl return copyout(&x, SCARG_P32(uap, data), sizeof x);
5102343525dSmrg }
5112343525dSmrg case _IO('t', 36): /* sun TIOCCONS, no parameters */
5122343525dSmrg {
5132343525dSmrg int on = 1;
51495a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCCONS, &on, l);
5152343525dSmrg }
5162343525dSmrg case _IOW('t', 37, struct sunos_ttysize):
5172343525dSmrg {
5182343525dSmrg struct winsize ws;
5192343525dSmrg struct sunos_ttysize ss;
5202343525dSmrg
521e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws,
522e19818fbSmsaitoh l);
523e19818fbSmsaitoh if (error != 0)
524e19818fbSmsaitoh return error;
5252343525dSmrg
526e19818fbSmsaitoh error = copyin(SCARG_P32(uap, data), &ss, sizeof(ss));
527e19818fbSmsaitoh if (error != 0)
5282343525dSmrg return error;
5292343525dSmrg
5302343525dSmrg ws.ws_row = ss.ts_row;
5312343525dSmrg ws.ws_col = ss.ts_col;
5322343525dSmrg
533e19818fbSmsaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSWINSZ, &ws, l);
5342343525dSmrg }
5352343525dSmrg case _IOW('t', 38, struct sunos_ttysize):
5362343525dSmrg {
5372343525dSmrg struct winsize ws;
5382343525dSmrg struct sunos_ttysize ss;
5392343525dSmrg
540e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGWINSZ, &ws,
541e19818fbSmsaitoh l);
542e19818fbSmsaitoh if (error != 0)
543e19818fbSmsaitoh return error;
5442343525dSmrg
545*41aa5859Sriastradh memset(&ss, 0, sizeof(ss));
5462343525dSmrg ss.ts_row = ws.ws_row;
5472343525dSmrg ss.ts_col = ws.ws_col;
5482343525dSmrg
549a065e516Sdsl return copyout(&ss, SCARG_P32(uap, data), sizeof(ss));
5502343525dSmrg }
5512343525dSmrg case _IOW('t', 130, int): /* TIOCSETPGRP: posix variant */
5527e2790cfSdsl SCARG(&bsd_ua, com) = TIOCSPGRP;
5532343525dSmrg break;
5542343525dSmrg case _IOR('t', 131, int): /* TIOCGETPGRP: posix variant */
5552343525dSmrg {
5562343525dSmrg /*
5572343525dSmrg * sigh, must do error translation on pty devices
5582343525dSmrg * (see also kern/tty_pty.c)
5592343525dSmrg */
5602343525dSmrg int pgrp;
561e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGPGRP, &pgrp,
562e19818fbSmsaitoh l);
56395a19579Sdsl if (error)
564e19818fbSmsaitoh return error;
565a065e516Sdsl return copyout(&pgrp, SCARG_P32(uap, data), sizeof(pgrp));
5662343525dSmrg }
5672343525dSmrg case _IO('t', 132):
5687e2790cfSdsl SCARG(&bsd_ua, com) = TIOCSCTTY;
5692343525dSmrg break;
5702343525dSmrg case SUNOS_TCGETA:
5712343525dSmrg case SUNOS_TCGETS:
5722343525dSmrg {
5732343525dSmrg struct termios bts;
5742343525dSmrg struct sunos_termios sts;
5752343525dSmrg struct sunos_termio st;
5762343525dSmrg
577e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA, &bts,
578e19818fbSmsaitoh l);
579e19818fbSmsaitoh if (error != 0)
5802343525dSmrg return error;
5812343525dSmrg
5822343525dSmrg btios2stios (&bts, &sts);
5832343525dSmrg if (SCARG(uap, com) == SUNOS_TCGETA) {
5842343525dSmrg stios2stio (&sts, &st);
585e19818fbSmsaitoh return copyout(&st, SCARG_P32(uap, data), sizeof(st));
5862343525dSmrg } else
587a065e516Sdsl return copyout(&sts, SCARG_P32(uap, data),
5882343525dSmrg sizeof(sts));
5892343525dSmrg /*NOTREACHED*/
5902343525dSmrg }
5912343525dSmrg case SUNOS_TCSETA:
5922343525dSmrg case SUNOS_TCSETAW:
5932343525dSmrg case SUNOS_TCSETAF:
5942343525dSmrg {
5952343525dSmrg struct termios bts;
5962343525dSmrg struct sunos_termios sts;
5972343525dSmrg struct sunos_termio st;
5982343525dSmrg
599a065e516Sdsl if ((error = copyin(SCARG_P32(uap, data), &st,
6002343525dSmrg sizeof(st))) != 0)
6012343525dSmrg return error;
6022343525dSmrg
6032343525dSmrg /* get full BSD termios so we don't lose information */
604e19818fbSmsaitoh if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCGETA,
605e19818fbSmsaitoh &bts, l)) != 0)
6062343525dSmrg return error;
6072343525dSmrg
6082343525dSmrg /*
6092343525dSmrg * convert to sun termios, copy in information from
6102343525dSmrg * termio, and convert back, then set new values.
6112343525dSmrg */
6122343525dSmrg btios2stios(&bts, &sts);
6132343525dSmrg stio2stios(&st, &sts);
6142343525dSmrg stios2btios(&sts, &bts);
6152343525dSmrg
616e19818fbSmsaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd),
617e19818fbSmsaitoh SCARG(uap, com) - SUNOS_TCSETA + TIOCSETA, &bts, l);
6182343525dSmrg }
6192343525dSmrg case SUNOS_TCSETS:
6202343525dSmrg case SUNOS_TCSETSW:
6212343525dSmrg case SUNOS_TCSETSF:
6222343525dSmrg {
6232343525dSmrg struct termios bts;
6242343525dSmrg struct sunos_termios sts;
6252343525dSmrg
626a065e516Sdsl if ((error = copyin(SCARG_P32(uap, data), &sts,
6272343525dSmrg sizeof(sts))) != 0)
6282343525dSmrg return error;
6292343525dSmrg stios2btios (&sts, &bts);
630e19818fbSmsaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd),
631e19818fbSmsaitoh SCARG(uap, com) - SUNOS_TCSETS + TIOCSETA, &bts, l);
6322343525dSmrg }
6332343525dSmrg /*
6342343525dSmrg * Pseudo-tty ioctl translations.
6352343525dSmrg */
6362343525dSmrg case _IOW('t', 32, int): { /* TIOCTCNTL */
637805ebc54Schristos int error1, on;
6382343525dSmrg
639a065e516Sdsl error1 = copyin(SCARG_P32(uap, data), &on, sizeof(on));
640805ebc54Schristos if (error1)
641805ebc54Schristos return error1;
64295a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCUCNTL, &on, l);
6432343525dSmrg }
6442343525dSmrg case _IOW('t', 33, int): { /* TIOCSIGNAL */
645805ebc54Schristos int error1, sig;
6462343525dSmrg
647a065e516Sdsl error1 = copyin(SCARG_P32(uap, data), &sig, sizeof(sig));
648805ebc54Schristos if (error1)
649805ebc54Schristos return error1;
65095a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCSIG, &sig, l);
6512343525dSmrg }
6522343525dSmrg
6532343525dSmrg /*
6542343525dSmrg * Socket ioctl translations.
6552343525dSmrg */
6562343525dSmrg #define IFREQ_IN(a) { \
65720bfd989Schristos struct oifreq ifreq; \
658a065e516Sdsl error = copyin(SCARG_P32(uap, data), &ifreq, sizeof(ifreq)); \
6592343525dSmrg if (error) \
6602343525dSmrg return error; \
66195a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l); \
6622343525dSmrg }
6632343525dSmrg #define IFREQ_INOUT(a) { \
66420bfd989Schristos struct oifreq ifreq; \
665a065e516Sdsl error = copyin(SCARG_P32(uap, data), &ifreq, sizeof(ifreq)); \
6662343525dSmrg if (error) \
6672343525dSmrg return error; \
66895a19579Sdsl if ((error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), a, &ifreq, l)) != 0) \
6692343525dSmrg return error; \
670a065e516Sdsl return copyout(&ifreq, SCARG_P32(uap, data), sizeof(ifreq)); \
6712343525dSmrg }
6722343525dSmrg
67320bfd989Schristos case _IOW('i', 12, struct oifreq):
6742343525dSmrg /* SIOCSIFADDR */
6752343525dSmrg break;
6762343525dSmrg
67720bfd989Schristos case _IOWR('i', 13, struct oifreq):
678b110563fShannken IFREQ_INOUT(OOSIOCGIFADDR);
6792343525dSmrg
68020bfd989Schristos case _IOW('i', 14, struct oifreq):
6812343525dSmrg /* SIOCSIFDSTADDR */
6822343525dSmrg break;
6832343525dSmrg
68420bfd989Schristos case _IOWR('i', 15, struct oifreq):
685b110563fShannken IFREQ_INOUT(OOSIOCGIFDSTADDR);
6862343525dSmrg
68720bfd989Schristos case _IOW('i', 16, struct oifreq):
6882343525dSmrg /* SIOCSIFFLAGS */
6892343525dSmrg break;
6902343525dSmrg
69120bfd989Schristos case _IOWR('i', 17, struct oifreq):
6922343525dSmrg /* SIOCGIFFLAGS */
6932343525dSmrg break;
6942343525dSmrg
69520bfd989Schristos case _IOW('i', 21, struct oifreq):
6962343525dSmrg IFREQ_IN(SIOCSIFMTU);
6972343525dSmrg
69820bfd989Schristos case _IOWR('i', 22, struct oifreq):
6992343525dSmrg IFREQ_INOUT(SIOCGIFMTU);
7002343525dSmrg
70120bfd989Schristos case _IOWR('i', 23, struct oifreq):
7022343525dSmrg IFREQ_INOUT(SIOCGIFBRDADDR);
7032343525dSmrg
70420bfd989Schristos case _IOW('i', 24, struct oifreq):
7052343525dSmrg IFREQ_IN(SIOCSIFBRDADDR);
7062343525dSmrg
70720bfd989Schristos case _IOWR('i', 25, struct oifreq):
708b110563fShannken IFREQ_INOUT(OOSIOCGIFNETMASK);
7092343525dSmrg
71020bfd989Schristos case _IOW('i', 26, struct oifreq):
7112343525dSmrg IFREQ_IN(SIOCSIFNETMASK);
7122343525dSmrg
71320bfd989Schristos case _IOWR('i', 27, struct oifreq):
7142343525dSmrg IFREQ_INOUT(SIOCGIFMETRIC);
7152343525dSmrg
71620bfd989Schristos case _IOWR('i', 28, struct oifreq):
7172343525dSmrg IFREQ_IN(SIOCSIFMETRIC);
7182343525dSmrg
7192343525dSmrg case _IOW('i', 30, struct arpreq):
7202343525dSmrg /* SIOCSARP */
7212343525dSmrg break;
7222343525dSmrg
7232343525dSmrg case _IOWR('i', 31, struct arpreq):
7242343525dSmrg /* SIOCGARP */
7252343525dSmrg break;
7262343525dSmrg
7272343525dSmrg case _IOW('i', 32, struct arpreq):
7282343525dSmrg /* SIOCDARP */
7292343525dSmrg break;
7302343525dSmrg
73120bfd989Schristos case _IOW('i', 18, struct oifreq): /* SIOCSIFMEM */
73220bfd989Schristos case _IOWR('i', 19, struct oifreq): /* SIOCGIFMEM */
73320bfd989Schristos case _IOW('i', 40, struct oifreq): /* SIOCUPPER */
73420bfd989Schristos case _IOW('i', 41, struct oifreq): /* SIOCLOWER */
73520bfd989Schristos case _IOW('i', 44, struct oifreq): /* SIOCSETSYNC */
73620bfd989Schristos case _IOWR('i', 45, struct oifreq): /* SIOCGETSYNC */
73720bfd989Schristos case _IOWR('i', 46, struct oifreq): /* SIOCSDSTATS */
73820bfd989Schristos case _IOWR('i', 47, struct oifreq): /* SIOCSESTATS */
7392343525dSmrg case _IOW('i', 48, int): /* SIOCSPROMISC */
74020bfd989Schristos case _IOW('i', 49, struct oifreq): /* SIOCADDMULTI */
74120bfd989Schristos case _IOW('i', 50, struct oifreq): /* SIOCDELMULTI */
7422343525dSmrg return EOPNOTSUPP;
7432343525dSmrg
74420bfd989Schristos case _IOWR('i', 20, struct oifconf): /* SIOCGIFCONF */
7452343525dSmrg {
74620bfd989Schristos struct oifconf ifcf;
7472343525dSmrg
7482343525dSmrg /*
7492343525dSmrg * XXX: two more problems
750e19818fbSmsaitoh * 1. our sockaddr's are variable length, not always
751e19818fbSmsaitoh * sizeof(sockaddr)
752e19818fbSmsaitoh * 2. this returns a name per protocol, ie. it returns two
753e19818fbSmsaitoh * "lo0"'s
7542343525dSmrg */
755e19818fbSmsaitoh error = copyin(SCARG_P32(uap, data), &ifcf, sizeof(ifcf));
7562343525dSmrg if (error)
7572343525dSmrg return error;
758e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), OOSIOCGIFCONF,
759e19818fbSmsaitoh &ifcf, l);
7602343525dSmrg if (error)
7612343525dSmrg return error;
762e19818fbSmsaitoh return copyout(&ifcf, SCARG_P32(uap, data), sizeof(ifcf));
7632343525dSmrg }
7642343525dSmrg
7652343525dSmrg /*
7662343525dSmrg * Audio ioctl translations.
7672343525dSmrg */
7682343525dSmrg case _IOR('A', 1, struct sunos_audio_info): /* AUDIO_GETINFO */
7692343525dSmrg sunos_au_getinfo:
7702343525dSmrg {
7712343525dSmrg struct audio_info aui;
7722343525dSmrg struct sunos_audio_info sunos_aui;
7732343525dSmrg
77495a19579Sdsl error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_GETINFO, &aui, l);
7752343525dSmrg if (error)
7762343525dSmrg return error;
7772343525dSmrg
778*41aa5859Sriastradh memset(&sunos_aui, 0, sizeof(sunos_aui));
779*41aa5859Sriastradh
7802343525dSmrg sunos_aui.play = *(struct sunos_audio_prinfo *)&aui.play;
7812343525dSmrg sunos_aui.record = *(struct sunos_audio_prinfo *)&aui.record;
7822343525dSmrg
7832343525dSmrg /* `avail_ports' is `seek' in BSD */
7842343525dSmrg sunos_aui.play.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
7852343525dSmrg sunos_aui.record.avail_ports = AUDIO_SPEAKER | AUDIO_HEADPHONE;
7862343525dSmrg
7872343525dSmrg sunos_aui.play.waiting = 0;
7882343525dSmrg sunos_aui.record.waiting = 0;
7892343525dSmrg sunos_aui.play.eof = 0;
7902343525dSmrg sunos_aui.record.eof = 0;
7912343525dSmrg sunos_aui.monitor_gain = 0; /* aui.__spare; XXX */
7922343525dSmrg /*XXXsunos_aui.output_muted = 0;*/
7932343525dSmrg /*XXX*/sunos_aui.reserved[0] = 0;
7942343525dSmrg /*XXX*/sunos_aui.reserved[1] = 0;
7952343525dSmrg /*XXX*/sunos_aui.reserved[2] = 0;
7962343525dSmrg /*XXX*/sunos_aui.reserved[3] = 0;
7972343525dSmrg
798a065e516Sdsl return copyout(&sunos_aui, SCARG_P32(uap, data),
7992343525dSmrg sizeof(sunos_aui));
8002343525dSmrg }
8012343525dSmrg
8022343525dSmrg case _IOWR('A', 2, struct sunos_audio_info): /* AUDIO_SETINFO */
8032343525dSmrg {
8042343525dSmrg struct audio_info aui;
8052343525dSmrg struct sunos_audio_info sunos_aui;
8062343525dSmrg
807a065e516Sdsl error = copyin(SCARG_P32(uap, data), &sunos_aui,
8082343525dSmrg sizeof(sunos_aui));
8092343525dSmrg if (error)
8102343525dSmrg return error;
8112343525dSmrg
8122343525dSmrg aui.play = *(struct audio_prinfo *)&sunos_aui.play;
8132343525dSmrg aui.record = *(struct audio_prinfo *)&sunos_aui.record;
8142343525dSmrg /* aui.__spare = sunos_aui.monitor_gain; */
8152343525dSmrg aui.blocksize = ~0;
8162343525dSmrg aui.hiwat = ~0;
8172343525dSmrg aui.lowat = ~0;
8182343525dSmrg /* XXX somebody check this please. - is: aui.backlog = ~0; */
8192343525dSmrg aui.mode = ~0;
8202343525dSmrg /*
8212343525dSmrg * The bsd driver does not distinguish between paused and
8222343525dSmrg * active. (In the sun driver, not active means samples are
823617b132aSwiz * not output at all, but paused means the last streams buffer
8242343525dSmrg * is drained and then output stops.) If either are 0, then
8252343525dSmrg * when stop output. Otherwise, if either are non-zero,
8262343525dSmrg * we resume.
8272343525dSmrg */
8282343525dSmrg if (sunos_aui.play.pause == 0 || sunos_aui.play.active == 0)
8292343525dSmrg aui.play.pause = 0;
8302343525dSmrg else if (sunos_aui.play.pause != (u_char)~0 ||
8312343525dSmrg sunos_aui.play.active != (u_char)~0)
8322343525dSmrg aui.play.pause = 1;
8332343525dSmrg if (sunos_aui.record.pause == 0 || sunos_aui.record.active == 0)
8342343525dSmrg aui.record.pause = 0;
8352343525dSmrg else if (sunos_aui.record.pause != (u_char)~0 ||
8362343525dSmrg sunos_aui.record.active != (u_char)~0)
8372343525dSmrg aui.record.pause = 1;
8382343525dSmrg
839e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_SETINFO,
840e19818fbSmsaitoh &aui, l);
8412343525dSmrg if (error)
8422343525dSmrg return error;
8432343525dSmrg /* Return new state */
8442343525dSmrg goto sunos_au_getinfo;
8452343525dSmrg }
8462343525dSmrg case _IO('A', 3): /* AUDIO_DRAIN */
847e19818fbSmsaitoh return sunos32_do_ioctl(SCARG(&bsd_ua, fd), AUDIO_DRAIN, NULL,
848e19818fbSmsaitoh l);
8492343525dSmrg case _IOR('A', 4, int): /* AUDIO_GETDEV */
8502343525dSmrg {
8512343525dSmrg int devtype = SUNOS_AUDIO_DEV_AMD;
852a065e516Sdsl return copyout(&devtype, SCARG_P32(uap, data),
8532343525dSmrg sizeof(devtype));
8542343525dSmrg }
8552343525dSmrg
8562343525dSmrg /*
8572343525dSmrg * Selected streams ioctls.
8582343525dSmrg */
8592343525dSmrg #define SUNOS_S_FLUSHR 1
8602343525dSmrg #define SUNOS_S_FLUSHW 2
8612343525dSmrg #define SUNOS_S_FLUSHRW 3
8622343525dSmrg
8632343525dSmrg #define SUNOS_S_INPUT 1
8642343525dSmrg #define SUNOS_S_HIPRI 2
8652343525dSmrg #define SUNOS_S_OUTPUT 4
8662343525dSmrg #define SUNOS_S_MSG 8
8672343525dSmrg
8682343525dSmrg case _IO('S', 5): /* I_FLUSH */
8692343525dSmrg {
8702343525dSmrg int tmp = 0;
871a065e516Sdsl switch ((intptr_t)SCARG_P32(uap, data)) {
8729e544026Smlelstv case SUNOS_S_FLUSHR: tmp = FREAD; break;
8739e544026Smlelstv case SUNOS_S_FLUSHW: tmp = FWRITE; break;
8749e544026Smlelstv case SUNOS_S_FLUSHRW: tmp = FREAD|FWRITE; break;
8752343525dSmrg }
87695a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), TIOCFLUSH, &tmp, l);
8772343525dSmrg }
8782343525dSmrg case _IO('S', 9): /* I_SETSIG */
8792343525dSmrg {
8802343525dSmrg int on = 1;
881a065e516Sdsl if (((intptr_t)SCARG_P32(uap, data) &
882e19818fbSmsaitoh (SUNOS_S_HIPRI|SUNOS_S_INPUT)) == SUNOS_S_HIPRI)
8832343525dSmrg return EOPNOTSUPP;
88495a19579Sdsl return sunos32_do_ioctl(SCARG(&bsd_ua, fd), FIOASYNC, &on, l);
8852343525dSmrg }
8862343525dSmrg /*
8872343525dSmrg * SunOS disk ioctls, taken from arch/sparc/sparc/disksubr.c
8882343525dSmrg * (which was from the old sparc/scsi/sun_disklabel.c), and
8892343525dSmrg * modified to suite.
8902343525dSmrg */
891ec9d9246Schristos case SUN_DKIOCGGEOM:
8922343525dSmrg {
8932343525dSmrg struct disklabel dl;
8942343525dSmrg
895e19818fbSmsaitoh error = sunos32_do_ioctl(SCARG(&bsd_ua, fd), DIOCGDINFO,
896e19818fbSmsaitoh &dl, l);
8972343525dSmrg if (error)
898e19818fbSmsaitoh return error;
8992343525dSmrg
900a065e516Sdsl #define datageom ((struct sun_dkgeom *)SCARG_P32(uap, data))
90160418b39Sdsl /* XXX can't do memset() on a user address (dsl) */
902a065e516Sdsl memset(SCARG_P32(uap, data), 0, sizeof(*datageom));
9032343525dSmrg
9042343525dSmrg datageom->sdkc_ncylinders = dl.d_ncylinders;
9052343525dSmrg datageom->sdkc_acylinders = dl.d_acylinders;
9062343525dSmrg datageom->sdkc_ntracks = dl.d_ntracks;
9072343525dSmrg datageom->sdkc_nsectors = dl.d_nsectors;
9082343525dSmrg datageom->sdkc_interleave = dl.d_interleave;
9092343525dSmrg datageom->sdkc_sparespercyl = dl.d_sparespercyl;
9102343525dSmrg datageom->sdkc_rpm = dl.d_rpm;
9112343525dSmrg datageom->sdkc_pcylinders = dl.d_ncylinders + dl.d_acylinders;
9122343525dSmrg #undef datageom
9132343525dSmrg break;
9142343525dSmrg }
9152343525dSmrg
916ec9d9246Schristos case SUN_DKIOCINFO:
9172343525dSmrg /* Homey don't do DKIOCINFO */
91860418b39Sdsl /* XXX can't do memset() on a user address (dsl) */
919a065e516Sdsl memset(SCARG_P32(uap, data), 0, sizeof(struct sun_dkctlr));
9202343525dSmrg break;
9212343525dSmrg
922ec9d9246Schristos case SUN_DKIOCGPART:
9232343525dSmrg {
9242343525dSmrg struct partinfo pi;
9258d10f962Schristos struct disklabel label;
9268d10f962Schristos int fd = SCARG(&bsd_ua, fd);
9272343525dSmrg
9288d10f962Schristos error = sunos32_do_ioctl(fd, DIOCGPARTINFO, &pi, l);
9292343525dSmrg if (error)
9308d10f962Schristos return error;
9318d10f962Schristos error = sunos32_do_ioctl(fd, DIOCGDINFO, &label, l);
9328d10f962Schristos if (error)
9338d10f962Schristos return error;
9342343525dSmrg
9358d10f962Schristos if (label.d_secpercyl == 0)
9368d10f962Schristos return ERANGE; /* XXX */
9378d10f962Schristos if (pi.pi_offset % label.d_secpercyl != 0)
9388d10f962Schristos return ERANGE; /* XXX */
939a065e516Sdsl /* XXX can't do direct writes to a user address (dsl) */
940a065e516Sdsl #define datapart ((struct sun_dkpart *)SCARG_P32(uap, data))
9418d10f962Schristos datapart->sdkp_cyloffset = pi.pi_offset / label.d_secpercyl;
9428d10f962Schristos datapart->sdkp_nsectors = pi.pi_size;
9432343525dSmrg #undef datapart
9442343525dSmrg }
9452343525dSmrg
9462343525dSmrg }
947e19818fbSmsaitoh return netbsd32_ioctl(l, &bsd_ua, retval);
9482343525dSmrg }
9492343525dSmrg
9502343525dSmrg /* SunOS fcntl(2) cmds not implemented */
9512343525dSmrg #define SUN_F_RGETLK 10
9522343525dSmrg #define SUN_F_RSETLK 11
9532343525dSmrg #define SUN_F_CNVT 12
9542343525dSmrg #define SUN_F_RSETLKW 13
9552343525dSmrg
9562343525dSmrg /* SunOS flock translation */
9572343525dSmrg struct sunos_flock {
9582343525dSmrg short l_type;
9592343525dSmrg short l_whence;
960973fe837Smrg netbsd32_long l_start;
961973fe837Smrg netbsd32_long l_len;
9622343525dSmrg short l_pid;
9632343525dSmrg short l_xxx;
9642343525dSmrg };
9652343525dSmrg
966f2af9174Sdsl static void bsd_to_sunos_flock(struct flock *, struct sunos_flock *);
967f2af9174Sdsl static void sunos_to_bsd_flock(struct sunos_flock *, struct flock *);
9682343525dSmrg
9692343525dSmrg #define SUNOS_F_RDLCK 1
9702343525dSmrg #define SUNOS_F_WRLCK 2
9712343525dSmrg #define SUNOS_F_UNLCK 3
9722343525dSmrg
9732343525dSmrg static void
bsd_to_sunos_flock(struct flock * iflp,struct sunos_flock * oflp)97428bae79bSdsl bsd_to_sunos_flock(struct flock *iflp, struct sunos_flock *oflp)
9752343525dSmrg {
976*41aa5859Sriastradh
977*41aa5859Sriastradh memset(oflp, 0, sizeof(*oflp));
978*41aa5859Sriastradh
9792343525dSmrg switch (iflp->l_type) {
9802343525dSmrg case F_RDLCK:
9812343525dSmrg oflp->l_type = SUNOS_F_RDLCK;
9822343525dSmrg break;
9832343525dSmrg case F_WRLCK:
9842343525dSmrg oflp->l_type = SUNOS_F_WRLCK;
9852343525dSmrg break;
9862343525dSmrg case F_UNLCK:
9872343525dSmrg oflp->l_type = SUNOS_F_UNLCK;
9882343525dSmrg break;
9892343525dSmrg default:
9902343525dSmrg oflp->l_type = -1;
9912343525dSmrg break;
9922343525dSmrg }
9932343525dSmrg
9942343525dSmrg oflp->l_whence = (short)iflp->l_whence;
995973fe837Smrg oflp->l_start = (netbsd32_long)iflp->l_start;
996973fe837Smrg oflp->l_len = (netbsd32_long)iflp->l_len;
9972343525dSmrg oflp->l_pid = (short)iflp->l_pid;
9982343525dSmrg oflp->l_xxx = 0;
9992343525dSmrg }
10002343525dSmrg
10012343525dSmrg
10022343525dSmrg static void
sunos_to_bsd_flock(struct sunos_flock * iflp,struct flock * oflp)100328bae79bSdsl sunos_to_bsd_flock(struct sunos_flock *iflp, struct flock *oflp)
10042343525dSmrg {
1005*41aa5859Sriastradh
1006*41aa5859Sriastradh memset(oflp, 0, sizeof(*oflp));
1007*41aa5859Sriastradh
10082343525dSmrg switch (iflp->l_type) {
10092343525dSmrg case SUNOS_F_RDLCK:
10102343525dSmrg oflp->l_type = F_RDLCK;
10112343525dSmrg break;
10122343525dSmrg case SUNOS_F_WRLCK:
10132343525dSmrg oflp->l_type = F_WRLCK;
10142343525dSmrg break;
10152343525dSmrg case SUNOS_F_UNLCK:
10162343525dSmrg oflp->l_type = F_UNLCK;
10172343525dSmrg break;
10182343525dSmrg default:
10192343525dSmrg oflp->l_type = -1;
10202343525dSmrg break;
10212343525dSmrg }
10222343525dSmrg
10232343525dSmrg oflp->l_whence = iflp->l_whence;
10242343525dSmrg oflp->l_start = (off_t) iflp->l_start;
10252343525dSmrg oflp->l_len = (off_t) iflp->l_len;
10262343525dSmrg oflp->l_pid = (pid_t) iflp->l_pid;
10272343525dSmrg
10282343525dSmrg }
10292343525dSmrg static struct {
1030973fe837Smrg netbsd32_long sun_flg;
1031973fe837Smrg netbsd32_long bsd_flg;
10322343525dSmrg } sunfcntl_flgtab[] = {
10332343525dSmrg /* F_[GS]ETFLags that differ: */
10342343525dSmrg #define SUN_FSETBLK 0x0010
10352343525dSmrg #define SUN_SHLOCK 0x0080
10362343525dSmrg #define SUN_EXLOCK 0x0100
10372343525dSmrg #define SUN_FNBIO 0x1000
10382343525dSmrg #define SUN_FSYNC 0x2000
10392343525dSmrg #define SUN_NONBLOCK 0x4000
10402343525dSmrg #define SUN_FNOCTTY 0x8000
10412343525dSmrg { SUN_NONBLOCK, O_NONBLOCK },
10422343525dSmrg { SUN_FNBIO, O_NONBLOCK },
10432343525dSmrg { SUN_SHLOCK, O_SHLOCK },
10442343525dSmrg { SUN_EXLOCK, O_EXLOCK },
10452343525dSmrg { SUN_FSYNC, O_FSYNC },
10462343525dSmrg { SUN_FSETBLK, 0 },
10472343525dSmrg { SUN_FNOCTTY, 0 }
10482343525dSmrg };
10492343525dSmrg
10502343525dSmrg int
sunos32_sys_fcntl(struct lwp * l,const struct sunos32_sys_fcntl_args * uap,register_t * retval)1051e19818fbSmsaitoh sunos32_sys_fcntl(struct lwp *l, const struct sunos32_sys_fcntl_args *uap,
1052e19818fbSmsaitoh register_t *retval)
10532343525dSmrg {
10547e2790cfSdsl /* {
1055973fe837Smrg syscallarg(int) fd;
1056973fe837Smrg syscallarg(int) cmd;
1057973fe837Smrg syscallarg(netbsd32_voidp) arg;
10587e2790cfSdsl } */
10597e2790cfSdsl struct sys_fcntl_args bsd_ua;
1060a065e516Sdsl uintptr_t flg;
10612343525dSmrg int n, ret;
10622343525dSmrg
10637e2790cfSdsl SCARG(&bsd_ua, fd) = SCARG(uap, fd);
10647e2790cfSdsl SCARG(&bsd_ua, cmd) = SCARG(uap, cmd);
10657e2790cfSdsl SCARG(&bsd_ua, arg) = SCARG_P32(uap, arg);
10667e2790cfSdsl
10672343525dSmrg switch (SCARG(uap, cmd)) {
10682343525dSmrg case F_SETFL:
1069a065e516Sdsl flg = (intptr_t)SCARG_P32(uap, arg);
10702343525dSmrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
10712343525dSmrg while (--n >= 0) {
10722343525dSmrg if (flg & sunfcntl_flgtab[n].sun_flg) {
10732343525dSmrg flg &= ~sunfcntl_flgtab[n].sun_flg;
10742343525dSmrg flg |= sunfcntl_flgtab[n].bsd_flg;
10752343525dSmrg }
10762343525dSmrg }
10777e2790cfSdsl SCARG(&bsd_ua, arg) = (void *)flg;
10782343525dSmrg break;
10792343525dSmrg
10802343525dSmrg case F_GETLK:
10812343525dSmrg case F_SETLK:
10822343525dSmrg case F_SETLKW:
10832343525dSmrg {
10842343525dSmrg int error;
10852343525dSmrg struct sunos_flock ifl;
1086701496b5Sdsl struct flock fl;
10872343525dSmrg
1088a065e516Sdsl error = copyin(SCARG_P32(uap, arg), &ifl, sizeof ifl);
10892343525dSmrg if (error)
10902343525dSmrg return error;
10912343525dSmrg sunos_to_bsd_flock(&ifl, &fl);
10922343525dSmrg
1093e19818fbSmsaitoh error = do_fcntl_lock(SCARG(uap, fd), SCARG(uap, cmd),
1094e19818fbSmsaitoh &fl);
1095701496b5Sdsl if (error || SCARG(uap, cmd) != F_GETLK)
10962343525dSmrg return error;
10972343525dSmrg
10982343525dSmrg bsd_to_sunos_flock(&fl, &ifl);
1099a065e516Sdsl return copyout(&ifl, SCARG_P32(uap, arg), sizeof ifl);
11002343525dSmrg }
11012343525dSmrg break;
11022343525dSmrg case SUN_F_RGETLK:
11032343525dSmrg case SUN_F_RSETLK:
11042343525dSmrg case SUN_F_CNVT:
11052343525dSmrg case SUN_F_RSETLKW:
1106e19818fbSmsaitoh return EOPNOTSUPP;
11072343525dSmrg }
11082343525dSmrg
11097e2790cfSdsl ret = sys_fcntl(l, &bsd_ua, retval);
11107e2790cfSdsl if (ret != 0)
11117e2790cfSdsl return ret;
11122343525dSmrg
11132343525dSmrg switch (SCARG(uap, cmd)) {
11142343525dSmrg case F_GETFL:
11152343525dSmrg n = sizeof(sunfcntl_flgtab) / sizeof(sunfcntl_flgtab[0]);
11167e2790cfSdsl ret = *retval;
11172343525dSmrg while (--n >= 0) {
11182343525dSmrg if (ret & sunfcntl_flgtab[n].bsd_flg) {
11192343525dSmrg ret &= ~sunfcntl_flgtab[n].bsd_flg;
11202343525dSmrg ret |= sunfcntl_flgtab[n].sun_flg;
11212343525dSmrg }
11222343525dSmrg }
11237e2790cfSdsl *retval = ret;
11242343525dSmrg break;
11252343525dSmrg }
11262343525dSmrg
11277e2790cfSdsl return 0;
11282343525dSmrg }
1129