Annotation of researchv10no/sys/io/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 "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.