aboutsummaryrefslogtreecommitdiff
path: root/kernel/tty_clk.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/tty_clk.c')
-rw-r--r--kernel/tty_clk.c317
1 files changed, 0 insertions, 317 deletions
diff --git a/kernel/tty_clk.c b/kernel/tty_clk.c
deleted file mode 100644
index 072061039bf3..000000000000
--- a/kernel/tty_clk.c
+++ /dev/null
@@ -1,317 +0,0 @@
-/* tty_clk.c,v 3.1 1993/07/06 01:07:33 jbj Exp
- * tty_clk.c - Generic line driver for receiving radio clock timecodes
- */
-
-#include "clk.h"
-#if NCLK > 0
-
-#include "../h/param.h"
-#include "../h/types.h"
-#include "../h/systm.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/ioctl.h"
-#include "../h/tty.h"
-#include "../h/proc.h"
-#include "../h/file.h"
-#include "../h/conf.h"
-#include "../h/buf.h"
-#include "../h/uio.h"
-#include "../h/clist.h"
-
-/*
- * This line discipline is intended to provide well performing
- * generic support for the reception and time stamping of radio clock
- * timecodes. Most radio clock devices return a string where a
- * particular character in the code (usually a \r) is on-time
- * synchronized with the clock. The idea here is to collect characters
- * until (one of) the synchronization character(s) (we allow two) is seen.
- * When the magic character arrives we take a timestamp by calling
- * microtime() and insert the eight bytes of struct timeval into the
- * buffer after the magic character. We then wake up anyone waiting
- * for the buffer and return the whole mess on the next read.
- *
- * To use this the calling program is expected to first open the
- * port, and then to set the port into raw mode with the speed
- * set appropriately with a TIOCSETP ioctl(), with the erase and kill
- * characters set to those to be considered magic (yes, I know this
- * is gross, but they were so convenient). If only one character is
- * magic you can set then both the same, or perhaps to the alternate
- * parity versions of said character. After getting all this set,
- * change the line discipline to CLKLDISC and you are on your way.
- *
- * The only other bit of magic we do in here is to flush the receive
- * buffers on writes if the CRMOD flag is set (hack, hack).
- */
-
-/*
- * We run this very much like a raw mode terminal, with the exception
- * that we store up characters locally until we hit one of the
- * magic ones and then dump it into the rawq all at once. We keep
- * the buffered data in clists since we can then often move it to
- * the rawq without copying. For sanity we limit the number of
- * characters between specials, and the total number of characters
- * before we flush the rawq, as follows.
- */
-#define CLKLINESIZE (256)
-#define NCLKCHARS (CLKLINESIZE*4)
-
-struct clkdata {
- int inuse;
- struct clist clkbuf;
-};
-#define clk_cc clkbuf.c_cc
-#define clk_cf clkbuf.c_cf
-#define clk_cl clkbuf.c_cl
-
-struct clkdata clk_data[NCLK];
-
-/*
- * Routine for flushing the internal clist
- */
-#define clk_bflush(clk) (ndflush(&((clk)->clkbuf), (clk)->clk_cc))
-
-int clk_debug = 0;
-
-/*ARGSUSED*/
-clkopen(dev, tp)
- dev_t dev;
- register struct tty *tp;
-{
- register struct clkdata *clk;
-
- /*
- * Don't allow multiple opens. This will also protect us
- * from someone opening /dev/tty
- */
- if (tp->t_line == CLKLDISC)
- return (EBUSY);
- ttywflush(tp);
- for (clk = clk_data; clk < &clk_data[NCLK]; clk++)
- if (!clk->inuse)
- break;
- if (clk >= &clk_data[NCLK])
- return (EBUSY);
- clk->inuse++;
- clk->clk_cc = 0;
- clk->clk_cf = clk->clk_cl = NULL;
- tp->T_LINEP = (caddr_t) clk;
- return (0);
-}
-
-
-/*
- * Break down... called when discipline changed or from device
- * close routine.
- */
-clkclose(tp)
- register struct tty *tp;
-{
- register struct clkdata *clk;
- register int s = spltty();
-
- clk = (struct clkdata *)tp->T_LINEP;
- if (clk->clk_cc > 0)
- clk_bflush(clk);
- clk->inuse = 0;
- tp->t_line = 0; /* paranoid: avoid races */
- splx(s);
-}
-
-
-/*
- * Receive a write request. We pass these requests on to the terminal
- * driver, except that if the CRMOD bit is set in the flags we
- * first flush the input queues.
- */
-clkwrite(tp, uio)
- register struct tty *tp;
- struct uio *uio;
-{
- if (tp->t_flags & CRMOD) {
- register struct clkdata *clk;
- int s;
-
- s = spltty();
- if (tp->t_rawq.c_cc > 0)
- ndflush(&tp->t_rawq, tp->t_rawq.c_cc);
- clk = (struct clkdata *) tp->T_LINEP;
- if (clk->clk_cc > 0)
- clk_bflush(clk);
- (void)splx(s);
- }
- ttwrite(tp, uio);
-}
-
-
-/*
- * Low level character input routine.
- * If the character looks okay, grab a time stamp. If the stuff in
- * the buffer is too old, dump it and start fresh. If the character is
- * non-BCDish, everything in the buffer too.
- */
-clkinput(c, tp)
- register int c;
- register struct tty *tp;
-{
- register struct clkdata *clk;
- register int i;
- register long s;
- struct timeval tv;
-
- /*
- * Check to see whether this isn't the magic character. If not,
- * save the character and return.
- */
-#ifdef ultrix
- if (c != tp->t_cc[VERASE] && c != tp->t_cc[VKILL]) {
-#else
- if (c != tp->t_erase && c != tp->t_kill) {
-#endif
- clk = (struct clkdata *) tp->T_LINEP;
- if (clk->clk_cc >= CLKLINESIZE)
- clk_bflush(clk);
- if (putc(c, &clk->clkbuf) == -1) {
- /*
- * Hopeless, no clists. Flush what we have
- * and hope things improve.
- */
- clk_bflush(clk);
- }
- return;
- }
-
- /*
- * Here we have a magic character. Get a timestamp and store
- * everything.
- */
- microtime(&tv);
- clk = (struct clkdata *) tp->T_LINEP;
-
- if (putc(c, &clk->clkbuf) == -1)
- goto flushout;
-
-#ifdef CLKLDISC
- /*
- * STREAMS people started writing timestamps this way.
- * It's not my fault, I am just going along with the flow...
- */
- for (i = 0; i < sizeof(struct timeval); i++)
- if (putc(*( ((char*)&tv) + i ), &clk->clkbuf) == -1)
- goto flushout;
-#else
- /*
- * This is a machine independant way of puting longs into
- * the datastream. It has fallen into disuse...
- */
- s = tv.tv_sec;
- for (i = 0; i < sizeof(long); i++) {
- if (putc((s >> 24) & 0xff, &clk->clkbuf) == -1)
- goto flushout;
- s <<= 8;
- }
-
- s = tv.tv_usec;
- for (i = 0; i < sizeof(long); i++) {
- if (putc((s >> 24) & 0xff, &clk->clkbuf) == -1)
- goto flushout;
- s <<= 8;
- }
-#endif
-
- /*
- * If the length of the rawq exceeds our sanity limit, dump
- * all the old crap in there before copying this in.
- */
- if (tp->t_rawq.c_cc > NCLKCHARS)
- ndflush(&tp->t_rawq, tp->t_rawq.c_cc);
-
- /*
- * Now copy the buffer in. There is a special case optimization
- * here. If there is nothing on the rawq at present we can
- * just copy the clists we own over. Otherwise we must concatenate
- * the present data on the end.
- */
- s = (long)spltty();
- if (tp->t_rawq.c_cc <= 0) {
- tp->t_rawq = clk->clkbuf;
- clk->clk_cc = 0;
- clk->clk_cl = clk->clk_cf = NULL;
- (void) splx((int)s);
- } else {
- (void) splx((int)s);
- catq(&clk->clkbuf, &tp->t_rawq);
- clk_bflush(clk);
- }
-
- /*
- * Tell the world
- */
- ttwakeup(tp);
- return;
-
-flushout:
- /*
- * It would be nice if this never happened. Flush the
- * internal clists and hope someone else frees some of them
- */
- clk_bflush(clk);
- return;
-}
-
-
-/*
- * Handle ioctls. We reject most tty-style except those that
- * change the line discipline and a couple of others..
- */
-clkioctl(tp, cmd, data, flag)
- struct tty *tp;
- int cmd;
- caddr_t data;
- int flag;
-{
- int flags;
- struct sgttyb *sg;
-
- if ((cmd>>8) != 't')
- return (-1);
- switch (cmd) {
- case TIOCSETD:
- case TIOCGETD:
- case TIOCGETP:
- case TIOCGETC:
- case TIOCOUTQ:
- return (-1);
-
- case TIOCSETP:
- /*
- * He likely wants to set new magic characters in.
- * Do this part.
- */
- sg = (struct sgttyb *)data;
-#ifdef ultrix
- tp->t_cc[VERASE] = sg->sg_erase;
- tp->t_cc[VKILL] = sg->sg_kill;
-#else
- tp->t_erase = sg->sg_erase;
- tp->t_kill = sg->sg_kill;
-#endif
- return (0);
-
- case TIOCFLUSH:
- flags = *(int *)data;
- if (flags == 0 || (flags & FREAD)) {
- register struct clkdata *clk;
-
- clk = (struct clkdata *) tp->T_LINEP;
- if (clk->clk_cc > 0)
- clk_bflush(clk);
- }
- return (-1);
-
- default:
- break;
- }
- return (ENOTTY); /* not quite appropriate */
-}
-#endif NCLK