1: #
2: /*
3: */
4:
5: /*
6: * DP-11 Synchronous interface driver
7: * This driver is rather insensitive to the remote
8: * device it talks to, which is to say most of the protocol
9: * must be supplied by the calling program.
10: * Exceptions: parity is even; 7 data bits per character;
11: * max. of 512 characters per record; 10 second timeout
12: * on waiting to receive; half-duplex transmission.
13: */
14:
15: #include "../param.h"
16: #include "../conf.h"
17: #include "../user.h"
18: #include "../buf.h"
19:
20: /* control info */
21: struct {
22: char *dp_buf;
23: char *dp_bufp;
24: int dp_nxmit;
25: char dp_state;
26: char dp_timer;
27: int dp_proc;
28: } dp11;
29:
30: /* device registers */
31: struct {
32: int dprcsr;
33: char dprbuf;
34: char dpsyn0;
35: int dptcsr;
36: char dptbuf;
37: char dpsyn1;
38: };
39:
40: /* bits */
41: #define ODDPAR 010000
42: #define IENABLE 0100
43: #define HDUPLX 02
44:
45: #define CTRANS 0100000
46: #define RORUN 040000
47: #define RING 020000
48: #define DSRDY 010000
49: #define CARRIER 04000
50: #define DONE 0200
51: #define IENABLE 0100
52: #define SIENABL 040
53:
54: #define WRITE 1
55: #define READ 0
56:
57: #define DTRDY 01
58: #define RCVACT 04000
59:
60: #define DPADDR 0174770
61: #define DPPRI 5
62: #define SYN 026 /* (receive) sync character */
63:
64: /*
65: * The open fails unless the device is not open or
66: * the opening process is the one that has it open already.
67: */
68: dpopen(dev, flag)
69: {
70: int dptimeout();
71:
72: if (dp11.dp_proc!=0 && dp11.dp_proc!=u.u_procp) {
73: u.u_error = ENXIO;
74: return;
75: }
76: dp11.dp_proc = u.u_procp;
77: dp11.dp_state = READ;
78: if (dp11.dp_buf==0) {
79: dp11.dp_buf = getblk(NODEV);
80: dp11.dp_bufp = dp11.dp_buf->b_addr;
81: dp11.dp_timer = HZ;
82: timeout(dptimeout, 0, HZ);
83: }
84: DPADDR->dpsyn0 = SYN;
85: DPADDR->dprcsr = HDUPLX|IENABLE;
86: DPADDR->dptcsr = IENABLE|SIENABL|DTRDY;
87: }
88:
89: dpclose()
90: {
91: DPADDR->dprcsr = 0;
92: DPADDR->dptcsr = 0;
93: dp11.dp_timer = 0;
94: dp11.dp_proc = 0;
95: if (dp11.dp_buf != 0) {
96: brelse(dp11.dp_buf);
97: dp11.dp_buf = 0;
98: }
99: }
100:
101: /*
102: * Read waits until:
103: * there is loss of "data set ready", or
104: * a timeout occurs, or
105: * a full record has been received.
106: * The former two result in an error.
107: */
108: dpread()
109: {
110: register char *bp, **epp;
111:
112: bp = dp11.dp_buf->b_addr;
113: epp = &dp11.dp_bufp;
114: for(;;) {
115: if(dpwait())
116: return;
117: if (*epp > bp)
118: break;
119: spl6();
120: if (dp11.dp_timer <= 1) {
121: spl0();
122: return;
123: }
124: sleep(&dp11, DPPRI);
125: spl0();
126: }
127: iomove(dp11.dp_buf, 0, min(u.u_count, *epp-bp), B_READ);
128: }
129:
130: /*
131: * write checks to make sure that the data set is not reading,
132: * and that it is ready. Then the record is copied
133: * and transmission started.
134: */
135: dpwrite()
136: {
137: register char *bp;
138:
139: if (u.u_count==0 || dpwait())
140: return;
141: dp11.dp_state = WRITE;
142: bp = dp11.dp_buf->b_addr;
143: dp11.dp_bufp = bp;
144: if (u.u_count>512)
145: u.u_count = 512;
146: dp11.dp_nxmit = u.u_count;
147: iomove(dp11.dp_buf, 0, u.u_count, B_WRITE);
148: dpstart();
149: }
150:
151: /*
152: * If "data set ready" is down return an error; otherwise
153: * wait until the dataset is in read state with no carrier,
154: * which means a record has just been received.
155: */
156: dpwait()
157: {
158: for(;;) {
159: if ((DPADDR->dptcsr&DSRDY)==0 || dp11.dp_buf==0) {
160: u.u_error = EIO;
161: return(1);
162: }
163: spl6();
164: if (dp11.dp_state==READ && (DPADDR->dptcsr&CARRIER)==0) {
165: spl0();
166: return(0);
167: }
168: sleep(&dp11, DPPRI);
169: spl0();
170: }
171: }
172:
173: /*
174: * Start off the next character to be transmitted;
175: * when the record is done, drop back into read state.
176: */
177: dpstart()
178: {
179: register int c;
180: extern char partab[];
181:
182: dp11.dp_timer = 10;
183: if (--dp11.dp_nxmit >= 0) {
184: c = (*dp11.dp_bufp++) & 0177;
185: DPADDR->dptbuf = c | ~partab[c]&0200;
186: } else {
187: dp11.dp_bufp = dp11.dp_buf->b_addr;
188: dp11.dp_state = READ;
189: }
190: }
191:
192: /*
193: * Count down the DP timer (once per second)
194: * If it runs out, it presumably means the other station
195: * won't speak.
196: */
197: dptimeout()
198: {
199: if (dp11.dp_timer==0)
200: return;
201: if (--dp11.dp_timer==0) {
202: dpturnaround();
203: dp11.dp_timer = 1;
204: }
205: timeout(dptimeout, 0, HZ);
206: }
207:
208: /*
209: * Receiver interrupt: if reading, stash character
210: * unless there is an overrun.
211: */
212: dprint()
213: {
214: register int c;
215:
216: c = DPADDR->dprbuf & 0177;
217: if (dp11.dp_state==READ) {
218: if ((DPADDR->dprcsr&ODDPAR) == 0)
219: c =| 0200;
220: if (dp11.dp_bufp < dp11.dp_buf->b_addr+512)
221: *dp11.dp_bufp++ = c;
222: }
223: }
224:
225: /*
226: * Transmitter interrupt:
227: * Knock down hardware bits.
228: * If carrier has dropped, the record is done, so turn the line around;
229: * otherwise start another character.
230: */
231: dpxint()
232: {
233: register int dpstat;
234:
235: dpstat = DPADDR->dptcsr;
236: DPADDR->dptcsr =& ~(CTRANS|RORUN|RING|DONE);
237: if (dpstat & (CTRANS|RORUN))
238: dpturnaround();
239: else if (dpstat&DONE && dp11.dp_state==WRITE)
240: dpstart();
241: }
242:
243: /*
244: * Change the state from writing to reading at the end of a record.
245: */
246: dpturnaround()
247: {
248: DPADDR->dprcsr =& ~RCVACT;
249: if (dp11.dp_state==WRITE) {
250: dp11.dp_timer = 10;
251: dp11.dp_state = READ;
252: dp11.dp_bufp = dp11.dp_buf->b_addr;
253: }
254: wakeup(&dp11);
255: }
Defined functions
Defined macros
DONE
defined in line
50; used 2 times
DPADDR
defined in line
60; used 13 times
DPPRI
defined in line
61; used 2 times
DSRDY
defined in line
48; used 1 times
DTRDY
defined in line
57; used 1 times
READ
defined in line
55; used 5 times
RING
defined in line
47; used 1 times
RORUN
defined in line
46; used 2 times
SYN
defined in line
62; used 1 times
WRITE
defined in line
54; used 3 times