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