|
|
1.1 root 1: /*
2: * Raw line discipline and communications with unixp datakit controller
3: */
4: #include "sys/param.h"
5: #include "sys/stream.h"
6: #include "sys/dkio.h"
7: #include "sys/conf.h"
8: #include "sys/dkstat.h"
9: #include "sys/dkmod.h"
10:
11: /*
12: * Unixp message structure
13: */
14: struct dialin {
15: char type;
16: char srv;
17: short param0;
18: short param1;
19: short param2;
20: short param3;
21: short param4;
22: };
23:
24: /*
25: * Message codes
26: */
27: #define T_SRV 1
28: #define T_REPLY 2
29: #define T_CHG 3
30: #define T_ALIVE 4
31: #define T_RESTART 8
32: #define D_CLOSE 1
33: #define D_ISCLOSED 2
34: #define D_CLOSEALL 3
35: #define D_OK 1
36: #define D_OPEN 2
37: #define D_FAIL 3
38: #define D_RESTART 1
39: #define D_XINIT 7
40:
41: /*
42: * Raw-mode line discipline for DK (only)
43: */
44: long xpopen();
45: int xpclose(), xpiput(), xpoput(), xposrv();
46: static struct qinit xprinit = { xpiput, NULL, xpopen, xpclose, 72, 36};
47: static struct qinit xpwinit = { xpoput, xposrv, xpopen, nulldev, 72, 36};
48: struct streamtab xpstream = { &xprinit, &xpwinit };
49:
50: extern struct dkstat dkstat;
51: extern struct dkmodule dkmod[];
52: extern int dkmodcnt;
53:
54: #define NDKRAW 32
55: struct xp {
56: struct queue *q;
57: struct dkmodule *module;
58: short chan;
59: } xp[NDKRAW];
60:
61: long
62: xpopen(q, dev)
63: register struct queue *q;
64: {
65: static timer_on = 0;
66: register struct xp *dkp, *edkp;
67: register struct dkmodule *dkm;
68:
69: if ((dkm = getdkmod(dev)) == NULL)
70: return (0);
71: edkp = NULL;
72: for (dkp=xp; dkp < &xp[NDKRAW]; dkp++) {
73: if (dkp->q == q) {
74: if (dkp->chan != minor(dev) - dkm->lo || WR(q)->ptr==NULL) {
75: printf("q %x dkp %x\n", q, dkp);
76: panic("xpopen");
77: }
78: return(1);
79: }
80: if (dkp->q == NULL && edkp==NULL)
81: edkp = dkp;
82: }
83: if (edkp==NULL)
84: return(0);
85: edkp->q = q;
86: edkp->chan = minor(dev) - dkm->lo;
87: edkp->module = dkm;
88: q->flag |= QDELIM;
89: q->ptr = 0;
90: WR(q)->ptr = (caddr_t)edkp;
91: if (timer_on==0) {
92: xptimer();
93: timer_on = 1;
94: }
95: return(1);
96: }
97:
98: xpclose(q)
99: register struct queue *q;
100: {
101: register struct block *bp;
102: register struct xp *dkp = (struct xp *)WR(q)->ptr;
103:
104: if (dkp==NULL) printf("null ptr; q %x wq %x\n", q, WR(q));
105: if (WR(q)==dkp->module->listnrq) {
106: dkp->module->listnrq = NULL;
107: dkp->module->type = 0;
108: }
109: while (bp = getq(q))
110: (*q->next->qinfo->putp)(q->next, bp);
111: dkp->q = NULL;
112: dkp->module = NULL;
113: }
114:
115: /*
116: * output put procedure.
117: */
118: xpoput(q, bp)
119: register struct queue *q;
120: register struct block *bp;
121: {
122: register struct xp *dkp = (struct xp *)q->ptr;
123: register struct dkmodule *modp = dkp->module;
124: register i;
125:
126: switch (bp->type) {
127:
128: case M_IOCTL:
129: switch (stiocom(bp)) {
130:
131: /* hang everybody up */
132: case DIOCHUP:
133: /* must be on low channels */
134: if (dkp->chan < 5) {
135: xpmesg(modp, T_ALIVE, D_RESTART, 0);
136: bp->type = M_IOCACK;
137: bp->rptr = bp->wptr;
138: qreply(q, bp);
139: return;
140: }
141: break;
142:
143: /* announce listener channel */
144: case DIOCLHN:
145: if (modp->listnrq == NULL) {
146: modp->listnrq = q;
147: modp->type = UNIXPLD;
148: xpmesg(modp, T_ALIVE, 0, 0);
149: bp->type = M_IOCACK;
150: bp->rptr = bp->wptr;
151: qreply(q, bp);
152: return;
153: }
154: break;
155:
156: /* delay input */
157: case DIOCSTOP:
158: RD(q)->ptr = (caddr_t)1;
159: bp->type = M_IOCACK;
160: bp->rptr = bp->wptr;
161: qreply(q, bp);
162: return;
163:
164: /* suggest a free outgoing channel */
165: case DIOCCHAN:
166: for (i=modp->lo + 2; i<modp->hi; i++) {
167: if (modp->dkstate[i]==DKCLOSED) {
168: *(int *)stiodata(bp) = i;
169: bp->wptr = bp->rptr+sizeof(int)+STIOCHDR;
170: bp->type = M_IOCACK;
171: break;
172: }
173: }
174: qreply(q, bp);
175: return;
176:
177: default:
178: (*q->next->qinfo->putp)(q->next, bp);
179: return;
180: }
181: bp->type = M_IOCNAK;
182: bp->wptr = bp->rptr;
183: qreply(q, bp);
184: return;
185: }
186: putq(q, bp);
187: }
188:
189: xposrv(q)
190: register struct queue *q;
191: {
192: register struct block *bp;
193:
194: while ((q->next->flag&QFULL)==0 && (bp = getq(q)))
195: (*q->next->qinfo->putp)(q->next, bp);
196: }
197:
198: /*
199: * input put procedure
200: * -- ignores almost all control bytes
201: */
202: xpiput(q, bp)
203: register struct queue *q;
204: register struct block *bp;
205: {
206: register struct xp *dkp = (struct xp *)WR(q)->ptr;
207:
208: switch (bp->type) {
209:
210: case M_DATA:
211: if (WR(q)==dkp->module->listnrq && xplstnr(dkp->module, bp))
212: return;
213: if (q->next->flag&QFULL) { /* sorry, you lose */
214: freeb(bp);
215: return;
216: }
217: bp->class |= S_DELIM;
218: if (q->ptr) { /* input delayed */
219: putq(q, bp);
220: return;
221: }
222: (*q->next->qinfo->putp)(q->next, bp);
223: return;
224:
225: case M_IOCACK:
226: case M_IOCNAK:
227: case M_HANGUP:
228: (*q->next->qinfo->putp)(q->next, bp);
229: return;
230:
231: case M_PRICTL:
232: switch (*bp->rptr) {
233: case DKMCLOSE:
234: dkp->module->dkstate[bp->rptr[1]] = DKLCLOSE;
235: xpmesg(dkp->module, T_CHG, D_CLOSE, bp->rptr[1]);
236: freeb(bp);
237: return;
238:
239: default:
240: freeb(bp);
241: return;
242: }
243:
244: default:
245: freeb(bp);
246: }
247: }
248:
249: /*
250: * listener sends a message to CMC
251: */
252: xpmesg(modp, type, srv, p0)
253: register struct dkmodule *modp;
254: {
255: register struct dialin *dp;
256: register struct block *bp;
257:
258: if (modp->listnrq==NULL || modp->listnrq->next->flag&QFULL)
259: return;
260: if ((bp = allocb(sizeof(struct dialin))) == NULL)
261: return; /* hope it will be retried later */
262: dp = (struct dialin *)bp->wptr;
263: dp->type = type;
264: dp->srv = srv;
265: dp->param0 = p0;
266: dp->param1 = 0;
267: dp->param2 = 0;
268: dp->param3 = 0;
269: dp->param4 = 0;
270: bp->wptr += sizeof(struct dialin);
271: bp->class |= S_DELIM;
272: (*modp->listnrq->next->qinfo->putp)(modp->listnrq->next, bp);
273: }
274:
275: /*
276: * Receive message for listener
277: */
278: xplstnr(modp, bp)
279: register struct block *bp;
280: struct dkmodule *modp;
281: {
282: register struct dialin *dialp;
283: register i;
284: register struct queue *listnrq = modp->listnrq;
285: register struct xp *dkp;
286: int t;
287:
288: dialp = (struct dialin *)bp->rptr;
289: i = dialp->param0;
290: t = dialp->param1;
291:
292: switch (dialp->type) {
293:
294: case T_CHG:
295: if (dialp->srv == D_CLOSEALL) {
296: printf("datakit closing all chans\n");
297: for(i=modp->hi-modp->lo-1; i > 0; i--) {
298: if(((struct xp *)listnrq->ptr)->chan == i)
299: continue;
300: switch (modp->dkstate[i]) {
301:
302: case DKRCLOSE:
303: dkstat.notclosed++;
304: case DKOPEN:
305: printf("closing %d\n", i);
306: putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
307: break;
308:
309: case DKLCLOSE:
310: printf("closed %d\n", i);
311: case DKCLOSED:
312: modp->dkstate[i] = DKCLOSED;
313: break;
314: }
315: }
316: freeb(bp);
317: return(1);
318: }
319: if (i <= 0 || i >= modp->hi - modp->lo) {
320: dkstat.chgstrange++;
321: if (dialp->srv)
322: xpmesg(modp, T_CHG, D_CLOSE, i);
323: freeb(bp);
324: return(1);
325: }
326: switch (dialp->srv) {
327:
328: case D_CLOSE: /* remote shutdown */
329: switch (modp->dkstate[i]) {
330:
331: case DKRCLOSE:
332: dkstat.notclosed++;
333: case DKOPEN:
334: putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
335: break;
336:
337: case DKLCLOSE:
338: case DKCLOSED:
339: xpmesg(modp, T_CHG, D_CLOSE, i);
340: break;
341: }
342: break;
343:
344: case D_ISCLOSED:
345: switch (modp->dkstate[i]) {
346:
347: case DKLCLOSE:
348: case DKCLOSED:
349: putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
350: break;
351:
352: case DKOPEN:
353: case DKRCLOSE:
354: dkstat.isclosed++;
355: break;
356: }
357: break;
358: }
359: freeb(bp);
360: return(1);
361:
362: case T_REPLY: /* CMC sends reply; find, and hand to process */
363: if (i < 0 || i >= modp->hi - modp->lo)
364: return(0);
365: for (dkp=xp; dkp<&xp[NDKRAW]; dkp++) {
366: if (dkp->module==modp && dkp->chan==i) {
367: (*dkp->q->next->qinfo->putp)(dkp->q->next, bp);
368: return(1);
369: }
370: }
371: return(0);
372:
373: case T_SRV:
374: /* see if we've been spliced */
375: if (dialp->srv == D_XINIT) {
376: if (i < 0 || i >= modp->hi - modp->lo)
377: return(0);
378: freeb(bp);
379: if((bp = allocb(4))==0)
380: return(0);
381: *bp->wptr++ = DKMXINIT;
382: *bp->wptr++ = i;
383: *bp->wptr++ = t>>8;
384: *bp->wptr++ = t;
385: bp->type = M_PRICTL;
386: (*listnrq->next->qinfo->putp)(listnrq->next, bp);
387: return(1);
388: }
389: return(0);
390:
391: case T_RESTART:
392: /* datakit has rebooted, tell it what we think is closed */
393: printf("datakit restart\n");
394: for(i = modp->hi - modp->lo - 1; i > 0; --i) {
395: switch (modp->dkstate[i]) {
396: case DKLCLOSE:
397: xpmesg(modp, T_CHG, D_CLOSE, i);
398: break;
399: }
400: }
401: freeb(bp);
402: return(1);
403:
404: default:
405: return(0);
406: }
407: }
408:
409: /*
410: * 15-second timer
411: */
412: xptimer()
413: {
414: register i;
415: register struct dkmodule *dkp;
416:
417: for (dkp = dkmod; dkp < &dkmod[dkmodcnt]; dkp++) {
418: if (dkp->listnrq && dkp->type == UNIXPLD) {
419: xpmesg(dkp, T_ALIVE, 0, 0);
420: for (i=dkp->hi - dkp->lo - 1; i >= 0; --i)
421: if (dkp->dkstate[i] == DKLCLOSE)
422: xpmesg(dkp, T_CHG, D_CLOSE, i);
423: }
424: }
425: timeout(xptimer, (caddr_t)NULL, 15*HZ);
426: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.