|
|
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.