Annotation of researchv10no/sys/io/unixpld.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.