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