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/dev/sun/sunkbd.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 /*      $NetBSD: sunkbd.c,v 1.19 2003/08/07 16:31:27 agc Exp $  */
    2 
    3 /*
    4  * Copyright (c) 1992, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This software was developed by the Computer Systems Engineering group
    8  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
    9  * contributed to Berkeley.
   10  *
   11  * All advertising materials mentioning features or use of this software
   12  * must display the following acknowledgement:
   13  *      This product includes software developed by the University of
   14  *      California, Lawrence Berkeley Laboratory.
   15  *
   16  * Redistribution and use in source and binary forms, with or without
   17  * modification, are permitted provided that the following conditions
   18  * are met:
   19  * 1. Redistributions of source code must retain the above copyright
   20  *    notice, this list of conditions and the following disclaimer.
   21  * 2. Redistributions in binary form must reproduce the above copyright
   22  *    notice, this list of conditions and the following disclaimer in the
   23  *    documentation and/or other materials provided with the distribution.
   24  * 3. Neither the name of the University nor the names of its contributors
   25  *    may be used to endorse or promote products derived from this software
   26  *    without specific prior written permission.
   27  *
   28  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   29  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   30  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   31  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   32  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   36  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   37  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   38  * SUCH DAMAGE.
   39  *
   40  *      @(#)kbd.c       8.2 (Berkeley) 10/30/93
   41  */
   42 
   43 /*
   44  * /dev/kbd lower layer for sun keyboard off a tty (line discipline).
   45  * This driver uses kbdsun middle layer to hook up to /dev/kbd.
   46  */
   47 
   48 /*
   49  * Keyboard interface line discipline.
   50  *
   51  */
   52 
   53 #include <sys/cdefs.h>
   54 __KERNEL_RCSID(0, "$NetBSD: sunkbd.c,v 1.19 2003/08/07 16:31:27 agc Exp $");
   55 
   56 #include <sys/param.h>
   57 #include <sys/systm.h>
   58 #include <sys/conf.h>
   59 #include <sys/device.h>
   60 #include <sys/kernel.h>
   61 #include <sys/malloc.h>
   62 #include <sys/proc.h>
   63 #include <sys/signal.h>
   64 #include <sys/signalvar.h>
   65 #include <sys/time.h>
   66 #include <sys/select.h>
   67 #include <sys/syslog.h>
   68 #include <sys/fcntl.h>
   69 #include <sys/tty.h>
   70 
   71 #include <dev/cons.h>
   72 #include <machine/vuid_event.h>
   73 #include <machine/kbd.h>
   74 #include <dev/sun/event_var.h>
   75 #include <dev/sun/kbd_xlate.h>
   76 #include <dev/sun/kbdvar.h>
   77 #include <dev/sun/kbdsunvar.h>
   78 #include <dev/sun/kbd_ms_ttyvar.h>
   79 
   80 /****************************************************************
   81  * Interface to the lower layer (ttycc)
   82  ****************************************************************/
   83 
   84 static int      sunkbd_match(struct device *, struct cfdata *, void *);
   85 static void     sunkbd_attach(struct device *, struct device *, void *);
   86 static void     sunkbd_write_data(struct kbd_sun_softc *, int);
   87 static int      sunkbdiopen(struct device *, int mode);
   88 
   89 #if NWSKBD > 0
   90 void kbd_wskbd_attach(struct kbd_softc *k, int isconsole);
   91 #endif
   92 
   93 int     sunkbdinput(int, struct tty *);
   94 int     sunkbdstart(struct tty *);
   95 
   96 /* Default keyboard baud rate */
   97 int     sunkbd_bps = KBD_DEFAULT_BPS;
   98 
   99 CFATTACH_DECL(kbd_tty, sizeof(struct kbd_sun_softc),
  100     sunkbd_match, sunkbd_attach, NULL, NULL);
  101 
  102 struct  linesw sunkbd_disc =
  103         { "sunkbd", 7, ttylopen, ttylclose, ttyerrio, ttyerrio, ttynullioctl,
  104           sunkbdinput, sunkbdstart, nullmodem, ttpoll }; /* 7- SUNKBDDISC */
  105 
  106 
  107 /*
  108  * sunkbd_match: how is this tty channel configured?
  109  */
  110 int
  111 sunkbd_match(parent, cf, aux)
  112         struct device *parent;
  113         struct cfdata *cf;
  114         void   *aux;
  115 {
  116         struct kbd_ms_tty_attach_args *args = aux;
  117 
  118         if (strcmp(args->kmta_name, "keyboard") == 0)
  119                 return (1);
  120 
  121         return 0;
  122 }
  123 
  124 void
  125 sunkbd_attach(parent, self, aux)
  126         struct device *parent, *self;
  127         void   *aux;
  128 {
  129         struct kbd_sun_softc *k = (void *) self;
  130         struct kbd_ms_tty_attach_args *args = aux;
  131         struct tty *tp = args->kmta_tp;
  132         struct cons_channel *cc;
  133 
  134         /* Set up the proper line discipline. */
  135         ttyldisc_init();
  136         if (ttyldisc_add(&sunkbd_disc, -1) == -1)
  137                 panic("sunkbd_attach: sunkbd_disc");
  138         tp->t_linesw = &sunkbd_disc;
  139         tp->t_oflag &= ~OPOST;
  140         tp->t_dev = args->kmta_dev;
  141 
  142         /* link the structures together. */
  143         k->k_priv = tp;
  144         tp->t_sc = (void *)k;
  145 
  146         /* provide our middle layer with a link to the lower layer (i.e. us) */
  147         k->k_deviopen = sunkbdiopen;
  148         k->k_deviclose = NULL;
  149         k->k_write_data = sunkbd_write_data;
  150 
  151         /* provide upper layer with a link to our middle layer */
  152         k->k_kbd.k_ops = &kbd_ops_sun;
  153 
  154         /* alloc console input channel */
  155         if ((cc = kbd_cc_alloc(&k->k_kbd)) == NULL)
  156                 return;
  157 
  158         if (args->kmta_consdev) {
  159                 char magic[4];
  160 
  161                 /*
  162                  * Hookup ourselves as the console input channel
  163                  */
  164                 args->kmta_baud = sunkbd_bps;
  165                 args->kmta_cflag = CLOCAL|CS8;
  166                 cons_attach_input(cc, args->kmta_consdev);
  167 
  168                 /* Tell our parent what the console should be. */
  169                 args->kmta_consdev = cn_tab;
  170                 k->k_kbd.k_isconsole = 1;
  171                 printf(" (console input)");
  172 
  173                 /* Set magic to "L1-A" */
  174                 magic[0] = KBD_L1;
  175                 magic[1] = KBD_A;
  176                 magic[2] = 0;
  177                 cn_set_magic(magic);
  178         } else {
  179                 extern void kd_attach_input(struct cons_channel *);
  180 
  181                 kd_attach_input(cc);
  182         }
  183 
  184 
  185         printf("\n");
  186 
  187 #if NWSKBD > 0
  188         kbd_wskbd_attach(&k->k_kbd, args->kmta_consdev != NULL);
  189 #endif
  190 
  191         /* Do this before any calls to kbd_rint(). */
  192         kbd_xlate_init(&k->k_kbd.k_state);
  193 
  194         /* Magic sequence. */
  195         k->k_magic1 = KBD_L1;
  196         k->k_magic2 = KBD_A;
  197 }
  198 
  199 /*
  200  * Internal open routine.  This really should be inside com.c
  201  * But I'm putting it here until we have a generic internal open
  202  * mechanism.
  203  */
  204 int
  205 sunkbdiopen(dev, flags)
  206         struct device *dev;
  207         int flags;
  208 {
  209         struct kbd_sun_softc *k = (void *) dev;
  210         struct tty *tp = (struct tty *)k->k_priv;
  211         struct proc *p = curproc ? curproc : &proc0;
  212         struct termios t;
  213         const struct cdevsw *cdev;
  214         int error;
  215 
  216         cdev = cdevsw_lookup(tp->t_dev);
  217         if (cdev == NULL)
  218                 return (ENXIO);
  219 
  220         /* Open the lower device */
  221         if ((error = (*cdev->d_open)(tp->t_dev, O_NONBLOCK|flags,
  222                                      0/* ignored? */, p)) != 0)
  223                 return (error);
  224 
  225         /* Now configure it for the console. */
  226         tp->t_ospeed = 0;
  227         t.c_ispeed = sunkbd_bps;
  228         t.c_ospeed = sunkbd_bps;
  229         t.c_cflag =  CLOCAL|CS8;
  230         (*tp->t_param)(tp, &t);
  231 
  232         return (0);
  233 }
  234 
  235 /*
  236  * TTY interface to handle input.
  237  */
  238 int
  239 sunkbdinput(c, tp)
  240         int c;
  241         struct tty *tp;
  242 {
  243         struct kbd_sun_softc *k = (void *) tp->t_sc;
  244         u_char *cc;
  245         int error;
  246 
  247 
  248         cc = tp->t_cc;
  249 
  250         /*
  251          * Handle exceptional conditions (break, parity, framing).
  252          */
  253         if ((error = ((c & TTY_ERRORMASK))) != 0) {
  254                 /*
  255                  * After garbage, flush pending input, and
  256                  * send a reset to resync key translation.
  257                  */
  258                 log(LOG_ERR, "%s: input error (0x%x)\n",
  259                         k->k_kbd.k_dev.dv_xname, c);
  260                 c &= TTY_CHARMASK;
  261                 if (!k->k_txflags & K_TXBUSY) {
  262                         ttyflush(tp, FREAD | FWRITE);
  263                         goto send_reset;
  264                 }
  265         }
  266 
  267         /*
  268          * Check for input buffer overflow
  269          */
  270         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
  271                 log(LOG_ERR, "%s: input overrun\n",
  272                     k->k_kbd.k_dev.dv_xname);
  273                 goto send_reset;
  274         }
  275 
  276         /* Pass this up to the "middle" layer. */
  277         kbd_sun_input(k, c);
  278         return (-1);
  279 
  280 send_reset:
  281         /* Send a reset to resync translation. */
  282         kbd_sun_output(k, KBD_CMD_RESET);
  283         return (ttstart(tp));
  284 
  285 }
  286 
  287 int
  288 sunkbdstart(tp)
  289         struct tty *tp;
  290 {
  291         struct kbd_sun_softc *k = (void *) tp->t_sc;
  292 
  293         /*
  294          * Transmit done.  Try to send more, or
  295          * clear busy and wakeup drain waiters.
  296          */
  297         k->k_txflags &= ~K_TXBUSY;
  298         kbd_sun_start_tx(k);
  299         ttstart(tp);
  300         return (0);
  301 }
  302 /*
  303  * used by kbd_sun_start_tx();
  304  */
  305 void
  306 sunkbd_write_data(k, c)
  307         struct kbd_sun_softc *k;
  308         int c;
  309 {
  310         struct tty *tp = (struct tty *)k->k_priv;
  311         int     s;
  312 
  313         s = spltty();
  314         ttyoutput(c, tp);
  315         ttstart(tp);
  316         splx(s);
  317 }

Cache object: 6fa43b0bf3fe7709ecdac07634a6e7fc


[ 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.