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*46426Smarc * @(#)tty_compat.c 7.7 (Berkeley) 02/15/91 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 3235763Smarc static struct speedtab compatspeeds[] = { 3335763Smarc 38400, 15, 3435763Smarc 19200, 14, 3535763Smarc 9600, 13, 3635763Smarc 4800, 12, 3735763Smarc 2400, 11, 3835763Smarc 1800, 10, 3935763Smarc 1200, 9, 4035763Smarc 600, 8, 4135763Smarc 300, 7, 4235763Smarc 200, 6, 4335763Smarc 150, 5, 4435763Smarc 134, 4, 4535763Smarc 110, 3, 4635763Smarc 75, 2, 4735763Smarc 50, 1, 4835763Smarc 0, 0, 4935763Smarc -1, -1, 5035763Smarc }; 5135763Smarc static int compatspcodes[16] = { 5235763Smarc 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 5335763Smarc 1800, 2400, 4800, 9600, 19200, 38400, 5435763Smarc }; 5535763Smarc 56*46426Smarc ttspeedtab(speed, table) 57*46426Smarc register struct speedtab *table; 58*46426Smarc { 59*46426Smarc 60*46426Smarc for ( ; table->sp_speed != -1; table++) 61*46426Smarc if (table->sp_speed == speed) 62*46426Smarc return (table->sp_code); 63*46426Smarc return (-1); 64*46426Smarc } 65*46426Smarc 6635763Smarc /*ARGSUSED*/ 6735763Smarc ttcompat(tp, com, data, flag) 6835763Smarc register struct tty *tp; 6935763Smarc caddr_t data; 7035763Smarc { 71*46426Smarc 72*46426Smarc switch (com) { 7335763Smarc case TIOCGETP: { 7435763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 7535763Smarc register u_char *cc = tp->t_cc; 7635763Smarc register speed; 7735763Smarc 7835763Smarc speed = ttspeedtab(tp->t_ospeed, compatspeeds); 7935763Smarc sg->sg_ospeed = (speed == -1) ? 15 : speed; 8035763Smarc if (tp->t_ispeed == 0) 8135763Smarc sg->sg_ispeed = sg->sg_ospeed; 8235763Smarc else { 8335763Smarc speed = ttspeedtab(tp->t_ispeed, compatspeeds); 8435763Smarc sg->sg_ispeed = (speed == -1) ? 15 : speed; 8535763Smarc } 8635763Smarc sg->sg_erase = cc[VERASE]; 8735763Smarc sg->sg_kill = cc[VKILL]; 8835811Smarc sg->sg_flags = ttcompatgetflags(tp); 8935763Smarc break; 9035763Smarc } 9135763Smarc 9235763Smarc case TIOCSETP: 9335763Smarc case TIOCSETN: { 9435763Smarc register struct sgttyb *sg = (struct sgttyb *)data; 9535763Smarc struct termios term; 9635763Smarc int speed; 9735763Smarc 9835763Smarc term = tp->t_termios; 9935763Smarc if ((speed = sg->sg_ispeed) > 15 || speed < 0) 10035763Smarc term.c_ispeed = speed; 10135763Smarc else 10235763Smarc term.c_ispeed = compatspcodes[speed]; 10335763Smarc if ((speed = sg->sg_ospeed) > 15 || speed < 0) 10435763Smarc term.c_ospeed = speed; 10535763Smarc else 10635763Smarc term.c_ospeed = compatspcodes[speed]; 10735763Smarc term.c_cc[VERASE] = sg->sg_erase; 10835763Smarc term.c_cc[VKILL] = sg->sg_kill; 109*46426Smarc tp->t_flags = tp->t_flags&0xffff0000 | sg->sg_flags&0xffff; 11035763Smarc ttcompatsetflags(tp, &term); 11135763Smarc return (ttioctl(tp, com == TIOCSETP ? TIOCSETAF : TIOCSETA, 11235763Smarc &term, flag)); 11335763Smarc } 11435763Smarc 11535763Smarc case TIOCGETC: { 11635763Smarc struct tchars *tc = (struct tchars *)data; 11735763Smarc register u_char *cc = tp->t_cc; 11835763Smarc 11935763Smarc tc->t_intrc = cc[VINTR]; 12035763Smarc tc->t_quitc = cc[VQUIT]; 12135763Smarc tc->t_startc = cc[VSTART]; 12235763Smarc tc->t_stopc = cc[VSTOP]; 12335763Smarc tc->t_eofc = cc[VEOF]; 12435763Smarc tc->t_brkc = cc[VEOL]; 12535763Smarc break; 12635763Smarc } 12735763Smarc case TIOCSETC: { 12835763Smarc struct tchars *tc = (struct tchars *)data; 12935763Smarc register u_char *cc = tp->t_cc; 13035763Smarc 13135763Smarc cc[VINTR] = tc->t_intrc; 13235763Smarc cc[VQUIT] = tc->t_quitc; 13335763Smarc cc[VSTART] = tc->t_startc; 13435763Smarc cc[VSTOP] = tc->t_stopc; 13535763Smarc cc[VEOF] = tc->t_eofc; 13635763Smarc cc[VEOL] = tc->t_brkc; 13735763Smarc if (tc->t_brkc == -1) 13835811Smarc cc[VEOL2] = _POSIX_VDISABLE; 13935763Smarc break; 14035763Smarc } 14135763Smarc case TIOCSLTC: { 14235763Smarc struct ltchars *ltc = (struct ltchars *)data; 14335763Smarc register u_char *cc = tp->t_cc; 14435763Smarc 14535763Smarc cc[VSUSP] = ltc->t_suspc; 14635763Smarc cc[VDSUSP] = ltc->t_dsuspc; 14735763Smarc cc[VREPRINT] = ltc->t_rprntc; 14843091Smarc cc[VDISCARD] = ltc->t_flushc; 14935763Smarc cc[VWERASE] = ltc->t_werasc; 15035763Smarc cc[VLNEXT] = ltc->t_lnextc; 15135763Smarc break; 15235763Smarc } 15335763Smarc case TIOCGLTC: { 15435763Smarc struct ltchars *ltc = (struct ltchars *)data; 15535763Smarc register u_char *cc = tp->t_cc; 15635763Smarc 15735763Smarc ltc->t_suspc = cc[VSUSP]; 15835763Smarc ltc->t_dsuspc = cc[VDSUSP]; 15935763Smarc ltc->t_rprntc = cc[VREPRINT]; 16043091Smarc ltc->t_flushc = cc[VDISCARD]; 16135763Smarc ltc->t_werasc = cc[VWERASE]; 16235763Smarc ltc->t_lnextc = cc[VLNEXT]; 16335763Smarc break; 16435763Smarc } 16535763Smarc case TIOCLBIS: 16635763Smarc case TIOCLBIC: 16735763Smarc case TIOCLSET: { 16835763Smarc struct termios term; 16935763Smarc 17035763Smarc term = tp->t_termios; 17135763Smarc if (com == TIOCLSET) 17235811Smarc tp->t_flags = (tp->t_flags&0xffff) | *(int *)data<<16; 17335763Smarc else { 17435763Smarc tp->t_flags = 17535763Smarc (ttcompatgetflags(tp)&0xffff0000)|(tp->t_flags&0xffff); 17635763Smarc if (com == TIOCLBIS) 17735811Smarc tp->t_flags |= *(int *)data<<16; 17835763Smarc else 17935811Smarc tp->t_flags &= ~(*(int *)data<<16); 18035763Smarc } 18135763Smarc ttcompatsetlflags(tp, &term); 18235763Smarc return (ttioctl(tp, TIOCSETA, &term, flag)); 18335763Smarc } 18435763Smarc case TIOCLGET: 18535811Smarc *(int *)data = ttcompatgetflags(tp)>>16; 18635811Smarc if (ttydebug) 18735811Smarc printf("CLGET: returning %x\n", *(int *)data); 18835763Smarc break; 18935811Smarc 19039567Smarc case OTIOCGETD: 19135811Smarc *(int *)data = tp->t_line ? tp->t_line : 2; 19235811Smarc break; 19335811Smarc 19439567Smarc case OTIOCSETD: { 19535811Smarc int ldisczero = 0; 19635811Smarc 197*46426Smarc return (ttioctl(tp, TIOCSETD, 19835811Smarc *(int *)data == 2 ? (caddr_t)&ldisczero : data, flag)); 199*46426Smarc } 20041994Smckusick 20141994Smckusick case OTIOCCONS: 20241994Smckusick *(int *)data = 1; 203*46426Smarc return (ttioctl(tp, TIOCCONS, data, flag)); 20435811Smarc 20535763Smarc default: 20635763Smarc return (-1); 20735763Smarc } 208*46426Smarc return (0); 20935763Smarc } 21035763Smarc 21135763Smarc ttcompatgetflags(tp) 21235763Smarc register struct tty *tp; 21335763Smarc { 21435763Smarc register long iflag = tp->t_iflag; 21535763Smarc register long lflag = tp->t_lflag; 21635763Smarc register long oflag = tp->t_oflag; 21735763Smarc register long cflag = tp->t_cflag; 21835763Smarc register flags = 0; 21935763Smarc 22035763Smarc if (iflag&IXOFF) 22135763Smarc flags |= TANDEM; 22235763Smarc if (iflag&ICRNL || oflag&ONLCR) 22335763Smarc flags |= CRMOD; 22435763Smarc if (cflag&PARENB) { 22535763Smarc if (iflag&INPCK) { 22635763Smarc if (cflag&PARODD) 22735763Smarc flags |= ODDP; 22835763Smarc else 22935763Smarc flags |= EVENP; 23035763Smarc } else 23135763Smarc flags |= EVENP | ODDP; 23235763Smarc } else { 23335763Smarc if ((tp->t_flags&LITOUT) && !(oflag&OPOST)) 23435763Smarc flags |= LITOUT; 23535763Smarc if (tp->t_flags&PASS8) 23635763Smarc flags |= PASS8; 23735763Smarc } 23835763Smarc 23935763Smarc if ((lflag&ICANON) == 0) { 24035763Smarc /* fudge */ 24135763Smarc if (iflag&IXON || lflag&ISIG || lflag&IEXTEN || cflag&PARENB) 24235763Smarc flags |= CBREAK; 24335763Smarc else 24435763Smarc flags |= RAW; 24535763Smarc } 24635763Smarc if (oflag&OXTABS) 24735763Smarc flags |= XTABS; 24835763Smarc if (lflag&ECHOE) 24935811Smarc flags |= CRTERA|CRTBS; 25035763Smarc if (lflag&ECHOKE) 25135811Smarc flags |= CRTKIL|CRTBS; 25235763Smarc if (lflag&ECHOPRT) 25335763Smarc flags |= PRTERA; 25435763Smarc if (lflag&ECHOCTL) 25535763Smarc flags |= CTLECH; 25635763Smarc if ((iflag&IXANY) == 0) 25735763Smarc flags |= DECCTQ; 25835763Smarc flags |= lflag&(ECHO|MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 25935811Smarc if (ttydebug) 26035811Smarc printf("getflags: %x\n", flags); 26135763Smarc return (flags); 26235763Smarc } 26335763Smarc 26435763Smarc ttcompatsetflags(tp, t) 26535763Smarc register struct tty *tp; 26635763Smarc register struct termios *t; 26735763Smarc { 26835763Smarc register flags = tp->t_flags; 26935763Smarc register long iflag = t->c_iflag; 27035763Smarc register long oflag = t->c_oflag; 27135763Smarc register long lflag = t->c_lflag; 27235763Smarc register long cflag = t->c_cflag; 27335763Smarc 27435763Smarc if (flags & RAW) { 27535763Smarc iflag &= IXOFF; 27635763Smarc oflag &= ~OPOST; 27738925Skarels lflag &= ~(ECHOCTL|ISIG|ICANON|IEXTEN); 27835763Smarc } else { 27938925Skarels iflag |= BRKINT|IXON|IMAXBEL; 28035763Smarc oflag |= OPOST; 281*46426Smarc lflag |= ISIG|IEXTEN|ECHOCTL; /* XXX was echoctl on ? */ 28235763Smarc if (flags & XTABS) 28335763Smarc oflag |= OXTABS; 28435763Smarc else 28535763Smarc oflag &= ~OXTABS; 28635763Smarc if (flags & CBREAK) 28735763Smarc lflag &= ~ICANON; 28835763Smarc else 28935763Smarc lflag |= ICANON; 29035763Smarc if (flags&CRMOD) { 29135763Smarc iflag |= ICRNL; 29235763Smarc oflag |= ONLCR; 29335763Smarc } else { 29435763Smarc iflag &= ~ICRNL; 29535763Smarc oflag &= ~ONLCR; 29635763Smarc } 29735763Smarc } 29835763Smarc if (flags&ECHO) 29935763Smarc lflag |= ECHO; 30035763Smarc else 30135763Smarc lflag &= ~ECHO; 30235763Smarc 30335763Smarc if (flags&(RAW|LITOUT|PASS8)) { 30435763Smarc cflag &= ~(CSIZE|PARENB); 30535763Smarc cflag |= CS8; 30635763Smarc if ((flags&(RAW|PASS8)) == 0) 30735763Smarc iflag |= ISTRIP; 308*46426Smarc else 309*46426Smarc iflag &= ~ISTRIP; 31035763Smarc } else { 31135763Smarc cflag &= ~CSIZE; 31235763Smarc cflag |= CS7|PARENB; 313*46426Smarc iflag |= ISTRIP; 31435763Smarc } 31535763Smarc if ((flags&(EVENP|ODDP)) == EVENP) { 31635763Smarc iflag |= INPCK; 31735763Smarc cflag &= ~PARODD; 31835763Smarc } else if ((flags&(EVENP|ODDP)) == ODDP) { 31935763Smarc iflag |= INPCK; 32035763Smarc cflag |= PARODD; 32135763Smarc } else 32235763Smarc iflag &= ~INPCK; 32335763Smarc if (flags&LITOUT) 32435763Smarc oflag &= ~OPOST; /* move earlier ? */ 32535763Smarc if (flags&TANDEM) 32635763Smarc iflag |= IXOFF; 32735763Smarc else 32835763Smarc iflag &= ~IXOFF; 32935763Smarc t->c_iflag = iflag; 33035763Smarc t->c_oflag = oflag; 33135763Smarc t->c_lflag = lflag; 33235763Smarc t->c_cflag = cflag; 33335763Smarc } 33435763Smarc 33535763Smarc ttcompatsetlflags(tp, t) 33635763Smarc register struct tty *tp; 33735763Smarc register struct termios *t; 33835763Smarc { 33935763Smarc register flags = tp->t_flags; 34035763Smarc register long iflag = t->c_iflag; 34135763Smarc register long oflag = t->c_oflag; 34235763Smarc register long lflag = t->c_lflag; 34335763Smarc register long cflag = t->c_cflag; 34435811Smarc 34535763Smarc if (flags&CRTERA) 34635763Smarc lflag |= ECHOE; 34735763Smarc else 34835811Smarc lflag &= ~ECHOE; 34935763Smarc if (flags&CRTKIL) 35035763Smarc lflag |= ECHOKE; 35135763Smarc else 35235763Smarc lflag &= ~ECHOKE; 35335763Smarc if (flags&PRTERA) 35435763Smarc lflag |= ECHOPRT; 35535763Smarc else 35635763Smarc lflag &= ~ECHOPRT; 35735763Smarc if (flags&CTLECH) 35835763Smarc lflag |= ECHOCTL; 35935763Smarc else 36035763Smarc lflag &= ~ECHOCTL; 36135763Smarc if ((flags&DECCTQ) == 0) 36235763Smarc lflag |= IXANY; 36335763Smarc else 36435763Smarc lflag &= ~IXANY; 36535763Smarc lflag &= ~(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 36635763Smarc lflag |= flags&(MDMBUF|TOSTOP|FLUSHO|NOHANG|PENDIN|NOFLSH); 36735763Smarc if (flags&(LITOUT|PASS8)) { 36835763Smarc iflag &= ~ISTRIP; 36935763Smarc cflag &= ~(CSIZE|PARENB); 37035763Smarc cflag |= CS8; 37135763Smarc if (flags&LITOUT) 37235763Smarc oflag &= ~OPOST; 37335763Smarc if ((flags&(PASS8|RAW)) == 0) 37435763Smarc iflag |= ISTRIP; 37535763Smarc } else if ((flags&RAW) == 0) { 37635763Smarc cflag &= ~CSIZE; 37735763Smarc cflag |= CS7|PARENB; 37835763Smarc oflag |= OPOST; 37935763Smarc } 38035763Smarc t->c_iflag = iflag; 38135763Smarc t->c_oflag = oflag; 38235763Smarc t->c_lflag = lflag; 38335763Smarc t->c_cflag = cflag; 38435763Smarc } 38535763Smarc #endif /* COMPAT_43 */ 386