xref: /original-bsd/sys/vax/vax/cons.c (revision d25e1985)
1 /*	cons.c	3.9	09/27/80	*/
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/tty.h"
11 #include "../h/systm.h"
12 #include "../h/cons.h"
13 #include "../h/mtpr.h"
14 
15 /*
16  * When running dz's using only SAE (silo alarm) on input
17  * it is necessary to call dzrint() at clock interrupt time.
18  * This is unsafe unless spl5()s in tty code are changed to
19  * spl6()s to block clock interrupts.  Note that the dh driver
20  * currently in use works the same way as the dz, even though
21  * we could try to more intelligently manage its silo.
22  * Thus don't take this out if you have no dz's unless you
23  * change clock.c and dhtimer().
24  */
25 #define	spl5	spl6
26 
27 #define	NL1	000400
28 #define	NL2	001000
29 #define	CR2	020000
30 #define	FF1	040000
31 #define	TAB1	002000
32 
33 struct	tty cons;
34 int	cnstart();
35 int	ttrstrt();
36 char	partab[];
37 
38 /*ARGSUSED*/
39 cnopen(dev, flag)
40 dev_t dev;
41 {
42 	register struct tty *tp;
43 
44 	tp = &cons;
45 	tp->t_oproc = cnstart;
46 	tp->t_iproc = NULL;
47 	if ((tp->t_state&ISOPEN) == 0) {
48 		ttychars(tp);
49 		tp->t_state = ISOPEN|CARR_ON;
50 		tp->t_flags = EVENP|ECHO|XTABS|CRMOD;
51 	}
52 	if (tp->t_state&XCLUDE && u.u_uid != 0) {
53 		u.u_error = EBUSY;
54 		return;
55 	}
56 	mtpr(RXCS, mfpr(RXCS)|RXCS_IE);
57 	mtpr(TXCS, mfpr(TXCS)|TXCS_IE);
58 	(*linesw[tp->t_line].l_open)(dev, tp);
59 }
60 
61 /*ARGSUSED*/
62 cnclose(dev)
63 dev_t dev;
64 {
65 	register struct tty *tp;
66 
67 	tp = &cons;
68 	(*linesw[tp->t_line].l_close)(tp);
69 	ttyclose(tp);
70 }
71 
72 /*ARGSUSED*/
73 cnread(dev)
74 dev_t dev;
75 {
76 	register struct tty *tp;
77 
78 	tp = &cons;
79 	(*linesw[tp->t_line].l_read)(tp);
80 }
81 
82 /*ARGSUSED*/
83 cnwrite(dev)
84 dev_t dev;
85 {
86 	register struct tty *tp;
87 
88 	tp = &cons;
89 	(*linesw[tp->t_line].l_write)(tp);
90 }
91 
92 /*
93  * Got a level-20 receive interrupt -
94  * the LSI wants to give us a character.
95  * Catch the character, and see who it goes to.
96  */
97 /*ARGSUSED*/
98 cnrint(dev)
99 dev_t dev;
100 {
101 	register int c;
102 	register struct tty *tp;
103 
104 	c = mfpr(RXDB);
105 	if (c&RXDB_ID) {
106 		cnrfl(c);
107 		return;
108 	}
109 	tp = &cons;
110 	(*linesw[tp->t_line].l_rint)(c, tp);
111 }
112 
113 /*ARGSUSED*/
114 cnioctl(dev, cmd, addr, flag)
115 dev_t dev;
116 caddr_t addr;
117 {
118 	register struct tty *tp;
119 
120 	tp = &cons;
121 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
122 	if (cmd == 0)
123 		return;
124 	if (ttioctl(cmd, tp, addr, dev, flag) == 0)
125 		u.u_error = ENOTTY;
126 }
127 
128 /*
129  * Got a level-20 transmission interrupt -
130  * the LSI wants another character.  First,
131  * see if we can send something to the typewriter.
132  * If not, try the floppy.
133  */
134 /*ARGSUSED*/
135 cnxint(dev)
136 dev_t dev;
137 {
138 	register struct tty *tp;
139 
140 	tp = &cons;
141 	tp->t_state &= ~BUSY;
142 	if (tp->t_line)
143 		(*linesw[tp->t_line].l_start)(tp);
144 	else
145 		cnstart(tp);
146 	if ((tp->t_state & BUSY) == 0)
147 		conxfl();
148 }
149 
150 cnstart(tp)
151 register struct tty *tp;
152 {
153 	register c;
154 	register s;
155 
156 	s = spl5();
157 	if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
158 		goto out;
159 	if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
160 		tp->t_state &= ~ASLEEP;
161 		if (tp->t_chan)
162 			mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
163 		else
164 			wakeup((caddr_t)&tp->t_outq);
165 	}
166 	if (tp->t_outq.c_cc == 0)
167 		goto out;
168 	if ((mfpr(TXCS)&TXCS_RDY) == 0)
169 		return;
170 	if ((c=getc(&tp->t_outq)) >= 0) {
171 		if (tp->t_flags&RAW)
172 			mtpr(TXDB, c&0xff);
173 		else if (c<=0177)
174 			mtpr(TXDB, (c | (partab[c]&0200))&0xff);
175 		else {
176 			timeout(ttrstrt, (caddr_t)tp, (c&0177));
177 			tp->t_state |= TIMEOUT;
178 			goto out;
179 		}
180 	}
181 	tp->t_state |= BUSY;
182     out:
183 	splx(s);
184 }
185 
186 /*
187  * Print a character on console.
188  * Attempts to save and restore device
189  * status.
190  */
191 cnputc(c)
192 register c;
193 {
194 	register s, timo;
195 
196 	timo = 30000;
197 	/*
198 	 * Try waiting for the console tty to come ready,
199 	 * otherwise give up after a reasonable time.
200 	 */
201 	while((mfpr(TXCS)&TXCS_RDY) == 0)
202 		if(--timo == 0)
203 			break;
204 	if(c == 0)
205 		return;
206 	s = mfpr(TXCS);
207 	mtpr(TXCS, 0);
208 	mtpr(TXDB, c&0xff);
209 	if(c == '\n')
210 		cnputc('\r');
211 	cnputc(0);
212 	mtpr(TXCS, s);
213 }
214