xref: /csrg-svn/sys/kern/tty_compat.c (revision 38925)
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