Annotation of researchv10no/sys/io/unixpld.c, revision 1.1.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.