Annotation of embedaddon/ntp/kernel/tty_chu.c, revision 1.1.1.1

1.1       misho       1: /* tty_chu.c,v 3.1 1993/07/06 01:07:30 jbj Exp
                      2:  * tty_chu.c - CHU line driver
                      3:  */
                      4: 
                      5: #include "chu.h"
                      6: #if NCHU > 0
                      7: 
                      8: #include "../h/param.h"
                      9: #include "../h/types.h"
                     10: #include "../h/systm.h"
                     11: #include "../h/dir.h"
                     12: #include "../h/user.h"
                     13: #include "../h/ioctl.h"
                     14: #include "../h/tty.h"
                     15: #include "../h/proc.h"
                     16: #include "../h/file.h"
                     17: #include "../h/conf.h"
                     18: #include "../h/buf.h"
                     19: #include "../h/uio.h"
                     20: 
                     21: #include "../h/chudefs.h"
                     22: 
                     23: /*
                     24:  * Line discipline for receiving CHU time codes.
                     25:  * Does elementary noise elimination, takes time stamps after
                     26:  * the arrival of each character, returns a buffer full of the
                     27:  * received 10 character code and the associated time stamps.
                     28:  */
                     29: #define        NUMCHUBUFS      3
                     30: 
                     31: struct chudata {
                     32:        u_char used;            /* Set to 1 when structure in use */
                     33:        u_char lastindex;       /* least recently used buffer */
                     34:        u_char curindex;        /* buffer to use */
                     35:        u_char sleeping;        /* set to 1 when we're sleeping on a buffer */
                     36:        struct chucode chubuf[NUMCHUBUFS];
                     37: } chu_data[NCHU];
                     38: 
                     39: /*
                     40:  * Number of microseconds we allow between
                     41:  * character arrivals.  The speed is 300 baud
                     42:  * so this should be somewhat more than 30 msec
                     43:  */
                     44: #define        CHUMAXUSEC      (50*1000)       /* 50 msec */
                     45: 
                     46: int chu_debug = 0;
                     47: 
                     48: /*
                     49:  * Open as CHU time discipline.  Called when discipline changed
                     50:  * with ioctl, and changes the interpretation of the information
                     51:  * in the tty structure.
                     52:  */
                     53: /*ARGSUSED*/
                     54: chuopen(dev, tp)
                     55:        dev_t dev;
                     56:        register struct tty *tp;
                     57: {
                     58:        register struct chudata *chu;
                     59: 
                     60:        /*
                     61:         * Don't allow multiple opens.  This will also protect us
                     62:         * from someone opening /dev/tty
                     63:         */
                     64:        if (tp->t_line == CHULDISC)
                     65:                return (EBUSY);
                     66:        ttywflush(tp);
                     67:        for (chu = chu_data; chu < &chu_data[NCHU]; chu++)
                     68:                if (!chu->used)
                     69:                        break;
                     70:        if (chu >= &chu[NCHU])
                     71:                return (EBUSY);
                     72:        chu->used++;
                     73:        chu->lastindex = chu->curindex = 0;
                     74:        chu->sleeping = 0;
                     75:        chu->chubuf[0].ncodechars = 0;
                     76:        tp->T_LINEP = (caddr_t) chu;
                     77:        return (0);
                     78: }
                     79: 
                     80: /*
                     81:  * Break down... called when discipline changed or from device
                     82:  * close routine.
                     83:  */
                     84: chuclose(tp)
                     85:        register struct tty *tp;
                     86: {
                     87:        register int s = spl5();
                     88: 
                     89:        ((struct chudata *) tp->T_LINEP)->used = 0;
                     90:        tp->t_cp = 0;
                     91:        tp->t_inbuf = 0;
                     92:        tp->t_rawq.c_cc = 0;            /* clear queues -- paranoid */
                     93:        tp->t_canq.c_cc = 0;
                     94:        tp->t_line = 0;                 /* paranoid: avoid races */
                     95:        splx(s);
                     96: }
                     97: 
                     98: /*
                     99:  * Read a CHU buffer.  Sleep on the current buffer
                    100:  */
                    101: churead(tp, uio)
                    102:        register struct tty *tp;
                    103:        struct uio *uio;
                    104: {
                    105:        register struct chudata *chu;
                    106:        register struct chucode *chucode;
                    107:        register int s;
                    108: 
                    109:        if ((tp->t_state&TS_CARR_ON)==0)
                    110:                return (EIO);
                    111: 
                    112:        chu = (struct chudata *) (tp->T_LINEP);
                    113: 
                    114:        s = spl5();
                    115:        chucode = &(chu->chubuf[chu->lastindex]);
                    116:        while (chu->curindex == chu->lastindex) {
                    117:                chu->sleeping = 1;
                    118:                sleep((caddr_t)chucode, TTIPRI);
                    119:        }
                    120:        chu->sleeping = 0;
                    121:        if (++(chu->lastindex) >= NUMCHUBUFS)
                    122:                chu->lastindex = 0;
                    123:        splx(s);
                    124: 
                    125:        return (uiomove((caddr_t)chucode, sizeof(*chucode), UIO_READ, uio));
                    126: }
                    127: 
                    128: /*
                    129:  * Low level character input routine.
                    130:  * If the character looks okay, grab a time stamp.  If the stuff in
                    131:  * the buffer is too old, dump it and start fresh.  If the character is
                    132:  * non-BCDish, everything in the buffer too.
                    133:  */
                    134: chuinput(c, tp)
                    135:        register int c;
                    136:        register struct tty *tp;
                    137: {
                    138:        register struct chudata *chu = (struct chudata *) tp->T_LINEP;
                    139:        register struct chucode *chuc;
                    140:        register int i;
                    141:        long sec, usec;
                    142:        struct timeval tv;
                    143: 
                    144:        /*
                    145:         * Do a check on the BSDness of the character.  This delays
                    146:         * the time stamp a bit but saves a fair amount of overhead
                    147:         * when the static is bad.
                    148:         */
                    149:        if (((c) & 0xf) > 9 || (((c)>>4) & 0xf) > 9) {
                    150:                chuc = &(chu->chubuf[chu->curindex]);
                    151:                chuc->ncodechars = 0;   /* blow all previous away */
                    152:                return;
                    153:        }
                    154: 
                    155:        /*
                    156:         * Call microtime() to get the current time of day
                    157:         */
                    158:        microtime(&tv);
                    159: 
                    160:        /*
                    161:         * Compute the difference in this character's time stamp
                    162:         * and the last.  If it exceeds the margin, blow away all
                    163:         * the characters currently in the buffer.
                    164:         */
                    165:        chuc = &(chu->chubuf[chu->curindex]);
                    166:        i = (int)chuc->ncodechars;
                    167:        if (i > 0) {
                    168:                sec = tv.tv_sec - chuc->codetimes[i-1].tv_sec;
                    169:                usec = tv.tv_usec - chuc->codetimes[i-1].tv_usec;
                    170:                if (usec < 0) {
                    171:                        sec -= 1;
                    172:                        usec += 1000000;
                    173:                }
                    174:                if (sec != 0 || usec > CHUMAXUSEC) {
                    175:                        i = 0;
                    176:                        chuc->ncodechars = 0;
                    177:                }
                    178:        }
                    179: 
                    180:        /*
                    181:         * Store the character.  If we're done, have to tell someone
                    182:         */
                    183:        chuc->codechars[i] = (u_char)c;
                    184:        chuc->codetimes[i] = tv;
                    185: 
                    186:        if (++i < NCHUCHARS) {
                    187:                /*
                    188:                 * Not much to do here.  Save the count and wait
                    189:                 * for another character.
                    190:                 */
                    191:                chuc->ncodechars = (u_char)i;
                    192:        } else {
                    193:                /*
                    194:                 * Mark this buffer full and point at next.  If the
                    195:                 * next buffer is full we overwrite it by bumping the
                    196:                 * next pointer.
                    197:                 */
                    198:                chuc->ncodechars = NCHUCHARS;
                    199:                if (++(chu->curindex) >= NUMCHUBUFS)
                    200:                        chu->curindex = 0;
                    201:                if (chu->curindex == chu->lastindex)
                    202:                        if (++(chu->lastindex) >= NUMCHUBUFS)
                    203:                                chu->lastindex = 0;
                    204:                chu->chubuf[chu->curindex].ncodechars = 0;
                    205: 
                    206:                /*
                    207:                 * Wake up anyone sleeping on this.  Also wake up
                    208:                 * selectors and/or deliver a SIGIO as required.
                    209:                 */
                    210:                if (tp->t_rsel) {
                    211:                        selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
                    212:                        tp->t_state &= ~TS_RCOLL;
                    213:                        tp->t_rsel = 0;
                    214:                }
                    215:                if (tp->t_state & TS_ASYNC)
                    216:                        gsignal(tp->t_pgrp, SIGIO);
                    217:                if (chu->sleeping)
                    218:                        (void) wakeup((caddr_t)chuc);
                    219:        }
                    220: }
                    221: 
                    222: /*
                    223:  * Handle ioctls.  We reject all tty-style except those that
                    224:  * change the line discipline.
                    225:  */
                    226: chuioctl(tp, cmd, data, flag)
                    227:        struct tty *tp;
                    228:        int cmd;
                    229:        caddr_t data;
                    230:        int flag;
                    231: {
                    232: 
                    233:        if ((cmd>>8) != 't')
                    234:                return (-1);
                    235:        switch (cmd) {
                    236:        case TIOCSETD:
                    237:        case TIOCGETD:
                    238:        case TIOCGETP:
                    239:        case TIOCGETC:
                    240:                return (-1);
                    241:        }
                    242:        return (ENOTTY);        /* not quite appropriate */
                    243: }
                    244: 
                    245: 
                    246: chuselect(dev, rw)
                    247:        dev_t dev;
                    248:        int rw;
                    249: {
                    250:        register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
                    251:        struct chudata *chu;
                    252:        int s = spl5();
                    253: 
                    254:        chu = (struct chudata *) (tp->T_LINEP);
                    255: 
                    256:        switch (rw) {
                    257: 
                    258:        case FREAD:
                    259:                if (chu->curindex != chu->lastindex)
                    260:                        goto win;
                    261:                if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
                    262:                        tp->t_state |= TS_RCOLL;
                    263:                else
                    264:                        tp->t_rsel = u.u_procp;
                    265:                break;
                    266: 
                    267:        case FWRITE:
                    268:                goto win;
                    269:        }
                    270:        splx(s);
                    271:        return (0);
                    272: win:
                    273:        splx(s);
                    274:        return (1);
                    275: }
                    276: #endif NCHU

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>