[BACK]Return to linux_termios.c CVS log [TXT][DIR] Up to [local] / sys / compat / linux

Annotation of sys/compat/linux/linux_termios.c, Revision 1.1.1.1

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

CVSweb