Annotation of researchv8dc/sys/dev/dkp.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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