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