Home | History | Annotate | Line # | Download | only in ultrix
ultrix_ioctl.c revision 1.17
      1  1.17   thorpej /*	$NetBSD: ultrix_ioctl.c,v 1.17 2001/06/14 20:32:46 thorpej Exp $ */
      2   1.1  jonathan /*	from : NetBSD: sunos_ioctl.c,v 1.21 1995/10/07 06:27:31 mycroft Exp */
      3   1.1  jonathan 
      4   1.1  jonathan /*
      5   1.1  jonathan  * Copyright (c) 1993 Markus Wild.
      6   1.1  jonathan  * All rights reserved.
      7   1.1  jonathan  *
      8   1.1  jonathan  * Redistribution and use in source and binary forms, with or without
      9   1.1  jonathan  * modification, are permitted provided that the following conditions
     10   1.1  jonathan  * are met:
     11   1.1  jonathan  * 1. Redistributions of source code must retain the above copyright
     12   1.1  jonathan  *    notice, this list of conditions and the following disclaimer.
     13   1.1  jonathan  * 2. The name of the author may not be used to endorse or promote products
     14   1.1  jonathan  *    derived from this software without specific prior written permission
     15   1.1  jonathan  *
     16   1.1  jonathan  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17   1.1  jonathan  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18   1.1  jonathan  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19   1.1  jonathan  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20   1.1  jonathan  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21   1.1  jonathan  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22   1.1  jonathan  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23   1.1  jonathan  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24   1.1  jonathan  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25   1.1  jonathan  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26   1.1  jonathan  *
     27   1.1  jonathan  * loosely from: Header: sunos_ioctl.c,v 1.7 93/05/28 04:40:43 torek Exp
     28   1.1  jonathan  */
     29  1.11   thorpej 
     30  1.16       mrg #if defined(_KERNEL_OPT)
     31  1.11   thorpej #include "opt_compat_ultrix.h"
     32  1.12   thorpej #include "opt_compat_sunos.h"
     33  1.15  jdolecek #endif
     34   1.1  jonathan 
     35   1.1  jonathan #include <sys/param.h>
     36   1.1  jonathan #include <sys/proc.h>
     37   1.1  jonathan #include <sys/systm.h>
     38   1.1  jonathan #include <sys/file.h>
     39   1.1  jonathan #include <sys/filedesc.h>
     40   1.1  jonathan #include <sys/ioctl.h>
     41   1.1  jonathan #include <sys/termios.h>
     42   1.1  jonathan #include <sys/tty.h>
     43   1.1  jonathan #include <sys/socket.h>
     44   1.1  jonathan #include <sys/audioio.h>
     45   1.1  jonathan #include <net/if.h>
     46   1.1  jonathan 
     47   1.1  jonathan #include <sys/mount.h>
     48   1.1  jonathan 
     49   1.1  jonathan #include <compat/ultrix/ultrix_syscallargs.h>
     50   1.1  jonathan #include <sys/syscallargs.h>
     51   1.1  jonathan 
     52   1.1  jonathan #include <compat/sunos/sunos.h>
     53   1.1  jonathan 
     54  1.15  jdolecek #include <compat/ultrix/ultrix_tty.h>
     55   1.1  jonathan 
     56   1.2  jonathan #define emul_termio	ultrix_termio
     57   1.2  jonathan #define emul_termios	ultrix_termios
     58   1.1  jonathan 
     59   1.1  jonathan /*
     60   1.1  jonathan  * SunOS ioctl calls.
     61   1.1  jonathan  * This file is something of a hodge-podge.
     62   1.1  jonathan  * Support gets added as things turn up....
     63   1.1  jonathan  */
     64   1.1  jonathan 
     65   1.1  jonathan static struct speedtab sptab[] = {
     66   1.1  jonathan 	{ 0, 0 },
     67   1.1  jonathan 	{ 50, 1 },
     68   1.1  jonathan 	{ 75, 2 },
     69   1.1  jonathan 	{ 110, 3 },
     70   1.1  jonathan 	{ 134, 4 },
     71   1.1  jonathan 	{ 135, 4 },
     72   1.1  jonathan 	{ 150, 5 },
     73   1.1  jonathan 	{ 200, 6 },
     74   1.1  jonathan 	{ 300, 7 },
     75   1.1  jonathan 	{ 600, 8 },
     76   1.1  jonathan 	{ 1200, 9 },
     77   1.1  jonathan 	{ 1800, 10 },
     78   1.1  jonathan 	{ 2400, 11 },
     79   1.1  jonathan 	{ 4800, 12 },
     80   1.1  jonathan 	{ 9600, 13 },
     81   1.1  jonathan 	{ 19200, 14 },
     82   1.1  jonathan 	{ 38400, 15 },
     83   1.1  jonathan 	{ -1, -1 }
     84   1.1  jonathan };
     85   1.1  jonathan 
     86   1.1  jonathan static u_long s2btab[] = {
     87   1.1  jonathan 	0,
     88   1.1  jonathan 	50,
     89   1.1  jonathan 	75,
     90   1.1  jonathan 	110,
     91   1.1  jonathan 	134,
     92   1.1  jonathan 	150,
     93   1.1  jonathan 	200,
     94   1.1  jonathan 	300,
     95   1.1  jonathan 	600,
     96   1.1  jonathan 	1200,
     97   1.1  jonathan 	1800,
     98   1.1  jonathan 	2400,
     99   1.1  jonathan 	4800,
    100   1.1  jonathan 	9600,
    101   1.1  jonathan 	19200,
    102   1.1  jonathan 	38400,
    103   1.1  jonathan };
    104   1.1  jonathan 
    105   1.2  jonathan 
    106   1.2  jonathan /*
    107   1.2  jonathan  * Translate a single tty control char from the emulation value
    108   1.2  jonathan  * to native termios, and vice-versa. Special-case
    109   1.2  jonathan  * the value of POSIX_VDISABLE, mapping it to and from 0.
    110   1.2  jonathan  */
    111   1.2  jonathan #define NATIVE_TO_EMUL_CC(bsd_cc) \
    112   1.2  jonathan  (((bsd_cc)   != _POSIX_VDISABLE) ? (bsd_cc) : 0)
    113   1.2  jonathan 
    114   1.2  jonathan #define EMUL_TO_NATIVE_CC(emul_cc) \
    115   1.2  jonathan  (emul_cc) ? (emul_cc) : _POSIX_VDISABLE;
    116   1.2  jonathan 
    117   1.2  jonathan 
    118  1.10  jonathan static void stios2btios __P((struct emul_termios *, struct termios *));
    119  1.10  jonathan static void btios2stios __P((struct termios *, struct emul_termios *));
    120  1.10  jonathan static void stios2stio __P((struct emul_termios *, struct emul_termio *));
    121  1.10  jonathan static void stio2stios __P((struct emul_termio *, struct emul_termios *));
    122   1.2  jonathan 
    123   1.1  jonathan /*
    124   1.1  jonathan  * these two conversion functions have mostly been done
    125   1.1  jonathan  * with some perl cut&paste, then handedited to comment
    126   1.1  jonathan  * out what doesn't exist under NetBSD.
    127   1.1  jonathan  * A note from Markus's code:
    128   1.1  jonathan  *	(l & BITMASK1) / BITMASK1 * BITMASK2  is translated
    129   1.1  jonathan  *	optimally by gcc m68k, much better than any ?: stuff.
    130   1.1  jonathan  *	Code may vary with different architectures of course.
    131   1.1  jonathan  *
    132   1.1  jonathan  * I don't know what optimizer you used, but seeing divu's and
    133   1.1  jonathan  * bfextu's in the m68k assembly output did not encourage me...
    134   1.1  jonathan  * as well, gcc on the sparc definately generates much better
    135   1.1  jonathan  * code with ?:.
    136   1.1  jonathan  */
    137   1.1  jonathan 
    138   1.2  jonathan 
    139   1.1  jonathan static void
    140   1.1  jonathan stios2btios(st, bt)
    141   1.2  jonathan 	struct emul_termios *st;
    142   1.1  jonathan 	struct termios *bt;
    143   1.1  jonathan {
    144  1.14  augustss 	u_long l, r;
    145   1.1  jonathan 
    146   1.1  jonathan 	l = st->c_iflag;
    147   1.1  jonathan 	r = 	((l & 0x00000001) ? IGNBRK	: 0);
    148   1.1  jonathan 	r |=	((l & 0x00000002) ? BRKINT	: 0);
    149   1.1  jonathan 	r |=	((l & 0x00000004) ? IGNPAR	: 0);
    150   1.1  jonathan 	r |=	((l & 0x00000008) ? PARMRK	: 0);
    151   1.1  jonathan 	r |=	((l & 0x00000010) ? INPCK	: 0);
    152   1.1  jonathan 	r |=	((l & 0x00000020) ? ISTRIP	: 0);
    153   1.1  jonathan 	r |= 	((l & 0x00000040) ? INLCR	: 0);
    154   1.1  jonathan 	r |=	((l & 0x00000080) ? IGNCR	: 0);
    155   1.1  jonathan 	r |=	((l & 0x00000100) ? ICRNL	: 0);
    156   1.1  jonathan 	/*	((l & 0x00000200) ? IUCLC	: 0) */
    157   1.1  jonathan 	r |=	((l & 0x00000400) ? IXON	: 0);
    158   1.1  jonathan 	r |=	((l & 0x00000800) ? IXANY	: 0);
    159   1.1  jonathan 	r |=	((l & 0x00001000) ? IXOFF	: 0);
    160   1.1  jonathan 	r |=	((l & 0x00002000) ? IMAXBEL	: 0);
    161   1.1  jonathan 	bt->c_iflag = r;
    162   1.1  jonathan 
    163   1.1  jonathan 	l = st->c_oflag;
    164   1.1  jonathan 	r = 	((l & 0x00000001) ? OPOST	: 0);
    165   1.1  jonathan 	/*	((l & 0x00000002) ? OLCUC	: 0) */
    166   1.1  jonathan 	r |=	((l & 0x00000004) ? ONLCR	: 0);
    167   1.1  jonathan 	/*	((l & 0x00000008) ? OCRNL	: 0) */
    168   1.1  jonathan 	/*	((l & 0x00000010) ? ONOCR	: 0) */
    169   1.1  jonathan 	/*	((l & 0x00000020) ? ONLRET	: 0) */
    170   1.1  jonathan 	/*	((l & 0x00000040) ? OFILL	: 0) */
    171   1.1  jonathan 	/*	((l & 0x00000080) ? OFDEL	: 0) */
    172   1.1  jonathan 	/*	((l & 0x00000100) ? NLDLY	: 0) */
    173   1.1  jonathan 	/*	((l & 0x00000100) ? NL1		: 0) */
    174   1.1  jonathan 	/*	((l & 0x00000600) ? CRDLY	: 0) */
    175   1.1  jonathan 	/*	((l & 0x00000200) ? CR1		: 0) */
    176   1.1  jonathan 	/*	((l & 0x00000400) ? CR2		: 0) */
    177   1.1  jonathan 	/*	((l & 0x00000600) ? CR3		: 0) */
    178   1.1  jonathan 	/*	((l & 0x00001800) ? TABDLY	: 0) */
    179   1.1  jonathan 	/*	((l & 0x00000800) ? TAB1	: 0) */
    180   1.1  jonathan 	/*	((l & 0x00001000) ? TAB2	: 0) */
    181   1.1  jonathan 	r |=	((l & 0x00001800) ? OXTABS	: 0);
    182   1.1  jonathan 	/*	((l & 0x00002000) ? BSDLY	: 0) */
    183   1.1  jonathan 	/*	((l & 0x00002000) ? BS1		: 0) */
    184   1.1  jonathan 	/*	((l & 0x00004000) ? VTDLY	: 0) */
    185   1.1  jonathan 	/*	((l & 0x00004000) ? VT1		: 0) */
    186   1.1  jonathan 	/*	((l & 0x00008000) ? FFDLY	: 0) */
    187   1.1  jonathan 	/*	((l & 0x00008000) ? FF1		: 0) */
    188   1.1  jonathan 	/*	((l & 0x00010000) ? PAGEOUT	: 0) */
    189   1.1  jonathan 	/*	((l & 0x00020000) ? WRAP	: 0) */
    190   1.1  jonathan 	bt->c_oflag = r;
    191   1.1  jonathan 
    192   1.1  jonathan 	l = st->c_cflag;
    193   1.1  jonathan 	switch (l & 0x00000030) {
    194   1.1  jonathan 	case 0:
    195   1.1  jonathan 		r = CS5;
    196   1.1  jonathan 		break;
    197   1.1  jonathan 	case 0x00000010:
    198   1.1  jonathan 		r = CS6;
    199   1.1  jonathan 		break;
    200   1.1  jonathan 	case 0x00000020:
    201   1.1  jonathan 		r = CS7;
    202   1.1  jonathan 		break;
    203   1.1  jonathan 	case 0x00000030:
    204   1.1  jonathan 		r = CS8;
    205   1.1  jonathan 		break;
    206   1.1  jonathan 	}
    207   1.1  jonathan 	r |=	((l & 0x00000040) ? CSTOPB	: 0);
    208   1.1  jonathan 	r |=	((l & 0x00000080) ? CREAD	: 0);
    209   1.1  jonathan 	r |= 	((l & 0x00000100) ? PARENB	: 0);
    210   1.1  jonathan 	r |=	((l & 0x00000200) ? PARODD	: 0);
    211   1.1  jonathan 	r |=	((l & 0x00000400) ? HUPCL	: 0);
    212   1.1  jonathan 	r |=	((l & 0x00000800) ? CLOCAL	: 0);
    213   1.1  jonathan 	/*	((l & 0x00001000) ? LOBLK	: 0) */
    214   1.1  jonathan 	r |=	((l & 0x80000000) ? (CRTS_IFLOW|CCTS_OFLOW) : 0);
    215   1.1  jonathan 	bt->c_cflag = r;
    216   1.1  jonathan 
    217   1.1  jonathan 	bt->c_ispeed = bt->c_ospeed = s2btab[l & 0x0000000f];
    218   1.1  jonathan 
    219   1.1  jonathan 	l = st->c_lflag;
    220   1.1  jonathan 	r = 	((l & 0x00000001) ? ISIG	: 0);
    221   1.1  jonathan 	r |=	((l & 0x00000002) ? ICANON	: 0);
    222   1.1  jonathan 	/*	((l & 0x00000004) ? XCASE	: 0) */
    223   1.1  jonathan 	r |=	((l & 0x00000008) ? ECHO	: 0);
    224   1.1  jonathan 	r |=	((l & 0x00000010) ? ECHOE	: 0);
    225   1.1  jonathan 	r |=	((l & 0x00000020) ? ECHOK	: 0);
    226   1.1  jonathan 	r |=	((l & 0x00000040) ? ECHONL	: 0);
    227   1.1  jonathan 	r |= 	((l & 0x00000080) ? NOFLSH	: 0);
    228   1.1  jonathan 	r |=	((l & 0x00000100) ? TOSTOP	: 0);
    229   1.1  jonathan 	r |=	((l & 0x00000200) ? ECHOCTL	: 0);
    230   1.1  jonathan 	r |=	((l & 0x00000400) ? ECHOPRT	: 0);
    231   1.1  jonathan 	r |=	((l & 0x00000800) ? ECHOKE	: 0);
    232   1.1  jonathan 	/*	((l & 0x00001000) ? DEFECHO	: 0) */
    233   1.1  jonathan 	r |=	((l & 0x00002000) ? FLUSHO	: 0);
    234   1.1  jonathan 	r |=	((l & 0x00004000) ? PENDIN	: 0);
    235   1.1  jonathan 	bt->c_lflag = r;
    236   1.1  jonathan 
    237   1.2  jonathan 	bt->c_cc[VINTR]    = EMUL_TO_NATIVE_CC(st->c_cc[0]);
    238   1.2  jonathan 	bt->c_cc[VQUIT]    = EMUL_TO_NATIVE_CC(st->c_cc[1]);
    239   1.2  jonathan 	bt->c_cc[VERASE]   = EMUL_TO_NATIVE_CC(st->c_cc[2]);
    240   1.2  jonathan 	bt->c_cc[VKILL]    = EMUL_TO_NATIVE_CC(st->c_cc[3]);
    241   1.2  jonathan 	bt->c_cc[VEOF]     = EMUL_TO_NATIVE_CC(st->c_cc[4]);
    242   1.2  jonathan 	bt->c_cc[VEOL]     = EMUL_TO_NATIVE_CC(st->c_cc[5]);
    243   1.2  jonathan 	bt->c_cc[VEOL2]    = EMUL_TO_NATIVE_CC(st->c_cc[6]);
    244   1.2  jonathan 	/* not present on NetBSD */
    245   1.2  jonathan 	/* bt->c_cc[VSWTCH]   = EMUL_TO_NATIVE_CC(st->c_cc[7]); */
    246   1.2  jonathan 	bt->c_cc[VSTART]   = EMUL_TO_NATIVE_CC(st->c_cc[10]);
    247   1.2  jonathan 	bt->c_cc[VSTOP]    = EMUL_TO_NATIVE_CC(st->c_cc[11]);
    248   1.4  jonathan 	bt->c_cc[VSUSP]    = EMUL_TO_NATIVE_CC(st->c_cc[12]);
    249   1.4  jonathan 	bt->c_cc[VDSUSP]   = EMUL_TO_NATIVE_CC(st->c_cc[13]);
    250   1.2  jonathan 	bt->c_cc[VREPRINT] = EMUL_TO_NATIVE_CC(st->c_cc[14]);
    251   1.2  jonathan 	bt->c_cc[VDISCARD] = EMUL_TO_NATIVE_CC(st->c_cc[15]);
    252   1.2  jonathan 	bt->c_cc[VWERASE]  = EMUL_TO_NATIVE_CC(st->c_cc[16]);
    253   1.2  jonathan 	bt->c_cc[VLNEXT]   = EMUL_TO_NATIVE_CC(st->c_cc[17]);
    254   1.2  jonathan 	bt->c_cc[VSTATUS]  = EMUL_TO_NATIVE_CC(st->c_cc[18]);
    255   1.2  jonathan 
    256   1.2  jonathan #ifdef COMPAT_ULTRIX
    257   1.2  jonathan 	/* Ultrix termio/termios has real vmin/vtime */
    258   1.2  jonathan 	bt->c_cc[VMIN]	   = EMUL_TO_NATIVE_CC(st->c_cc[8]);
    259   1.2  jonathan 	bt->c_cc[VTIME]	   = EMUL_TO_NATIVE_CC(st->c_cc[9]);
    260   1.2  jonathan #else
    261   1.1  jonathan 	/* if `raw mode', create native VMIN/VTIME from SunOS VEOF/VEOL */
    262   1.1  jonathan 	bt->c_cc[VMIN]	   = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOF];
    263   1.1  jonathan 	bt->c_cc[VTIME]	   = (bt->c_lflag & ICANON) ? 1 : bt->c_cc[VEOL];
    264   1.2  jonathan #endif
    265   1.2  jonathan 
    266   1.1  jonathan }
    267   1.1  jonathan 
    268   1.2  jonathan /*
    269   1.2  jonathan  * Convert bsd termios to "sunos" emulated termios
    270   1.2  jonathan  */
    271   1.1  jonathan static void
    272   1.1  jonathan btios2stios(bt, st)
    273   1.1  jonathan 	struct termios *bt;
    274   1.2  jonathan 	struct emul_termios *st;
    275   1.1  jonathan {
    276  1.14  augustss 	u_long l, r;
    277   1.1  jonathan 
    278   1.1  jonathan 	l = bt->c_iflag;
    279   1.1  jonathan 	r = 	((l &  IGNBRK) ? 0x00000001	: 0);
    280   1.1  jonathan 	r |=	((l &  BRKINT) ? 0x00000002	: 0);
    281   1.1  jonathan 	r |=	((l &  IGNPAR) ? 0x00000004	: 0);
    282   1.1  jonathan 	r |=	((l &  PARMRK) ? 0x00000008	: 0);
    283   1.1  jonathan 	r |=	((l &   INPCK) ? 0x00000010	: 0);
    284   1.1  jonathan 	r |=	((l &  ISTRIP) ? 0x00000020	: 0);
    285   1.1  jonathan 	r |=	((l &   INLCR) ? 0x00000040	: 0);
    286   1.1  jonathan 	r |=	((l &   IGNCR) ? 0x00000080	: 0);
    287   1.1  jonathan 	r |=	((l &   ICRNL) ? 0x00000100	: 0);
    288   1.1  jonathan 	/*	((l &   IUCLC) ? 0x00000200	: 0) */
    289   1.1  jonathan 	r |=	((l &    IXON) ? 0x00000400	: 0);
    290   1.1  jonathan 	r |=	((l &   IXANY) ? 0x00000800	: 0);
    291   1.1  jonathan 	r |=	((l &   IXOFF) ? 0x00001000	: 0);
    292   1.1  jonathan 	r |=	((l & IMAXBEL) ? 0x00002000	: 0);
    293   1.1  jonathan 	st->c_iflag = r;
    294   1.1  jonathan 
    295   1.1  jonathan 	l = bt->c_oflag;
    296   1.1  jonathan 	r =	((l &   OPOST) ? 0x00000001	: 0);
    297   1.1  jonathan 	/*	((l &   OLCUC) ? 0x00000002	: 0) */
    298   1.1  jonathan 	r |=	((l &   ONLCR) ? 0x00000004	: 0);
    299   1.1  jonathan 	/*	((l &   OCRNL) ? 0x00000008	: 0) */
    300   1.1  jonathan 	/*	((l &   ONOCR) ? 0x00000010	: 0) */
    301   1.1  jonathan 	/*	((l &  ONLRET) ? 0x00000020	: 0) */
    302   1.1  jonathan 	/*	((l &   OFILL) ? 0x00000040	: 0) */
    303   1.1  jonathan 	/*	((l &   OFDEL) ? 0x00000080	: 0) */
    304   1.1  jonathan 	/*	((l &   NLDLY) ? 0x00000100	: 0) */
    305   1.1  jonathan 	/*	((l &     NL1) ? 0x00000100	: 0) */
    306   1.1  jonathan 	/*	((l &   CRDLY) ? 0x00000600	: 0) */
    307   1.1  jonathan 	/*	((l &     CR1) ? 0x00000200	: 0) */
    308   1.1  jonathan 	/*	((l &     CR2) ? 0x00000400	: 0) */
    309   1.1  jonathan 	/*	((l &     CR3) ? 0x00000600	: 0) */
    310   1.1  jonathan 	/*	((l &  TABDLY) ? 0x00001800	: 0) */
    311   1.1  jonathan 	/*	((l &    TAB1) ? 0x00000800	: 0) */
    312   1.1  jonathan 	/*	((l &    TAB2) ? 0x00001000	: 0) */
    313   1.1  jonathan 	r |=	((l &  OXTABS) ? 0x00001800	: 0);
    314   1.1  jonathan 	/*	((l &   BSDLY) ? 0x00002000	: 0) */
    315   1.1  jonathan 	/*	((l &     BS1) ? 0x00002000	: 0) */
    316   1.1  jonathan 	/*	((l &   VTDLY) ? 0x00004000	: 0) */
    317   1.1  jonathan 	/*	((l &     VT1) ? 0x00004000	: 0) */
    318   1.1  jonathan 	/*	((l &   FFDLY) ? 0x00008000	: 0) */
    319   1.1  jonathan 	/*	((l &     FF1) ? 0x00008000	: 0) */
    320   1.1  jonathan 	/*	((l & PAGEOUT) ? 0x00010000	: 0) */
    321   1.1  jonathan 	/*	((l &    WRAP) ? 0x00020000	: 0) */
    322   1.1  jonathan 	st->c_oflag = r;
    323   1.1  jonathan 
    324   1.1  jonathan 	l = bt->c_cflag;
    325   1.1  jonathan 	switch (l & CSIZE) {
    326   1.1  jonathan 	case CS5:
    327   1.1  jonathan 		r = 0;
    328   1.1  jonathan 		break;
    329   1.1  jonathan 	case CS6:
    330   1.1  jonathan 		r = 0x00000010;
    331   1.1  jonathan 		break;
    332   1.1  jonathan 	case CS7:
    333   1.1  jonathan 		r = 0x00000020;
    334   1.1  jonathan 		break;
    335   1.1  jonathan 	case CS8:
    336   1.1  jonathan 		r = 0x00000030;
    337   1.1  jonathan 		break;
    338   1.1  jonathan 	}
    339   1.1  jonathan 	r |=	((l &  CSTOPB) ? 0x00000040	: 0);
    340   1.1  jonathan 	r |=	((l &   CREAD) ? 0x00000080	: 0);
    341   1.1  jonathan 	r |=	((l &  PARENB) ? 0x00000100	: 0);
    342   1.1  jonathan 	r |=	((l &  PARODD) ? 0x00000200	: 0);
    343   1.1  jonathan 	r |=	((l &   HUPCL) ? 0x00000400	: 0);
    344   1.1  jonathan 	r |=	((l &  CLOCAL) ? 0x00000800	: 0);
    345   1.1  jonathan 	/*	((l &   LOBLK) ? 0x00001000	: 0) */
    346   1.1  jonathan 	r |=	((l & (CRTS_IFLOW|CCTS_OFLOW)) ? 0x80000000 : 0);
    347   1.1  jonathan 	st->c_cflag = r;
    348   1.1  jonathan 
    349   1.1  jonathan 	l = bt->c_lflag;
    350   1.1  jonathan 	r =	((l &    ISIG) ? 0x00000001	: 0);
    351   1.1  jonathan 	r |=	((l &  ICANON) ? 0x00000002	: 0);
    352   1.1  jonathan 	/*	((l &   XCASE) ? 0x00000004	: 0) */
    353   1.1  jonathan 	r |=	((l &    ECHO) ? 0x00000008	: 0);
    354   1.1  jonathan 	r |=	((l &   ECHOE) ? 0x00000010	: 0);
    355   1.1  jonathan 	r |=	((l &   ECHOK) ? 0x00000020	: 0);
    356   1.1  jonathan 	r |=	((l &  ECHONL) ? 0x00000040	: 0);
    357   1.1  jonathan 	r |=	((l &  NOFLSH) ? 0x00000080	: 0);
    358   1.1  jonathan 	r |=	((l &  TOSTOP) ? 0x00000100	: 0);
    359   1.1  jonathan 	r |=	((l & ECHOCTL) ? 0x00000200	: 0);
    360   1.1  jonathan 	r |=	((l & ECHOPRT) ? 0x00000400	: 0);
    361   1.1  jonathan 	r |=	((l &  ECHOKE) ? 0x00000800	: 0);
    362   1.1  jonathan 	/*	((l & DEFECHO) ? 0x00001000	: 0) */
    363   1.1  jonathan 	r |=	((l &  FLUSHO) ? 0x00002000	: 0);
    364   1.1  jonathan 	r |=	((l &  PENDIN) ? 0x00004000	: 0);
    365   1.1  jonathan 	st->c_lflag = r;
    366   1.1  jonathan 
    367   1.1  jonathan 	l = ttspeedtab(bt->c_ospeed, sptab);
    368   1.1  jonathan 	if (l >= 0)
    369   1.1  jonathan 		st->c_cflag |= l;
    370   1.1  jonathan 
    371   1.2  jonathan 	st->c_cc[0] = NATIVE_TO_EMUL_CC(bt->c_cc[VINTR]);
    372   1.2  jonathan 	st->c_cc[1] = NATIVE_TO_EMUL_CC(bt->c_cc[VQUIT]);
    373   1.2  jonathan 	st->c_cc[2] = NATIVE_TO_EMUL_CC(bt->c_cc[VERASE]);
    374   1.2  jonathan 	st->c_cc[3] = NATIVE_TO_EMUL_CC(bt->c_cc[VKILL]);
    375   1.2  jonathan 	st->c_cc[4] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOF]);
    376   1.2  jonathan 	st->c_cc[5] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL]);
    377   1.2  jonathan 	st->c_cc[6] = NATIVE_TO_EMUL_CC(bt->c_cc[VEOL2]);
    378   1.9  jonathan 
    379   1.9  jonathan 	/* XXX ultrix has a VSWTCH.  NetBSD does not. */
    380   1.9  jonathan #ifdef notdef
    381   1.2  jonathan 	st->c_cc[7] = NATIVE_TO_EMUL_CC(bt->c_cc[VSWTCH]);
    382   1.2  jonathan #else
    383   1.1  jonathan 	st->c_cc[7] = 0;
    384   1.2  jonathan #endif
    385   1.2  jonathan 	st->c_cc[10] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTART]);
    386   1.2  jonathan 	st->c_cc[11] = NATIVE_TO_EMUL_CC(bt->c_cc[VSTOP]);
    387   1.2  jonathan 	st->c_cc[12]= NATIVE_TO_EMUL_CC(bt->c_cc[VSUSP]);
    388   1.2  jonathan 	st->c_cc[13]= NATIVE_TO_EMUL_CC(bt->c_cc[VDSUSP]);
    389   1.2  jonathan 	st->c_cc[14]= NATIVE_TO_EMUL_CC(bt->c_cc[VREPRINT]);
    390   1.2  jonathan 	st->c_cc[15]= NATIVE_TO_EMUL_CC(bt->c_cc[VDISCARD]);
    391   1.2  jonathan 	st->c_cc[16]= NATIVE_TO_EMUL_CC(bt->c_cc[VWERASE]);
    392   1.2  jonathan 	st->c_cc[17]= NATIVE_TO_EMUL_CC(bt->c_cc[VLNEXT]);
    393   1.2  jonathan 	st->c_cc[18]= NATIVE_TO_EMUL_CC(bt->c_cc[VSTATUS]);
    394   1.2  jonathan 
    395   1.2  jonathan #ifdef COMPAT_ULTRIX
    396   1.2  jonathan 	st->c_cc[8]= NATIVE_TO_EMUL_CC(bt->c_cc[VMIN]);
    397   1.2  jonathan 	st->c_cc[9]= NATIVE_TO_EMUL_CC(bt->c_cc[VTIME]);
    398   1.2  jonathan #else
    399   1.1  jonathan 	if (!(bt->c_lflag & ICANON)) {
    400   1.1  jonathan 		/* SunOS stores VMIN/VTIME in VEOF/VEOL (if ICANON is off) */
    401   1.1  jonathan 		st->c_cc[4] = bt->c_cc[VMIN];
    402   1.1  jonathan 		st->c_cc[5] = bt->c_cc[VTIME];
    403   1.1  jonathan 	}
    404   1.2  jonathan #endif
    405   1.1  jonathan 
    406   1.2  jonathan #ifdef COMPAT_SUNOS
    407   1.2  jonathan 	st->c_line = 0;	/* 4.3bsd "old" line discipline */
    408   1.2  jonathan #else
    409   1.9  jonathan 	st->c_line = 2;	/* 4.3bsd "new" line discipline, Ultrix default. */
    410   1.2  jonathan #endif
    411   1.1  jonathan }
    412   1.1  jonathan 
    413   1.2  jonathan #define TERMIO_NCC 10	/* ultrix termio NCC is 10 */
    414   1.2  jonathan 
    415   1.2  jonathan /*
    416   1.2  jonathan  * Convert emulated struct termios to termio(?)
    417   1.2  jonathan  */
    418   1.1  jonathan static void
    419   1.1  jonathan stios2stio(ts, t)
    420   1.2  jonathan 	struct emul_termios *ts;
    421   1.2  jonathan 	struct emul_termio *t;
    422   1.1  jonathan {
    423   1.1  jonathan 	t->c_iflag = ts->c_iflag;
    424   1.1  jonathan 	t->c_oflag = ts->c_oflag;
    425   1.1  jonathan 	t->c_cflag = ts->c_cflag;
    426   1.1  jonathan 	t->c_lflag = ts->c_lflag;
    427   1.1  jonathan 	t->c_line  = ts->c_line;
    428  1.13     perry 	memcpy(t->c_cc, ts->c_cc, TERMIO_NCC);
    429   1.1  jonathan }
    430   1.1  jonathan 
    431   1.2  jonathan /*
    432   1.2  jonathan  * Convert the other way
    433   1.2  jonathan  */
    434   1.1  jonathan static void
    435   1.1  jonathan stio2stios(t, ts)
    436   1.2  jonathan 	struct emul_termio *t;
    437   1.2  jonathan 	struct emul_termios *ts;
    438   1.1  jonathan {
    439   1.1  jonathan 	ts->c_iflag = t->c_iflag;
    440   1.1  jonathan 	ts->c_oflag = t->c_oflag;
    441   1.1  jonathan 	ts->c_cflag = t->c_cflag;
    442   1.1  jonathan 	ts->c_lflag = t->c_lflag;
    443   1.1  jonathan 	ts->c_line  = t->c_line;
    444  1.13     perry 	memcpy(ts->c_cc, t->c_cc, TERMIO_NCC); /* don't touch the upper fields! */
    445   1.1  jonathan }
    446   1.1  jonathan 
    447   1.1  jonathan int
    448   1.1  jonathan ultrix_sys_ioctl(p, v, retval)
    449  1.14  augustss 	struct proc *p;
    450   1.1  jonathan 	void *v;
    451   1.1  jonathan 	register_t *retval;
    452   1.1  jonathan {
    453   1.1  jonathan 	struct ultrix_sys_ioctl_args *uap = v;
    454  1.14  augustss 	struct filedesc *fdp = p->p_fd;
    455  1.14  augustss 	struct file *fp;
    456  1.14  augustss 	int (*ctl) __P((struct file *, u_long, caddr_t, struct proc *));
    457   1.1  jonathan 	int error;
    458   1.1  jonathan 
    459  1.17   thorpej 	if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
    460   1.1  jonathan 		return EBADF;
    461   1.1  jonathan 
    462   1.1  jonathan 	if ((fp->f_flag & (FREAD|FWRITE)) == 0)
    463   1.1  jonathan 		return EBADF;
    464   1.1  jonathan 
    465   1.1  jonathan 	ctl = fp->f_ops->fo_ioctl;
    466   1.1  jonathan 
    467   1.1  jonathan 	switch (SCARG(uap, com)) {
    468   1.1  jonathan 	case _IOR('t', 0, int):
    469   1.1  jonathan 		SCARG(uap, com) = TIOCGETD;
    470   1.1  jonathan 		break;
    471   1.1  jonathan 	case _IOW('t', 1, int):
    472   1.1  jonathan 	    {
    473   1.1  jonathan 		int disc;
    474   1.1  jonathan 
    475   1.1  jonathan 		if ((error = copyin(SCARG(uap, data), (caddr_t)&disc,
    476   1.1  jonathan 		    sizeof disc)) != 0)
    477   1.1  jonathan 			return error;
    478   1.1  jonathan 
    479   1.1  jonathan 		/* map SunOS NTTYDISC into our termios discipline */
    480   1.1  jonathan 		if (disc == 2)
    481   1.1  jonathan 			disc = 0;
    482   1.1  jonathan 		/* all other disciplines are not supported by NetBSD */
    483   1.1  jonathan 		if (disc)
    484   1.1  jonathan 			return ENXIO;
    485   1.1  jonathan 
    486   1.1  jonathan 		return (*ctl)(fp, TIOCSETD, (caddr_t)&disc, p);
    487   1.1  jonathan 	    }
    488   1.1  jonathan 	case _IOW('t', 101, int):	/* sun SUNOS_TIOCSSOFTCAR */
    489   1.1  jonathan 	    {
    490   1.1  jonathan 		int x;	/* unused */
    491   1.1  jonathan 
    492   1.1  jonathan 		return copyin((caddr_t)&x, SCARG(uap, data), sizeof x);
    493   1.1  jonathan 	    }
    494   1.1  jonathan 	case _IOR('t', 100, int):	/* sun SUNOS_TIOCSSOFTCAR */
    495   1.1  jonathan 	    {
    496   1.1  jonathan 		int x = 0;
    497   1.1  jonathan 
    498   1.1  jonathan 		return copyout((caddr_t)&x, SCARG(uap, data), sizeof x);
    499   1.1  jonathan 	    }
    500   1.1  jonathan 	case _IO('t', 36): 		/* sun TIOCCONS, no parameters */
    501   1.1  jonathan 	    {
    502   1.1  jonathan 		int on = 1;
    503   1.1  jonathan 		return (*ctl)(fp, TIOCCONS, (caddr_t)&on, p);
    504   1.1  jonathan 	    }
    505   1.1  jonathan 	case _IOW('t', 37, struct sunos_ttysize):
    506   1.1  jonathan 	    {
    507   1.1  jonathan 		struct winsize ws;
    508   1.1  jonathan 		struct sunos_ttysize ss;
    509   1.1  jonathan 
    510   1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
    511   1.1  jonathan 			return (error);
    512   1.1  jonathan 
    513   1.1  jonathan 		if ((error = copyin (SCARG(uap, data), &ss, sizeof (ss))) != 0)
    514   1.1  jonathan 			return error;
    515   1.1  jonathan 
    516   1.1  jonathan 		ws.ws_row = ss.ts_row;
    517   1.1  jonathan 		ws.ws_col = ss.ts_col;
    518   1.1  jonathan 
    519   1.1  jonathan 		return ((*ctl)(fp, TIOCSWINSZ, (caddr_t)&ws, p));
    520   1.1  jonathan 	    }
    521   1.1  jonathan 	case _IOW('t', 38, struct sunos_ttysize):
    522   1.1  jonathan 	    {
    523   1.1  jonathan 		struct winsize ws;
    524   1.1  jonathan 		struct sunos_ttysize ss;
    525   1.1  jonathan 
    526   1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGWINSZ, (caddr_t)&ws, p)) != 0)
    527   1.1  jonathan 			return (error);
    528   1.1  jonathan 
    529   1.1  jonathan 		ss.ts_row = ws.ws_row;
    530   1.1  jonathan 		ss.ts_col = ws.ws_col;
    531   1.1  jonathan 
    532   1.1  jonathan 		return copyout ((caddr_t)&ss, SCARG(uap, data), sizeof (ss));
    533   1.1  jonathan 	    }
    534   1.8  jonathan 	case _IOW('t', 118, int):
    535   1.1  jonathan 		SCARG(uap, com) = TIOCSPGRP;
    536   1.1  jonathan 		break;
    537   1.8  jonathan 	case _IOR('t', 119, int):
    538   1.1  jonathan 		SCARG(uap, com) = TIOCGPGRP;
    539   1.1  jonathan 		break;
    540   1.8  jonathan 
    541   1.2  jonathan 	/* Emulate termio or termios tcget() */
    542   1.1  jonathan 	case ULTRIX_TCGETA:
    543   1.1  jonathan 	case ULTRIX_TCGETS:
    544   1.1  jonathan 	    {
    545   1.1  jonathan 		struct termios bts;
    546   1.1  jonathan 		struct ultrix_termios sts;
    547   1.1  jonathan 		struct ultrix_termio st;
    548   1.1  jonathan 
    549   1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
    550   1.1  jonathan 			return error;
    551   1.1  jonathan 
    552   1.1  jonathan 		btios2stios (&bts, &sts);
    553   1.1  jonathan 		if (SCARG(uap, com) == ULTRIX_TCGETA) {
    554   1.1  jonathan 			stios2stio (&sts, &st);
    555   1.1  jonathan 			return copyout((caddr_t)&st, SCARG(uap, data),
    556   1.1  jonathan 			    sizeof (st));
    557   1.1  jonathan 		} else
    558   1.1  jonathan 			return copyout((caddr_t)&sts, SCARG(uap, data),
    559   1.1  jonathan 			    sizeof (sts));
    560   1.1  jonathan 		/*NOTREACHED*/
    561   1.1  jonathan 	    }
    562   1.2  jonathan 	/* Emulate termio tcset() */
    563   1.1  jonathan 	case ULTRIX_TCSETA:
    564   1.1  jonathan 	case ULTRIX_TCSETAW:
    565   1.1  jonathan 	case ULTRIX_TCSETAF:
    566   1.1  jonathan 	    {
    567   1.1  jonathan 		struct termios bts;
    568   1.1  jonathan 		struct ultrix_termios sts;
    569   1.1  jonathan 		struct ultrix_termio st;
    570   1.1  jonathan 		int result;
    571   1.1  jonathan 
    572   1.1  jonathan 		if ((error = copyin(SCARG(uap, data), (caddr_t)&st,
    573   1.1  jonathan 		    sizeof (st))) != 0)
    574   1.1  jonathan 			return error;
    575   1.1  jonathan 
    576   1.1  jonathan 		/* get full BSD termios so we don't lose information */
    577   1.1  jonathan 		if ((error = (*ctl)(fp, TIOCGETA, (caddr_t)&bts, p)) != 0)
    578   1.1  jonathan 			return error;
    579   1.1  jonathan 
    580   1.1  jonathan 		/*
    581   1.1  jonathan 		 * convert to sun termios, copy in information from
    582   1.1  jonathan 		 * termio, and convert back, then set new values.
    583   1.1  jonathan 		 */
    584   1.1  jonathan 		btios2stios(&bts, &sts);
    585   1.1  jonathan 		stio2stios(&st, &sts);
    586   1.1  jonathan 		stios2btios(&sts, &bts);
    587   1.1  jonathan 
    588   1.1  jonathan 		/*
    589   1.1  jonathan 		 * map ioctl code: ultrix tcsets are numbered in reverse order
    590   1.1  jonathan 		 */
    591   1.1  jonathan #ifdef notyet
    592   1.1  jonathan 		return (*ctl)(fp, ULTRIX_TCSETA - SCARG(uap, com) + TIOCSETA,
    593   1.1  jonathan 		    (caddr_t)&bts, p);
    594   1.1  jonathan #else
    595   1.1  jonathan 		result= (*ctl)(fp, ULTRIX_TCSETA -  SCARG(uap, com) + TIOCSETA,
    596   1.1  jonathan 		    (caddr_t)&bts, p);
    597   1.7  christos 		printf("ultrix TCSETA %lx returns %d\n",
    598   1.6  christos 		    ULTRIX_TCSETA - SCARG(uap, com), result);
    599   1.1  jonathan 		return result;
    600   1.1  jonathan #endif
    601   1.1  jonathan 
    602   1.1  jonathan 	    }
    603   1.2  jonathan 	/* Emulate termios tcset() */
    604   1.1  jonathan 	case ULTRIX_TCSETS:
    605   1.1  jonathan 	case ULTRIX_TCSETSW:
    606   1.1  jonathan 	case ULTRIX_TCSETSF:
    607   1.1  jonathan 	    {
    608   1.1  jonathan 		struct termios bts;
    609   1.1  jonathan 		struct ultrix_termios sts;
    610   1.1  jonathan 
    611   1.1  jonathan 		if ((error = copyin (SCARG(uap, data), (caddr_t)&sts,
    612   1.1  jonathan 		    sizeof (sts))) != 0)
    613   1.1  jonathan 			return error;
    614   1.1  jonathan 		stios2btios (&sts, &bts);
    615   1.1  jonathan 		return (*ctl)(fp, ULTRIX_TCSETS - SCARG(uap, com) + TIOCSETA,
    616   1.1  jonathan 		    (caddr_t)&bts, p);
    617   1.1  jonathan 	    }
    618   1.1  jonathan /*
    619   1.1  jonathan  * Pseudo-tty ioctl translations.
    620   1.1  jonathan  */
    621   1.1  jonathan 	case _IOW('t', 32, int): {	/* TIOCTCNTL */
    622   1.1  jonathan 		int error, on;
    623   1.1  jonathan 
    624   1.3  jonathan 		error = copyin (SCARG(uap, data), (caddr_t)&on, sizeof (on));
    625   1.3  jonathan 		if (error != 0)
    626   1.1  jonathan 			return error;
    627   1.1  jonathan 		return (*ctl)(fp, TIOCUCNTL, (caddr_t)&on, p);
    628   1.1  jonathan 	}
    629   1.1  jonathan 	case _IOW('t', 33, int): {	/* TIOCSIGNAL */
    630   1.1  jonathan 		int error, sig;
    631   1.1  jonathan 
    632   1.3  jonathan 		error = copyin (SCARG(uap, data), (caddr_t)&sig, sizeof (sig));
    633   1.3  jonathan 		if (error != 0)
    634   1.1  jonathan 			return error;
    635   1.1  jonathan 		return (*ctl)(fp, TIOCSIG, (caddr_t)&sig, p);
    636   1.1  jonathan 	}
    637   1.8  jonathan 
    638   1.1  jonathan /*
    639   1.1  jonathan  * Socket ioctl translations.
    640   1.1  jonathan  */
    641   1.3  jonathan #define IN_TYPE(a, type_t) { \
    642   1.3  jonathan 	type_t localbuf; \
    643   1.3  jonathan 	if ((error = copyin (SCARG(uap, data), \
    644   1.3  jonathan 				(caddr_t)&localbuf, sizeof (type_t))) != 0) \
    645   1.3  jonathan 		return error; \
    646   1.3  jonathan 	return (*ctl)(fp, a, (caddr_t)&localbuf, p); \
    647   1.3  jonathan }
    648   1.3  jonathan 
    649   1.3  jonathan #define INOUT_TYPE(a, type_t) { \
    650   1.3  jonathan 	type_t localbuf; \
    651   1.3  jonathan 	if ((error = copyin (SCARG(uap, data), (caddr_t)&localbuf,	\
    652   1.3  jonathan 			     sizeof (type_t))) != 0) \
    653   1.3  jonathan 		return error; \
    654   1.3  jonathan 	if ((error = (*ctl)(fp, a, (caddr_t)&localbuf, p)) != 0) \
    655   1.3  jonathan 		return error; \
    656   1.3  jonathan 	return copyout ((caddr_t)&localbuf, SCARG(uap, data), sizeof (type_t)); \
    657   1.3  jonathan }
    658   1.3  jonathan 
    659   1.3  jonathan 
    660   1.1  jonathan #define IFREQ_IN(a) { \
    661   1.1  jonathan 	struct ifreq ifreq; \
    662   1.3  jonathan 	if ((error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) != 0) \
    663   1.1  jonathan 		return error; \
    664   1.1  jonathan 	return (*ctl)(fp, a, (caddr_t)&ifreq, p); \
    665   1.1  jonathan }
    666   1.3  jonathan 
    667   1.1  jonathan #define IFREQ_INOUT(a) { \
    668   1.1  jonathan 	struct ifreq ifreq; \
    669   1.3  jonathan 	if ((error = copyin (SCARG(uap, data), (caddr_t)&ifreq, sizeof (ifreq))) != 0) \
    670   1.1  jonathan 		return error; \
    671   1.3  jonathan 	if ((error = (*ctl)(fp, a, (caddr_t)&ifreq, p)) != 0) \
    672   1.1  jonathan 		return error; \
    673   1.1  jonathan 	return copyout ((caddr_t)&ifreq, SCARG(uap, data), sizeof (ifreq)); \
    674   1.1  jonathan }
    675   1.1  jonathan 
    676   1.1  jonathan 	case _IOW('i', 12, struct ifreq):
    677   1.1  jonathan 		/* SIOCSIFADDR */
    678   1.1  jonathan 		break;
    679   1.1  jonathan 
    680   1.1  jonathan 	case _IOWR('i', 13, struct ifreq):
    681   1.1  jonathan 		IFREQ_INOUT(OSIOCGIFADDR);
    682   1.1  jonathan 
    683   1.1  jonathan 	case _IOW('i', 14, struct ifreq):
    684   1.1  jonathan 		/* SIOCSIFDSTADDR */
    685   1.1  jonathan 		break;
    686   1.1  jonathan 
    687   1.1  jonathan 	case _IOWR('i', 15, struct ifreq):
    688   1.1  jonathan 		IFREQ_INOUT(OSIOCGIFDSTADDR);
    689   1.1  jonathan 
    690   1.1  jonathan 	case _IOW('i', 16, struct ifreq):
    691   1.1  jonathan 		/* SIOCSIFFLAGS */
    692   1.1  jonathan 		break;
    693   1.1  jonathan 
    694   1.1  jonathan 	case _IOWR('i', 17, struct ifreq):
    695   1.1  jonathan 		/* SIOCGIFFLAGS */
    696   1.1  jonathan 		break;
    697   1.1  jonathan 
    698   1.8  jonathan 	case _IOWR('i', 18, struct ifreq):
    699   1.1  jonathan 		IFREQ_INOUT(SIOCGIFBRDADDR);
    700   1.1  jonathan 
    701   1.8  jonathan 	case _IOWR('i', 19, struct ifreq):
    702   1.8  jonathan 		IFREQ_INOUT(SIOCSIFBRDADDR);
    703   1.1  jonathan 
    704   1.8  jonathan 	case _IOWR('i', 21, struct ifreq):
    705   1.1  jonathan 		IFREQ_INOUT(OSIOCGIFNETMASK);
    706   1.1  jonathan 
    707   1.8  jonathan 	case _IOW('i', 22, struct ifreq):
    708   1.1  jonathan 		IFREQ_IN(SIOCSIFNETMASK);
    709   1.1  jonathan 
    710   1.8  jonathan 	/* 18: _IOWR('i', 18, struct ifreq):  Ultrix SIOCGIFBRDADDR */
    711   1.8  jonathan 	/* 19: _IOW('i',  19, struct ifreq):  Ultrix SIOCSIFBRDADDR */
    712   1.8  jonathan 	/* 20: _IOWR('i', 20, struct ifreq):  Ultrix SIOCSIFCONF */
    713   1.8  jonathan 	/* 21: _IOWR('i', 21, struct ifreq):  Ultrix SIOCGIFNETMASK */
    714   1.8  jonathan 	/* 22: _IOW('i',  22, struct ifreq):  Ultrix SIOCSIFNETMASK */
    715   1.8  jonathan 	/* 23: _IOWR('i', 23, struct ifreq):  Ultrix SIOCSPHYADDR */
    716   1.8  jonathan 	/* 24: _IOWR('i', 24, struct ifreq):  Ultrix SIOCSADDMULTI */
    717   1.8  jonathan 	/* 25: _IOWR('i', 25, struct ifreq):  Ultrix SIOCSDELMULTI */
    718   1.8  jonathan 
    719   1.8  jonathan 	/* 30: _IOWR('i', 30, struct arpreq):  Ultrix SIOCSARP */
    720   1.8  jonathan 	/* 31: _IOWR('i', 31, struct arpreq):  Ultrix SIOCGARP */
    721   1.8  jonathan 	/* 32: _IOWR('i', 32, struct arpreq):  Ultrix SIOCDARP */
    722   1.8  jonathan 
    723   1.8  jonathan 	case _IOWR('i', 41, struct ifreq):
    724   1.1  jonathan 		IFREQ_INOUT(SIOCGIFMETRIC);
    725   1.1  jonathan 
    726   1.8  jonathan 	case _IOWR('i', 42, struct ifreq):
    727   1.1  jonathan 		IFREQ_IN(SIOCSIFMETRIC);
    728   1.1  jonathan 
    729   1.1  jonathan 	case _IOW('i', 30, struct arpreq):
    730   1.1  jonathan 		/* SIOCSARP */
    731   1.1  jonathan 		break;
    732   1.1  jonathan 
    733   1.1  jonathan 	case _IOWR('i', 31, struct arpreq):
    734   1.1  jonathan 		/* SIOCGARP */
    735   1.1  jonathan 		break;
    736   1.1  jonathan 
    737   1.1  jonathan 	case _IOW('i', 32, struct arpreq):
    738   1.1  jonathan 		/* SIOCDARP */
    739   1.1  jonathan 		break;
    740   1.1  jonathan 
    741   1.8  jonathan 	case _IOW('i',  26, struct ifreq):	/* SIOCSIFRDCTRS? */
    742   1.8  jonathan 	case _IOWR('i', 27, struct ifreq):	/* SIOCGIFZCTRS? */
    743   1.8  jonathan 	case _IOWR('i', 28, struct ifreq):	/* read physaddr ? */
    744   1.8  jonathan 
    745   1.8  jonathan 	case _IOW('i', 40, struct ifreq):	/* SIOCARPREQ */
    746   1.1  jonathan 	case _IOW('i', 44, struct ifreq):	/* SIOCSETSYNC */
    747   1.1  jonathan 	case _IOWR('i', 45, struct ifreq):	/* SIOCGETSYNC */
    748   1.1  jonathan 	case _IOWR('i', 46, struct ifreq):	/* SIOCSDSTATS */
    749   1.1  jonathan 	case _IOWR('i', 47, struct ifreq):	/* SIOCSESTATS */
    750   1.1  jonathan 	case _IOW('i', 48, int):		/* SIOCSPROMISC */
    751   1.8  jonathan 		return EOPNOTSUPP;
    752   1.8  jonathan 
    753   1.8  jonathan 	/* emulate for vat, vic tools */
    754   1.1  jonathan 	case _IOW('i', 49, struct ifreq):	/* SIOCADDMULTI */
    755   1.1  jonathan 	case _IOW('i', 50, struct ifreq):	/* SIOCDELMULTI */
    756   1.1  jonathan 		return EOPNOTSUPP;
    757   1.1  jonathan 
    758   1.1  jonathan 	case _IOWR('i', 20, struct ifconf):	/* SIOCGIFCONF */
    759   1.1  jonathan 	    {
    760   1.1  jonathan 		struct ifconf ifconf;
    761   1.1  jonathan 
    762   1.1  jonathan 		/*
    763   1.1  jonathan 		 * XXX: two more problems
    764   1.1  jonathan 		 * 1. our sockaddr's are variable length, not always sizeof(sockaddr)
    765   1.1  jonathan 		 * 2. this returns a name per protocol, ie. it returns two "lo0"'s
    766   1.1  jonathan 		 */
    767   1.8  jonathan 		error = copyin (SCARG(uap, data), (caddr_t)&ifconf,
    768   1.8  jonathan 		    sizeof (ifconf));
    769   1.8  jonathan 		if (error)
    770   1.1  jonathan 			return error;
    771   1.8  jonathan 		error = (*ctl)(fp, OSIOCGIFCONF, (caddr_t)&ifconf, p);
    772   1.8  jonathan 		if (error)
    773   1.1  jonathan 			return error;
    774   1.1  jonathan 		return copyout ((caddr_t)&ifconf, SCARG(uap, data),
    775   1.1  jonathan 		    sizeof (ifconf));
    776   1.1  jonathan 	    }
    777   1.1  jonathan 
    778   1.1  jonathan 	}
    779   1.1  jonathan 	return (sys_ioctl(p, uap, retval));
    780   1.1  jonathan }
    781