Annotation of researchv8dc/sys/dev/cmcld.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  Raw line discipline and listener stuff for talking to controller
        !             3:  */
        !             4: #include "cm.h"
        !             5: #if NCM
        !             6: #include "../h/param.h"
        !             7: #include "../h/systm.h"
        !             8: #include "../h/stream.h"
        !             9: #include "../h/ioctl.h"
        !            10: #include "../h/pte.h"
        !            11: #include "../h/map.h"
        !            12: #include "../h/buf.h"
        !            13: #include "../h/ubavar.h"
        !            14: #include "../h/conf.h"
        !            15: #include "../h/dkstat.h"
        !            16: #include "../h/dkmod.h"
        !            17: #include "sparam.h"
        !            18: #include "dk.h"
        !            19: #include "kdi.h"
        !            20: #include "kmc.h"
        !            21: 
        !            22: /* channel states */
        !            23: #define        CLOSED  0
        !            24: #define        RCLOSE  1
        !            25: #define        LCLOSE  2
        !            26: #define        OPEN    3
        !            27: 
        !            28: /*
        !            29:  * CMC/Listener message structure
        !            30:  */
        !            31: struct dialin {
        !            32:        char    type;
        !            33:        char    srv;
        !            34:        short   param0;
        !            35:        short   param1;
        !            36:        short   param2;
        !            37:        short   param3;
        !            38:        short   param4;
        !            39:        short   param5;
        !            40: };
        !            41: 
        !            42: struct dialout {
        !            43:        short   chan;
        !            44:        struct  dialin d;
        !            45: };
        !            46: 
        !            47: /*
        !            48:  * Message codes
        !            49:  */
        !            50: #define        T_LSTNR 4
        !            51: #define        T_CHG   3
        !            52: #define        T_REPLY 10
        !            53: #define        D_CLOSE 1
        !            54: #define        D_ISCLOSED 2
        !            55: 
        !            56: /*
        !            57:  * Raw-mode line discipline for DK (only)
        !            58:  */
        !            59: int    nulldev(), rdkopen(), rdkclose(), rdkiput(), rdkoput(), rdkosrv();
        !            60: static struct qinit rdkrinit = { rdkiput, NULL, rdkopen, rdkclose, 72, 36};
        !            61: static struct qinit rdkwinit = { rdkoput, rdkosrv, rdkopen, nulldev, 72, 36};
        !            62: struct streamtab rdkinfo = { &rdkrinit, &rdkwinit };
        !            63: 
        !            64: extern struct  dkstat dkstat;
        !            65: #define        NDKMOD  (NDK+NKMC)      /* number of different DK devices */
        !            66: struct dkmodule dkmod[NDKMOD];
        !            67: 
        !            68: #define        NDKRAW  32
        !            69: struct rdk {
        !            70:        struct  queue *q;
        !            71:        struct  dkmodule *module;
        !            72:        short   chan;
        !            73: } rdk[NDKRAW];
        !            74: 
        !            75: rdkopen(q, dev)
        !            76: register struct queue *q;
        !            77: {
        !            78:        static timer_on = 0;
        !            79:        register struct rdk *dkp, *edkp;
        !            80:        register struct dkmodule *dkm;
        !            81: 
        !            82:        edkp = NULL;
        !            83:        for (dkp=rdk; ; dkp++) {
        !            84:                if (dkp >= &rdk[NDKRAW])
        !            85:                        break;
        !            86:                if (dkp->q == q) {
        !            87:                        if (dkp->chan != minor(dev) || WR(q)->ptr==NULL) {
        !            88:                                printf("q %x dkp %x\n", q, dkp);
        !            89:                                panic("rdkopen botch");
        !            90:                        }
        !            91:                        return(1);
        !            92:                }
        !            93:                if (dkp->q == NULL && edkp==NULL)
        !            94:                        edkp = dkp;
        !            95:        }
        !            96:        if (edkp==NULL)
        !            97:                return(0);
        !            98:        for (dkm=dkmod; ; dkm++) {
        !            99:                if (dkm >= &dkmod[NDKMOD])
        !           100:                        return(0);
        !           101:                if (major(dev) == dkm->dev)
        !           102:                        break;
        !           103:        }
        !           104:        edkp->q = q;
        !           105:        edkp->chan = minor(dev);
        !           106:        edkp->module = dkm;
        !           107:        q->flag |= QDELIM;
        !           108:        q->ptr = 0;
        !           109:        WR(q)->ptr = (caddr_t)edkp;
        !           110:        if (timer_on==0) {
        !           111:                dktimer();
        !           112:                timer_on = 1;
        !           113:        }
        !           114:        return(1);
        !           115: }
        !           116: 
        !           117: rdkclose(q)
        !           118: register struct queue *q;
        !           119: {
        !           120:        register i;
        !           121:        register struct block *bp;
        !           122:        register struct rdk *dkp = (struct rdk *)WR(q)->ptr;
        !           123: 
        !           124: if (dkp==NULL) printf("null ptr; q %x wq %x\n", q, WR(q));
        !           125:        if (WR(q)==dkp->module->listnrq)
        !           126:                dkp->module->listnrq = NULL;
        !           127:        while (bp = getq(q))
        !           128:                (*q->next->qinfo->putp)(q->next, bp);
        !           129:        dkp->q = NULL;
        !           130:        dkp->module = NULL;
        !           131: }
        !           132: 
        !           133: /*
        !           134:  * output put procedure.
        !           135:  */
        !           136: rdkoput(q, bp)
        !           137: register struct queue *q;
        !           138: register struct block *bp;
        !           139: {
        !           140:        register struct block *bp1;
        !           141:        register struct ioctl1 {
        !           142:                int     com;
        !           143:                int     stuff;
        !           144:        } *iop;
        !           145:        register struct rdk *dkp = (struct rdk *)q->ptr;
        !           146:        register struct dkmodule *modp = dkp->module;
        !           147:        register i;
        !           148: 
        !           149:        switch (bp->type) {
        !           150: 
        !           151:        case M_IOCTL:
        !           152:                switch (((struct ioctl1 *)bp->rptr)->com) {
        !           153: 
        !           154:                /* hang everybody up */
        !           155:                case DIOCHUP:
        !           156:                        /* must be on channel 1 or 0 */
        !           157:                        if (dkp->chan <= 1) {
        !           158:                                dkmesg(modp, T_LSTNR, 0, 0, 0, 1);
        !           159:                                bp->type = M_IOCACK;
        !           160:                                bp->rptr = bp->wptr;
        !           161:                                qreply(q, bp);
        !           162:                                return;
        !           163:                        }
        !           164:                        break;
        !           165: 
        !           166:                /* announce listener channel */
        !           167:                case DIOCLHN:
        !           168:                        if (modp->listnrq == NULL) {
        !           169:                                modp->listnrq = q;
        !           170:                                dkmesg(modp, T_LSTNR, 0, 0, 0, 0);
        !           171:                                bp->type = M_IOCACK;
        !           172:                                bp->rptr = bp->wptr;
        !           173:                                qreply(q, bp);
        !           174:                                return;
        !           175:                        }
        !           176:                        break;
        !           177: 
        !           178:                /* delay input */
        !           179:                case DIOCSTOP:
        !           180:                        RD(q)->ptr = (caddr_t)1;
        !           181:                        bp->type = M_IOCACK;
        !           182:                        bp->rptr = bp->wptr;
        !           183:                        qreply(q, bp);
        !           184:                        return;
        !           185: 
        !           186:                /* suggest a free outgoing channel */
        !           187:                case DIOCCHAN:
        !           188:                        for (i=3; i<modp->nchan; i+=2) {
        !           189:                                if (modp->dkstate[i]==CLOSED) {
        !           190:                                        ((struct ioctl1 *)bp->rptr)->stuff = i;
        !           191:                                        bp->wptr =
        !           192:                                             bp->rptr+sizeof(struct ioctl1);
        !           193:                                        bp->type = M_IOCACK;
        !           194:                                        break;
        !           195:                                }
        !           196:                        }
        !           197:                        qreply(q, bp);
        !           198:                        return;
        !           199: 
        !           200:                default:
        !           201:                        (*q->next->qinfo->putp)(q->next, bp);
        !           202:                        return;
        !           203:                }
        !           204:                bp->type = M_IOCNAK;
        !           205:                bp->wptr = bp->rptr;
        !           206:                qreply(q, bp);
        !           207:                return;
        !           208:        }
        !           209:        putq(q, bp);
        !           210: }
        !           211: 
        !           212: rdkosrv(q)
        !           213: register struct queue *q;
        !           214: {
        !           215:        register struct block *bp;
        !           216: 
        !           217:        while ((q->next->flag&QFULL)==0 && (bp = getq(q)))
        !           218:                (*q->next->qinfo->putp)(q->next, bp);
        !           219: }
        !           220: 
        !           221: /*
        !           222:  * input put procedure
        !           223:  *   -- ignores all control bytes
        !           224:  */
        !           225: rdkiput(q, bp)
        !           226: register struct queue *q;
        !           227: register struct block *bp;
        !           228: {
        !           229:        register struct rdk *dkp = (struct rdk *)WR(q)->ptr;
        !           230: 
        !           231:        switch (bp->type) {
        !           232: 
        !           233:        case M_DATA:
        !           234:                if (WR(q)==dkp->module->listnrq && dklstnr(dkp->module, bp))
        !           235:                        return;
        !           236:                if (q->next->flag&QFULL) { /* sorry, you lose */
        !           237:                        freeb(bp);
        !           238:                        return;
        !           239:                }
        !           240:                if (q->ptr) {   /* input delayed */
        !           241:                        putq(q, bp);
        !           242:                        qpctl(q, M_DELIM);
        !           243:                        return;
        !           244:                }
        !           245:                (*q->next->qinfo->putp)(q->next, bp);
        !           246:                putctl(q->next, M_DELIM);
        !           247:                return;
        !           248: 
        !           249:        case M_IOCACK:
        !           250:        case M_IOCNAK:
        !           251:        case M_HANGUP:
        !           252:                (*q->next->qinfo->putp)(q->next, bp);
        !           253:                return;
        !           254: 
        !           255:        case M_CLOSE:
        !           256:                if (dkp->module->dkstate[*bp->rptr] == RCLOSE)
        !           257:                        dkmesg(dkp->module, T_CHG, D_ISCLOSED, 0, *bp->rptr, 0);
        !           258:                else
        !           259:                        dkmesg(dkp->module, T_CHG, D_CLOSE, 0, *bp->rptr, 0);
        !           260:                freeb(bp);
        !           261:                return;
        !           262: 
        !           263:        default:
        !           264:                freeb(bp);
        !           265:        }
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * listener sends a message to CMC
        !           270:  */
        !           271: dkmesg(modp, type, srv, p0, p1, p2)
        !           272: register struct dkmodule *modp;
        !           273: {
        !           274:        register struct dialout *dp;
        !           275:        register struct block *bp;
        !           276: 
        !           277:        if (modp->listnrq==NULL || modp->listnrq->next->flag&QFULL)
        !           278:                return;
        !           279:        if ((bp = allocb(sizeof(struct dialout))) == NULL)
        !           280:                return;         /* hope it will be retried later */
        !           281:        dp = (struct dialout *)bp->wptr;
        !           282:        dp->chan = 1;           /* channel 1 builtin */
        !           283:        dp->d.type = type;
        !           284:        dp->d.srv = srv;
        !           285:        dp->d.param0 = p0;
        !           286:        dp->d.param1 = p1;
        !           287:        dp->d.param2 = p2;
        !           288:        bp->wptr += sizeof(struct dialout);
        !           289:        (*modp->listnrq->next->qinfo->putp)(modp->listnrq->next, bp);
        !           290:        putctl(modp->listnrq->next, M_DELIM);
        !           291: }
        !           292: 
        !           293: /*
        !           294:  * Receive message for listener
        !           295:  */
        !           296: dklstnr(modp, bp)
        !           297: register struct block *bp;
        !           298: struct dkmodule *modp;
        !           299: {
        !           300:        register struct dialin *dialp;
        !           301:        register i;
        !           302:        register struct queue *listnrq = modp->listnrq;
        !           303:        register struct rdk *dkp;
        !           304: 
        !           305:        dialp = (struct dialin *)bp->rptr;
        !           306:        switch (dialp->type) {
        !           307: 
        !           308:        case T_CHG:
        !           309:                i = dialp->param1;
        !           310:                if (i <= 0 || i >= modp->nchan) {
        !           311:                        dkstat.chgstrange++;
        !           312:                        if (dialp->srv)
        !           313:                                dkmesg(modp, T_CHG, D_ISCLOSED, 0, i, 0);
        !           314:                        freeb(bp);
        !           315:                        return(1);
        !           316:                }
        !           317:                switch (dialp->srv) {
        !           318: 
        !           319:                case D_CLOSE:           /* remote shutdown */
        !           320:                        switch (modp->dkstate[i]) {
        !           321: 
        !           322:                        case RCLOSE:
        !           323:                                dkstat.notclosed++;
        !           324:                        case OPEN:
        !           325:                                putctl1(listnrq->next, M_CLOSE, i);
        !           326:                                break;
        !           327: 
        !           328:                        case LCLOSE:
        !           329:                        case CLOSED:
        !           330:                                dkmesg(modp, T_CHG, D_ISCLOSED, 0, i, 0);
        !           331:                                putctl1(listnrq->next, M_CLOSE, i);
        !           332:                                break;
        !           333:                        }
        !           334:                        break;
        !           335:                
        !           336:                case D_ISCLOSED:
        !           337:                        switch (modp->dkstate[i]) {
        !           338: 
        !           339:                        case LCLOSE:
        !           340:                        case CLOSED:
        !           341:                                putctl1(listnrq->next, M_CLOSE, i);
        !           342:                                break;
        !           343: 
        !           344:                        case OPEN:
        !           345:                        case RCLOSE:
        !           346:                                dkstat.isclosed++;
        !           347:                                break;
        !           348:                        }
        !           349:                        break;
        !           350:                }
        !           351:                freeb(bp);
        !           352:                return(1);
        !           353: 
        !           354:        case T_REPLY:   /* CMC sends reply; find, and hand to process */
        !           355:                i = dialp->param0;
        !           356:                if (i < 0 || i >= modp->nchan)
        !           357:                        return(0);
        !           358:                for (dkp=rdk; dkp<&rdk[NDKRAW]; dkp++) {
        !           359:                        if (dkp->module==modp && dkp->chan==i) {
        !           360:                                (*dkp->q->next->qinfo->putp)(dkp->q->next, bp);
        !           361:                                putctl(dkp->q->next, M_DELIM);
        !           362:                                return(1);
        !           363:                        }
        !           364:                }
        !           365:                return(0);
        !           366: 
        !           367:        default:
        !           368:                return(0);
        !           369:        }
        !           370: }
        !           371: 
        !           372: /*
        !           373:  * 15-second timer
        !           374:  */
        !           375: dktimer()
        !           376: {
        !           377:        register i;
        !           378:        register struct dkmodule *dkp;
        !           379: 
        !           380:        for (dkp = dkmod; dkp < &dkmod[NDKMOD]; dkp++) {
        !           381:                if (dkp->listnrq) {
        !           382:                        dkmesg(dkp, T_LSTNR, 0, 0, 0, 0);
        !           383:                        for (i=0; i< dkp->nchan; i++)
        !           384:                                if (dkp->dkstate[i] == LCLOSE)
        !           385:                                        dkmesg(dkp, T_CHG, D_CLOSE, 0, i, 0);
        !           386:                }
        !           387:        }
        !           388:        timeout(dktimer, (caddr_t)NULL, 15*hz);
        !           389: }
        !           390: #endif

unix.superglobalmegacorp.com

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