Annotation of sys/compat/linux/linux_termios.c, Revision 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