Commit | Line | Data |
---|---|---|
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 | ||
34 | struct tty cons; | |
35 | int cnstart(); | |
36 | int ttrstrt(); | |
37 | char partab[]; | |
38 | ||
39 | /*ARGSUSED*/ | |
40 | cnopen(dev, flag) | |
41 | dev_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*/ | |
63 | cnclose(dev) | |
64 | dev_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*/ | |
74 | cnread(dev) | |
75 | dev_t dev; | |
76 | { | |
77 | register struct tty *tp; | |
78 | ||
79 | tp = &cons; | |
80 | (*linesw[tp->t_line].l_read)(tp); | |
81 | } | |
82 | ||
83 | /*ARGSUSED*/ | |
84 | cnwrite(dev) | |
85 | dev_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*/ | |
99 | cnrint(dev) | |
100 | dev_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*/ | |
115 | cnioctl(dev, cmd, addr, flag) | |
116 | dev_t dev; | |
117 | caddr_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*/ | |
136 | cnxint(dev) | |
137 | dev_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 | ||
151 | cnstart(tp) | |
152 | register 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 | */ | |
192 | cnputc(c) | |
193 | register 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 | } |