xref: /original-bsd/sys/vax/vax/cons.c (revision 9087ff44)
1 /*
2  * Copyright (c) 1982 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)cons.c	6.3 (Berkeley) 06/08/85
7  */
8 
9 /*
10  * VAX console driver (and floppy interface)
11  */
12 #include "param.h"
13 #include "conf.h"
14 #include "dir.h"
15 #include "user.h"
16 #include "proc.h"
17 #include "ioctl.h"
18 #include "tty.h"
19 #include "systm.h"
20 #include "uio.h"
21 
22 #include "cpu.h"
23 #include "cons.h"
24 #include "mtpr.h"
25 
26 struct	tty cons;
27 int	cnstart();
28 int	ttrstrt();
29 char	partab[];
30 
31 /*ARGSUSED*/
32 cnopen(dev, flag)
33 	dev_t dev;
34 {
35 	register struct tty *tp = &cons;
36 
37 	tp->t_oproc = cnstart;
38 	if ((tp->t_state&TS_ISOPEN) == 0) {
39 		ttychars(tp);
40 		tp->t_state = TS_ISOPEN|TS_CARR_ON;
41 		tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
42 	}
43 	if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
44 		return (EBUSY);
45 	mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
46 	mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
47 	return ((*linesw[tp->t_line].l_open)(dev, tp));
48 }
49 
50 /*ARGSUSED*/
51 cnclose(dev)
52 	dev_t dev;
53 {
54 	register struct tty *tp = &cons;
55 
56 	(*linesw[tp->t_line].l_close)(tp);
57 	ttyclose(tp);
58 }
59 
60 /*ARGSUSED*/
61 cnread(dev, uio)
62 	dev_t dev;
63 	struct uio *uio;
64 {
65 	register struct tty *tp = &cons;
66 
67 	return ((*linesw[tp->t_line].l_read)(tp, uio));
68 }
69 
70 /*ARGSUSED*/
71 cnwrite(dev, uio)
72 	dev_t dev;
73 	struct uio *uio;
74 {
75 	register struct tty *tp = &cons;
76 
77 	return ((*linesw[tp->t_line].l_write)(tp, uio));
78 }
79 
80 /*
81  * Got a level-20 receive interrupt -
82  * the LSI wants to give us a character.
83  * Catch the character, and see who it goes to.
84  */
85 /*ARGSUSED*/
86 cnrint(dev)
87 	dev_t dev;
88 {
89 	register int c;
90 	register struct tty *tp;
91 
92 	c = mfpr(RXDB);
93 	if (c&RXDB_ID) {
94 #if VAX780
95 		if (cpu == VAX_780)
96 			cnrfl(c);
97 #endif
98 		return;
99 	}
100 	tp = &cons;
101 	(*linesw[tp->t_line].l_rint)(c, tp);
102 }
103 
104 /*ARGSUSED*/
105 cnioctl(dev, cmd, addr, flag)
106 	dev_t dev;
107 	caddr_t addr;
108 {
109 	register struct tty *tp = &cons;
110 	int error;
111 
112 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
113 	if (error >= 0)
114 		return (error);
115 	error = ttioctl(tp, cmd, addr, flag);
116 	if (error < 0)
117 		error = ENOTTY;
118 	return (error);
119 }
120 
121 int	consdone = 1;
122 /*
123  * Got a level-20 transmission interrupt -
124  * the LSI wants another character.  First,
125  * see if we can send something to the typewriter.
126  * If not, try the floppy.
127  */
128 /*ARGSUSED*/
129 cnxint(dev)
130 	dev_t dev;
131 {
132 	register struct tty *tp = &cons;
133 
134 	consdone++;
135 	tp->t_state &= ~TS_BUSY;
136 	if (tp->t_line)
137 		(*linesw[tp->t_line].l_start)(tp);
138 	else
139 		cnstart(tp);
140 #if VAX780
141 	if (cpu==VAX_780 && (tp->t_state & TS_BUSY) == 0)
142 		conxfl();
143 #endif
144 }
145 
146 cnstart(tp)
147 	register struct tty *tp;
148 {
149 	register int c, s;
150 
151 	s = spl5();
152 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
153 		goto out;
154 	if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
155 		if (tp->t_state&TS_ASLEEP) {
156 			tp->t_state &= ~TS_ASLEEP;
157 			wakeup((caddr_t)&tp->t_outq);
158 		}
159 		if (tp->t_wsel) {
160 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
161 			tp->t_wsel = 0;
162 			tp->t_state &= ~TS_WCOLL;
163 		}
164 	}
165 	if (tp->t_outq.c_cc == 0)
166 		goto out;
167 	if (consdone == 0)
168 		return;
169 	c = getc(&tp->t_outq);
170 	if (tp->t_flags&(RAW|LITOUT))
171 		mtpr(TXDB, c&0xff);
172 	else if (c <= 0177)
173 		mtpr(TXDB, (c | (partab[c]&0200))&0xff);
174 	else {
175 		timeout(ttrstrt, (caddr_t)tp, (c&0177));
176 		tp->t_state |= TS_TIMEOUT;
177 		goto out;
178 	}
179 	consdone = 0;
180 	tp->t_state |= TS_BUSY;
181 out:
182 	splx(s);
183 }
184 
185 /*
186  * Print a character on console.
187  * Attempts to save and restore device
188  * status.
189  */
190 cnputc(c)
191 	register int c;
192 {
193 	register int s, timo;
194 
195 	timo = 30000;
196 	/*
197 	 * Try waiting for the console tty to come ready,
198 	 * otherwise give up after a reasonable time.
199 	 */
200 	while ((mfpr(TXCS)&TXCS_RDY) == 0)
201 		if(--timo == 0)
202 			break;
203 	if (c == 0)
204 		return;
205 	s = mfpr(TXCS);
206 	mtpr(TXCS, 0);
207 	mtpr(TXDB, c&0xff);
208 	if (c == '\n')
209 		cnputc('\r');
210 	cnputc(0);
211 	mtpr(TXCS, s);
212 }
213