xref: /netbsd-src/sys/compat/sunos32/sunos32_ioctl.c (revision 41aa5859b647891f23013f613e0858c4b789a7bf)
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