|
|
1.1 root 1: /* dhdm.c 3.1 9/14/80 */
2:
3: /*
4: * DM-BB driver
5: */
6: #include "../h/param.h"
7: #include "../h/tty.h"
8: #include "../h/conf.h"
9: #include "../h/map.h"
10: #include "../h/pte.h"
11: #include "../h/uba.h"
12:
13: #define DMADDR ((struct device *)(UBA0_DEV+0170500))
14:
15: struct tty dh11[];
16: int ndh11; /* Set by dh.c to number of lines */
17:
18: #define DONE 0200
19: #define SCENABL 040
20: #define CLSCAN 01000
21: #define TURNON 03 /* CD lead, line enable */
22: #define RQS 04 /* request to send */
23: #define TURNOFF 1 /* line enable only */
24: #define CARRIER 0100
25:
26: struct device
27: {
28: short dmcsr;
29: short dmlstat;
30: short junk[2];
31: };
32:
33: /*
34: * Turn on the line associated with the (DH) device dev.
35: */
36: dmopen(dev)
37: {
38: register struct tty *tp;
39: register struct device *addr;
40: register d;
41:
42: d = minor(dev);
43: tp = &dh11[d];
44: addr = DMADDR;
45: addr += d>>4;
46: spl5();
47: addr->dmcsr &= ~SCENABL;
48: while (addr->dmcsr & SCBUSY)
49: ;
50: addr->dmcsr = d&017;
51: addr->dmlstat = TURNON;
52: if (addr->dmlstat&CARRIER)
53: tp->t_state |= CARR_ON;
54: addr->dmcsr = IENABLE|SCENABL;
55: while ((tp->t_state&CARR_ON)==0)
56: sleep((caddr_t)&tp->t_rawq, TTIPRI);
57: spl0();
58: }
59:
60: /*
61: * Dump control bits into the DM registers.
62: */
63: dmctl(dev, bits, how)
64: {
65: register struct device *addr;
66: register d, s;
67:
68: d = minor(dev);
69: if (d >= ndh11)
70: return;
71: addr = DMADDR;
72: addr += d>>4;
73: s = spl5();
74: addr->dmcsr &= ~SCENABL;
75: while (addr->dmcsr & SCBUSY)
76: ;
77: addr->dmcsr = d&017;
78: switch(how) {
79: case DMSET:
80: addr->dmlstat = bits;
81: break;
82: case DMBIS:
83: addr->dmlstat |= bits;
84: break;
85: case DMBIC:
86: addr->dmlstat &= ~bits;
87: break;
88: }
89: addr->dmcsr = IENABLE|SCENABL;
90: splx(s);
91: }
92:
93: /*
94: * DM11 interrupt.
95: * Mainly, deal with carrier transitions.
96: */
97: dmint(dev)
98: {
99: register struct tty *tp;
100: register struct device *addr;
101: register d;
102:
103: d = minor(dev);
104: addr = DMADDR;
105: addr += d;
106: if (addr->dmcsr&DONE && addr->dmcsr&CARRTRANS) {
107: tp = &dh11[(d<<4)+(addr->dmcsr&017)];
108: if (tp < &dh11[ndh11]) {
109: wakeup((caddr_t)&tp->t_rawq);
110: if ((tp->t_state&WOPEN)==0 &&
111: (tp->t_local&LMDMBUF)) {
112: if (addr->dmlstat & CARRIER) {
113: tp->t_state &= ~TTSTOP;
114: ttstart(tp);
115: } else if ((tp->t_state&TTSTOP) == 0) {
116: tp->t_state |= TTSTOP;
117: dhstop(tp, 0);
118: }
119: else if ((addr->dmlstat&CARRIER)==0) {
120: if ((tp->t_state&WOPEN)==0 &&
121: (tp->t_local&LNOHANG)==0) {
122: gsignal(tp->t_pgrp, SIGHUP);
123: gsignal(tp->t_pgrp, SIGCONT);
124: addr->dmlstat = 0;
125: flushtty(tp, FREAD|FWRITE);
126: }
127: tp->t_state &= ~CARR_ON;
128: } else
129: tp->t_state |= CARR_ON;
130: }
131: addr->dmcsr = IENABLE|SCENABL;
132: }
133: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.