Annotation of researchv10dc/lsys/io/dkp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Datakit URP protocol
                      3:  *
                      4:  * In the language we speak to the device driver,
                      5:  * M_DATA blocks contain data envelopes
                      6:  * M_CTL blocks contain a control envelope,
                      7:  * followed by zero or more data envelopes
                      8:  *
                      9:  * Drivers are allowed to store up blocks for a while;
                     10:  * the S_DELIM bit means that stored date must now be sent.
                     11:  * The point is to work with some broken URP implementations
                     12:  * that have found their way into Datakit controllers;
                     13:  * a driver that speaks to one might have to save data up,
                     14:  * then send it with no intervening control-nulls when S_DELIM comes.
                     15:  */
                     16: 
                     17: #include "sys/param.h"
                     18: #include "sys/stream.h"
                     19: #include "sys/conf.h"
                     20: #include "sys/ttyio.h"
                     21: #include "sys/dkio.h"
                     22: #include "sys/dkstat.h"
                     23: #include "sys/dkp.h"
                     24: #include "sys/dkmod.h"
                     25: 
                     26: #ifdef CAREFUL
                     27: #define        TRC(c)  *dkptrp++ = c; if (dkptrp>=&dkptrb[1024]) dkptrp=dkptrb
                     28: char   dkptrb[1024]; char *dkptrp = dkptrb;
                     29: #else
                     30: #define        TRC(c)
                     31: #endif
                     32: 
                     33: extern struct  dkstat dkstat;
                     34: 
                     35: /*
                     36:  *  Protocol control bytes
                     37:  */
                     38: #define        SEQ     0010            /* sequence number, ends trailers */
                     39: #undef ECHO
                     40: #define        ECHO    0020            /* echos, data given to next queue */
                     41: #define        REJ     0030            /* rejections, transmission error */
                     42: #define        ACK     0040            /* acknowledgments */
                     43: #define        BOT     0050            /* beginning of trailer */
                     44: #define        BOTM    0051            /* beginning of trailer, more data follows */
                     45: #define        BOTS    0052            /* seq update algorithm on this trailer */
                     46: #define        SOU     0053            /* start of unsequenced trailer */
                     47: #define        EOU     0054            /* end of unsequenced trailer */
                     48: #define        ENQ     0055            /* xmitter requests flow/error status */
                     49: #define        CHECK   0056            /* xmitter requests error status */
                     50: #define        INITREQ 0057            /* request initialization */
                     51: #define        INIT0   0060            /* disable trailer processing */
                     52: #define        INIT1   0061            /* enable trailer procesing */
                     53: #define        AINIT   0062            /* response to INIT0/INIT1 */
                     54: #undef DELAY
                     55: #define        DELAY   0100            /* real-time printing delay */
                     56: #define        BREAK   0110            /* Send/receive break (new style) */
                     57: 
                     58: #define        OPEN    01
                     59: #define        LCLOSE  02
                     60: #define        RCLOSE  04
                     61: #define        XCHARMODE 010
                     62: #define        OPENING 020
                     63: #define        RJING   040
                     64: #define        STOPPED 0100
                     65: #define        RCHARMODE 0200
                     66: 
                     67: #define        DKPPRI  28
                     68: #define        DKPTIME 2
                     69: 
                     70: extern struct dkp dkp[];
                     71: extern int     dkpcnt;
                     72: long   dkpopen(), cdkpopen();
                     73: int    dkpiput(), dkpisrv(), dkpoput(), dkposrv();
                     74: int    dkpclose();
                     75: static struct qinit cdkprinit = { dkpiput,dkpisrv,cdkpopen,dkpclose,512,64 };
                     76: static struct qinit cdkpwinit = { dkpoput,dkposrv,cdkpopen,dkpclose,128,65 };
                     77: static struct qinit dkprinit = { dkpiput,dkpisrv,dkpopen,dkpclose,1500,512 };
                     78: static struct qinit dkpwinit = { dkpoput,dkposrv,dkpopen,dkpclose,1500,512 };
                     79: struct streamtab dkpstream = { &dkprinit, &dkpwinit };
                     80: struct streamtab cdkpstream = { &cdkprinit, &cdkpwinit };
                     81: 
                     82: #define        MAXMSG  4096            /* max message size allowed */
                     83: 
                     84: long
                     85: dkpopen(q)
                     86: struct queue *q;
                     87: {
                     88:        return(rdkpopen(q, !XCHARMODE));
                     89: }
                     90: 
                     91: long
                     92: cdkpopen(q)
                     93: struct queue *q;
                     94: {
                     95:        return(rdkpopen(q, XCHARMODE));
                     96: }
                     97: 
                     98: rdkpopen(q, mode)
                     99: register struct queue *q;
                    100: {
                    101:        register struct dkp *dkpp;
                    102:        static timer = 0;
                    103:        int dkptimer();
                    104: 
                    105:        if (timer == 0) {
                    106:                timer = 1;
                    107:                timeout(dkptimer, (caddr_t)NULL, HZ);
                    108:        }
                    109:        if (q->ptr == NULL) {
                    110:                for (dkpp = dkp; dkpp->state!=0; dkpp++)
                    111:                        if (dkpp >= &dkp[dkpcnt])
                    112:                                return(0);
                    113:                dkpp->rdq = q;
                    114:                q->ptr = (caddr_t)dkpp;
                    115:                WR(q)->ptr = (caddr_t)dkpp;
                    116:                WR(q)->flag |= QNOENB;
                    117:                putctl(q->next, M_FLUSH);
                    118:                dkpp->timer = DKPTIME;
                    119:                dkpp->trx = 0;
                    120:                dkpp->iseq = 0;
                    121:                dkpp->lastecho = ECHO+0;
                    122:                dkpp->WS = 1;
                    123:                dkpp->WACK = 1;
                    124:                dkpp->WNX = 1;
                    125:                dkpp->XW = 3;
                    126:                dkpp->xsize = 64;
                    127:                dkpp->lastctl = 0;
                    128:                if (mode!=XCHARMODE) {
                    129:                        WR(q)->flag |= QDELIM;
                    130:                        dkpp->state = OPENING | RCHARMODE;
                    131:                        putctl1d(WR(q)->next, M_CTL, INIT1);
                    132:                } else {
                    133:                        dkpp->XW = 1;
                    134:                        dkpp->state = RCHARMODE | XCHARMODE | OPEN;
                    135:                        putctl1d(WR(q)->next, M_CTL, INIT0);
                    136:                }
                    137:        }
                    138:        return(1);
                    139: }
                    140: 
                    141: /*
                    142:  * Shut it down.
                    143:  *  The problem is to dispose of unacked stuff in the window.
                    144:  *   -- no real solution; the receiver might hang on for hours.
                    145:  *   Give it 15 seconds.
                    146:  */
                    147: dkpclose(q)
                    148: register struct queue *q;
                    149: {
                    150:        register struct dkp *dkpp;
                    151:        register s = spl5();
                    152:        register i;
                    153: 
                    154:        dkpp = (struct dkp *)q->ptr;
                    155:        dkpp->state |= LCLOSE;
                    156:        flushq(q, 1);
                    157:        for (i=0; dkpp->WACK < dkpp->WNX && i<15; i++)
                    158:                tsleep((caddr_t)dkpp, DKPPRI, 1);
                    159:        if (dkpp->WACK < dkpp->WNX)
                    160:                dkprack(dkpp, ACK+((dkpp->WNX-1) & 07));
                    161:        dkpinflush(dkpp);
                    162:        splx(s);
                    163:        dkpp->state = 0;
                    164:        flushq(WR(q), 1);
                    165: }
                    166: 
                    167: 
                    168: /*
                    169:  * Process a bunch of input
                    170:  *   -- for now, ignore strange control bytes
                    171:  */
                    172: dkpisrv(q)
                    173: register struct queue *q;
                    174: {
                    175:        register struct dkp *dkpp = (struct dkp *)q->ptr;
                    176:        register struct block *bp;
                    177:        register c;
                    178: 
                    179:        while (bp = getq(q)) {
                    180:                if (bp->type == M_CTL) {
                    181:                        c = *bp->rptr & 0370;
                    182:                        if (c==REJ || c==ECHO) {
                    183:                                dkpp->lastecho = *bp->rptr;
                    184:                                bp->class |= S_DELIM;
                    185:                                (*WR(q)->next->qinfo->putp)(WR(q)->next, bp);
                    186:                        } else
                    187:                                freeb(bp);      /* unknown control */
                    188:                        continue;
                    189:                }
                    190:                if ((q->next->flag&QFULL)==0 || bp->type>=QPCTL
                    191:                 || dkpp->state&RCLOSE) {
                    192:                        TRC('G'); TRC(*bp->rptr);
                    193:                        (*q->next->qinfo->putp)(q->next, bp);
                    194:                } else {
                    195:                        putbq(q, bp);
                    196:                        return;
                    197:                }
                    198:        }
                    199: }
                    200: 
                    201: /*
                    202:  * Packet arrives.
                    203:  */
                    204: dkpiput(q, bp)
                    205: struct queue *q;
                    206: register struct block *bp;
                    207: {
                    208:        register struct dkp *dkpp;
                    209:        register i;
                    210:        register struct block *nbp;
                    211: 
                    212:        if ((dkpp = (struct dkp *)q->ptr)==NULL) {
                    213:                freeb(bp);
                    214:                return;
                    215:        }
                    216:        switch (bp->type) {
                    217: 
                    218:        moredata:
                    219:                bp->rptr++;
                    220:                bp->type = M_DATA;
                    221:        case M_DATA:
                    222:                bp->class &= ~S_DELIM;
                    223:                if (bp->rptr >= bp->wptr||q->flag&QFULL||dkpp->state&LCLOSE) {
                    224:                        freeb(bp);
                    225:                        return;
                    226:                }
                    227:                if (dkpp->state & RCHARMODE) {
                    228:                        putq(q, bp);
                    229:                        return;
                    230:                }
                    231:                switch (dkpp->trx) {
                    232: 
                    233:                        case 1:
                    234:                        case 2:
                    235:                                dkpp->trbuf[dkpp->trx++] = *bp->rptr;
                    236:                                goto moredata;
                    237:                        
                    238:                        default:
                    239:                                dkpp->trx = 0;
                    240:                        case 0:
                    241:                                break;
                    242:                }
                    243:                bp->next = NULL;
                    244:                if (dkpp->indata > MAXMSG) {    /* protect against garbage */
                    245:                        freeb(bp);
                    246:                        return;
                    247:                }
                    248:                if (dkpp->inp) {
                    249:                        dkpp->inpe->next = bp;
                    250:                        dkpp->inpe = bp;
                    251:                } else {
                    252:                        dkpp->inp = bp;
                    253:                        dkpp->inpe = bp;
                    254:                }
                    255:                dkpp->indata += bp->wptr - bp->rptr;
                    256:                return;
                    257: 
                    258:        case M_CTL:
                    259:                switch (*bp->rptr) {
                    260: 
                    261:                case ENQ:
                    262:                        putctl1(WR(q)->next, M_CTL, dkpp->lastecho);
                    263:                case CHECK:
                    264:                        putctl1d(WR(q)->next, M_CTL, ACK+dkpp->iseq);
                    265:                        dkpinflush(dkpp);
                    266:                        goto moredata;
                    267: 
                    268:                case AINIT:
                    269:                        dkpp->state &= ~OPENING;
                    270:                        dkpp->state |= OPEN;
                    271:                        qenable(WR(q));
                    272:                        dkpinflush(dkpp);
                    273:                        goto moredata;
                    274: 
                    275:                case INIT0:
                    276:                case INIT1:
                    277:                        putctl1d(WR(q)->next, M_CTL, AINIT);
                    278:                        if (*bp->rptr==INIT0 && (dkpp->state&RCHARMODE)==0) {
                    279:                                dkpp->state |= RCHARMODE;
                    280:                                dkpp->XW = 1;   /* why? */
                    281:                                q->flag &= ~QDELIM;
                    282:                        } else if (*bp->rptr==INIT1 && (dkpp->state&RCHARMODE)) {
                    283:                                dkpp->state &= ~RCHARMODE;
                    284:                                dkpp->XW = 3;   /* why? */
                    285:                                q->flag |= QDELIM;
                    286:                        }
                    287:                        dkpinflush(dkpp);
                    288:                        dkpp->iseq = 0;
                    289:                        wakeup((caddr_t)dkpp);
                    290:                        goto moredata;
                    291: 
                    292:                case INITREQ:
                    293:                        if (dkpp->state&XCHARMODE)
                    294:                                putctl1d(WR(q)->next, M_CTL, INIT0);
                    295:                        else {
                    296:                                if (dkpp->WS < dkpp->WNX)
                    297:                                        dkprack(dkpp, ECHO+((dkpp->WNX-1)&07));
                    298:                                dkpp->WS = 1;
                    299:                                dkpp->WACK = 1;
                    300:                                dkpp->WNX = 1;
                    301:                                putctl1d(WR(q)->next, M_CTL, INIT1);
                    302:                        }
                    303:                        dkpinflush(dkpp);
                    304:                        goto moredata;
                    305: 
                    306:                case BREAK:
                    307:                        qpctl(q, M_BREAK);
                    308:                        dkpp->indata++;
                    309:                        goto moredata;
                    310: 
                    311:                case BOT:
                    312:                case BOTS:
                    313:                case BOTM:
                    314:                        dkpp->trx = 1;
                    315:                        dkpp->trbuf[0] = *bp->rptr;
                    316:                        goto moredata;
                    317: 
                    318:                case REJ+0: case REJ+1: case REJ+2: case REJ+3:
                    319:                case REJ+4: case REJ+5: case REJ+6: case REJ+7:
                    320:                        if (dkpp->state&XCHARMODE)
                    321:                                goto moredata;
                    322:                        TRC('r');
                    323:                        if (((*bp->rptr+1)&07) == (dkpp->WACK&07)
                    324:                         && (dkpp->state&RJING) == 0) {
                    325:                                dkstat.dkprxmit++;
                    326:                                for (i=dkpp->WACK; i<dkpp->WNX; i++) {
                    327:                                        TRC('Z');
                    328:                                        TRC('0' + (i&07));
                    329:                                        dkpp->state |= RJING;
                    330:                                        dkpxmit(WR(q), dkpp->xb[i&07], i);
                    331:                                }
                    332:                        }
                    333:                        goto moredata;
                    334:                
                    335:                case ACK+0: case ACK+1: case ACK+2: case ACK+3:
                    336:                case ACK+4: case ACK+5: case ACK+6: case ACK+7:
                    337:                case ECHO+0: case ECHO+1: case ECHO+2: case ECHO+3:
                    338:                case ECHO+4: case ECHO+5: case ECHO+6: case ECHO+7:
                    339:                        dkprack(dkpp, *bp->rptr);
                    340:                        goto moredata;
                    341: 
                    342:                case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3:
                    343:                case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7:
                    344:                        i = *bp->rptr & 07;
                    345:                        if (dkpp->state & RCHARMODE) {
                    346:                                TRC('e');
                    347:                                qpctl1(q, M_CTL, ECHO+i);
                    348:                                goto moredata;
                    349:                        }
                    350:                        if (dkpp->trx !=3
                    351:                         || dkpp->indata != dkpp->trbuf[1] + (dkpp->trbuf[2]<<8)
                    352:                         || i != ((dkpp->iseq+1)&07)) { /* reject? */
                    353:                                if (dkpp->trx != 3)
                    354:                                        dkstat.dkprjtrs++;
                    355:                                else if (i != ((dkpp->iseq+1)&07))
                    356:                                        dkstat.dkprjseq++;
                    357:                                else
                    358:                                        dkstat.dkprjpks++;
                    359:                                dkpinflush(dkpp);
                    360:                                if (dkpp->trbuf[0]==BOTS)
                    361:                                        dkpp->iseq = i;
                    362:                                TRC('R'); TRC('0'+dkpp->iseq);
                    363:                                TRC(dkpp->trx!=3?'t':(i!=(dkpp->iseq+1)&07?'s':'c'));
                    364:                                qpctl1(q, M_CTL, REJ+dkpp->iseq);
                    365:                                goto moredata;
                    366:                        }
                    367:                        /* accept */
                    368:                        if (dkpp->inpe==NULL)
                    369:                                dkpp->inp = dkpp->inpe = allocb(0);
                    370:                        if (dkpp->trbuf[0] != BOTM && q->flag&QDELIM)
                    371:                                dkpp->inpe->class |= S_DELIM;
                    372:                        while (nbp = dkpp->inp) {
                    373:                                dkpp->inp = nbp->next;
                    374:                                putq(q, nbp);
                    375:                        }
                    376:                        TRC('A'); TRC('0'+i);
                    377:                        dkpp->inpe = NULL;
                    378:                        dkpp->trx = 0;
                    379:                        dkpp->indata = 0;
                    380:                        dkpp->iseq = i;
                    381:                        qpctl1(q, M_CTL, ECHO+i);
                    382:                        goto moredata;
                    383: 
                    384:                default:
                    385:                        if (*bp->rptr < 0200)   /* non-supervisory */
                    386:                                dkpp->indata++;
                    387:                        dkpp->lastctl = *bp->rptr;
                    388:                        qpctl1(q, M_CTL, *bp->rptr);
                    389:                        goto moredata;
                    390:                }
                    391: 
                    392:        case M_HANGUP:
                    393:                dkpp->state |= RCLOSE;
                    394:                flushq(WR(q), 1);
                    395:                dkprack(dkpp, ECHO+((dkpp->WNX-1) & 07));
                    396:                putq(q, bp);
                    397:                return;
                    398: 
                    399:        case M_IOCACK:
                    400:        case M_IOCNAK:
                    401:                (*q->next->qinfo->putp)(q->next, bp);
                    402:                return;
                    403: 
                    404:        case M_PRICTL:
                    405:                if (*bp->rptr != DKMXINIT) {
                    406:                        (*q->next->qinfo->putp)(q->next, bp);
                    407:                        return;
                    408:                }
                    409:                bp->type = M_CTL;
                    410:                bp->wptr = bp->rptr;
                    411:                *bp->wptr++ = INITREQ;
                    412:                dkpiput(q, bp);
                    413:                putctl1d(WR(q)->next, M_CTL, INITREQ);
                    414:                return;
                    415: 
                    416:        default:
                    417:                freeb(bp);
                    418:                return;
                    419:        }
                    420: }
                    421: 
                    422: /*
                    423:  * --- Output processor
                    424:  */
                    425: 
                    426: /*
                    427:  * accept data from writer
                    428:  *  -- handle most non-data messages
                    429:  */
                    430: 
                    431: int dkpwbig = 200;
                    432: 
                    433: dkpoput(q, bp)
                    434: register struct queue *q;
                    435: register struct block *bp;
                    436: {
                    437:        register struct dkp *dkpp = (struct dkp *)q->ptr;
                    438:        register unsigned char *sp;
                    439:        register x;
                    440:        struct block *xbp;
                    441: 
                    442:        if (dkpp->state & RCLOSE) {
                    443:                freeb(bp);
                    444:                return;
                    445:        }
                    446:        switch (bp->type) {
                    447: 
                    448:        case M_STOP:
                    449:                dkpp->state |= STOPPED;
                    450:                freeb(bp);
                    451:                return;
                    452: 
                    453:        case M_START:
                    454:                dkpp->state &= ~STOPPED;
                    455:                freeb(bp);
                    456:                qenable(q);
                    457:                return;
                    458: 
                    459:        case M_FLUSH:
                    460:                /* annul data for blocks in transit */
                    461:                for (x=0; x<8; x++)
                    462:                        if (dkpp->xb[x])
                    463:                                dkpp->xb[x]->wptr = dkpp->xb[x]->rptr;
                    464:                flushq(q, 0);
                    465:                freeb(bp);
                    466:                return;
                    467: 
                    468:        case M_IOCTL:
                    469:                sp = (unsigned char *)stiodata(bp);
                    470:                switch (stiocom(bp)) {
                    471: 
                    472:                case TIOCSDEV:
                    473:                        x = ((struct ttydevb *)sp)->ispeed;
                    474:                        bp->wptr = bp->rptr;
                    475:                        bp->type = M_IOCACK;
                    476:                        qreply(q, bp);
                    477:                        if (x==0)
                    478:                                putctl(OTHERQ(q), M_HANGUP);
                    479:                        return;
                    480: 
                    481:                case TIOCGDEV:
                    482:                        ((struct ttydevb *)sp)->ispeed = ((struct ttydevb *)sp)->ospeed = B9600;
                    483:                        bp->wptr = bp->rptr + sizeof(struct ttydevb) + STIOCHDR;
                    484:                        if (bp->wptr >= bp->lim)
                    485:                                panic("dkioc");
                    486:                        bp->type = M_IOCACK;
                    487:                        qreply(q, bp);
                    488:                        return;
                    489: 
                    490:                case DIOCSTREAM:
                    491:                        RD(q)->flag &= ~QDELIM;
                    492:                        bp->wptr = bp->rptr;
                    493:                        bp->type = M_IOCACK;
                    494:                        qreply(q, bp);
                    495:                        return;
                    496:                
                    497:                case DIOCRECORD:
                    498:                        if ((dkpp->state&RCHARMODE) == 0) {
                    499:                                RD(q)->flag |= QDELIM;
                    500:                                bp->type = M_IOCACK;
                    501:                        } else
                    502:                                bp->type = M_IOCNAK;
                    503:                        bp->wptr = bp->rptr;
                    504:                        qreply(q, bp);
                    505:                        return;
                    506: 
                    507:                case KIOCINIT:
                    508:                        if (dkpp->state&XCHARMODE)
                    509:                                putctl1d(q->next, M_CTL, INIT0);
                    510:                        else {
                    511:                                if (dkpp->WS < dkpp->WNX)
                    512:                                        dkprack(dkpp, ECHO+((dkpp->WNX-1)&07));
                    513:                                dkpp->WS = 1;
                    514:                                dkpp->WACK = 1;
                    515:                                dkpp->WNX = 1;
                    516:                                putctl1d(q->next, M_CTL, INIT1);
                    517:                        }
                    518:                        bp->wptr = bp->rptr;
                    519:                        bp->type = M_IOCACK;
                    520:                        qreply(q, bp);
                    521:                        return;
                    522: 
                    523:                case KIOCISURP:
                    524:                        bp->wptr = bp->rptr;
                    525:                        bp->type = M_IOCACK;
                    526:                        qreply(q, bp);
                    527:                        return;
                    528: 
                    529:                case DIOCSCTL:
                    530:                        bp->type = M_IOCACK;
                    531:                        bp->wptr = bp->rptr;
                    532:                        if (*sp == 0) {
                    533:                                qreply(q, bp);
                    534:                                return;
                    535:                        }
                    536:                        if ((xbp = allocb(1)) == NULL)
                    537:                                bp->type = M_IOCNAK;
                    538:                        else {
                    539:                                xbp->type = M_CTL;
                    540:                                xbp->class |= S_DELIM;
                    541:                                *xbp->wptr++ = *sp;
                    542:                                putq(q, xbp);
                    543:                                if (dkpp->WNX < dkpp->WS+dkpp->XW)
                    544:                                        qenable(q);
                    545:                        }
                    546:                        qreply(q, bp);
                    547:                        return;
                    548: 
                    549:                case DIOCRCTL:
                    550:                        *sp = dkpp->lastctl;
                    551:                        dkpp->lastctl = 0;
                    552:                        bp->type = M_IOCACK;
                    553:                        bp->wptr = sp + 1;
                    554:                        qreply(q, bp);
                    555:                        return;
                    556: 
                    557:                case DIOCXWIN:
                    558:                        bp->type = M_IOCACK;
                    559:                        if (sp[4] >= 8 || sp[4] <= 0)
                    560:                                bp->type = M_IOCNAK;
                    561:                        else if ((x = sp[0] + (sp[1]<<8)) < 0 || x > MAXMSG)
                    562:                                bp->type = M_IOCNAK;
                    563:                        else {
                    564:                                dkpp->xsize = x;
                    565:                                dkpp->XW = sp[4];
                    566:                                if (x > dkpwbig)
                    567:                                        q->flag |= QBIGB;
                    568:                                else
                    569:                                        q->flag &=~ QBIGB;
                    570:                        }
                    571:                        bp->wptr = bp->rptr;
                    572:                        qreply(q, bp);
                    573:                        return;
                    574: 
                    575:                default:
                    576:                        (*q->next->qinfo->putp)(q->next, bp);
                    577:                        return;
                    578:                }
                    579: 
                    580:        case M_DELAY:
                    581:                x = *bp->rptr;
                    582:                *bp->rptr = DELAY;
                    583:                bp->type = M_CTL;
                    584:                while (x) {
                    585:                        (*bp->rptr)++;
                    586:                        x >>= 1;
                    587:                }
                    588:                goto putonq;
                    589: 
                    590:        case M_PRICTL:
                    591:                (*q->next->qinfo->putp)(q->next, bp);
                    592:                return;
                    593: 
                    594:        default:
                    595:                freeb(bp);
                    596:                return;
                    597: 
                    598:        case M_BREAK:
                    599:                bp->type = M_CTL;
                    600:                *bp->wptr++ = BREAK;
                    601:        case M_DATA:
                    602:        case M_CTL:
                    603:        putonq:
                    604:                putq(q, bp);
                    605:                if (dkpp->WNX < dkpp->WS+dkpp->XW)
                    606:                        qenable(q);
                    607:                return;
                    608:        }
                    609: }
                    610: 
                    611: /*
                    612:  * Out server:
                    613:  *  if space in window, process queue
                    614:  */
                    615: dkposrv(q)
                    616: register struct queue *q;
                    617: {
                    618:        register struct dkp *dkpp = (struct dkp *)q->ptr;
                    619:        register struct block *bp, *xbp;
                    620:        register int seqno;
                    621: 
                    622:        if (dkpp->state & (STOPPED|OPENING))
                    623:                return;
                    624:        while (dkpp->WNX < dkpp->WS+dkpp->XW) {
                    625:                if ((bp = getq(q)) == NULL)
                    626:                        break;
                    627:                /*
                    628:                 * Bite off one URP block; put back the rest.
                    629:                 * The initial blocks are passed by reference.
                    630:                 */
                    631:                if (bp->type==M_DATA && bp->wptr-bp->rptr > dkpp->xsize) {
                    632:                        xbp = dupb(bp);
                    633:                        bp->rptr += dkpp->xsize;
                    634:                        xbp->wptr = xbp->rptr+dkpp->xsize;
                    635:                        xbp->class &= ~S_DELIM;
                    636:                        putbq(q, bp);
                    637:                        bp = xbp;
                    638:                }
                    639:                if (dkpp->state & XCHARMODE) {
                    640:                        dkpp->outcnt += bp->wptr - bp->rptr;
                    641:                        (*q->next->qinfo->putp)(q->next, bp);
                    642:                        if (dkpp->outcnt >= dkpp->xsize) {
                    643:                                putctl1d(q->next, M_CTL, SEQ+(dkpp->WNX&07));
                    644:                                dkpp->WNX++;
                    645:                                dkpp->WACK = dkpp->WNX;
                    646:                                dkpp->outcnt = 0;
                    647:                        }
                    648:                        continue;
                    649:                }
                    650:                TRC('x'); TRC('0'+dkpp->WS/10); TRC('0'+dkpp->WS%10);
                    651:                TRC('.'); TRC('0'+dkpp->WNX/10); TRC('0'+dkpp->WNX%10);
                    652:                if (dkpp->xb[dkpp->WNX&07]) {
                    653:                        freeb(dkpp->xb[dkpp->WNX&07]);
                    654:                        printf("dkp losing block\n");
                    655:                }
                    656:                dkpp->xb[dkpp->WNX & 07] = bp;
                    657:                seqno = dkpp->WNX++;            /* in case ECHO comes right away */
                    658:                dkpxmit(q, bp, seqno);
                    659:        }
                    660: }
                    661: 
                    662: /*
                    663:  *  Send out a message, with trailer.
                    664:  */
                    665: dkpxmit(q, bp, seqno)
                    666: register struct queue *q;
                    667: register struct block *bp;
                    668: {
                    669:        register size;
                    670:        register struct block *xbp;
                    671:        register struct dkp *dkpp = (struct dkp *)q->ptr;
                    672: 
                    673:        if (bp==NULL) {
                    674:                printf("null bp in dkpxmit\n");
                    675:                return;
                    676:        }
                    677:        size = bp->wptr - bp->rptr;
                    678:        seqno &= 07;
                    679:        /* send ptr to block, if non-empty */
                    680:        if (size) {
                    681:                if ((xbp = dupb(bp)) == NULL)
                    682:                        return;
                    683:                xbp->class &=~ S_DELIM;
                    684:                TRC('X'); TRC('0'+seqno);
                    685:                (*q->next->qinfo->putp)(q->next, xbp);
                    686:        }
                    687:        /* send trailer */
                    688:        if ((xbp = allocb(3)) == NULL)
                    689:                return;
                    690:        xbp->type = M_CTL;
                    691:        *xbp->wptr++ = bp->class&S_DELIM? BOT: BOTM;
                    692:        *xbp->wptr++ = size;
                    693:        *xbp->wptr++ = size >> 8;
                    694:        (*q->next->qinfo->putp)(q->next, xbp);
                    695:        putctl1d(q->next, M_CTL, SEQ + seqno);
                    696:        dkpp->timer = DKPTIME;
                    697: }
                    698: 
                    699: /*
                    700:  * Receive an ack of some sort for a transmitted message.
                    701:  *  Advance various windows.
                    702:  */
                    703: dkprack(dkpp, msg)
                    704: register struct dkp *dkpp;
                    705: {
                    706:        register struct block **bpp;
                    707:        register seqno, i;
                    708: 
                    709:        seqno = msg & 07;
                    710:        msg &= 0370;
                    711:        /* invariants: 0 <= WS <= WACK <= WNX; seqno maximal < WNX; WS < 8 */
                    712:        if (seqno >= dkpp->WNX)
                    713:                seqno -= 8;
                    714:        else if (seqno+8 < dkpp->WNX)
                    715:                seqno += 8;
                    716:        dkpp->state &= ~RJING;
                    717:        for (i=dkpp->WS; i<=seqno; i++) {
                    718:                bpp = &dkpp->xb[i&07];
                    719:                if (*bpp) {
                    720:                        freeb(*bpp);
                    721:                        *bpp = NULL;
                    722:                }
                    723:        }
                    724:        if ((int)dkpp->WACK <= seqno)
                    725:                dkpp->WACK = seqno+1;
                    726:        if (msg==ECHO) {
                    727:                TRC('E'); TRC('0'+(seqno&07));
                    728:                if (dkpp->WS <= seqno) {
                    729:                        dkpp->timer = DKPTIME;  /* push off timeout */
                    730:                        dkpp->WS = seqno+1;
                    731:                        if (dkpp->WNX<dkpp->WS+dkpp->XW && WR(dkpp->rdq)->count)
                    732:                                qenable(WR(dkpp->rdq));
                    733:                }
                    734:        } else {
                    735:                for (i=dkpp->WACK; i<dkpp->WNX; i++) {
                    736:                        if (dkpp->xb[i&07]==0)
                    737:                         printf("WS %d WACK %d WNX %d i %d seqno %d\n",
                    738:                           dkpp->WS, dkpp->WACK, dkpp->WNX, i, seqno);
                    739:                        dkpxmit(WR(dkpp->rdq), dkpp->xb[i&07], i);
                    740:                        dkstat.dkprxmit++;
                    741:                }
                    742:        }
                    743:        if (dkpp->WS >= 8) {
                    744:                dkpp->WS -= 8;
                    745:                dkpp->WACK -= 8;
                    746:                dkpp->WNX -= 8;
                    747:        }
                    748: }
                    749: 
                    750: dkptimer()
                    751: {
                    752:        register struct dkp *dkpp;
                    753:        register struct queue *q;
                    754:        register int i;
                    755: 
                    756:        for (dkpp = dkp, i = dkpcnt; i > 0; dkpp++, --i) {
                    757:                if ((dkpp->state&(OPEN|OPENING)) == 0)
                    758:                        continue;
                    759:                if (--dkpp->timer>0)
                    760:                        continue;
                    761:                q = WR(dkpp->rdq)->next;
                    762:                if (q->flag&QFULL)
                    763:                        continue;
                    764:                if (dkpp->state & XCHARMODE) {
                    765:                        if (dkpp->WS < dkpp->WNX)
                    766:                                putctl1d(q, M_CTL, SEQ+((dkpp->WNX-1)&07));
                    767:                        dkpp->timer = 10;
                    768:                        continue;
                    769:                }
                    770:                if (dkpp->state&OPENING)
                    771:                        putctl1d(q, M_CTL, INIT1);
                    772:                if (dkpp->WS != dkpp->WNX)
                    773:                        putctl1d(q, M_CTL, ENQ);
                    774:                dkpp->timer = DKPTIME;
                    775:        }
                    776:        timeout(dkptimer, (caddr_t)NULL, HZ);
                    777: }
                    778: 
                    779: /*
                    780:  * throw away data in front of the barrier, and clear the trailer buffer
                    781:  */
                    782: dkpinflush(dkpp)
                    783: register struct dkp *dkpp;
                    784: {
                    785:        register struct block *bp;
                    786: 
                    787:        while (bp = dkpp->inp) {
                    788:                dkpp->inp = bp->next;
                    789:                freeb(bp);
                    790:        }
                    791:        dkpp->inpe = NULL;
                    792:        dkpp->trx = 0;
                    793:        dkpp->indata = 0;
                    794: }

unix.superglobalmegacorp.com

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