|
|
1.1 root 1: /*
2: * Datakit driver
3: */
4: #include "dk.h"
5: #if NDK
6: #include "../h/param.h"
7: #include "../h/systm.h"
8: #include "../h/stream.h"
9: #include "../h/ioctl.h"
10: #include "../h/pte.h"
11: #include "../h/map.h"
12: #include "../h/buf.h"
13: #include "../h/ubavar.h"
14: #include "../h/conf.h"
15: #include "../h/dkstat.h"
16: #include "../h/dkmod.h"
17: #include "sparam.h"
18:
19: struct device {
20: unsigned short csr;
21: unsigned short dko;
22: unsigned short dki;
23: };
24:
25: struct device *DKADDR;
26: #ifndef NDKLINE
27: #define NDKLINE 64
28: #endif NDKLINE
29:
30: struct dk {
31: struct queue *dkrq;
32: u_char chan;
33: } dk[NDKLINE];
34:
35: int dkalive;
36: struct dkstat dkstat;
37: extern struct dkmodule dkmod[];
38: struct dkmodule *dkmodp;
39: char dkstate[NDKLINE];
40:
41: /*
42: * channel states
43: */
44: #define CLOSED 0
45: #define RCLOSE 1 /* remote hung up, local still around */
46: #define LCLOSE 2 /* closed locally, CMC hasn't acked yet */
47: #define OPEN 3 /* in use */
48:
49: /*
50: * Hardware control bits
51: */
52: #define DKTENAB 0100
53: #define DKRENAB 040
54: #define ENABS (DKRENAB)
55: #define DKTDONE 0200
56: #define DKRDONE 0100000
57: #define D_OSEQ 0
58: #define D_READ 01
59: #define D_WRITE 02
60: #define D_XPACK 03
61: #define DKMARK 01000
62: #define DKDATA 0400
63: #define DKPARITY 0100000
64:
65: #define DKISIZ 16
66:
67: int nodev(), dkopen(), dkclose(), dkput();
68:
69: static struct qinit dkrinit = { nodev, NULL, dkopen, dkclose, 0, 0 };
70: struct qinit dkwinit = { dkput, NULL, dkopen, dkclose, 0, 0 };
71: struct streamtab dkinfo = { &dkrinit, &dkwinit };
72:
73: int dkattach(), dkprobe();
74: struct uba_device *dkstuff[NDK];
75: u_short dkstd[] = { 0 };
76: struct uba_driver dkdriver =
77: { dkprobe, 0, dkattach, 0, dkstd, "dk", dkstuff };
78:
79: dkprobe(reg)
80: caddr_t reg;
81: {
82: register int br, cvec;
83: register struct device *dkaddr = (struct device *)reg;
84:
85: dkaddr->csr = D_OSEQ;
86: dkaddr->dko = 0; /* this clears fifos */
87: DELAY(1000); /* wait for board to reset */
88: dkaddr->csr = D_WRITE;
89: dkaddr->dko = DKMARK + 511; /* pack on 511 */
90: dkaddr->csr = D_XPACK+DKTENAB;
91: dkaddr->dko = 0;
92: DELAY(10000);
93: dkaddr->csr = 0;
94: DKADDR = dkaddr;
95: return(1);
96: }
97:
98: dkattach()
99: {
100: }
101:
102: /*
103: * open DK channel
104: */
105: dkopen(q, dev)
106: register struct queue *q;
107: register dev_t dev;
108: {
109: register struct dk *dkp;
110: static opened, badtime;
111: register maj = major(dev);
112:
113: dev = minor(dev);
114: if (dev<=0 || dev>=NDKLINE)
115: return(0);
116: if (!opened) {
117: register sane;
118:
119: if (DKADDR == NULL)
120: return(0);
121: DKADDR->csr = D_OSEQ;
122: DKADDR->dko = 0; /* Clear fifo's */
123: sane = 256;
124: do {
125: if (DKADDR->csr & DKTDONE) {
126: dkalive = 0;
127: if (time > badtime + 300) {
128: badtime = time;
129: printf("DK interface bad\n");
130: }
131: return(0);
132: }
133: } while (--sane);
134: for (dkmodp=dkmod; ; dkmodp++) {
135: if (dkmodp->dev==0 || dkmodp->dev==maj) {
136: dkmodp->dev = maj;
137: dkmodp->dkstate = dkstate;
138: dkmodp->nchan = NDKLINE;
139: break;
140: }
141: }
142: dkalive = 1;
143: for (dkp = &dk[0]; dkp < &dk[NDKLINE]; dkp++)
144: dkp->chan = dkp - &dk[0];
145: DKADDR->csr = ENABS;
146: opened++;
147: dkrecover(dev);
148: }
149: dkp = &dk[dev];
150: if (dkmodp->dkstate[dev] != CLOSED) { /* already open */
151: if (dev&01 && dev>1) /* outgoing channels can't reopen */
152: return(0);
153: if (dkmodp->dkstate[dev] != OPEN)
154: return(0); /* closing channels can't reopen */
155: return(1);
156: }
157: dkp->dkrq = q;
158: q->ptr = (caddr_t)dkp;
159: WR(q)->ptr = (caddr_t)dkp;
160: dkmodp->dkstate[dev] = OPEN;
161: return(1);
162: }
163:
164: /*
165: * Timer to recover from lost interrupt condition.
166: */
167: dkrecover(dev)
168: dev_t dev;
169: {
170: register int ps = spl5();
171:
172: if (DKADDR->csr & DKRDONE)
173: dkrint(dev);
174: splx(ps);
175:
176: timeout(dkrecover, dev, hz/2);
177: }
178:
179: /*
180: * close DK channel
181: */
182: dkclose(q)
183: register struct queue *q;
184: {
185: register struct dk *dkp;
186:
187: dkp = (struct dk *)q->ptr;
188: dkp->dkrq = NULL;
189: if (dkmodp->dkstate[dkp->chan] == RCLOSE || dkmodp->listnrq==NULL)
190: dkmodp->dkstate[dkp->chan] = CLOSED;
191: else if (dkmodp->dkstate[dkp->chan] == OPEN)
192: dkmodp->dkstate[dkp->chan] = LCLOSE;
193: if (dkmodp->listnrq)
194: putctl1(RD(dkmodp->listnrq), M_CLOSE, dkp->chan);
195: }
196:
197: /*
198: * DK receiver interrupt.
199: */
200: dkrint(dev)
201: {
202: register struct queue *q;
203: register struct block *bp, **bpp;
204: register c, nbytes, sts, sane, chan;
205: struct block *blist[DKISIZ+1];
206:
207: sts = DKADDR->csr;
208: c = 0;
209: while (DKADDR->csr & DKRDONE) {
210: DKADDR->csr = D_READ|ENABS;
211: if ((c & DKMARK) == 0) {
212: /* Search for channel number */
213: sane = 256;
214: do {
215: c = DKADDR->dki;
216: if (c & DKMARK || --sane==0)
217: break;
218: } while (DKADDR->csr & DKRDONE);
219: }
220: if ((c & DKMARK) == 0) {
221: dkstat.markflt++;
222: continue;
223: }
224: if ((c & DKPARITY) == 0) {
225: dkstat.markparity++;
226: c = 0;
227: continue;
228: }
229: /* check channel */
230: chan = c & 0777;
231: if (chan == 0 || chan >= NDKLINE || (q = dk[chan].dkrq)==NULL) {
232: if (chan>0 && chan<NDKLINE) {
233: if (dkmodp->listnrq)
234: putctl1(RD(dkmodp->listnrq),
235: M_CLOSE, chan);
236: dkstat.closepack++;
237: } else if (chan == 0)
238: dkstat.pack0++;
239: else
240: dkstat.packstrange++;
241: for (nbytes=0; nbytes<DKISIZ; nbytes++) {
242: c = DKADDR->dki;
243: if (c & DKMARK)
244: break;
245: }
246: continue;
247: }
248: bp = allocb(DKISIZ);
249: if (bp == NULL)
250: return;
251: bpp = blist;
252: for (nbytes=0; nbytes<DKISIZ; nbytes++) {
253: if ((DKADDR->csr&DKRDONE) == 0)
254: break;
255: c = DKADDR->dki;
256: if ((c & (DKPARITY|DKDATA|DKMARK))!=(DKPARITY|DKDATA)) {
257: if (c & DKMARK) {
258: dkstat.shortpack++;
259: break;
260: }
261: if ((c & DKPARITY) == 0) {
262: dkstat.parity++;
263: break;
264: } else { /* it's control */
265: if ((c & 0377) == 0)
266: continue;
267: if (bp->wptr > bp->rptr) {
268: *bpp++ = bp;
269: bp = allocb(DKISIZ);
270: if (bp == NULL)
271: break;
272: }
273: }
274: bp->type = M_CTL;
275: }
276: *bp->wptr++ = c;
277: }
278: *bpp++ = bp;
279: *bpp++ = NULL;
280: bpp = blist;
281: if (nbytes!=DKISIZ) {
282: while (*bpp)
283: freeb(*bpp++);
284: continue;
285: }
286: while (*bpp) {
287: dkstat.input += bp->wptr - bp->rptr;
288: if ((q->next->flag & QFULL) == 0)
289: (*q->next->qinfo->putp)(q->next, *bpp++);
290: else
291: freeb(*bpp++);
292: }
293: }
294: DKADDR->csr = sts;
295: }
296:
297: /*
298: * DK put procedure
299: */
300: dkput(q, bp)
301: register struct queue *q;
302: register struct block *bp;
303: {
304: register n, isdata = DKDATA;
305: struct dk *dp;
306: int chan, s;
307: struct ioctl1 {
308: int com;
309: int lhn;
310: } *iop;
311:
312: dp = (struct dk *)q->ptr;
313: chan = dp->chan;
314: switch (bp->type) {
315:
316: case M_IOCTL:
317: bp->type = M_IOCACK;
318: iop = (struct ioctl1 *)bp->rptr;
319: switch (iop->com) {
320:
321: default:
322: bp->type = M_IOCNAK;
323: break;
324: }
325: qreply(q, bp);
326: return;
327:
328: case M_CTL:
329: isdata = 0;
330: case M_DATA:
331: break;
332:
333: case M_CLOSE:
334: n = *bp->rptr;
335: if (n < NDKLINE) {
336: if (dkmodp->dkstate[n] == OPEN) {
337: dkmodp->dkstate[n] = RCLOSE;
338: putctl(dk[n].dkrq->next, M_HANGUP);
339: } else if (dkmodp->dkstate[n] == LCLOSE)
340: dkmodp->dkstate[n] = CLOSED;
341: }
342: freeb(bp);
343: return;
344:
345: default:
346: freeb(bp);
347: return;
348: }
349: dkstat.output += bp->wptr - bp->rptr;
350: s = spl6();
351: if (dkalive) {
352: register struct device *dkaddr = DKADDR;
353: int r = dkaddr->csr;
354: while ((n = bp->wptr - bp->rptr) > 0) {
355: if (n > DKISIZ)
356: n = DKISIZ;
357: dkaddr->csr = D_WRITE + ENABS;
358: dkaddr->dko = DKMARK + chan;
359: dkaddr->dko = *bp->rptr++ | isdata;
360: while (--n)
361: dkaddr->dko = *bp->rptr++ | DKDATA;
362: dkaddr->csr = D_XPACK + ENABS;
363: dkaddr->dko = 0;
364: }
365: dkaddr->csr = r;
366: }
367: splx(s);
368: freeb(bp);
369: }
370:
371: /*
372: * unibus reset
373: */
374: dkreset()
375: {
376: if (DKADDR)
377: DKADDR->csr = ENABS;
378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.