Home | History | Annotate | Line # | Download | only in common
linux_termios.c revision 1.15
      1  1.15  augustss /*	$NetBSD: linux_termios.c,v 1.15 2001/12/19 15:20:16 augustss Exp $	*/
      2   1.4       erh 
      3   1.4       erh /*-
      4   1.6      fvdl  * Copyright (c) 1995, 1998 The NetBSD Foundation, Inc.
      5   1.4       erh  * All rights reserved.
      6   1.4       erh  *
      7   1.4       erh  * This code is derived from software contributed to The NetBSD Foundation
      8   1.6      fvdl  * by Frank van der Linden and Eric Haszlakiewicz.
      9   1.4       erh  *
     10   1.4       erh  * Redistribution and use in source and binary forms, with or without
     11   1.4       erh  * modification, are permitted provided that the following conditions
     12   1.4       erh  * are met:
     13   1.4       erh  * 1. Redistributions of source code must retain the above copyright
     14   1.4       erh  *    notice, this list of conditions and the following disclaimer.
     15   1.4       erh  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.4       erh  *    notice, this list of conditions and the following disclaimer in the
     17   1.4       erh  *    documentation and/or other materials provided with the distribution.
     18   1.4       erh  * 3. All advertising materials mentioning features or use of this software
     19   1.4       erh  *    must display the following acknowledgement:
     20   1.4       erh  *	This product includes software developed by the NetBSD
     21   1.4       erh  *	Foundation, Inc. and its contributors.
     22   1.4       erh  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23   1.4       erh  *    contributors may be used to endorse or promote products derived
     24   1.4       erh  *    from this software without specific prior written permission.
     25   1.4       erh  *
     26   1.4       erh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27   1.4       erh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28   1.4       erh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29   1.4       erh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30   1.4       erh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31   1.4       erh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32   1.4       erh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33   1.4       erh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34   1.4       erh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35   1.4       erh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36   1.4       erh  * POSSIBILITY OF SUCH DAMAGE.
     37   1.1   mycroft  */
     38  1.14     lukem 
     39  1.14     lukem #include <sys/cdefs.h>
     40  1.15  augustss __KERNEL_RCSID(0, "$NetBSD: linux_termios.c,v 1.15 2001/12/19 15:20:16 augustss Exp $");
     41   1.1   mycroft 
     42   1.1   mycroft #include <sys/param.h>
     43   1.1   mycroft #include <sys/proc.h>
     44   1.1   mycroft #include <sys/systm.h>
     45   1.1   mycroft #include <sys/file.h>
     46   1.1   mycroft #include <sys/filedesc.h>
     47   1.1   mycroft #include <sys/ioctl.h>
     48   1.1   mycroft #include <sys/mount.h>
     49   1.1   mycroft #include <sys/termios.h>
     50   1.1   mycroft 
     51   1.1   mycroft #include <sys/syscallargs.h>
     52   1.1   mycroft 
     53   1.5  christos #include <compat/linux/common/linux_types.h>
     54   1.5  christos #include <compat/linux/common/linux_ioctl.h>
     55   1.5  christos #include <compat/linux/common/linux_signal.h>
     56   1.5  christos #include <compat/linux/common/linux_util.h>
     57   1.5  christos #include <compat/linux/common/linux_termios.h>
     58   1.5  christos 
     59   1.1   mycroft #include <compat/linux/linux_syscallargs.h>
     60   1.1   mycroft 
     61   1.1   mycroft static speed_t linux_speeds[] = {
     62   1.1   mycroft 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
     63   1.4       erh 	9600, 19200, 38400, 57600, 115200, 230400
     64   1.1   mycroft };
     65   1.1   mycroft 
     66  1.11  jdolecek static const int linux_spmasks[] = {
     67   1.1   mycroft 	LINUX_B0, LINUX_B50, LINUX_B75, LINUX_B110, LINUX_B134, LINUX_B150,
     68   1.1   mycroft 	LINUX_B200, LINUX_B300, LINUX_B600, LINUX_B1200, LINUX_B1800,
     69   1.1   mycroft 	LINUX_B2400, LINUX_B4800, LINUX_B9600, LINUX_B19200, LINUX_B38400,
     70   1.1   mycroft 	LINUX_B57600, LINUX_B115200, LINUX_B230400
     71   1.1   mycroft };
     72   1.3  christos 
     73   1.3  christos 
     74   1.3  christos static void linux_termio_to_bsd_termios __P((struct linux_termio *,
     75   1.3  christos 					     struct termios *));
     76   1.3  christos static void bsd_termios_to_linux_termio __P((struct termios *,
     77   1.3  christos 					     struct linux_termio *));
     78   1.3  christos static void linux_termios_to_bsd_termios __P((struct linux_termios *,
     79   1.3  christos 					      struct termios *));
     80   1.3  christos static void bsd_termios_to_linux_termios __P((struct termios *,
     81   1.3  christos 					      struct linux_termios *));
     82   1.1   mycroft 
     83   1.1   mycroft /*
     84   1.1   mycroft  * Deal with termio ioctl cruft. This doesn't look very good..
     85   1.1   mycroft  * XXX too much code duplication, obviously..
     86   1.1   mycroft  *
     87   1.1   mycroft  * The conversion routines between Linux and BSD structures assume
     88   1.1   mycroft  * that the fields are already filled with the current values,
     89   1.1   mycroft  * so that fields present in BSD but not in Linux keep their current
     90   1.1   mycroft  * values.
     91   1.1   mycroft  */
     92   1.1   mycroft 
     93   1.2   mycroft static void
     94   1.1   mycroft linux_termio_to_bsd_termios(lt, bts)
     95   1.7  augustss 	struct linux_termio *lt;
     96   1.7  augustss 	struct termios *bts;
     97   1.1   mycroft {
     98   1.1   mycroft 	int index;
     99   1.1   mycroft 
    100   1.1   mycroft 	bts->c_iflag = 0;
    101   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNBRK, IGNBRK);
    102   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_BRKINT, BRKINT);
    103   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNPAR, IGNPAR);
    104   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INPCK, INPCK);
    105   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ISTRIP, ISTRIP);
    106   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_INLCR, INLCR);
    107   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IGNCR, IGNCR);
    108   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_ICRNL, ICRNL);
    109   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXON, IXON);
    110   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXANY, IXANY);
    111   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IXOFF, IXOFF);
    112   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lt->c_iflag, LINUX_IMAXBEL, IMAXBEL);
    113   1.1   mycroft 
    114   1.1   mycroft 	bts->c_oflag = 0;
    115   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_OPOST, OPOST);
    116   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_ONLCR, ONLCR);
    117   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lt->c_oflag, LINUX_XTABS, OXTABS);
    118   1.1   mycroft 
    119   1.1   mycroft 	/*
    120   1.1   mycroft 	 * This could have been:
    121   1.1   mycroft 	 * bts->c_cflag = (lt->c_flag & LINUX_CSIZE) << 4
    122   1.1   mycroft 	 * But who knows, those values might perhaps change one day.
    123   1.1   mycroft 	 */
    124   1.1   mycroft 	switch (lt->c_cflag & LINUX_CSIZE) {
    125   1.1   mycroft 	case LINUX_CS5:
    126   1.1   mycroft 		bts->c_cflag = CS5;
    127   1.1   mycroft 		break;
    128   1.1   mycroft 	case LINUX_CS6:
    129   1.1   mycroft 		bts->c_cflag = CS6;
    130   1.1   mycroft 		break;
    131   1.1   mycroft 	case LINUX_CS7:
    132   1.1   mycroft 		bts->c_cflag = CS7;
    133   1.1   mycroft 		break;
    134   1.1   mycroft 	case LINUX_CS8:
    135   1.1   mycroft 		bts->c_cflag = CS8;
    136   1.1   mycroft 		break;
    137   1.1   mycroft 	}
    138   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CSTOPB, CSTOPB);
    139   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CREAD, CREAD);
    140   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARENB, PARENB);
    141   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_PARODD, PARODD);
    142   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_HUPCL, HUPCL);
    143   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CLOCAL, CLOCAL);
    144   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lt->c_cflag, LINUX_CRTSCTS, CRTSCTS);
    145   1.1   mycroft 
    146   1.1   mycroft 	bts->c_lflag = 0;
    147   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ISIG, ISIG);
    148   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ICANON, ICANON);
    149   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHO, ECHO);
    150   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOE, ECHOE);
    151   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOK, ECHOK);
    152   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHONL, ECHONL);
    153   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_NOFLSH, NOFLSH);
    154   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_TOSTOP, TOSTOP);
    155   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOCTL, ECHOCTL);
    156   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOPRT, ECHOPRT);
    157   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_ECHOKE, ECHOKE);
    158   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_FLUSHO, FLUSHO);
    159   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_PENDIN, PENDIN);
    160   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lt->c_lflag, LINUX_IEXTEN, IEXTEN);
    161   1.1   mycroft 
    162   1.1   mycroft 	index = lt->c_cflag & LINUX_CBAUD;
    163   1.1   mycroft 	if (index & LINUX_CBAUDEX)
    164   1.1   mycroft 		index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
    165   1.1   mycroft 	bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
    166   1.1   mycroft 
    167   1.4       erh 	bts->c_cc[VINTR] = lt->c_cc[LINUX_OLD_VINTR];
    168   1.4       erh 	bts->c_cc[VQUIT] = lt->c_cc[LINUX_OLD_VQUIT];
    169   1.4       erh 	bts->c_cc[VERASE] = lt->c_cc[LINUX_OLD_VERASE];
    170   1.4       erh 	bts->c_cc[VKILL] = lt->c_cc[LINUX_OLD_VKILL];
    171   1.4       erh 	bts->c_cc[VEOF] = lt->c_cc[LINUX_OLD_VEOF];
    172   1.4       erh 	bts->c_cc[VTIME] = lt->c_cc[LINUX_OLD_VTIME];
    173   1.4       erh 	bts->c_cc[VMIN] = lt->c_cc[LINUX_OLD_VMIN];
    174   1.1   mycroft }
    175   1.1   mycroft 
    176   1.2   mycroft static void
    177   1.1   mycroft bsd_termios_to_linux_termio(bts, lt)
    178   1.7  augustss 	struct termios *bts;
    179   1.7  augustss 	struct linux_termio *lt;
    180   1.1   mycroft {
    181   1.1   mycroft 	int i, mask;
    182   1.1   mycroft 
    183   1.1   mycroft 	lt->c_iflag = 0;
    184   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
    185   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
    186   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
    187   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
    188   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
    189   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
    190   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
    191   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
    192   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
    193   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
    194   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
    195   1.1   mycroft 	lt->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
    196   1.1   mycroft 
    197   1.1   mycroft 	lt->c_oflag = 0;
    198   1.1   mycroft 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
    199   1.1   mycroft 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
    200   1.1   mycroft 	lt->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
    201   1.1   mycroft 
    202   1.1   mycroft 	switch (bts->c_cflag & CSIZE) {
    203   1.1   mycroft 	case CS5:
    204   1.1   mycroft 		lt->c_cflag = LINUX_CS5;
    205   1.1   mycroft 		break;
    206   1.1   mycroft 	case CS6:
    207   1.1   mycroft 		lt->c_cflag = LINUX_CS6;
    208   1.1   mycroft 		break;
    209   1.1   mycroft 	case CS7:
    210   1.1   mycroft 		lt->c_cflag = LINUX_CS7;
    211   1.1   mycroft 		break;
    212   1.1   mycroft 	case CS8:
    213   1.1   mycroft 		lt->c_cflag = LINUX_CS8;
    214   1.1   mycroft 		break;
    215   1.1   mycroft 	}
    216   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
    217   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
    218   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
    219   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
    220   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
    221   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
    222   1.1   mycroft 	lt->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
    223   1.1   mycroft 
    224   1.1   mycroft 	lt->c_lflag = 0;
    225   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
    226   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
    227   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
    228   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
    229   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
    230   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
    231   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
    232   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
    233   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
    234   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
    235   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
    236   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
    237   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
    238   1.1   mycroft 	lt->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
    239   1.1   mycroft 
    240   1.1   mycroft 	mask = LINUX_B9600;	/* XXX default value should this be 0? */
    241   1.1   mycroft 	for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
    242   1.1   mycroft 		if (bts->c_ospeed == linux_speeds[i]) {
    243   1.1   mycroft 			mask = linux_spmasks[i];
    244   1.1   mycroft 			break;
    245   1.1   mycroft 		}
    246   1.1   mycroft 	}
    247   1.1   mycroft 	lt->c_cflag |= mask;
    248   1.1   mycroft 
    249   1.1   mycroft 	lt->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
    250   1.1   mycroft 	lt->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
    251   1.1   mycroft 	lt->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
    252   1.1   mycroft 	lt->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
    253   1.1   mycroft 	lt->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
    254   1.1   mycroft 	lt->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
    255   1.1   mycroft 	lt->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
    256   1.1   mycroft 	lt->c_cc[LINUX_VSWTC] = 0;
    257   1.1   mycroft 
    258   1.1   mycroft 	/* XXX should be fixed someday */
    259   1.1   mycroft 	lt->c_line = 0;
    260   1.1   mycroft }
    261   1.1   mycroft 
    262   1.2   mycroft static void
    263   1.1   mycroft linux_termios_to_bsd_termios(lts, bts)
    264   1.7  augustss 	struct linux_termios *lts;
    265   1.7  augustss 	struct termios *bts;
    266   1.1   mycroft {
    267   1.1   mycroft 	int index;
    268   1.1   mycroft 
    269   1.1   mycroft 	bts->c_iflag = 0;
    270   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNBRK, IGNBRK);
    271   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_BRKINT, BRKINT);
    272   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNPAR, IGNPAR);
    273   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INPCK, INPCK);
    274   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ISTRIP, ISTRIP);
    275   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_INLCR, INLCR);
    276   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IGNCR, IGNCR);
    277   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_ICRNL, ICRNL);
    278   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXON, IXON);
    279   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXANY, IXANY);
    280   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IXOFF, IXOFF);
    281   1.1   mycroft 	bts->c_iflag |= cvtto_bsd_mask(lts->c_iflag, LINUX_IMAXBEL, IMAXBEL);
    282   1.1   mycroft 
    283   1.1   mycroft 	bts->c_oflag = 0;
    284   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_OPOST, OPOST);
    285   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_ONLCR, ONLCR);
    286   1.1   mycroft 	bts->c_oflag |= cvtto_bsd_mask(lts->c_oflag, LINUX_XTABS, OXTABS);
    287   1.1   mycroft 
    288   1.1   mycroft 	bts->c_cflag = 0;
    289   1.1   mycroft 	switch (lts->c_cflag & LINUX_CSIZE) {
    290   1.1   mycroft 	case LINUX_CS5:
    291   1.1   mycroft 		bts->c_cflag = CS5;
    292   1.1   mycroft 		break;
    293   1.1   mycroft 	case LINUX_CS6:
    294   1.1   mycroft 		bts->c_cflag = CS6;
    295   1.1   mycroft 		break;
    296   1.1   mycroft 	case LINUX_CS7:
    297   1.1   mycroft 		bts->c_cflag = CS7;
    298   1.1   mycroft 		break;
    299   1.1   mycroft 	case LINUX_CS8:
    300   1.1   mycroft 		bts->c_cflag = CS8;
    301   1.1   mycroft 		break;
    302   1.1   mycroft 	}
    303   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CSTOPB, CSTOPB);
    304   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CREAD, CREAD);
    305   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARENB, PARENB);
    306   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_PARODD, PARODD);
    307   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_HUPCL, HUPCL);
    308   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CLOCAL, CLOCAL);
    309   1.1   mycroft 	bts->c_cflag |= cvtto_bsd_mask(lts->c_cflag, LINUX_CRTSCTS, CRTSCTS);
    310   1.1   mycroft 
    311   1.1   mycroft 	bts->c_lflag = 0;
    312   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ISIG, ISIG);
    313   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ICANON, ICANON);
    314   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHO, ECHO);
    315   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOE, ECHOE);
    316   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOK, ECHOK);
    317   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHONL, ECHONL);
    318   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_NOFLSH, NOFLSH);
    319   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_TOSTOP, TOSTOP);
    320   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOCTL, ECHOCTL);
    321   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOPRT, ECHOPRT);
    322   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_ECHOKE, ECHOKE);
    323   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_FLUSHO, FLUSHO);
    324   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_PENDIN, PENDIN);
    325   1.1   mycroft 	bts->c_lflag |= cvtto_bsd_mask(lts->c_lflag, LINUX_IEXTEN, IEXTEN);
    326   1.1   mycroft 
    327   1.1   mycroft 	index = lts->c_cflag & LINUX_CBAUD;
    328   1.1   mycroft 	if (index & LINUX_CBAUDEX)
    329   1.1   mycroft 		index = (index & ~LINUX_CBAUDEX) + LINUX_NSPEEDS - 1;
    330   1.1   mycroft 	bts->c_ispeed = bts->c_ospeed = linux_speeds[index];
    331  1.12      manu 	/*
    332  1.12      manu 	 * A null c_ospeed causes NetBSD to hangup the terminal.
    333  1.12      manu 	 * Linux does not do this, and it sets c_ospeed to zero
    334  1.12      manu 	 * sometimes. If it is null, we store -1 in the kernel
    335  1.12      manu 	 */
    336  1.12      manu 	if (bts->c_ospeed == 0)
    337  1.12      manu 		bts->c_ospeed = -1;
    338   1.1   mycroft 
    339   1.1   mycroft 	bts->c_cc[VINTR] = lts->c_cc[LINUX_VINTR];
    340   1.1   mycroft 	bts->c_cc[VQUIT] = lts->c_cc[LINUX_VQUIT];
    341   1.1   mycroft 	bts->c_cc[VERASE] = lts->c_cc[LINUX_VERASE];
    342   1.1   mycroft 	bts->c_cc[VKILL] = lts->c_cc[LINUX_VKILL];
    343   1.1   mycroft 	bts->c_cc[VEOF] = lts->c_cc[LINUX_VEOF];
    344   1.1   mycroft 	bts->c_cc[VTIME] = lts->c_cc[LINUX_VTIME];
    345   1.1   mycroft 	bts->c_cc[VMIN] = lts->c_cc[LINUX_VMIN];
    346   1.1   mycroft 	bts->c_cc[VEOL] = lts->c_cc[LINUX_VEOL];
    347   1.1   mycroft 	bts->c_cc[VEOL2] = lts->c_cc[LINUX_VEOL2];
    348   1.1   mycroft 	bts->c_cc[VWERASE] = lts->c_cc[LINUX_VWERASE];
    349   1.1   mycroft 	bts->c_cc[VSUSP] = lts->c_cc[LINUX_VSUSP];
    350   1.1   mycroft 	bts->c_cc[VSTART] = lts->c_cc[LINUX_VSTART];
    351   1.1   mycroft 	bts->c_cc[VSTOP] = lts->c_cc[LINUX_VSTOP];
    352   1.1   mycroft 	bts->c_cc[VLNEXT] = lts->c_cc[LINUX_VLNEXT];
    353   1.1   mycroft 	bts->c_cc[VDISCARD] = lts->c_cc[LINUX_VDISCARD];
    354   1.1   mycroft 	bts->c_cc[VREPRINT] = lts->c_cc[LINUX_VREPRINT];
    355   1.1   mycroft }
    356   1.1   mycroft 
    357   1.2   mycroft static void
    358   1.1   mycroft bsd_termios_to_linux_termios(bts, lts)
    359   1.7  augustss 	struct termios *bts;
    360   1.7  augustss 	struct linux_termios *lts;
    361   1.1   mycroft {
    362   1.1   mycroft 	int i, mask;
    363   1.1   mycroft 
    364   1.1   mycroft 	lts->c_iflag = 0;
    365   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNBRK, LINUX_IGNBRK);
    366   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, BRKINT, LINUX_BRKINT);
    367   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNPAR, LINUX_IGNPAR);
    368   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INPCK, LINUX_INPCK);
    369   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ISTRIP, LINUX_ISTRIP);
    370   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, INLCR, LINUX_INLCR);
    371   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IGNCR, LINUX_IGNCR);
    372   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, ICRNL, LINUX_ICRNL);
    373   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXON, LINUX_IXON);
    374   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXANY, LINUX_IXANY);
    375   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IXOFF, LINUX_IXOFF);
    376   1.1   mycroft 	lts->c_iflag |= cvtto_linux_mask(bts->c_iflag, IMAXBEL, LINUX_IMAXBEL);
    377   1.1   mycroft 
    378   1.1   mycroft 	lts->c_oflag = 0;
    379   1.1   mycroft 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OPOST, LINUX_OPOST);
    380   1.1   mycroft 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, ONLCR, LINUX_ONLCR);
    381   1.1   mycroft 	lts->c_oflag |= cvtto_linux_mask(bts->c_oflag, OXTABS, LINUX_XTABS);
    382   1.1   mycroft 
    383   1.1   mycroft 	switch (bts->c_cflag & CSIZE) {
    384   1.1   mycroft 	case CS5:
    385   1.1   mycroft 		lts->c_cflag = LINUX_CS5;
    386   1.1   mycroft 		break;
    387   1.1   mycroft 	case CS6:
    388   1.1   mycroft 		lts->c_cflag = LINUX_CS6;
    389   1.1   mycroft 		break;
    390   1.1   mycroft 	case CS7:
    391   1.1   mycroft 		lts->c_cflag = LINUX_CS7;
    392   1.1   mycroft 		break;
    393   1.1   mycroft 	case CS8:
    394   1.1   mycroft 		lts->c_cflag = LINUX_CS8;
    395   1.1   mycroft 		break;
    396   1.1   mycroft 	}
    397   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS5, LINUX_CS5);
    398   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS6, LINUX_CS6);
    399   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS7, LINUX_CS7);
    400   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CS8, LINUX_CS8);
    401   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CSTOPB, LINUX_CSTOPB);
    402   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CREAD, LINUX_CREAD);
    403   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARENB, LINUX_PARENB);
    404   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, PARODD, LINUX_PARODD);
    405   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, HUPCL, LINUX_HUPCL);
    406   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CLOCAL, LINUX_CLOCAL);
    407   1.1   mycroft 	lts->c_cflag |= cvtto_linux_mask(bts->c_cflag, CRTSCTS, LINUX_CRTSCTS);
    408   1.1   mycroft 
    409   1.1   mycroft 	lts->c_lflag = 0;
    410   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ISIG, LINUX_ISIG);
    411   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ICANON, LINUX_ICANON);
    412   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHO, LINUX_ECHO);
    413   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOE, LINUX_ECHOE);
    414   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOK, LINUX_ECHOK);
    415   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHONL, LINUX_ECHONL);
    416   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, NOFLSH, LINUX_NOFLSH);
    417   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, TOSTOP, LINUX_TOSTOP);
    418   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOCTL, LINUX_ECHOCTL);
    419   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOPRT, LINUX_ECHOPRT);
    420   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, ECHOKE, LINUX_ECHOKE);
    421   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, FLUSHO, LINUX_FLUSHO);
    422   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, PENDIN, LINUX_PENDIN);
    423   1.1   mycroft 	lts->c_lflag |= cvtto_linux_mask(bts->c_lflag, IEXTEN, LINUX_IEXTEN);
    424   1.1   mycroft 
    425   1.1   mycroft 	mask = LINUX_B9600;	/* XXX default value */
    426   1.1   mycroft 	for (i = 0; i < sizeof (linux_speeds) / sizeof (speed_t); i++) {
    427   1.1   mycroft 		if (bts->c_ospeed == linux_speeds[i]) {
    428   1.1   mycroft 			mask = linux_spmasks[i];
    429   1.1   mycroft 			break;
    430   1.1   mycroft 		}
    431   1.1   mycroft 	}
    432  1.12      manu 	/*
    433  1.12      manu 	 * A null c_ospeed causes NetBSD to hangup the terminal.
    434  1.12      manu 	 * Linux does not do this, and it sets c_ospeed to zero
    435  1.12      manu 	 * sometimes. If it is null, we store -1 in the kernel
    436  1.12      manu 	 */
    437  1.12      manu 	if (bts->c_ospeed == -1)
    438  1.12      manu 		bts->c_ospeed = 0;
    439   1.1   mycroft 	lts->c_cflag |= mask;
    440   1.1   mycroft 
    441   1.1   mycroft 	lts->c_cc[LINUX_VINTR] = bts->c_cc[VINTR];
    442   1.1   mycroft 	lts->c_cc[LINUX_VQUIT] = bts->c_cc[VQUIT];
    443   1.1   mycroft 	lts->c_cc[LINUX_VERASE] = bts->c_cc[VERASE];
    444   1.1   mycroft 	lts->c_cc[LINUX_VKILL] = bts->c_cc[VKILL];
    445   1.1   mycroft 	lts->c_cc[LINUX_VEOF] = bts->c_cc[VEOF];
    446   1.1   mycroft 	lts->c_cc[LINUX_VTIME] = bts->c_cc[VTIME];
    447   1.1   mycroft 	lts->c_cc[LINUX_VMIN] = bts->c_cc[VMIN];
    448   1.1   mycroft 	lts->c_cc[LINUX_VEOL] = bts->c_cc[VEOL];
    449   1.1   mycroft 	lts->c_cc[LINUX_VEOL2] = bts->c_cc[VEOL2];
    450   1.1   mycroft 	lts->c_cc[LINUX_VWERASE] = bts->c_cc[VWERASE];
    451   1.1   mycroft 	lts->c_cc[LINUX_VSUSP] = bts->c_cc[VSUSP];
    452   1.1   mycroft 	lts->c_cc[LINUX_VSTART] = bts->c_cc[VSTART];
    453   1.1   mycroft 	lts->c_cc[LINUX_VSTOP] = bts->c_cc[VSTOP];
    454   1.1   mycroft 	lts->c_cc[LINUX_VLNEXT] = bts->c_cc[VLNEXT];
    455   1.1   mycroft 	lts->c_cc[LINUX_VDISCARD] = bts->c_cc[VDISCARD];
    456   1.1   mycroft 	lts->c_cc[LINUX_VREPRINT] = bts->c_cc[VREPRINT];
    457   1.1   mycroft 	lts->c_cc[LINUX_VSWTC] = 0;
    458   1.1   mycroft 
    459   1.1   mycroft 	/* XXX should be fixed someday */
    460   1.1   mycroft 	lts->c_line = 0;
    461   1.1   mycroft }
    462   1.1   mycroft 
    463   1.1   mycroft int
    464   1.1   mycroft linux_ioctl_termios(p, uap, retval)
    465   1.7  augustss 	struct proc *p;
    466   1.7  augustss 	struct linux_sys_ioctl_args /* {
    467   1.1   mycroft 		syscallarg(int) fd;
    468   1.1   mycroft 		syscallarg(u_long) com;
    469   1.1   mycroft 		syscallarg(caddr_t) data;
    470   1.1   mycroft 	} */ *uap;
    471   1.1   mycroft 	register_t *retval;
    472   1.1   mycroft {
    473   1.7  augustss 	struct file *fp;
    474   1.7  augustss 	struct filedesc *fdp;
    475   1.1   mycroft 	u_long com;
    476   1.1   mycroft 	struct linux_termio tmplt;
    477   1.1   mycroft 	struct linux_termios tmplts;
    478   1.1   mycroft 	struct termios tmpbts;
    479   1.1   mycroft 	int idat;
    480   1.1   mycroft 	struct sys_ioctl_args ia;
    481   1.1   mycroft 	int error;
    482   1.8      fvdl 	char tioclinux;
    483   1.9      ross 	int (*bsdioctl) __P((struct file *, u_long, caddr_t, struct proc *));
    484   1.1   mycroft 
    485   1.1   mycroft 	fdp = p->p_fd;
    486  1.13   thorpej 	if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
    487   1.1   mycroft 		return (EBADF);
    488   1.1   mycroft 
    489   1.1   mycroft 	if ((fp->f_flag & (FREAD | FWRITE)) == 0)
    490   1.1   mycroft 		return (EBADF);
    491   1.1   mycroft 
    492   1.9      ross 	bsdioctl = fp->f_ops->fo_ioctl;
    493   1.1   mycroft 	com = SCARG(uap, com);
    494   1.1   mycroft 	retval[0] = 0;
    495   1.1   mycroft 
    496   1.1   mycroft 	switch (com) {
    497   1.1   mycroft 	case LINUX_TCGETS:
    498   1.9      ross 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
    499   1.1   mycroft 		if (error)
    500   1.1   mycroft 			return error;
    501   1.1   mycroft 		bsd_termios_to_linux_termios(&tmpbts, &tmplts);
    502   1.1   mycroft 		error = copyout(&tmplts, SCARG(uap, data), sizeof tmplts);
    503   1.1   mycroft 		if (error)
    504   1.1   mycroft 			return error;
    505   1.1   mycroft 		return 0;
    506   1.1   mycroft 	case LINUX_TCSETS:
    507   1.1   mycroft 	case LINUX_TCSETSW:
    508   1.1   mycroft 	case LINUX_TCSETSF:
    509   1.1   mycroft 		/*
    510   1.1   mycroft 		 * First fill in all fields, so that we keep the current
    511   1.1   mycroft 		 * values for fields that Linux doesn't know about.
    512   1.1   mycroft 		 */
    513   1.9      ross 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
    514   1.1   mycroft 		if (error)
    515   1.1   mycroft 			return error;
    516   1.1   mycroft 		error = copyin(SCARG(uap, data), &tmplts, sizeof tmplts);
    517   1.1   mycroft 		if (error)
    518   1.1   mycroft 			return error;
    519   1.1   mycroft 		linux_termios_to_bsd_termios(&tmplts, &tmpbts);
    520   1.1   mycroft 		switch (com) {
    521   1.1   mycroft 		case LINUX_TCSETS:
    522   1.1   mycroft 			com = TIOCSETA;
    523   1.1   mycroft 			break;
    524   1.1   mycroft 		case LINUX_TCSETSW:
    525   1.1   mycroft 			com = TIOCSETAW;
    526   1.1   mycroft 			break;
    527   1.1   mycroft 		case LINUX_TCSETSF:
    528   1.1   mycroft 			com = TIOCSETAF;
    529   1.1   mycroft 			break;
    530   1.1   mycroft 		}
    531   1.9      ross 		error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
    532   1.1   mycroft 		if (error)
    533   1.1   mycroft 			return error;
    534   1.1   mycroft 		return 0;
    535   1.1   mycroft 	case LINUX_TCGETA:
    536   1.9      ross 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
    537   1.1   mycroft 		if (error)
    538   1.1   mycroft 			return error;
    539   1.1   mycroft 		bsd_termios_to_linux_termio(&tmpbts, &tmplt);
    540   1.1   mycroft 		error = copyout(&tmplt, SCARG(uap, data), sizeof tmplt);
    541   1.1   mycroft 		if (error)
    542   1.1   mycroft 			return error;
    543   1.1   mycroft 		return 0;
    544   1.1   mycroft 	case LINUX_TCSETA:
    545   1.1   mycroft 	case LINUX_TCSETAW:
    546   1.1   mycroft 	case LINUX_TCSETAF:
    547   1.1   mycroft 		/*
    548   1.1   mycroft 		 * First fill in all fields, so that we keep the current
    549   1.1   mycroft 		 * values for fields that Linux doesn't know about.
    550   1.1   mycroft 		 */
    551   1.9      ross 		error = (*bsdioctl)(fp, TIOCGETA, (caddr_t)&tmpbts, p);
    552   1.1   mycroft 		if (error)
    553   1.1   mycroft 			return error;
    554   1.1   mycroft 		error = copyin(SCARG(uap, data), &tmplt, sizeof tmplt);
    555   1.1   mycroft 		if (error)
    556   1.1   mycroft 			return error;
    557   1.1   mycroft 		linux_termio_to_bsd_termios(&tmplt, &tmpbts);
    558   1.1   mycroft 		switch (com) {
    559   1.1   mycroft 		case LINUX_TCSETA:
    560   1.1   mycroft 			com = TIOCSETA;
    561   1.1   mycroft 			break;
    562   1.1   mycroft 		case LINUX_TCSETAW:
    563   1.1   mycroft 			com = TIOCSETAW;
    564   1.1   mycroft 			break;
    565   1.1   mycroft 		case LINUX_TCSETAF:
    566   1.1   mycroft 			com = TIOCSETAF;
    567   1.1   mycroft 			break;
    568   1.1   mycroft 		}
    569   1.9      ross 		error = (*bsdioctl)(fp, com, (caddr_t)&tmpbts, p);
    570   1.1   mycroft 		if (error)
    571   1.1   mycroft 			return error;
    572   1.1   mycroft 		return 0;
    573   1.9      ross 	case LINUX_TCFLSH:
    574  1.10    itojun 		switch((u_long)SCARG(uap, data)) {
    575   1.9      ross 		case 0:
    576   1.9      ross 			idat = FREAD;
    577   1.9      ross 			break;
    578   1.9      ross 		case 1:
    579   1.9      ross 			idat = FWRITE;
    580   1.9      ross 			break;
    581   1.9      ross 		case 2:
    582   1.9      ross 			idat = 0;
    583   1.9      ross 			break;
    584   1.9      ross 		default:
    585   1.9      ross 			return EINVAL;
    586   1.9      ross 		}
    587   1.9      ross 		return (*bsdioctl)(fp, TIOCFLUSH, (caddr_t)&idat, p);
    588   1.1   mycroft 	case LINUX_TIOCGETD:
    589   1.9      ross 		error = (*bsdioctl)(fp, TIOCGETD, (caddr_t)&idat, p);
    590   1.1   mycroft 		if (error)
    591   1.1   mycroft 			return error;
    592   1.1   mycroft 		switch (idat) {
    593   1.1   mycroft 		case TTYDISC:
    594   1.1   mycroft 			idat = LINUX_N_TTY;
    595   1.1   mycroft 			break;
    596   1.1   mycroft 		case SLIPDISC:
    597   1.1   mycroft 			idat = LINUX_N_SLIP;
    598   1.1   mycroft 			break;
    599   1.1   mycroft 		case PPPDISC:
    600   1.1   mycroft 			idat = LINUX_N_PPP;
    601   1.1   mycroft 			break;
    602   1.4       erh 		case STRIPDISC:
    603   1.4       erh 			idat = LINUX_N_STRIP;
    604   1.4       erh 			break;
    605   1.1   mycroft 		/*
    606   1.1   mycroft 		 * Linux does not have the tablet line discipline.
    607   1.1   mycroft 		 */
    608   1.1   mycroft 		case TABLDISC:
    609   1.1   mycroft 		default:
    610   1.1   mycroft 			idat = -1;	/* XXX What should this be? */
    611   1.1   mycroft 			break;
    612   1.1   mycroft 		}
    613   1.1   mycroft 		error = copyout(&idat, SCARG(uap, data), sizeof idat);
    614   1.1   mycroft 		if (error)
    615   1.1   mycroft 			return error;
    616   1.1   mycroft 		return 0;
    617   1.1   mycroft 	case LINUX_TIOCSETD:
    618   1.1   mycroft 		error = copyin(SCARG(uap, data), &idat, sizeof idat);
    619   1.1   mycroft 		if (error)
    620   1.1   mycroft 			return error;
    621   1.1   mycroft 		switch (idat) {
    622   1.1   mycroft 		case LINUX_N_TTY:
    623   1.1   mycroft 			idat = TTYDISC;
    624   1.1   mycroft 			break;
    625   1.1   mycroft 		case LINUX_N_SLIP:
    626   1.1   mycroft 			idat = SLIPDISC;
    627   1.1   mycroft 			break;
    628   1.1   mycroft 		case LINUX_N_PPP:
    629   1.1   mycroft 			idat = PPPDISC;
    630   1.1   mycroft 			break;
    631   1.4       erh 		case LINUX_N_STRIP:
    632   1.4       erh 			idat = STRIPDISC;
    633   1.4       erh 			break;
    634   1.1   mycroft 		/*
    635   1.1   mycroft 		 * We can't handle the mouse line discipline Linux has.
    636   1.1   mycroft 		 */
    637   1.1   mycroft 		case LINUX_N_MOUSE:
    638   1.4       erh 		case LINUX_N_AX25:
    639   1.4       erh 		case LINUX_N_X25:
    640   1.4       erh 		case LINUX_N_6PACK:
    641   1.1   mycroft 		default:
    642   1.1   mycroft 			return EINVAL;
    643   1.1   mycroft 		}
    644   1.9      ross 		error = (*bsdioctl)(fp, TIOCSETD, (caddr_t)&idat, p);
    645   1.1   mycroft 		if (error)
    646   1.1   mycroft 			return error;
    647   1.1   mycroft 		return 0;
    648   1.8      fvdl 	case LINUX_TIOCLINUX:
    649   1.8      fvdl 		error = copyin(SCARG(uap, data), &tioclinux, sizeof tioclinux);
    650   1.8      fvdl 		if (error != 0)
    651   1.8      fvdl 			return error;
    652   1.8      fvdl 		switch (tioclinux) {
    653   1.8      fvdl 		case LINUX_TIOCLINUX_KERNMSG:
    654   1.8      fvdl 			/*
    655   1.8      fvdl 			 * XXX needed to not fail for some things. Could
    656   1.8      fvdl 			 * try to use TIOCCONS, but the char argument
    657   1.8      fvdl 			 * specifies the VT #, not an fd.
    658   1.8      fvdl 			 */
    659   1.8      fvdl 			return 0;
    660   1.8      fvdl 		case LINUX_TIOCLINUX_COPY:
    661   1.8      fvdl 		case LINUX_TIOCLINUX_PASTE:
    662   1.8      fvdl 		case LINUX_TIOCLINUX_UNBLANK:
    663   1.8      fvdl 		case LINUX_TIOCLINUX_LOADLUT:
    664   1.8      fvdl 		case LINUX_TIOCLINUX_READSHIFT:
    665   1.8      fvdl 		case LINUX_TIOCLINUX_READMOUSE:
    666   1.8      fvdl 		case LINUX_TIOCLINUX_VESABLANK:
    667   1.8      fvdl 		case LINUX_TIOCLINUX_CURCONS:	/* could use VT_GETACTIVE */
    668   1.8      fvdl 			return EINVAL;
    669   1.8      fvdl 		}
    670   1.8      fvdl 		break;
    671   1.1   mycroft 	case LINUX_TIOCGWINSZ:
    672   1.1   mycroft 		SCARG(&ia, com) = TIOCGWINSZ;
    673   1.1   mycroft 		break;
    674   1.1   mycroft 	case LINUX_TIOCSWINSZ:
    675   1.1   mycroft 		SCARG(&ia, com) = TIOCSWINSZ;
    676   1.1   mycroft 		break;
    677   1.1   mycroft 	case LINUX_TIOCGPGRP:
    678   1.1   mycroft 		SCARG(&ia, com) = TIOCGPGRP;
    679   1.1   mycroft 		break;
    680   1.1   mycroft 	case LINUX_TIOCSPGRP:
    681   1.1   mycroft 		SCARG(&ia, com) = TIOCSPGRP;
    682   1.1   mycroft 		break;
    683   1.1   mycroft 	case LINUX_FIONREAD:
    684   1.1   mycroft 		SCARG(&ia, com) = FIONREAD;
    685   1.1   mycroft 		break;
    686   1.1   mycroft 	case LINUX_FIONBIO:
    687   1.1   mycroft 		SCARG(&ia, com) = FIONBIO;
    688   1.1   mycroft 		break;
    689   1.1   mycroft 	case LINUX_FIOASYNC:
    690   1.1   mycroft 		SCARG(&ia, com) = FIOASYNC;
    691   1.1   mycroft 		break;
    692   1.1   mycroft 	case LINUX_TIOCEXCL:
    693   1.1   mycroft 		SCARG(&ia, com) = TIOCEXCL;
    694   1.1   mycroft 		break;
    695   1.1   mycroft 	case LINUX_TIOCNXCL:
    696   1.1   mycroft 		SCARG(&ia, com) = TIOCNXCL;
    697   1.1   mycroft 		break;
    698   1.1   mycroft 	case LINUX_TIOCCONS:
    699   1.1   mycroft 		SCARG(&ia, com) = TIOCCONS;
    700   1.1   mycroft 		break;
    701   1.1   mycroft 	case LINUX_TIOCNOTTY:
    702   1.1   mycroft 		SCARG(&ia, com) = TIOCNOTTY;
    703  1.15  augustss 		break;
    704  1.15  augustss 	case LINUX_TCSBRK:
    705  1.15  augustss 		SCARG(&ia, com) = SCARG(uap, data) ? TIOCDRAIN : TIOCSBRK;
    706  1.15  augustss 		break;
    707  1.15  augustss 	case LINUX_TIOCMGET:
    708  1.15  augustss 		SCARG(&ia, com) = TIOCMGET;
    709  1.15  augustss 		break;
    710  1.15  augustss 	case LINUX_TIOCMSET:
    711  1.15  augustss 		SCARG(&ia, com) = TIOCMSET;
    712   1.1   mycroft 		break;
    713   1.1   mycroft 	default:
    714   1.1   mycroft 		return EINVAL;
    715   1.1   mycroft 	}
    716   1.1   mycroft 
    717   1.1   mycroft 	SCARG(&ia, fd) = SCARG(uap, fd);
    718   1.1   mycroft 	SCARG(&ia, data) = SCARG(uap, data);
    719   1.1   mycroft 	return sys_ioctl(p, &ia, retval);
    720   1.1   mycroft }
    721