1: #
2: /*
3: */
4:
5: /*
6: * DH-11 driver
7: * This driver calls on the DHDM driver.
8: * If the DH has no DM11-BB, then the latter will
9: * be fake. To insure loading of the correct DM code,
10: * lib2 should have dhdm.o, dh.o and dhfdm.o in that order.
11: */
12:
13: #include "../param.h"
14: #include "../conf.h"
15: #include "../user.h"
16: #include "../tty.h"
17: #include "../proc.h"
18:
19: #define DHADDR 0160020
20: #define NDH11 16 /* number of lines */
21: #define DHNCH 8 /* max number of DMA chars */
22:
23: struct tty dh11[NDH11];
24: /*
25: * Place from which to do DMA on output
26: */
27: char dh_clist[NDH11][DHNCH];
28:
29: /*
30: * Used to communicate the number of lines to the DM
31: */
32: int ndh11 NDH11;
33:
34: /*
35: * Hardware control bits
36: */
37: #define BITS6 01
38: #define BITS7 02
39: #define BITS8 03
40: #define TWOSB 04
41: #define PENABLE 020
42: /* DEC manuals incorrectly say this bit causes generation of even parity. */
43: #define OPAR 040
44: #define HDUPLX 040000
45:
46: #define IENABLE 030100
47: #define PERROR 010000
48: #define FRERROR 020000
49: #define XINT 0100000
50: #define SSPEED 7 /* standard speed: 300 baud */
51:
52: /*
53: * Software copy of last dhbar
54: */
55: int dhsar;
56:
57: struct dhregs {
58: int dhcsr;
59: int dhnxch;
60: int dhlpr;
61: int dhcar;
62: int dhbcr;
63: int dhbar;
64: int dhbreak;
65: int dhsilo;
66: };
67:
68: /*
69: * Open a DH11 line.
70: */
71: dhopen(dev, flag)
72: {
73: register struct tty *tp;
74: extern dhstart();
75:
76: if (dev.d_minor >= NDH11) {
77: u.u_error = ENXIO;
78: return;
79: }
80: tp = &dh11[dev.d_minor];
81: tp->t_addr = dhstart;
82: tp->t_dev = dev;
83: DHADDR->dhcsr =| IENABLE;
84: tp->t_state =| WOPEN|SSTART;
85: if ((tp->t_state&ISOPEN) == 0) {
86: tp->t_erase = CERASE;
87: tp->t_kill = CKILL;
88: tp->t_speeds = SSPEED | (SSPEED<<8);
89: tp->t_flags = ODDP|EVENP|ECHO;
90: dhparam(tp);
91: }
92: dmopen(dev);
93: tp->t_state =& ~WOPEN;
94: tp->t_state =| ISOPEN;
95: if (u.u_procp->p_ttyp == 0)
96: u.u_procp->p_ttyp = tp;
97: }
98:
99: /*
100: * Close a DH11 line.
101: */
102: dhclose(dev)
103: {
104: register struct tty *tp;
105:
106: tp = &dh11[dev.d_minor];
107: dmclose(dev);
108: tp->t_state =& (CARR_ON|SSTART);
109: wflushtty(tp);
110: }
111:
112: /*
113: * Read from a DH11 line.
114: */
115: dhread(dev)
116: {
117: ttread(&dh11[dev.d_minor]);
118: }
119:
120: /*
121: * write on a DH11 line
122: */
123: dhwrite(dev)
124: {
125: ttwrite(&dh11[dev.d_minor]);
126: }
127:
128: /*
129: * DH11 receiver interrupt.
130: */
131: dhrint()
132: {
133: register struct tty *tp;
134: register int c;
135:
136: while ((c = DHADDR->dhnxch) < 0) { /* char. present */
137: tp = &dh11[(c>>8)&017];
138: if (tp >= &dh11[NDH11])
139: continue;
140: if((tp->t_state&ISOPEN)==0 || (c&PERROR)) {
141: wakeup(tp);
142: continue;
143: }
144: if (c&FRERROR) /* break */
145: if (tp->t_flags&RAW)
146: c = 0; /* null (for getty) */
147: else
148: c = 0177; /* DEL (intr) */
149: ttyinput(c, tp);
150: }
151: }
152:
153: /*
154: * stty/gtty for DH11
155: */
156: dhsgtty(dev, av)
157: int *av;
158: {
159: register struct tty *tp;
160: register r;
161:
162: tp = &dh11[dev.d_minor];
163: if (ttystty(tp, av))
164: return;
165: dhparam(tp);
166: }
167:
168: /*
169: * Set parameters from open or stty into the DH hardware
170: * registers.
171: */
172: dhparam(atp)
173: struct tty *atp;
174: {
175: register struct tty *tp;
176: register int lpr;
177:
178: tp = atp;
179: spl5();
180: DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
181: /*
182: * Hang up line?
183: */
184: if (tp->t_speeds.lobyte==0) {
185: tp->t_flags =| HUPCL;
186: dmclose(tp->t_dev);
187: return;
188: }
189: lpr = (tp->t_speeds.hibyte<<10) | (tp->t_speeds.lobyte<<6);
190: if (tp->t_speeds.lobyte == 4) /* 134.5 baud */
191: lpr =| BITS6|PENABLE|HDUPLX; else
192: if (tp->t_flags&EVENP)
193: if (tp->t_flags&ODDP)
194: lpr =| BITS8; else
195: lpr =| BITS7|PENABLE; else
196: lpr =| BITS7|OPAR|PENABLE;
197: if (tp->t_speeds.lobyte == 3) /* 110 baud */
198: lpr =| TWOSB;
199: DHADDR->dhlpr = lpr;
200: spl0();
201: }
202:
203: /*
204: * DH11 transmitter interrupt.
205: * Restart each line which used to be active but has
206: * terminated transmission since the last interrupt.
207: */
208: dhxint()
209: {
210: register struct tty *tp;
211: register ttybit, bar;
212:
213: bar = dhsar & ~DHADDR->dhbar;
214: DHADDR->dhcsr =& ~XINT;
215: ttybit = 1;
216: for (tp = dh11; bar; tp++) {
217: if(bar&ttybit) {
218: dhsar =& ~ttybit;
219: bar =& ~ttybit;
220: tp->t_state =& ~BUSY;
221: dhstart(tp);
222: }
223: ttybit =<< 1;
224: }
225: }
226:
227: /*
228: * Start (restart) transmission on the given DH11 line.
229: */
230: dhstart(atp)
231: struct tty *atp;
232: {
233: extern ttrstrt();
234: register c, nch;
235: register struct tty *tp;
236: int sps;
237: char *cp;
238:
239: sps = PS->integ;
240: spl5();
241: tp = atp;
242: /*
243: * If it's currently active, or delaying,
244: * no need to do anything.
245: */
246: if (tp->t_state&(TIMEOUT|BUSY))
247: goto out;
248: /*
249: * t_char is a delay indicator which may have been
250: * left over from the last start.
251: * Arrange for the delay.
252: */
253: if (c = tp->t_char) {
254: tp->t_char = 0;
255: timeout(ttrstrt, tp, (c&0177)+6);
256: tp->t_state =| TIMEOUT;
257: goto out;
258: }
259: cp = dh_clist[tp->t_dev.d_minor];
260: nch = 0;
261: /*
262: * Copy DHNCH characters, or up to a delay indicator,
263: * to the DMA area.
264: */
265: while (nch > -DHNCH && (c = getc(&tp->t_outq))>=0) {
266: if (c >= 0200) {
267: tp->t_char = c;
268: break;
269: }
270: *cp++ = c;
271: nch--;
272: }
273: /*
274: * If the writer was sleeping on output overflow,
275: * wake him when low tide is reached.
276: */
277: if (tp->t_outq.c_cc<=TTLOWAT && tp->t_state&ASLEEP) {
278: tp->t_state =& ~ASLEEP;
279: wakeup(&tp->t_outq);
280: }
281: /*
282: * If any characters were set up, start transmission;
283: * otherwise, check for possible delay.
284: */
285: if (nch) {
286: DHADDR->dhcsr.lobyte = tp->t_dev.d_minor | IENABLE;
287: DHADDR->dhcar = cp+nch;
288: DHADDR->dhbcr = nch;
289: c = 1<<tp->t_dev.d_minor;
290: DHADDR->dhbar =| c;
291: dhsar =| c;
292: tp->t_state =| BUSY;
293: } else if (c = tp->t_char) {
294: tp->t_char = 0;
295: timeout(ttrstrt, tp, (c&0177)+6);
296: tp->t_state =| TIMEOUT;
297: }
298: out:
299: PS->integ = sps;
300: }
Defined functions
Defined variables
NDH11
defined in line
32;
never used
dh11
defined in line
23; used 8 times
dhsar
defined in line
55; used 3 times
ndh11
defined in line
32;
never used
Defined struct's
Defined macros
BITS6
defined in line
37; used 1 times
BITS7
defined in line
38; used 2 times
BITS8
defined in line
39; used 1 times
DHADDR
defined in line
19; used 10 times
DHNCH
defined in line
21; used 2 times
NDH11
defined in line
20; used 4 times
OPAR
defined in line
43; used 1 times
TWOSB
defined in line
40; used 1 times
XINT
defined in line
49; used 1 times