Annotation of researchv8dc/sys/dev/cmcld.c, revision 1.1.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.