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

1.1     ! root        1: /*
        !             2:  *  Raw line discipline and listener stuff for talking to 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:  * CMC/Listener 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:        short   param5;
        !            23: };
        !            24: 
        !            25: struct dialout {
        !            26:        short   chan;
        !            27:        struct  dialin d;
        !            28: };
        !            29: 
        !            30: /*
        !            31:  * Message codes
        !            32:  */
        !            33: #define        T_LSTNR 4
        !            34: #define        T_CHG   3
        !            35: #define        T_REPLY 10
        !            36: #define        D_CLOSE 1
        !            37: #define        D_ISCLOSED 2
        !            38: #define        D_ENQ   3
        !            39: #define        D_ENQANS 4
        !            40: 
        !            41: /*
        !            42:  * Raw-mode line discipline for DK (only)
        !            43:  */
        !            44: long   rdkopen();
        !            45: int    rdkclose(), rdkiput(), rdkoput(), rdkosrv();
        !            46: static struct qinit rdkrinit = { rdkiput, NULL, rdkopen, rdkclose, 72, 36};
        !            47: static struct qinit rdkwinit = { rdkoput, rdkosrv, rdkopen, nulldev, 72, 36};
        !            48: struct streamtab rdkstream = { &rdkrinit, &rdkwinit };
        !            49: 
        !            50: extern struct  dkstat dkstat;
        !            51: extern struct  dkmodule dkmod[];
        !            52: extern int dkmodcnt;
        !            53: 
        !            54: #define        NDKRAW  32
        !            55: struct rdk {
        !            56:        struct  queue *q;
        !            57:        struct  dkmodule *module;
        !            58:        short   chan;
        !            59: } rdk[NDKRAW];
        !            60: 
        !            61: long
        !            62: rdkopen(q, dev)
        !            63: register struct queue *q;
        !            64: {
        !            65:        static timer_on = 0;
        !            66:        register struct rdk *dkp, *edkp;
        !            67:        register struct dkmodule *dkm;
        !            68: 
        !            69:        if ((dkm = getdkmod(dev)) == NULL)
        !            70:                return (0);
        !            71:        edkp = NULL;
        !            72:        for (dkp=rdk; dkp < &rdk[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("rdkopen");
        !            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->module = dkm;
        !            87:        edkp->chan = minor(dev) - dkm->lo;
        !            88:        q->flag |= QDELIM;
        !            89:        q->ptr = 0;
        !            90:        WR(q)->ptr = (caddr_t)edkp;
        !            91:        if (timer_on==0) {
        !            92:                dktimer();
        !            93:                timer_on = 1;
        !            94:        }
        !            95:        return(1);
        !            96: }
        !            97: 
        !            98: rdkclose(q)
        !            99: register struct queue *q;
        !           100: {
        !           101:        register struct block *bp;
        !           102:        register struct rdk *dkp = (struct rdk *)WR(q)->ptr;
        !           103: 
        !           104:        if (WR(q)==dkp->module->listnrq) {
        !           105:                dkp->module->listnrq = NULL;
        !           106:                dkp->module->type = 0;
        !           107:        }
        !           108:        while (bp = getq(q))
        !           109:                (*q->next->qinfo->putp)(q->next, bp);
        !           110:        dkp->q = NULL;
        !           111:        dkp->module = NULL;
        !           112: }
        !           113: 
        !           114: /*
        !           115:  * output put procedure.
        !           116:  */
        !           117: rdkoput(q, bp)
        !           118: register struct queue *q;
        !           119: register struct block *bp;
        !           120: {
        !           121:        register struct rdk *dkp = (struct rdk *)q->ptr;
        !           122:        register struct dkmodule *modp = dkp->module;
        !           123:        register i;
        !           124: 
        !           125:        switch (bp->type) {
        !           126: 
        !           127:        case M_IOCTL:
        !           128:                switch (stiocom(bp)) {
        !           129: 
        !           130:                /* hang everybody up */
        !           131:                case DIOCHUP:
        !           132:                        /* must be on listener chan */
        !           133:                        if (q == modp->listnrq) {
        !           134:                                dkmesg(modp, T_LSTNR, 0, 0, 0, 1);
        !           135:                                bp->type = M_IOCACK;
        !           136:                                bp->rptr = bp->wptr;
        !           137:                                qreply(q, bp);
        !           138:                                return;
        !           139:                        }
        !           140:                        break;
        !           141: 
        !           142:                /* announce listener channel */
        !           143:                case DIOCLHN:
        !           144:                        if (modp->listnrq == NULL) {
        !           145:                                modp->listnrq = q;
        !           146:                                modp->type = CMCLD;
        !           147:                                dkmesg(modp, T_LSTNR, 0, 0, 0, 0);
        !           148:                                bp->type = M_IOCACK;
        !           149:                                bp->rptr = bp->wptr;
        !           150:                                qreply(q, bp);
        !           151:                                return;
        !           152:                        }
        !           153:                        break;
        !           154: 
        !           155:                /* delay input */
        !           156:                case DIOCSTOP:
        !           157:                        RD(q)->ptr = (caddr_t)1;
        !           158:                        bp->type = M_IOCACK;
        !           159:                        bp->rptr = bp->wptr;
        !           160:                        qreply(q, bp);
        !           161:                        return;
        !           162: 
        !           163:                /* suggest a free outgoing channel */
        !           164:                case DIOCCHAN:
        !           165:                        for (i=modp->lo + 3; i<modp->hi; i+=2) {
        !           166:                                if (modp->dkstate[i]==DKCLOSED) {
        !           167:                                        stiodata(bp)[0] = i;
        !           168:                                        for (i = 1; i < sizeof(int); i++)
        !           169:                                                stiodata(bp)[i] = 0;    /* silly */
        !           170:                                        bp->wptr = bp->rptr+STIOCHDR+sizeof(int);
        !           171:                                        bp->type = M_IOCACK;
        !           172:                                        break;
        !           173:                                }
        !           174:                        }
        !           175:                        qreply(q, bp);
        !           176:                        return;
        !           177: 
        !           178:                default:
        !           179:                        (*q->next->qinfo->putp)(q->next, bp);
        !           180:                        return;
        !           181:                }
        !           182:                bp->type = M_IOCNAK;
        !           183:                bp->wptr = bp->rptr;
        !           184:                qreply(q, bp);
        !           185:                return;
        !           186:        }
        !           187:        putq(q, bp);
        !           188: }
        !           189: 
        !           190: rdkosrv(q)
        !           191: register struct queue *q;
        !           192: {
        !           193:        register struct block *bp;
        !           194: 
        !           195:        while ((q->next->flag&QFULL)==0 && (bp = getq(q)))
        !           196:                (*q->next->qinfo->putp)(q->next, bp);
        !           197: }
        !           198: 
        !           199: /*
        !           200:  * input put procedure
        !           201:  *   -- ignores all control bytes
        !           202:  */
        !           203: rdkiput(q, bp)
        !           204: register struct queue *q;
        !           205: register struct block *bp;
        !           206: {
        !           207:        register struct rdk *dkp = (struct rdk *)WR(q)->ptr;
        !           208: 
        !           209:        switch (bp->type) {
        !           210: 
        !           211:        case M_DATA:
        !           212:                if (WR(q)==dkp->module->listnrq && dklstnr(dkp->module, bp))
        !           213:                        return;
        !           214:                if (q->next->flag&QFULL) { /* you lose */
        !           215:                        freeb(bp);
        !           216:                        return;
        !           217:                }
        !           218:                bp->class |= S_DELIM;   /* always push through */
        !           219:                if (q->ptr) {   /* input delayed */
        !           220:                        putq(q, bp);
        !           221:                        return;
        !           222:                }
        !           223:                (*q->next->qinfo->putp)(q->next, bp);
        !           224:                return;
        !           225: 
        !           226:        case M_IOCACK:
        !           227:        case M_IOCNAK:
        !           228:        case M_HANGUP:
        !           229:                (*q->next->qinfo->putp)(q->next, bp);
        !           230:                return;
        !           231: 
        !           232:        case M_PRICTL:
        !           233:                switch (*bp->rptr) {
        !           234:                case DKMCLOSE:
        !           235:                        if (dkp->module->dkstate[bp->rptr[1]] == DKRCLOSE)
        !           236:                                dkmesg(dkp->module, T_CHG, D_ISCLOSED, 0, bp->rptr[1], 0);
        !           237:                        else
        !           238:                                dkmesg(dkp->module, T_CHG, D_CLOSE, 0, bp->rptr[1], 0);
        !           239:                        freeb(bp);
        !           240:                        return;
        !           241: 
        !           242:                default:
        !           243:                        freeb(bp);
        !           244:                        return;
        !           245:                }
        !           246: 
        !           247:        default:
        !           248:                freeb(bp);
        !           249:        }
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * listener sends a message to CMC
        !           254:  */
        !           255: dkmesg(modp, type, srv, p0, p1, p2)
        !           256: register struct dkmodule *modp;
        !           257: {
        !           258:        register struct dialout *dp;
        !           259:        register struct block *bp;
        !           260: 
        !           261:        if (modp->listnrq==NULL || modp->listnrq->next->flag&QFULL)
        !           262:                return;
        !           263:        if ((bp = allocb(sizeof(struct dialout))) == NULL)
        !           264:                return;         /* hope it will be retried later */
        !           265:        dp = (struct dialout *)bp->wptr;
        !           266:        dp->chan = ((struct rdk *)modp->listnrq->ptr)->chan;
        !           267:        dp->d.type = type;
        !           268:        dp->d.srv = srv;
        !           269:        dp->d.param0 = p0;
        !           270:        dp->d.param1 = p1;
        !           271:        dp->d.param2 = p2;
        !           272:        bp->wptr += sizeof(struct dialout);
        !           273:        bp->class |= S_DELIM;
        !           274:        (*modp->listnrq->next->qinfo->putp)(modp->listnrq->next, bp);
        !           275: }
        !           276: 
        !           277: /*
        !           278:  * Receive message for listener
        !           279:  */
        !           280: dklstnr(modp, bp)
        !           281: register struct block *bp;
        !           282: struct dkmodule *modp;
        !           283: {
        !           284:        register struct dialin *dialp;
        !           285:        register i;
        !           286:        register struct queue *listnrq = modp->listnrq;
        !           287:        register struct rdk *dkp;
        !           288: 
        !           289:        dialp = (struct dialin *)bp->rptr;
        !           290:        switch (dialp->type) {
        !           291: 
        !           292:        case T_CHG:
        !           293:                i = dialp->param1;
        !           294:                if (i <= 0 || i >= modp->hi - modp->lo) {
        !           295:                        dkstat.chgstrange++;
        !           296:                        if (dialp->srv)
        !           297:                                dkmesg(modp, T_CHG, D_ISCLOSED, 0, i, 0);
        !           298:                        freeb(bp);
        !           299:                        return(1);
        !           300:                }
        !           301:                switch (dialp->srv) {
        !           302: 
        !           303:                case D_CLOSE:           /* remote shutdown */
        !           304:                        switch (modp->dkstate[i]) {
        !           305: 
        !           306:                        case DKRCLOSE:
        !           307:                                dkstat.notclosed++;
        !           308:                        case DKOPEN:
        !           309:                                putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
        !           310:                                break;
        !           311: 
        !           312:                        case DKLCLOSE:
        !           313:                        case DKCLOSED:
        !           314:                                dkmesg(modp, T_CHG, D_ISCLOSED, 0, i, 0);
        !           315:                                putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
        !           316:                                break;
        !           317:                        }
        !           318:                        break;
        !           319:                
        !           320:                case D_ISCLOSED:
        !           321:                        switch (modp->dkstate[i]) {
        !           322: 
        !           323:                        case DKLCLOSE:
        !           324:                        case DKCLOSED:
        !           325:                                putctl2(listnrq->next, M_PRICTL, DKMCLOSE, i);
        !           326:                                break;
        !           327: 
        !           328:                        case DKOPEN:
        !           329:                        case DKRCLOSE:
        !           330:                                dkstat.isclosed++;
        !           331:                                break;
        !           332:                        }
        !           333:                        break;
        !           334: 
        !           335:                case D_ENQ:
        !           336:                        dkmesg(modp, T_CHG, D_ENQANS, 0, i, modp->dkstate[i]);
        !           337:                        break;
        !           338:                }
        !           339:                freeb(bp);
        !           340:                return(1);
        !           341: 
        !           342:        case T_REPLY:   /* CMC sends reply; find, and hand to process */
        !           343:                i = dialp->param0;
        !           344:                if (i < 0 || i >= modp->hi - modp->lo)
        !           345:                        return(0);
        !           346:                for (dkp=rdk; dkp<&rdk[NDKRAW]; dkp++) {
        !           347:                        if (dkp->module==modp && dkp->chan==i) {
        !           348:                                bp->class |= S_DELIM;
        !           349:                                (*dkp->q->next->qinfo->putp)(dkp->q->next, bp);
        !           350:                                return(1);
        !           351:                        }
        !           352:                }
        !           353:                return(0);
        !           354: 
        !           355:        default:
        !           356:                return(0);
        !           357:        }
        !           358: }
        !           359: 
        !           360: /*
        !           361:  * 15-second timer
        !           362:  * -- should look at dkmod->type, so different
        !           363:  * listeners can coexist
        !           364:  */
        !           365: dktimer()
        !           366: {
        !           367:        register i;
        !           368:        register struct dkmodule *dkp;
        !           369: 
        !           370:        for (dkp = dkmod; dkp < &dkmod[dkmodcnt]; dkp++) {
        !           371:                if (dkp->listnrq && dkp->type == CMCLD) {
        !           372:                        dkmesg(dkp, T_LSTNR, 0, 0, 0, 0);
        !           373:                        for (i=dkp->hi - dkp->lo - 1; i >= 0; --i)
        !           374:                                if (dkp->dkstate[i] == DKLCLOSE)
        !           375:                                        dkmesg(dkp, T_CHG, D_CLOSE, 0, i, 0);
        !           376:                }
        !           377:        }
        !           378:        timeout(dktimer, (caddr_t)NULL, 15*HZ);
        !           379: }

unix.superglobalmegacorp.com

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