Annotation of researchv8dc/sys/dev/dtline.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Line discipline for Datakit TDK protocol
        !             3:  */
        !             4: #define        NDT     16
        !             5: #define        TR(x)   /**/
        !             6: 
        !             7: #include "../h/param.h"
        !             8: #include "../h/stream.h"
        !             9: #include "../h/conf.h"
        !            10: #include "../h/ioctl.h"
        !            11: #include "../h/ttyld.h"
        !            12: 
        !            13: struct dt {
        !            14:        char    nack;
        !            15:        char    cack;
        !            16:        char    nchar;
        !            17:        char    state;
        !            18:        short   lastecho;
        !            19:        struct  queue *queue;
        !            20: } dt[NDT];
        !            21: 
        !            22: /* states */
        !            23: #define        CLOG1   01
        !            24: #define        CLOG2   02
        !            25: #define        STOP    04
        !            26: #define USE    010
        !            27: 
        !            28: /* DK control packet codes */
        !            29: #define        D_BREAK 07
        !            30: #define        D_ECHO  010
        !            31: #define        D_ACK   020
        !            32: #define        D_DELAY 030
        !            33: #define        D_SNDBRK 03
        !            34: #define DKDATA 0400
        !            35: 
        !            36: #define        DTNC    32              /* chars sent between ECHO requests */
        !            37: 
        !            38: int dtliput(), dtlisrv(), dtlopen(), dtlclose(), putq(), dtlosrv();
        !            39: static struct qinit dtlrinit = {dtliput, dtlisrv, dtlopen, dtlclose, 129, 129};
        !            40: static struct qinit dtlwinit = {putq, dtlosrv, dtlopen, dtlclose, 129, 65};
        !            41: struct streamtab  dtlinfo = {&dtlrinit, &dtlwinit};
        !            42: 
        !            43: /*
        !            44:  * open
        !            45:  */
        !            46: dtlopen(q, dev)
        !            47: register struct queue *q;
        !            48: {
        !            49:        register struct dt *dp;
        !            50:        extern int dtltimer(), hz;
        !            51:        static timer_on = 0;
        !            52: 
        !            53:        if (timer_on==0) {
        !            54:                timeout(dtltimer, (caddr_t)NULL, 10*hz);
        !            55:                timer_on = 1;
        !            56:        }
        !            57:        dp = (struct dt *)q->ptr;
        !            58:        if (dp)
        !            59:                return(1);
        !            60:        for (dp = dt; dp < &dt[NDT]; dp++) {
        !            61:                if ((dp->state&USE)==0) {
        !            62:                        dp->state = USE;
        !            63:                        dp->lastecho = 0;
        !            64:                        dp->cack = 0;
        !            65:                        dp->nack = 0;
        !            66:                        q->ptr = (caddr_t)dp;
        !            67:                        WR(q)->ptr = (caddr_t)dp;
        !            68:                        dp->queue = WR(q);
        !            69:                        q->flag &= ~QNOENB;
        !            70:                        return(1);
        !            71:                }
        !            72:        }
        !            73:        return(0);
        !            74: }
        !            75: 
        !            76: dtlclose(q)
        !            77: register struct queue *q;
        !            78: {
        !            79:        register struct dt *dp = (struct dt *)q->ptr;
        !            80: 
        !            81:        dp->state = 0;
        !            82: }
        !            83: 
        !            84: 
        !            85: /*
        !            86:  * output server
        !            87:  */
        !            88: dtlosrv(q)
        !            89: register struct queue *q;
        !            90: {
        !            91:        register struct block *bp;
        !            92:        register struct dt *dp;
        !            93:        register c;
        !            94: 
        !            95:        dp = (struct dt *)q->ptr;
        !            96:        for (;;) {
        !            97:                if (q->next->flag & QFULL)      /* unlikely for DK */
        !            98:                        return;
        !            99:                if ((bp = getq(q)) == NULL)
        !           100:                        return;
        !           101:                if (dp->state & (STOP|CLOG1)) {
        !           102:                        switch (bp->type) {
        !           103: 
        !           104:                        case M_DATA:
        !           105:                        case M_BREAK:
        !           106:                        case M_DELAY:
        !           107:                                putbq(q, bp);
        !           108:                                q->flag |= QWANTR;
        !           109:                                return;
        !           110:                        }
        !           111:                }
        !           112:                switch (bp->type) {
        !           113: 
        !           114:                case M_STOP:
        !           115:                        freeb(bp);
        !           116:                        dp->state |= STOP;
        !           117:                        q->flag |= QWANTR;
        !           118:                        continue;               /* in case there is a START */
        !           119: 
        !           120:                case M_START:
        !           121:                        freeb(bp);
        !           122:                        dp->state &= ~STOP;
        !           123:                        continue;
        !           124: 
        !           125:                case M_FLUSH:
        !           126:                        flushq(q, 0);
        !           127:                        freeb(bp);
        !           128:                        dp->state &= ~STOP;
        !           129:                        continue;
        !           130: 
        !           131:                case M_DATA:
        !           132:                        if (bp->wptr - bp->rptr <= DTNC - dp->nchar) {
        !           133:                                TR(bp->wptr-bp->rptr);
        !           134:                                dp->nchar += bp->wptr - bp->rptr;
        !           135:                                (*q->next->qinfo->putp)(q->next, bp);
        !           136:                        } else if (dp->nchar < DTNC) {
        !           137:                                register struct block *bp1;
        !           138:                                bp1 = allocb(DTNC);
        !           139:                                if (bp1==NULL) {
        !           140:                                        putbq(q, bp);
        !           141:                                        dp->state |= CLOG1;
        !           142:                                        return;
        !           143:                                }
        !           144:                                bcopy(bp->rptr, bp1->wptr, DTNC-dp->nchar);
        !           145:                                bp->rptr += DTNC-dp->nchar;
        !           146:                                bp1->wptr += DTNC-dp->nchar;
        !           147:                                dp->nchar = DTNC;
        !           148:                                TR(bp1->wptr-bp1->rptr);
        !           149:                                (*q->next->qinfo->putp)(q->next, bp1);
        !           150:                                putbq(q, bp);
        !           151:                        }
        !           152:                        break;
        !           153: 
        !           154:                case M_BREAK:
        !           155:                        bp->type = M_CTL;
        !           156:                        *bp->wptr++ = D_SNDBRK;
        !           157:                        (*q->next->qinfo->putp)(q->next, bp);
        !           158:                        dp->nchar++;
        !           159:                        break;
        !           160: 
        !           161:                case M_DELAY:
        !           162:                        c = *bp->rptr;
        !           163:                        *bp->rptr = D_DELAY;
        !           164:                        bp->type = M_CTL;
        !           165:                        while (c) {
        !           166:                                (*bp->rptr)++;
        !           167:                                c >>= 1;
        !           168:                        }
        !           169:                        TR(0377);
        !           170:                        (*q->next->qinfo->putp)(q->next, bp);
        !           171:                        dp->nchar++;
        !           172:                        break;
        !           173: 
        !           174:                case M_DELIM:
        !           175:                        freeb(bp);
        !           176:                        continue;
        !           177: 
        !           178:                case M_IOCTL:
        !           179:                        switch (((union stmsg *)bp->rptr)->ioc0.com) {
        !           180: 
        !           181:                        case TIOCSETP:
        !           182:                        case TIOCSETN:
        !           183:                                bp->wptr = bp->rptr;
        !           184:                        case TIOCGETP:
        !           185:                                bp->type = M_IOCACK;
        !           186:                                qreply(q, bp);
        !           187:                                continue;
        !           188:                        }
        !           189:                        /* flow through to */
        !           190:                default:
        !           191:                        dp->nchar += bp->wptr - bp->rptr;
        !           192:                        (*q->next->qinfo->putp)(q->next, bp);
        !           193:                        break;
        !           194:                }
        !           195:                if (dp->nchar >= DTNC) {
        !           196:                        if ((bp = allocb(1)) == NULL) {
        !           197:                                dp->state |= CLOG1;
        !           198:                                return;
        !           199:                        }
        !           200:                        dp->nchar -= DTNC;
        !           201:                        dp->nack++;
        !           202:                        dp->nack &= 03;
        !           203:                        if (dp->cack == ((dp->nack+2) & 03))
        !           204:                                dp->state |= CLOG1;
        !           205:                        TR(0200+dp->nack+(((dp->state&CLOG1)!=0)<<5));
        !           206:                        bp->type = M_CTL;
        !           207:                        *bp->wptr++ = D_ECHO + dp->nack;
        !           208:                        (*q->next->qinfo->putp)(q->next, bp);
        !           209:                }
        !           210:        }
        !           211: }
        !           212: 
        !           213: /*
        !           214:  * put procedure for input.
        !           215:  */
        !           216: dtliput(q, bp)
        !           217: register struct queue *q;
        !           218: register struct block *bp;
        !           219: {
        !           220:        register struct dt *dp;
        !           221:        register c;
        !           222: 
        !           223:        dp = (struct dt *)q->ptr;
        !           224:        switch (bp->type) {
        !           225: 
        !           226:        case M_CTL:
        !           227:                bp->type = M_DATA;
        !           228:                c = *bp->rptr++;
        !           229:                if ((c & 0370) == D_ACK) {      /* resp to my ECHO */
        !           230:                        dp->cack = c&03;
        !           231:                        if (dp->state & CLOG1) {
        !           232:                                dp->state &= ~(CLOG1|CLOG2);
        !           233:                                qenable(WR(q));
        !           234:                        }
        !           235:                        TR(0300+dp->cack);
        !           236:                } else if ((c & 0370) == D_ECHO) {      /* request for an ACK */
        !           237:                        dp->lastecho = D_ACK + (c&07);
        !           238:                        qenable(q);
        !           239:                } else if (c == D_BREAK) {
        !           240:                        flushq(q, 0);
        !           241:                        putctl(q->next, M_BREAK);
        !           242:                } else
        !           243:                        printf("DT unkn ctrl %o\n", c);
        !           244:                break;
        !           245: 
        !           246:        case M_DATA:
        !           247:                break;
        !           248: 
        !           249:        case M_IOCACK:
        !           250:        case M_IOCNAK:
        !           251:        case M_HANGUP:
        !           252:                (*q->next->qinfo->putp)(q->next, bp);
        !           253:                return;
        !           254: 
        !           255:        default:
        !           256:                printf("unknown msg type %d in dtliput\n", bp->type);
        !           257:                freeb(bp);
        !           258:                return;
        !           259:        }
        !           260:        if (bp->wptr > bp->rptr && (q->flag&QFULL)==0)
        !           261:                putq(q, bp);
        !           262:        else
        !           263:                freeb(bp);
        !           264: }
        !           265: 
        !           266: /*
        !           267:  * DT input server
        !           268:  *  -- copy data; send out latest ack if next queue is not full.
        !           269:  */
        !           270: dtlisrv(q)
        !           271: register struct queue *q;
        !           272: {
        !           273:        register struct block *bp;
        !           274:        register struct dt *dp;
        !           275:        register s;
        !           276: 
        !           277:        while ((q->next->flag & QFULL) == 0) {
        !           278:                bp = getq(q);
        !           279:                if (bp == NULL) {
        !           280:                        dp = (struct dt *)q->ptr;
        !           281:                        s = spl5();
        !           282:                        if (dp->lastecho) {
        !           283:                                putctl1(WR(q)->next, M_CTL, dp->lastecho);
        !           284:                                dp->lastecho = 0;
        !           285:                        }
        !           286:                        splx(s);
        !           287:                        return;
        !           288:                }
        !           289:                (*q->next->qinfo->putp)(q->next, bp);
        !           290:        }
        !           291: }
        !           292: 
        !           293: dtltimer()
        !           294: {
        !           295:        register struct dt *dp;
        !           296: 
        !           297:        for (dp = dt; dp < &dt[NDT]; dp++) {
        !           298:                if ((dp->state&(USE|CLOG1)) == (USE|CLOG1)) {
        !           299:                        if (dp->state&CLOG2) {
        !           300:                                register struct queue *q = dp->queue;
        !           301:                                putctl1(q->next, M_CTL, D_ECHO + dp->nack);
        !           302:                                TR(0340+dp->nack);
        !           303:                        }
        !           304:                        dp->state |= CLOG2;
        !           305:                }
        !           306:        }
        !           307:        timeout(dtltimer, (caddr_t)NULL, 10*hz);
        !           308: }

unix.superglobalmegacorp.com

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