135763Smarc /* 235763Smarc * Copyright (c) 1982, 1986 Regents of the University of California. 335763Smarc * All rights reserved. The Berkeley software License Agreement 435763Smarc * specifies the terms and conditions for redistribution. 535763Smarc * 6*38925Skarels * @(#)tty_compat.c 1.5 (Berkeley) 09/03/89 735763Smarc */ 835763Smarc 935763Smarc /* 1035811Smarc * mapping routines for old line discipline (yuck) 1135763Smarc */ 1235763Smarc #ifdef COMPAT_43 1335763Smarc 1435763Smarc #include "param.h" 1535763Smarc #include "systm.h" 1635763Smarc #include "user.h" 1735763Smarc #include "ioctl.h" 1835763Smarc #include "tty.h" 1935763Smarc #include "termios.h" 2035763Smarc #include "proc.h" 2135763Smarc #include "file.h" 2235763Smarc #include "conf.h" 2335763Smarc #include "dkstat.h" 2435763Smarc #include "uio.h" 2535763Smarc #include "kernel.h" 2635763Smarc #include "syslog.h" 2735763Smarc 2837526Smckusick #include "machine/reg.h" 2937526Smckusick 3035811Smarc int ttydebug = 0; 3135763Smarc 3235811Smarc /* XXX - fold these two tables into one */ 3335763Smarc static struct speedtab compatspeeds[] = { 3435763Smarc 38400, 15, 3535763Smarc 19200, 14, 3635763Smarc 9600, 13, 3735763Smarc 4800, 12, 3835763Smarc 2400, 11, 3935763Smarc 1800, 10, 4035763Smarc 1200, 9, 4135763Smarc 600, 8, 4235763Smarc 300, 7, 4335763Smarc 200, 6, 4435763Smarc 150, 5, 4535763Smarc 134, 4, 4635763Smarc 110, 3, 4735763Smarc 75, 2, 4835763Smarc 50, 1, 4935763Smarc 0, 0, 5035763Smarc -1, -1, 5135763Smarc }; 5235763Smarc static int compatspcodes[16] = { 5335763Smarc 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 5435763Smarc 1800, 2400, 4800, 9600, 19200, 38400, 5535763Smarc }; 5635763Smarc 5735763Smarc /*ARGSUSED*/ 5835763Smarc ttcompat(tp, com, data, flag) 5935763Smarc register struct tty *tp; 6035763Smarc caddr_t data; 6135763Smarc { 6235763Smarc switch(com) { 6335763Smarc case TIOCGETP: { 6435763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 6535763Smarc register u_char *cc = tp->t_cc; 6635763Smarc register speed; 6735763Smarc 6835763Smarc speed = ttspeedtab(tp->t_ospeed, compatspeeds); 6935763Smarc sg->sg_ospeed = (speed == -1) ? 15 : speed; 7035763Smarc if (tp->t_ispeed == 0) 7135763Smarc sg->sg_ispeed = sg->sg_ospeed; 7235763Smarc else { 7335763Smarc speed = ttspeedtab(tp->t_ispeed, compatspeeds); 7435763Smarc sg->sg_ispeed = (speed == -1) ? 15 : speed; 7535763Smarc } 7635763Smarc sg->sg_erase = cc[VERASE]; 7735763Smarc sg->sg_kill = cc[VKILL]; 7835811Smarc sg->sg_flags = ttcompatgetflags(tp); 7935763Smarc break; 8035763Smarc } 8135763Smarc 8235763Smarc case TIOCSETP: 8335763Smarc case TIOCSETN: { 8435763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 8535763Smarc struct termios term; 8635763Smarc int speed; 8735763Smarc 8835763Smarc term = tp->t_termios; 8935763Smarc if ((speed = sg->sg_ispeed) > 15 || speed < 0) 9035763Smarc term.c_ispeed = speed; 9135763Smarc else 9235763Smarc term.c_ispeed = compatspcodes[speed]; 9335763Smarc if ((speed = sg->sg_ospeed) > 15 || speed < 0) 9435763Smarc term.c_ospeed = speed; 9535763Smarc else 9635763Smarc term.c_ospeed = compatspcodes[speed]; 9735763Smarc term.c_cc[VERASE] = sg->sg_erase; 9835763Smarc term.c_cc[VKILL] = sg->sg_kill; 9935763Smarc if (sg->sg_erase == -1) 10035811Smarc term.c_cc[VERASE2] = _POSIX_VDISABLE; 10135763Smarc tp->t_flags = (tp->t_flags&0xffff0000) | sg->sg_flags; 10235763Smarc ttcompatsetflags(tp, &term); 10335763Smarc return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 10435763Smarc &term, flag)); 10535763Smarc } 10635763Smarc 10735763Smarc case TIOCGETC: { 10835763Smarc struct tchars *tc = (struct tchars *)data; 10935763Smarc register u_char *cc = tp->t_cc; 11035763Smarc 11135763Smarc tc->t_intrc = cc[VINTR]; 11235763Smarc tc->t_quitc = cc[VQUIT]; 11335763Smarc tc->t_startc = cc[VSTART]; 11435763Smarc tc->t_stopc = cc[VSTOP]; 11535763Smarc tc->t_eofc = cc[VEOF]; 11635763Smarc tc->t_brkc = cc[VEOL]; 11735763Smarc break; 11835763Smarc } 11935763Smarc case TIOCSETC: { 12035763Smarc struct tchars *tc = (struct tchars *)data; 12135763Smarc register u_char *cc = tp->t_cc; 12235763Smarc 12335763Smarc cc[VINTR] = tc->t_intrc; 12435763Smarc cc[VQUIT] = tc->t_quitc; 12535763Smarc cc[VSTART] = tc->t_startc; 12635763Smarc cc[VSTOP] = tc->t_stopc; 12735763Smarc cc[VEOF] = tc->t_eofc; 12835763Smarc cc[VEOL] = tc->t_brkc; 12935763Smarc if (tc->t_brkc == -1) 13035811Smarc cc[VEOL2] = _POSIX_VDISABLE; 13135763Smarc break; 13235763Smarc } 13335763Smarc case TIOCSLTC: { 13435763Smarc struct ltchars *ltc = (struct ltchars *)data; 13535763Smarc register u_char *cc = tp->t_cc; 13635763Smarc 13735763Smarc cc[VSUSP] = ltc->t_suspc; 13835763Smarc cc[VDSUSP] = ltc->t_dsuspc; 13935763Smarc cc[VREPRINT] = ltc->t_rprntc; 14035763Smarc cc[VFLUSHO] = ltc->t_flushc; 14135763Smarc cc[VWERASE] = ltc->t_werasc; 14235763Smarc cc[VLNEXT] = ltc->t_lnextc; 14335763Smarc break; 14435763Smarc } 14535763Smarc case TIOCGLTC: { 14635763Smarc struct ltchars *ltc = (struct ltchars *)data; 14735763Smarc register u_char *cc = tp->t_cc; 14835763Smarc 14935763Smarc ltc->t_suspc = cc[VSUSP]; 15035763Smarc ltc->t_dsuspc = cc[VDSUSP]; 15135763Smarc ltc->t_rprntc = cc[VREPRINT]; 15235763Smarc ltc->t_flushc = cc[VFLUSHO]; 15335763Smarc ltc->t_werasc = cc[VWERASE]; 15435763Smarc ltc->t_lnextc = cc[VLNEXT]; 15535763Smarc break; 15635763Smarc } 15735763Smarc case TIOCLBIS: 15835763Smarc case TIOCLBIC: 15935763Smarc case TIOCLSET: { 16035763Smarc struct termios term; 16135763Smarc 16235763Smarc term = tp->t_termios; 16335763Smarc if (com == TIOCLSET) 16435811Smarc tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 16535763Smarc else { 16635763Smarc tp->t_flags = 16735763Smarc (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 16835763Smarc if (com == TIOCLBIS) 16935811Smarc tp->t_flags |= *(int *)data<<16; 17035763Smarc else 17135811Smarc tp->t_flags &= ~(*(int *)data<<16); 17235763Smarc } 17335763Smarc ttcompatsetlflags(tp, &term); 17435763Smarc return (ttioctl(tp, TIOCSETA, &term, flag)); 17535763Smarc } 17635763Smarc case TIOCLGET: 17735811Smarc *(int *)data = ttcompatgetflags(tp)>>16; 17835811Smarc if (ttydebug) 17935811Smarc printf("CLGET: returning %x\n", *(int *)data); 18035763Smarc break; 18135811Smarc 18235811Smarc case TIOCGETDCOMPAT: 18335811Smarc *(int *)data = tp->t_line ? tp->t_line : 2; 18435811Smarc break; 18535811Smarc 18635811Smarc case TIOCSETDCOMPAT: { 18735811Smarc int ldisczero = 0; 18835811Smarc 18935811Smarc return(ttioctl(tp, TIOCSETD, 19035811Smarc *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 19135811Smarc } 19235811Smarc 19335763Smarc default: 19435763Smarc return (-1); 19535763Smarc } 19635763Smarc return(0); 19735763Smarc } 19835763Smarc 19935763Smarc ttcompatgetflags(tp) 20035763Smarc register struct tty *tp; 20135763Smarc { 20235763Smarc register long iflag = tp->t_iflag; 20335763Smarc register long lflag = tp->t_lflag; 20435763Smarc register long oflag = tp->t_oflag; 20535763Smarc register long cflag = tp->t_cflag; 20635763Smarc register flags = 0; 20735763Smarc 20835763Smarc if (iflag&IXOFF) 20935763Smarc flags |= TANDEM; 21035763Smarc if (iflag&ICRNL || oflag&ONLCR) 21135763Smarc flags |= CRMOD; 21235763Smarc if (cflag&PARENB) { 21335763Smarc if (iflag&INPCK) { 21435763Smarc if (cflag&PARODD) 21535763Smarc flags |= ODDP; 21635763Smarc else 21735763Smarc flags |= EVENP; 21835763Smarc } else 21935763Smarc flags |= EVENP | ODDP; 22035763Smarc } else { 22135763Smarc if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 22235763Smarc flags |= LITOUT; 22335763Smarc if (tp->t_flags&PASS8) 22435763Smarc flags |= PASS8; 22535763Smarc } 22635763Smarc 22735763Smarc if ((lflag&ICANON) == 0) { 22835763Smarc /* fudge */ 22935763Smarc if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 23035763Smarc flags |= CBREAK; 23135763Smarc else 23235763Smarc flags |= RAW; 23335763Smarc } 23435763Smarc if (oflag&OXTABS) 23535763Smarc flags |= XTABS; 23635763Smarc if (lflag&ECHOE) 23735811Smarc flags |= CRTERA|CRTBS; 23835763Smarc if (lflag&ECHOKE) 23935811Smarc flags |= CRTKIL|CRTBS; 24035763Smarc if (lflag&ECHOPRT) 24135763Smarc flags |= PRTERA; 24235763Smarc if (lflag&ECHOCTL) 24335763Smarc flags |= CTLECH; 24435763Smarc if ((iflag&IXANY) == 0) 24535763Smarc flags |= DECCTQ; 24635763Smarc flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 24735811Smarc if (ttydebug) 24835811Smarc printf("getflags: %x\n", flags); 24935763Smarc return (flags); 25035763Smarc } 25135763Smarc 25235763Smarc ttcompatsetflags(tp, t) 25335763Smarc register struct tty *tp; 25435763Smarc register struct termios *t; 25535763Smarc { 25635763Smarc register flags = tp->t_flags; 25735763Smarc register long iflag = t->c_iflag; 25835763Smarc register long oflag = t->c_oflag; 25935763Smarc register long lflag = t->c_lflag; 26035763Smarc register long cflag = t->c_cflag; 26135763Smarc 26235763Smarc if (flags & RAW) { 26335763Smarc iflag &= IXOFF; 26435763Smarc oflag &= ~OPOST; 265*38925Skarels lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 26635763Smarc } else { 267*38925Skarels iflag |= BRKINT|IXON|IMAXBEL; 26835763Smarc oflag |= OPOST; 269*38925Skarels lflag |= ISIG|IEXTEN; 27035763Smarc if (flags & XTABS) 27135763Smarc oflag |= OXTABS; 27235763Smarc else 27335763Smarc oflag &= ~OXTABS; 27435763Smarc if (flags & CBREAK) 27535763Smarc lflag &= ~ICANON; 27635763Smarc else 27735763Smarc lflag |= ICANON; 27835763Smarc if (flags&CRMOD) { 27935763Smarc iflag |= ICRNL; 28035763Smarc oflag |= ONLCR; 28135763Smarc } else { 28235763Smarc iflag &= ~ICRNL; 28335763Smarc oflag &= ~ONLCR; 28435763Smarc } 28535763Smarc } 28635763Smarc if (flags&ECHO) 28735763Smarc lflag |= ECHO; 28835763Smarc else 28935763Smarc lflag &= ~ECHO; 29035763Smarc 29135763Smarc if (flags&(RAW|LITOUT|PASS8)) { 29235763Smarc cflag &= ~(CSIZE|PARENB); 29335763Smarc cflag |= CS8; 29435763Smarc if ((flags&(RAW|PASS8)) == 0) 29535763Smarc iflag |= ISTRIP; 29635763Smarc } else { 29735763Smarc cflag &= ~CSIZE; 29835763Smarc cflag |= CS7|PARENB; 29935763Smarc } 30035763Smarc if ((flags&(EVENP|ODDP)) == EVENP) { 30135763Smarc iflag |= INPCK; 30235763Smarc cflag &= ~PARODD; 30335763Smarc } else if ((flags&(EVENP|ODDP)) == ODDP) { 30435763Smarc iflag |= INPCK; 30535763Smarc cflag |= PARODD; 30635763Smarc } else 30735763Smarc iflag &= ~INPCK; 30835763Smarc if (flags&LITOUT) 30935763Smarc oflag &= ~OPOST; /* move earlier ? */ 31035763Smarc if (flags&TANDEM) 31135763Smarc iflag |= IXOFF; 31235763Smarc else 31335763Smarc iflag &= ~IXOFF; 31435763Smarc t->c_iflag = iflag; 31535763Smarc t->c_oflag = oflag; 31635763Smarc t->c_lflag = lflag; 31735763Smarc t->c_cflag = cflag; 31835763Smarc } 31935763Smarc 32035763Smarc ttcompatsetlflags(tp, t) 32135763Smarc register struct tty *tp; 32235763Smarc register struct termios *t; 32335763Smarc { 32435763Smarc register flags = tp->t_flags; 32535763Smarc register long iflag = t->c_iflag; 32635763Smarc register long oflag = t->c_oflag; 32735763Smarc register long lflag = t->c_lflag; 32835763Smarc register long cflag = t->c_cflag; 32935811Smarc 33035763Smarc if (flags&CRTERA) 33135763Smarc lflag |= ECHOE; 33235763Smarc else 33335811Smarc lflag &= ~ECHOE; 33435763Smarc if (flags&CRTKIL) 33535763Smarc lflag |= ECHOKE; 33635763Smarc else 33735763Smarc lflag &= ~ECHOKE; 33835763Smarc if (flags&PRTERA) 33935763Smarc lflag |= ECHOPRT; 34035763Smarc else 34135763Smarc lflag &= ~ECHOPRT; 34235763Smarc if (flags&CTLECH) 34335763Smarc lflag |= ECHOCTL; 34435763Smarc else 34535763Smarc lflag &= ~ECHOCTL; 34635763Smarc if ((flags&DECCTQ) == 0) 34735763Smarc lflag |= IXANY; 34835763Smarc else 34935763Smarc lflag &= ~IXANY; 35035763Smarc lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 35135763Smarc lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 35235763Smarc if (flags&(LITOUT|PASS8)) { 35335763Smarc iflag &= ~ISTRIP; 35435763Smarc cflag &= ~(CSIZE|PARENB); 35535763Smarc cflag |= CS8; 35635763Smarc if (flags&LITOUT) 35735763Smarc oflag &= ~OPOST; 35835763Smarc if ((flags&(PASS8|RAW)) == 0) 35935763Smarc iflag |= ISTRIP; 36035763Smarc } else if ((flags&RAW) == 0) { 36135763Smarc cflag &= ~CSIZE; 36235763Smarc cflag |= CS7|PARENB; 36335763Smarc oflag |= OPOST; 36435763Smarc } 36535763Smarc t->c_iflag = iflag; 36635763Smarc t->c_oflag = oflag; 36735763Smarc t->c_lflag = lflag; 36835763Smarc t->c_cflag = cflag; 36935763Smarc } 37035763Smarc #endif /* COMPAT_43 */ 371