|
|
1.1 root 1: /*
2: * trilog driver
3: */
4:
5: #include "tri.h"
6: #if NTRI>0
7: #include "../h/param.h"
8: #include "../h/dir.h"
9: #include "../h/user.h"
10: #include "../h/buf.h"
11: #include "../h/pte.h"
12: #include "../h/ubavar.h"
13: #include "../h/ubareg.h"
14: #include "../h/systm.h"
15:
16:
17: #define LPPRI PZERO+10
18: #define LPLOWAT 50
19:
20: struct device {
21: short tricsr, tribuf;
22: };
23:
24: #define ERRBIT 0100000
25: #define BUFSIZ 512
26: #define LPSIZ (2*BUFSIZ)
27:
28: struct tri {
29: char tricbuf[LPSIZ]; /* one buffer, no clist */
30: char *trir,*triw; /* and two chasing pointers */
31: int tricc; /* char count to disambiguate */
32: char flag; /* the case of trir == triw */
33: } tritab[NTRI];
34:
35: int tritimeout;
36:
37: /*
38: * flag bits
39: */
40: #define OPEN 010
41: #define LBUSY 020
42: #define NOCR 040
43: #define ASLP 0100
44: #define ESLP 0200
45:
46: #define IENABLE 0100
47: #define DONE 0200
48:
49: int triattach(), triprobe();
50: struct uba_device *triinfo[NTRI];
51: u_short tristd[] = { 0 };
52: struct uba_driver tridriver =
53: { triprobe, 0, triattach, 0, tristd, "tri", triinfo };
54:
55: triprobe(reg)
56: caddr_t reg;
57: {
58: register int br, cvec;
59: register struct device *triaddr = (struct device *)reg;
60:
61: triaddr->tricsr = IENABLE;
62: triaddr->tribuf = '\0';
63: DELAY(10000);
64: return(1);
65: }
66:
67: triattach()
68: {
69: }
70:
71: triopen(dev, flag)
72: dev_t dev;
73: {
74: register int s;
75: register unit, d;
76: int tritimer();
77: register struct tri *tri;
78: register struct uba_device *ui;
79:
80: d = minor(dev);
81: unit = d&07;
82: tri = &tritab[unit];
83: ui = triinfo[unit];
84: if (unit>=NTRI || tri->flag || ui->ui_alive==0) {
85: u.u_error = ENXIO;
86: return;
87: }
88: tri->flag = (d&077)|OPEN;
89: tri->triw = tri->trir = tri->tricbuf;
90: tri->tricc = 0;
91: while ((((struct device *)ui->ui_addr)->tricsr&DONE) == 0)
92: sleep((caddr_t)&lbolt, LPPRI);
93: if (tritimeout==0) {
94: tritimeout++;
95: timeout(tritimer, (caddr_t)0, 10*hz);
96: }
97: }
98:
99: tritimer()
100: {
101: register struct tri *tri;
102: register unit, flag;
103:
104: for (unit=flag=0; unit<NTRI; unit++) {
105: tri = &tritab[unit];
106: if (tri->flag==0) {
107: continue;
108: }
109: flag++;
110: if (tri->flag&ESLP) {
111: tri->flag &= ~ESLP;
112: triintr(unit);
113: }
114: }
115: if (flag) {
116: timeout(tritimer, (caddr_t)0, 10*hz);
117: } else {
118: tritimeout = 0;
119: }
120: }
121:
122:
123:
124: triclose(dev)
125: register dev_t dev;
126: {
127: register unit;
128: register struct tri *tri;
129:
130: unit = minor(dev)&07;
131: tri = &tritab[unit];
132:
133: triwait(tri, 0);
134: tri->flag = 0;
135: ((struct device *)triinfo[unit]->ui_addr)->tricsr = 0;
136: }
137:
138:
139: triwait(tri, count)
140: register struct tri *tri;
141: register count;
142: {
143: register int s, times;
144: register r;
145:
146: times = 60;
147: while (tri->tricc > count) {
148: tri->flag |= ASLP;
149: r = tsleep((caddr_t)tri, LPPRI, 10);
150: if (r==TS_TIME) {
151: s = spl4();
152: if ((tri->flag&LBUSY)==0)
153: triintr(tri-tritab);
154: splx(s);
155: times--;
156: if (times==0) {
157: printf ("cpr timeout, buffer flushed\n");
158: goto flush;
159: }
160: }
161: if (r==TS_SIG) {
162: flush:
163: tri->trir = tri->triw = tri->tricbuf;
164: tri->tricc = 0;
165: }
166: }
167: }
168:
169: triwrite(dev)
170: {
171: register struct tri *tri;
172: register char *p;
173: register c, cc;
174: register s;
175: register char *trir;
176:
177: dev = minor(dev);
178: tri = &tritab[dev];
179: while(u.u_count) {
180: trir = tri->trir;
181: if (trir > tri->triw)
182: cc = trir - tri->triw;
183: else if (trir == tri->triw && tri->tricc != 0)
184: cc = 0; /* buffer full */
185: else /* from triw to the end of the buffer */
186: cc = tri->tricbuf + LPSIZ - tri->triw;
187: if (u.u_count < cc)
188: cc = u.u_count;
189: if (cc == 0) { /* buffer must be full */
190: s = spl4();
191: if ((tri->flag&LBUSY) == 0) {
192: triintr(dev); /* poke it */
193: }
194: splx(s);
195: triwait(tri,LPLOWAT);
196: } else { /* queue up some characters */
197: iomove(tri->triw, cc, B_WRITE);
198: if ((tri->triw += cc) >= tri->tricbuf + LPSIZ)
199: tri->triw = tri->tricbuf;
200: tri->tricc += cc;
201: s = spl4();
202: if ((tri->flag&LBUSY) == 0)
203: triintr(dev);
204: splx(s);
205: }
206: }
207: }
208:
209:
210: triintr(dev)
211: register dev;
212: {
213: register struct tri *tri;
214: register struct device *addr;
215: register c, cc;
216:
217: tri = &tritab[dev];
218: addr = (struct device *)triinfo[dev]->ui_addr;
219: if ((addr->tricsr&DONE)==0) {
220: return;
221: }
222: tri->flag &= ~LBUSY;
223: if (addr->tricsr&ERRBIT) {
224: addr->tricsr = 0;
225: tri->flag &= ~LBUSY;
226: tri->flag |= ESLP;
227: return;
228: }
229: cc = 0;
230: while (addr->tricsr&DONE && (tri->tricc > 0)) {
231: addr->tribuf = *(tri->trir)++;
232: if (tri->trir == tri->tricbuf + LPSIZ)
233: tri->trir = tri->tricbuf;
234: tri->tricc--;
235: cc++;
236: }
237: if (cc) {
238: addr->tricsr |= IENABLE;
239: tri->flag |= LBUSY;
240: }
241: if (tri->tricc <= LPLOWAT && tri->flag&ASLP) {
242: tri->flag &= ~ASLP;
243: wakeup((caddr_t)tri);
244: }
245: }
246: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.