1: /*
2: * DU-11 Synchronous interface driver
3: */
4:
5: #include "../h/param.h"
6: #include "../h/systm.h"
7: #include "../h/dir.h"
8: #include "../h/user.h"
9: #include "../h/buf.h"
10:
11: /* device registers */
12: struct dureg {
13: int rxcsr, rxdbuf;
14: #define parcsr rxdbuf
15: int txcsr, txdbuf;
16: };
17:
18: struct du {
19: struct dureg *du_addr;
20: int du_state;
21: struct proc *du_proc;
22: struct buf *du_buf;
23: caddr_t du_bufb;
24: caddr_t du_bufp;
25: int du_nxmit;
26: int du_timer;
27: } du[] = {
28: { (struct dureg *) 0160110 },
29: };
30:
31: #define NDU (sizeof(du)/sizeof(du[0]))
32:
33: #define DONE 0200
34: #define IE 0100
35: #define SIE 040
36: #define CTS 020000
37: #define CARRIER 010000
38: #define RCVACT 04000
39: #define DSR 01000
40: #define STRIP 0400
41: #define SCH 020
42: #define RTS 04
43: #define DTR 02
44: #define MR 0400
45: #define SEND 020
46: #define HALF 010
47:
48: #define READ 0
49: #define WRITE 1
50: #define PWRIT 2
51:
52: #define DUPRI (PZERO+1)
53:
54: duopen(dev)
55: register dev;
56: {
57: int dutimeout();
58: register struct du *dp;
59: register struct dureg *lp;
60:
61: dev = minor(dev);
62: if (dev >= NDU ||
63: ((dp = &du[dev])->du_proc!=NULL && dp->du_proc!=u.u_procp)) {
64: u.u_error = ENXIO;
65: return;
66: }
67: dp->du_proc = u.u_procp;
68: lp = dp->du_addr;
69: if (dp->du_buf==NULL) {
70: dp->du_buf = geteblk();
71: dp->du_bufb = dp->du_buf->b_un.b_addr;
72: dp->du_state = WRITE;
73: lp->txcsr = MR;
74: lp->parcsr = 035026; /* Sync Int, 7 bits, even parity, sync=026 */
75: timeout(dutimeout, (caddr_t)dp, HZ);
76: duturn(dp);
77: }
78: }
79:
80: duclose(dev)
81: {
82: register struct du *dp;
83: register struct dureg *lp;
84:
85: dp = &du[minor(dev)];
86: lp = dp->du_addr;
87: lp->rxcsr = 0;
88: lp->txcsr = 0;
89: dp->du_timer = 0;
90: dp->du_proc = 0;
91: if (dp->du_buf != NULL) {
92: brelse(dp->du_buf);
93: dp->du_buf = NULL;
94: }
95: }
96:
97: duread(dev)
98: {
99: register char *bp;
100: register struct du *dp;
101:
102: dp = &du[minor(dev)];
103: bp = dp->du_bufb;
104: for(;;) {
105: if(duwait(dev))
106: return;
107: if (dp->du_bufp > bp)
108: break;
109: spl6();
110: if (dp->du_timer <= 1) {
111: spl0();
112: return;
113: }
114: sleep((caddr_t)dp, DUPRI);
115: spl0();
116: }
117: u.u_offset = 0;
118: iomove(dp->du_bufb, (int)min(u.u_count, (unsigned)(dp->du_bufp-bp)), B_READ);
119: }
120:
121: duwrite(dev)
122: {
123: register struct du *dp;
124: register struct dureg *lp;
125:
126: dev = minor(dev);
127: dp = &du[dev];
128: if (u.u_count==0 || duwait(dev))
129: return;
130: dp->du_bufp = dp->du_bufb;
131: dp->du_state = PWRIT;
132: dp->du_addr->rxcsr &= ~SCH;
133: dp->du_addr->rxcsr = SIE|RTS|DTR;
134: if (u.u_count > BSIZE)
135: u.u_count = BSIZE;
136: dp->du_nxmit = u.u_count;
137: u.u_offset = 0;
138: iomove(dp->du_bufb, (int)u.u_count, B_WRITE);
139: lp = dp->du_addr;
140: dp->du_timer = 10;
141: spl6();
142: while((lp->rxcsr&CTS)==0)
143: sleep((caddr_t)dp, DUPRI);
144: if (dp->du_state != WRITE) {
145: dp->du_state = WRITE;
146: lp->txcsr = IE|SIE|SEND|HALF;
147: dustart(dev);
148: }
149: spl0();
150: }
151:
152: duwait(dev)
153: {
154: register struct du *dp;
155: register struct dureg *lp;
156:
157: dp = &du[minor(dev)];
158: lp = dp->du_addr;
159: for(;;) {
160: if ((lp->rxcsr&DSR)==0 || dp->du_buf==0) {
161: u.u_error = EIO;
162: return(1);
163: }
164: spl6();
165: if (dp->du_state==READ &&
166: ((lp->rxcsr&RCVACT)==0)) {
167: spl0();
168: return(0);
169: }
170: sleep((caddr_t)dp, DUPRI);
171: spl0();
172: }
173: }
174:
175: dustart(dev)
176: {
177: register struct du *dp;
178: register struct dureg *lp;
179:
180: dp = &du[minor(dev)];
181: lp = dp->du_addr;
182: dp->du_timer = 10;
183: if (dp->du_nxmit > 0) {
184: dp->du_nxmit--;
185: lp->txdbuf = *dp->du_bufp++;
186: } else {
187: duturn(dp);
188: }
189: }
190:
191: durint(dev)
192: {
193: register struct du *dp;
194: register c, s;
195: int dustat;
196:
197: dp = &du[minor(dev)];
198: dustat = dp->du_addr->rxcsr;
199: if(dustat<0) {
200: if((dustat&CARRIER)==0 && dp->du_state==READ)
201: duturn(dp);
202: else
203: wakeup((caddr_t)dp);
204: } else
205: if(dustat&DONE) {
206: dp->du_addr->rxcsr = IE|SIE|SCH|DTR;
207: c = s = dp->du_addr->rxdbuf;
208: c &= 0177;
209: if(s<0)
210: c |= 0200;
211: if (dp->du_bufp < dp->du_bufb+BSIZE)
212: *dp->du_bufp++ = c;
213: }
214: }
215:
216: duxint(dev)
217: {
218: register struct du *dp;
219: register struct dureg *lp;
220: register int dustat;
221:
222: dp = &du[minor(dev)];
223: lp = dp->du_addr;
224: dustat = lp->txcsr;
225: if(dustat<0)
226: duturn(dp);
227: else if(dustat&DONE)
228: dustart(dev);
229: }
230:
231: duturn(dp)
232: register struct du *dp;
233: {
234: register struct dureg *lp;
235:
236: lp = dp->du_addr;
237: if (dp->du_state!=READ) {
238: dp->du_state = READ;
239: dp->du_timer = 10;
240: dp->du_bufp = dp->du_bufb;
241: }
242: lp->txcsr = HALF;
243: lp->rxcsr &= ~SCH;
244: lp->rxcsr = STRIP|IE|SIE|SCH|DTR;
245: wakeup((caddr_t)dp);
246: }
247:
248: dutimeout(dp)
249: register struct du *dp;
250: {
251: if (dp->du_timer == 0)
252: return;
253: if (--dp->du_timer == 0) {
254: duturn(dp);
255: dp->du_timer = 1;
256: }
257: timeout(dutimeout, (caddr_t)dp, HZ);
258: }
Defined functions
Defined variables
du
defined in line
27; used 10 times
Defined struct's
du
defined in line
18; used 20 times
dureg
defined in line
12; used 18 times
Defined macros
CTS
defined in line
36; used 1 times
DONE
defined in line
33; used 2 times
DSR
defined in line
39; used 1 times
DTR
defined in line
43; used 3 times
DUPRI
defined in line
52; used 3 times
HALF
defined in line
46; used 2 times
IE
defined in line
34; used 3 times
MR
defined in line
44; used 1 times
NDU
defined in line
31; used 1 times
PWRIT
defined in line
50; used 1 times
READ
defined in line
48; used 4 times
RTS
defined in line
42; used 1 times
SCH
defined in line
41; used 4 times
SEND
defined in line
45; used 1 times
SIE
defined in line
35; used 4 times
STRIP
defined in line
40; used 1 times
WRITE
defined in line
49; used 3 times