|
|
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: extern struct kb kb[];
52: extern int kbcnt;
53: extern 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: dkstat.closepack++;
263: freeb(bp);
264: return;
265: }
266: dkstat.input += bp->wptr - bp->rptr;
267: if ((q->next->flag & QFULL) == 0)
268: (*q->next->qinfo->putp)(q->next, bp);
269: else
270: freeb(bp);
271: }
272:
273: /*
274: * start the next input buffer
275: */
276: kbistart(kk)
277: register struct kbkmc *kk;
278: {
279: register struct device *reg;
280: register int sts;
281: register struct block *bp;
282: register int n;
283: register uaddr_t ua;
284:
285: if ((reg = kk->addr) == NULL)
286: return;
287: if (kk->ibuf)
288: return;
289: for (sts = 0, n = 0; n < STALL; n++) {
290: if ((reg->cmd & CGO) == 0
291: && (sts = reg->sts) & SRRDY)
292: break;
293: /* delay to free up unibus? */
294: }
295: if ((sts & SRRDY) == 0) {
296: printf("kb rcv not ready, sts %o cmd %o\n", reg->sts, reg->cmd);
297: panic("kbistart");
298: return;
299: }
300: if (sts & SERROR)
301: printf("kb err, sts %o\n", sts&0177777);
302: if ((bp = allocb(DKISIZE)) == NULL
303: || (kk->imap = ubmblk(kk->ubno, bp, 0)) == 0) {
304: panic("kbistart can't alloc\n"); /* later printf */
305: if (bp)
306: freeb(bp);
307: return;
308: }
309: kk->ibuf = bp;
310: if ((int)bp->rptr & 01)
311: bp->rptr++;
312: kk->iaddr = ua = ubadrptr(kk->ubno, bp, kk->imap);
313: reg->bc = bp->rptr - bp->lim; /* sic - negative count */
314: reg->ba = ua;
315: n = (ua >> 16) << XASHIFT;
316: n &= CXA;
317: n |= CIE|CRCV;
318: reg->cmd = n;
319: }
320:
321: /*
322: * put procedure for output
323: */
324: kbput(q, bp)
325: struct queue *q;
326: register struct block *bp;
327: {
328: register struct kb *dkp;
329: register struct kbkmc *kk;
330: register int n;
331: register struct device *reg;
332: register int sts;
333: int s;
334:
335: dkp = (struct kb *)q->ptr;
336: kk = &kbkmc[KBNO];
337: switch (bp->type) {
338:
339: case M_IOCTL:
340: switch (stiocom(bp)) {
341: case DIOCNXCL:
342: dkp->flag &=~ DKXCL;
343: bp->wptr = bp->rptr;
344: bp->type = M_IOCACK;
345: break;
346:
347: case KIOCINIT:
348: /* eventually, reset things here */
349:
350: default:
351: bp->type = M_IOCNAK;
352: break;
353: }
354: qreply(q, bp);
355: return;
356:
357: case M_CTL:
358: case M_DATA:
359: if (bp->rptr == bp->wptr) {
360: freeb(bp);
361: return;
362: }
363: dkstat.output += bp->wptr - bp->rptr;
364: s = spl5();
365: reg = kk->addr;
366: for (sts = 0, n = 0; n < STALL; n++) {
367: if ((reg->cmd & CGO) == 0
368: && (sts = reg->sts) & SXRDY)
369: break;
370: DELAY(40); /* get off the UNIBUS */
371: }
372: if ((sts & SXRDY) == 0) { /* n >= STALL */
373: printf("kb xmit not ready, sts %o, cmd %o\n", sts, reg->cmd);
374: splx(s);
375: freeb(bp);
376: return;
377: }
378: if (sts & SERROR)
379: printf("kb err, sts %o\n", sts&0177777);
380: ubmflush(kk->ubno, ubmpath(kk->omap));
381: if (kk->obuf) {
382: freeb(kk->obuf);
383: kk->obuf = NULL;
384: }
385: n = bp->wptr - bp->rptr;
386: kk->oaddr = ubmaddr(kk->ubno, bp->rptr, n, kk->omap);
387: reg->bc = -n;
388: reg->ba = kk->oaddr;
389: n = (kk->oaddr >> 16)<<XASHIFT;
390: n &= CXA;
391: n |= dkp->chan;
392: if (bp->type == M_DATA)
393: n |= CSEND;
394: else
395: n |= CSCTL;
396: reg->cmd = n;
397: kk->obuf = bp;
398: splx(s);
399: return;
400:
401: case M_PRICTL:
402: switch (*bp->rptr) {
403: case DKMCLOSE:
404: n = bp->rptr[1];
405: if (n < kbcnt) {
406: if (kbstate[n] == DKOPEN) {
407: kbstate[n] = DKRCLOSE;
408: putctl(kb[n].dkrq->next, M_HANGUP);
409: } else if (kbstate[n] == DKLCLOSE)
410: kbstate[n] = DKCLOSED;
411: }
412: freeb(bp);
413: return;
414:
415: case DKMXINIT:
416: n = bp->rptr[1];
417: if (n < kbcnt && kbstate[n] == DKOPEN)
418: (*kb[n].dkrq->next->qinfo->putp)(kb[n].dkrq->next, bp);
419: else
420: freeb(bp);
421: return;
422:
423: default:
424: freeb(bp);
425: return;
426: }
427:
428: default:
429: freeb(bp);
430: return;
431: }
432: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.