|
|
1.1 root 1: /*
2: * simple two-stream kmc datakit driver
3: * -- assumes it is the first kmc, and only one allowed for now
4: * (the latter not severe, as 256 channels are permitted)
5: */
6: #include "sys/param.h"
7: #include "sys/stream.h"
8: #include "sys/dkio.h"
9: #include "sys/ubaddr.h"
10: #include "sys/conf.h"
11: #include "sys/kb.h"
12: #include "sys/kmc.h"
13: #include "sys/dkstat.h"
14: #include "sys/dkmod.h"
15:
16: /*
17: * hardware stuff
18: */
19:
20: struct device {
21: short sts; /* written by KMC */
22: short cmd; /* command and transmit chan -- written by host */
23: short ba; /* low bus address -- written by host */
24: short bc; /* negative buffer size -- written by host */
25: };
26:
27: /*
28: * status info
29: */
30: #define SCOUNT 0xfff /* receive buffer resid count */
31: #define SRRDY (020<<8) /* receive ready */
32: #define SOK (040<<8) /* init ok */
33: #define SERROR (0100<<8) /* transfer or other error */
34: #define SXRDY (0200<<8) /* transmit ready */
35:
36: /*
37: * commands
38: */
39: #define CGO (01<<8) /* turned off when command read */
40: #define CRCV (01<<8) /* here is a receive buffer */
41: #define CSEND (03<<8) /* send this buffer of data */
42: #define CSCTL (043<<8) /* send this data, first char is ctl */
43: #define CIE (020<<8) /* interrupt after this command */
44: #define CXA (014<<8) /* high address bits */
45: #define XASHIFT 10 /* shift high address bits this much */
46:
47: #define STALL 10000 /* max time to stall waiting for ready */
48: /*
49: * per-channel stuff
50: */
51: struct kb kb[];
52: extern int kbcnt;
53: char kbstate[];
54:
55: /*
56: * kb flags
57: */
58: #define DKXCL 01 /* exclusive open */
59: #define DKXWANT 02 /* output pending this channel */
60:
61: /*
62: * per-controller stuff;
63: * always just one for now
64: */
65:
66: struct kbkmc kbkmc[1];
67: #define KBNO 0 /* always this kb for now */
68:
69: /*
70: * kbkmc flags
71: */
72: #define INIT 01
73:
74: /*
75: * illicit linkage to other datakit code
76: */
77:
78: struct dkstat dkstat;
79:
80: /*
81: * illicit linkage to kmc driver
82: */
83:
84: extern struct kmc kmc[];
85: extern struct ubaddr kmcaddr[];
86: extern int kmccnt;
87: #define KNO 0 /* kmc0 is ours, by fiat */
88:
89: #define DKISIZE 1024 /* preferred input buffer size */
90: #define MAXOBUF 4096 /* max allowed output buffer -- for unibus map */
91:
92: long kbopen();
93: int kbclose(), kbput(), kbosrv();
94:
95: static struct qinit kbrinit = { nodev, NULL, kbopen, kbclose, 0, 0 };
96: struct qinit kbwinit = { kbput, NULL, kbopen, kbclose, 1500, 600 };
97: struct streamtab kbinfo = { &kbrinit, &kbwinit };
98: struct cdevsw kbcdev = cstrinit(&kbinfo);
99:
100: /*
101: * open DK channel
102: */
103: long
104: kbopen(q, dev)
105: register struct queue *q;
106: register dev_t dev;
107: {
108: register struct kb *dkp;
109: register struct kbkmc *kk;
110: register chan;
111:
112: chan = minor(dev);
113: if (chan<=0 || chan>=kbcnt)
114: return(0);
115: kk = &kbkmc[KBNO];
116: if ((kk->flags & INIT) == 0) {
117: if ((kk->modp = dkmodall(dev, 0, kbcnt)) == NULL)
118: return (0);
119: kk->modp->dkstate = kbstate;
120: if (kbinit(kk) == 0)
121: return (0);
122: kk->flags |= INIT;
123: }
124: dkp = &kb[chan];
125: if (kbstate[chan] != DKCLOSED) { /* already open */
126: if (dkp->flag & DKXCL)
127: return(0);
128: if (kbstate[chan] != DKOPEN)
129: return(0); /* closing channels can't reopen */
130: return(1);
131: }
132: dkp->dkrq = q;
133: q->ptr = (caddr_t)dkp;
134: WR(q)->ptr = (caddr_t)dkp;
135: WR(q)->flag |= QNOENB|QBIGB;
136: dkp->flag = DKXCL;
137: dkp->chan = chan;
138: kbstate[chan] = DKOPEN;
139: return(1);
140: }
141:
142: /*
143: * make sure kmc is alive;
144: * init data structures once
145: */
146: kbinit(kk)
147: register struct kbkmc *kk;
148: {
149: register struct kmc *kp;
150: register struct device *reg;
151: register int i;
152: extern kbintr(), kbreset();
153:
154: kk->kno = KNO;
155: kk->ubno = kmcaddr[KNO].ubno; /* cheat */
156: kp = &kmc[kk->kno];
157: if ((reg = kp->k_addr) == 0)
158: return (0);
159: if ((reg->sts & SOK) == 0)
160: return (0);
161: if ((kk->omap = ubmalloc(kk->ubno, MAXOBUF, UBDP)) == 0)
162: return (0);
163: kp->k_rint = kbintr;
164: kp->k_xint = kbintr;
165: kp->k_reset = kbreset;
166: kk->addr = reg;
167: i = spl5();
168: kbistart(kk);
169: splx(i);
170: return (1);
171: }
172:
173: /*
174: * called when, e.g., kmc is reloaded
175: */
176: kbreset(kno)
177: int kno;
178: {
179: register struct kbkmc *kk;
180: register int s;
181:
182: kk = &kbkmc[KNO];
183: if (kk->obuf) {
184: freeb(kk->obuf);
185: kk->obuf = NULL;
186: }
187: if (kk->imap) {
188: ubmfree(kk->ubno, kk->imap);
189: kk->imap = 0;
190: }
191: if (kk->ibuf) {
192: freeb(kk->ibuf);
193: kk->ibuf = NULL;
194: }
195: s = spl5();
196: kbistart(kk);
197: splx(s);
198: }
199:
200: /*
201: * close DK channel
202: */
203: kbclose(q)
204: register struct queue *q;
205: {
206: register struct kb *dkp;
207: register struct kbkmc *kk;
208:
209: kk = &kbkmc[KBNO];
210: dkp = (struct kb *)q->ptr;
211: if (dkp == NULL)
212: panic("kbclose");
213: dkp->dkrq = NULL;
214: dkp->flag = 0;
215: if (kbstate[dkp->chan] == DKRCLOSE || kk->modp->listnrq==NULL)
216: kbstate[dkp->chan] = DKCLOSED;
217: else if (kbstate[dkp->chan] == DKOPEN)
218: kbstate[dkp->chan] = DKLCLOSE;
219: if (kk->modp->listnrq)
220: putctl2(RD(kk->modp->listnrq), M_PRICTL, DKMCLOSE, dkp->chan);
221: }
222:
223: /*
224: * interrupt -- receiver only
225: * try to short-circuit interrupts;
226: * data often comes in a large piece, followed by two small ones (URP trailer)
227: */
228:
229: kbintr(dev)
230: {
231: register struct kbkmc *kk;
232: register struct block *bp;
233: register struct queue *q;
234: register int i;
235:
236: kk = &kbkmc[KBNO];
237: if (kk->addr == NULL)
238: return;
239: i = kk->addr->sts;
240: if ((bp = kk->ibuf) == NULL) { /* shouldn't happen */
241: kbistart(kk);
242: return;
243: }
244: ubmfree(kk->ubno, kk->imap);
245: kk->ibuf = NULL;
246: kbistart(kk);
247: i |= ~SCOUNT; /* crypto-sign-extend */
248: if ((i & SCOUNT) == 0)
249: i = 0; /* overflow just means buffer full */
250: bp->wptr = bp->lim + i; /* lim - residue */
251: i = *bp->rptr; /* channel */
252: bp->rptr++;
253: if (*bp->rptr) /* ctl flag */
254: bp->type = M_CTL;
255: bp->rptr++;
256: if (i == 0 || i >= kbcnt || (q = kb[i].dkrq) == NULL) {
257: if (i == 0)
258: dkstat.pack0++;
259: else if (i >= kbcnt)
260: dkstat.packstrange++;
261: else {
262: if (kk->modp->listnrq)
263: putctl2(RD(kk->modp->listnrq), M_PRICTL, DKMCLOSE, i);
264: dkstat.closepack++;
265: }
266: freeb(bp);
267: return;
268: }
269: dkstat.input += bp->wptr - bp->rptr;
270: if ((q->next->flag & QFULL) == 0)
271: (*q->next->qinfo->putp)(q->next, bp);
272: else
273: freeb(bp);
274: }
275:
276: /*
277: * start the next input buffer
278: */
279: kbistart(kk)
280: register struct kbkmc *kk;
281: {
282: register struct device *reg;
283: register int sts;
284: register struct block *bp;
285: register int n;
286: register uaddr_t ua;
287:
288: if ((reg = kk->addr) == NULL)
289: return;
290: if (kk->ibuf)
291: return;
292: for (sts = 0, n = 0; n < STALL; n++) {
293: if ((reg->cmd & CGO) == 0
294: && (sts = reg->sts) & SRRDY)
295: break;
296: /* delay to free up unibus? */
297: }
298: if ((sts & SRRDY) == 0) {
299: printf("kb rcv not ready, sts %o cmd %o\n", reg->sts, reg->cmd);
300: panic("kbistart");
301: return;
302: }
303: if (sts & SERROR)
304: printf("kb err, sts %o\n", sts&0177777);
305: if ((bp = allocb(DKISIZE)) == NULL
306: || (kk->imap = ubmblk(kk->ubno, bp, 0)) == 0) {
307: panic("kbistart can't alloc\n"); /* later printf */
308: if (bp)
309: freeb(bp);
310: return;
311: }
312: kk->ibuf = bp;
313: if ((int)bp->rptr & 01)
314: bp->rptr++;
315: kk->iaddr = ua = ubadrptr(kk->ubno, bp, kk->imap);
316: reg->bc = bp->rptr - bp->lim; /* sic - negative count */
317: reg->ba = ua;
318: n = (ua >> 16) << XASHIFT;
319: n &= CXA;
320: n |= CIE|CRCV;
321: reg->cmd = n;
322: }
323:
324: /*
325: * put procedure for output
326: */
327: kbput(q, bp)
328: struct queue *q;
329: register struct block *bp;
330: {
331: register struct kb *dkp;
332: register struct kbkmc *kk;
333: register int n;
334: register struct device *reg;
335: register int sts;
336: int s;
337:
338: dkp = (struct kb *)q->ptr;
339: kk = &kbkmc[KBNO];
340: switch (bp->type) {
341:
342: case M_IOCTL:
343: switch (stiocom(bp)) {
344: case DIOCNXCL:
345: dkp->flag &=~ DKXCL;
346: bp->wptr = bp->rptr;
347: bp->type = M_IOCACK;
348: break;
349:
350: case KIOCINIT:
351: /* eventually, reset things here */
352:
353: default:
354: bp->type = M_IOCNAK;
355: break;
356: }
357: qreply(q, bp);
358: return;
359:
360: case M_CTL:
361: case M_DATA:
362: if (bp->rptr == bp->wptr) {
363: freeb(bp);
364: return;
365: }
366: dkstat.output += bp->wptr - bp->rptr;
367: s = spl5();
368: reg = kk->addr;
369: for (sts = 0, n = 0; n < STALL; n++) {
370: if ((reg->cmd & CGO) == 0
371: && (sts = reg->sts) & SXRDY)
372: break;
373: DELAY(40); /* get off the UNIBUS */
374: }
375: if ((sts & SXRDY) == 0) { /* n >= STALL */
376: printf("kb xmit not ready, sts %o, cmd %o\n", sts, reg->cmd);
377: splx(s);
378: freeb(bp);
379: return;
380: }
381: if (sts & SERROR)
382: printf("kb err, sts %o\n", sts&0177777);
383: ubmflush(kk->ubno, ubmpath(kk->omap));
384: if (kk->obuf) {
385: freeb(kk->obuf);
386: kk->obuf = NULL;
387: }
388: n = bp->wptr - bp->rptr;
389: kk->oaddr = ubmaddr(kk->ubno, bp->rptr, n, kk->omap);
390: reg->bc = -n;
391: reg->ba = kk->oaddr;
392: n = (kk->oaddr >> 16)<<XASHIFT;
393: n &= CXA;
394: n |= dkp->chan;
395: if (bp->type == M_DATA)
396: n |= CSEND;
397: else
398: n |= CSCTL;
399: reg->cmd = n;
400: kk->obuf = bp;
401: splx(s);
402: return;
403:
404: case M_PRICTL:
405: switch (*bp->rptr) {
406: case DKMCLOSE:
407: n = bp->rptr[1];
408: if (n < kbcnt) {
409: if (kbstate[n] == DKOPEN) {
410: kbstate[n] = DKRCLOSE;
411: putctl(kb[n].dkrq->next, M_HANGUP);
412: } else if (kbstate[n] == DKLCLOSE)
413: kbstate[n] = DKCLOSED;
414: }
415: freeb(bp);
416: return;
417:
418: case DKMXINIT:
419: n = bp->rptr[1];
420: if (n < kbcnt && kbstate[n] == DKOPEN)
421: (*kb[n].dkrq->next->qinfo->putp)(kb[n].dkrq->next, bp);
422: else
423: freeb(bp);
424: return;
425:
426: default:
427: freeb(bp);
428: return;
429: }
430:
431: default:
432: freeb(bp);
433: return;
434: }
435: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.