Annotation of researchv8dc/sys/dev/dtline.c, revision 1.1.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.