The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/tty_tb.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1982, 1986, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)tty_tb.c    8.1 (Berkeley) 6/10/93
   34  * $FreeBSD: src/sys/kern/tty_tb.c,v 1.2.12.1 1999/09/05 08:15:29 peter Exp $
   35  */
   36 
   37 #include "tb.h"
   38 #if NTB > 0
   39 
   40 /*
   41  * Line discipline for RS232 tablets;
   42  * supplies binary coordinate data.
   43  */
   44 #include <sys/param.h>
   45 #include <sys/tablet.h>
   46 #include <sys/tty.h>
   47 
   48 /*
   49  * Tablet configuration table.
   50  */
   51 struct  tbconf {
   52         short   tbc_recsize;    /* input record size in bytes */
   53         short   tbc_uiosize;    /* size of data record returned user */
   54         int     tbc_sync;       /* mask for finding sync byte/bit */
   55         int     (*tbc_decode)();/* decoding routine */
   56         char    *tbc_run;       /* enter run mode sequence */
   57         char    *tbc_point;     /* enter point mode sequence */
   58         char    *tbc_stop;      /* stop sequence */
   59         char    *tbc_start;     /* start/restart sequence */
   60         int     tbc_flags;
   61 #define TBF_POL         0x1     /* polhemus hack */
   62 #define TBF_INPROX      0x2     /* tablet has proximity info */
   63 };
   64 
   65 static  int tbdecode(), gtcodecode(), poldecode();
   66 static  int tblresdecode(), tbhresdecode();
   67 
   68 struct  tbconf tbconf[TBTYPE] = {
   69 { 0 },
   70 { 5, sizeof (struct tbpos), 0200, tbdecode, "6", "4" },
   71 { 5, sizeof (struct tbpos), 0200, tbdecode, "\1CN", "\1RT", "\2", "\4" },
   72 { 8, sizeof (struct gtcopos), 0200, gtcodecode },
   73 {17, sizeof (struct polpos), 0200, poldecode, 0, 0, "\21", "\5\22\2\23",
   74   TBF_POL },
   75 { 5, sizeof (struct tbpos), 0100, tblresdecode, "\1CN", "\1PT", "\2", "\4",
   76   TBF_INPROX },
   77 { 6, sizeof (struct tbpos), 0200, tbhresdecode, "\1CN", "\1PT", "\2", "\4",
   78   TBF_INPROX },
   79 { 5, sizeof (struct tbpos), 0100, tblresdecode, "\1CL\33", "\1PT\33", 0, 0},
   80 { 6, sizeof (struct tbpos), 0200, tbhresdecode, "\1CL\33", "\1PT\33", 0, 0},
   81 };
   82 
   83 /*
   84  * Tablet state
   85  */
   86 struct tb {
   87         int     tbflags;                /* mode & type bits */
   88 #define TBMAXREC        17      /* max input record size */
   89         char    cbuf[TBMAXREC];         /* input buffer */
   90         union {
   91                 struct  tbpos tbpos;
   92                 struct  gtcopos gtcopos;
   93                 struct  polpos polpos;
   94         } rets;                         /* processed state */
   95 #define NTBS    16
   96 } tb[NTBS];
   97 
   98 /*
   99  * Open as tablet discipline; called on discipline change.
  100  */
  101 /*ARGSUSED*/
  102 tbopen(dev, tp)
  103         dev_t dev;
  104         register struct tty *tp;
  105 {
  106         register struct tb *tbp;
  107 
  108         if (tp->t_line == TABLDISC)
  109                 return (ENODEV);
  110         ttywflush(tp);
  111         for (tbp = tb; tbp < &tb[NTBS]; tbp++)
  112                 if (tbp->tbflags == 0)
  113                         break;
  114         if (tbp >= &tb[NTBS])
  115                 return (EBUSY);
  116         tbp->tbflags = TBTIGER|TBPOINT;         /* default */
  117         tp->t_cp = tbp->cbuf;
  118         tp->t_inbuf = 0;
  119         bzero((caddr_t)&tbp->rets, sizeof (tbp->rets));
  120         tp->T_LINEP = (caddr_t)tbp;
  121         tp->t_flags |= LITOUT;
  122         return (0);
  123 }
  124 
  125 /*
  126  * Line discipline change or last device close.
  127  */
  128 tbclose(tp)
  129         register struct tty *tp;
  130 {
  131         register int s;
  132         int modebits = TBPOINT|TBSTOP;
  133 
  134         tbioctl(tp, BIOSMODE, &modebits, 0);
  135         s = spltty();
  136         ((struct tb *)tp->T_LINEP)->tbflags = 0;
  137         tp->t_cp = 0;
  138         tp->t_inbuf = 0;
  139         tp->t_rawq.c_cc = 0;            /* clear queues -- paranoid */
  140         tp->t_canq.c_cc = 0;
  141         tp->t_line = 0;                 /* paranoid: avoid races */
  142         splx(s);
  143 }
  144 
  145 /*
  146  * Read from a tablet line.
  147  * Characters have been buffered in a buffer and decoded.
  148  */
  149 tbread(tp, uio)
  150         register struct tty *tp;
  151         struct uio *uio;
  152 {
  153         register struct tb *tbp = (struct tb *)tp->T_LINEP;
  154         register struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE];
  155         int ret;
  156 
  157         if ((tp->t_state&TS_CARR_ON) == 0)
  158                 return (EIO);
  159         ret = uiomove(&tbp->rets, tc->tbc_uiosize, uio);
  160         if (tc->tbc_flags&TBF_POL)
  161                 tbp->rets.polpos.p_key = ' ';
  162         return (ret);
  163 }
  164 
  165 /*
  166  * Low level character input routine.
  167  * Stuff the character in the buffer, and decode
  168  * if all the chars are there.
  169  *
  170  * This routine could be expanded in-line in the receiver
  171  * interrupt routine to make it run as fast as possible.
  172  */
  173 tbinput(c, tp)
  174         register int c;
  175         register struct tty *tp;
  176 {
  177         register struct tb *tbp = (struct tb *)tp->T_LINEP;
  178         register struct tbconf *tc = &tbconf[tbp->tbflags & TBTYPE];
  179 
  180         if (tc->tbc_recsize == 0 || tc->tbc_decode == 0)        /* paranoid? */
  181                 return;
  182         /*
  183          * Locate sync bit/byte or reset input buffer.
  184          */
  185         if (c&tc->tbc_sync || tp->t_inbuf == tc->tbc_recsize) {
  186                 tp->t_cp = tbp->cbuf;
  187                 tp->t_inbuf = 0;
  188         }
  189         *tp->t_cp++ = c&0177;
  190         /*
  191          * Call decode routine only if a full record has been collected.
  192          */
  193         if (++tp->t_inbuf == tc->tbc_recsize)
  194                 (*tc->tbc_decode)(tc, tbp->cbuf, &tbp->rets);
  195 }
  196 
  197 /*
  198  * Decode GTCO 8 byte format (high res, tilt, and pressure).
  199  */
  200 static
  201 gtcodecode(tc, cp, tbpos)
  202         struct tbconf *tc;
  203         register char *cp;
  204         register struct gtcopos *tbpos;
  205 {
  206 
  207         tbpos->pressure = *cp >> 2;
  208         tbpos->status = (tbpos->pressure > 16) | TBINPROX; /* half way down */
  209         tbpos->xpos = (*cp++ & 03) << 14;
  210         tbpos->xpos |= *cp++ << 7;
  211         tbpos->xpos |= *cp++;
  212         tbpos->ypos = (*cp++ & 03) << 14;
  213         tbpos->ypos |= *cp++ << 7;
  214         tbpos->ypos |= *cp++;
  215         tbpos->xtilt = *cp++;
  216         tbpos->ytilt = *cp++;
  217         tbpos->scount++;
  218 }
  219 
  220 /*
  221  * Decode old Hitachi 5 byte format (low res).
  222  */
  223 static
  224 tbdecode(tc, cp, tbpos)
  225         struct tbconf *tc;
  226         register char *cp;
  227         register struct tbpos *tbpos;
  228 {
  229         register char byte;
  230 
  231         byte = *cp++;
  232         tbpos->status = (byte&0100) ? TBINPROX : 0;
  233         byte &= ~0100;
  234         if (byte > 036)
  235                 tbpos->status |= 1 << ((byte-040)/2);
  236         tbpos->xpos = *cp++ << 7;
  237         tbpos->xpos |= *cp++;
  238         if (tbpos->xpos < 256)                  /* tablet wraps around at 256 */
  239                 tbpos->status &= ~TBINPROX;     /* make it out of proximity */
  240         tbpos->ypos = *cp++ << 7;
  241         tbpos->ypos |= *cp++;
  242         tbpos->scount++;
  243 }
  244 
  245 /*
  246  * Decode new Hitach 5-byte format (low res).
  247  */
  248 static
  249 tblresdecode(tc, cp, tbpos)
  250         struct tbconf *tc;
  251         register char *cp;
  252         register struct tbpos *tbpos;
  253 {
  254 
  255         *cp &= ~0100;           /* mask sync bit */
  256         tbpos->status = (*cp++ >> 2) | TBINPROX;
  257         if (tc->tbc_flags&TBF_INPROX && tbpos->status&020)
  258                 tbpos->status &= ~(020|TBINPROX);
  259         tbpos->xpos = *cp++;
  260         tbpos->xpos |= *cp++ << 6;
  261         tbpos->ypos = *cp++;
  262         tbpos->ypos |= *cp++ << 6;
  263         tbpos->scount++;
  264 }
  265 
  266 /*
  267  * Decode new Hitach 6-byte format (high res).
  268  */
  269 static
  270 tbhresdecode(tc, cp, tbpos)
  271         struct tbconf *tc;
  272         register char *cp;
  273         register struct tbpos *tbpos;
  274 {
  275         char byte;
  276 
  277         byte = *cp++;
  278         tbpos->xpos = (byte & 03) << 14;
  279         tbpos->xpos |= *cp++ << 7;
  280         tbpos->xpos |= *cp++;
  281         tbpos->ypos = *cp++ << 14;
  282         tbpos->ypos |= *cp++ << 7;
  283         tbpos->ypos |= *cp++;
  284         tbpos->status = (byte >> 2) | TBINPROX;
  285         if (tc->tbc_flags&TBF_INPROX && tbpos->status&020)
  286                 tbpos->status &= ~(020|TBINPROX);
  287         tbpos->scount++;
  288 }
  289 
  290 /*
  291  * Polhemus decode.
  292  */
  293 static
  294 poldecode(tc, cp, polpos)
  295         struct tbconf *tc;
  296         register char *cp;
  297         register struct polpos *polpos;
  298 {
  299 
  300         polpos->p_x = cp[4] | cp[3]<<7 | (cp[9] & 0x03) << 14;
  301         polpos->p_y = cp[6] | cp[5]<<7 | (cp[9] & 0x0c) << 12;
  302         polpos->p_z = cp[8] | cp[7]<<7 | (cp[9] & 0x30) << 10;
  303         polpos->p_azi = cp[11] | cp[10]<<7 | (cp[16] & 0x03) << 14;
  304         polpos->p_pit = cp[13] | cp[12]<<7 | (cp[16] & 0x0c) << 12;
  305         polpos->p_rol = cp[15] | cp[14]<<7 | (cp[16] & 0x30) << 10;
  306         polpos->p_stat = cp[1] | cp[0]<<7;
  307         if (cp[2] != ' ')
  308                 polpos->p_key = cp[2];
  309 }
  310 
  311 /*ARGSUSED*/
  312 tbioctl(tp, cmd, data, flag)
  313         struct tty *tp;
  314         caddr_t data;
  315 {
  316         register struct tb *tbp = (struct tb *)tp->T_LINEP;
  317 
  318         switch (cmd) {
  319 
  320         case BIOGMODE:
  321                 *(int *)data = tbp->tbflags & TBMODE;
  322                 break;
  323 
  324         case BIOSTYPE:
  325                 if (tbconf[*(int *)data & TBTYPE].tbc_recsize == 0 ||
  326                     tbconf[*(int *)data & TBTYPE].tbc_decode == 0)
  327                         return (EINVAL);
  328                 tbp->tbflags &= ~TBTYPE;
  329                 tbp->tbflags |= *(int *)data & TBTYPE;
  330                 /* fall thru... to set mode bits */
  331 
  332         case BIOSMODE: {
  333                 register struct tbconf *tc;
  334 
  335                 tbp->tbflags &= ~TBMODE;
  336                 tbp->tbflags |= *(int *)data & TBMODE;
  337                 tc = &tbconf[tbp->tbflags & TBTYPE];
  338                 if (tbp->tbflags&TBSTOP) {
  339                         if (tc->tbc_stop)
  340                                 ttyout(tc->tbc_stop, tp);
  341                 } else if (tc->tbc_start)
  342                         ttyout(tc->tbc_start, tp);
  343                 if (tbp->tbflags&TBPOINT) {
  344                         if (tc->tbc_point)
  345                                 ttyout(tc->tbc_point, tp);
  346                 } else if (tc->tbc_run)
  347                         ttyout(tc->tbc_run, tp);
  348                 ttstart(tp);
  349                 break;
  350         }
  351 
  352         case BIOGTYPE:
  353                 *(int *)data = tbp->tbflags & TBTYPE;
  354                 break;
  355 
  356         case TIOCSETD:
  357         case TIOCGETD:
  358         case TIOCGETP:
  359         case TIOCGETC:
  360                 return (-1);            /* pass thru... */
  361 
  362         default:
  363                 return (ENOTTY);
  364         }
  365         return (0);
  366 }
  367 #endif

Cache object: 7f9c5235c415e87bd4cbdd8d4bc86235


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.