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/pckbport/pckbd.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: pckbd.c,v 1.2 2004/03/18 21:05:19 bjh21 Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*-
   40  * Copyright (c) 1990 The Regents of the University of California.
   41  * All rights reserved.
   42  *
   43  * This code is derived from software contributed to Berkeley by
   44  * William Jolitz and Don Ahn.
   45  *
   46  * Redistribution and use in source and binary forms, with or without
   47  * modification, are permitted provided that the following conditions
   48  * are met:
   49  * 1. Redistributions of source code must retain the above copyright
   50  *    notice, this list of conditions and the following disclaimer.
   51  * 2. Redistributions in binary form must reproduce the above copyright
   52  *    notice, this list of conditions and the following disclaimer in the
   53  *    documentation and/or other materials provided with the distribution.
   54  * 3. Neither the name of the University nor the names of its contributors
   55  *    may be used to endorse or promote products derived from this software
   56  *    without specific prior written permission.
   57  *
   58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   68  * SUCH DAMAGE.
   69  *
   70  *      @(#)pccons.c    5.11 (Berkeley) 5/21/91
   71  */
   72 
   73 /*
   74  * code to work keyboard for PC-style console
   75  */
   76 
   77 #include <sys/cdefs.h>
   78 __KERNEL_RCSID(0, "$NetBSD: pckbd.c,v 1.2 2004/03/18 21:05:19 bjh21 Exp $");
   79 
   80 #include <sys/param.h>
   81 #include <sys/systm.h>
   82 #include <sys/device.h>
   83 #include <sys/malloc.h>
   84 #include <sys/ioctl.h>
   85 
   86 #include <machine/bus.h>
   87 
   88 #include <dev/pckbport/pckbportvar.h>
   89 
   90 #include <dev/pckbport/pckbdreg.h>
   91 #include <dev/pckbport/pckbdvar.h>
   92 #include <dev/pckbport/wskbdmap_mfii.h>
   93 
   94 #include <dev/wscons/wsconsio.h>
   95 #include <dev/wscons/wskbdvar.h>
   96 #include <dev/wscons/wsksymdef.h>
   97 #include <dev/wscons/wsksymvar.h>
   98 
   99 #include "locators.h"
  100 
  101 #include "opt_pckbd_layout.h"
  102 #include "opt_wsdisplay_compat.h"
  103 
  104 struct pckbd_internal {
  105         int t_isconsole;
  106         pckbport_tag_t t_kbctag;
  107         pckbport_slot_t t_kbcslot;
  108 
  109         int t_lastchar;
  110         int t_extended0;
  111         int t_extended1;
  112 
  113         struct pckbd_softc *t_sc; /* back pointer */
  114 };
  115 
  116 struct pckbd_softc {
  117         struct  device sc_dev;
  118 
  119         struct pckbd_internal *id;
  120         int sc_enabled;
  121 
  122         int sc_ledstate;
  123 
  124         struct device *sc_wskbddev;
  125 #ifdef WSDISPLAY_COMPAT_RAWKBD
  126         int rawkbd;
  127 #endif
  128 };
  129 
  130 static int pckbd_is_console(pckbport_tag_t, pckbport_slot_t);
  131 
  132 int pckbdprobe(struct device *, struct cfdata *, void *);
  133 void pckbdattach(struct device *, struct device *, void *);
  134 
  135 CFATTACH_DECL(pckbd, sizeof(struct pckbd_softc),
  136     pckbdprobe, pckbdattach, NULL, NULL);
  137 
  138 int     pckbd_enable(void *, int);
  139 void    pckbd_set_leds(void *, int);
  140 int     pckbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
  141 
  142 const struct wskbd_accessops pckbd_accessops = {
  143         pckbd_enable,
  144         pckbd_set_leds,
  145         pckbd_ioctl,
  146 };
  147 
  148 void    pckbd_cngetc(void *, u_int *, int *);
  149 void    pckbd_cnpollc(void *, int);
  150 void    pckbd_cnbell(void *, u_int, u_int, u_int);
  151 
  152 const struct wskbd_consops pckbd_consops = {
  153         pckbd_cngetc,
  154         pckbd_cnpollc,
  155         pckbd_cnbell,
  156 };
  157 
  158 const struct wskbd_mapdata pckbd_keymapdata = {
  159         pckbd_keydesctab,
  160 #ifdef PCKBD_LAYOUT
  161         PCKBD_LAYOUT,
  162 #else
  163         KB_US,
  164 #endif
  165 };
  166 
  167 /*
  168  * Hackish support for a bell on the PC Keyboard; when a suitable feeper
  169  * is found, it attaches itself into the pckbd driver here.
  170  */
  171 void    (*pckbd_bell_fn)(void *, u_int, u_int, u_int, int);
  172 void    *pckbd_bell_fn_arg;
  173 
  174 void    pckbd_bell(u_int, u_int, u_int, int);
  175 
  176 int     pckbd_set_xtscancode(pckbport_tag_t, pckbport_slot_t);
  177 int     pckbd_init(struct pckbd_internal *, pckbport_tag_t, pckbport_slot_t,
  178                         int);
  179 void    pckbd_input(void *, int);
  180 
  181 static int      pckbd_decode(struct pckbd_internal *, int, u_int *, int *);
  182 static int      pckbd_led_encode(int);
  183 static int      pckbd_led_decode(int);
  184 
  185 struct pckbd_internal pckbd_consdata;
  186 
  187 int
  188 pckbd_set_xtscancode(pckbport_tag_t kbctag, pckbport_slot_t kbcslot)
  189 {
  190         int res;
  191         u_char cmd[2];
  192 
  193         /*
  194          * Some keyboard/8042 combinations do not seem to work if the keyboard
  195          * is set to table 1; in fact, it would appear that some keyboards just
  196          * ignore the command altogether.  So by default, we use the AT scan
  197          * codes and have the 8042 translate them.  Unfortunately, this is
  198          * known to not work on some PS/2 machines.  We try desperately to deal
  199          * with this by checking the (lack of a) translate bit in the 8042 and
  200          * attempting to set the keyboard to XT mode.  If this all fails, well,
  201          * tough luck.
  202          *
  203          * XXX It would perhaps be a better choice to just use AT scan codes
  204          * and not bother with this.
  205          */
  206         if (pckbport_xt_translation(kbctag, kbcslot, 1)) {
  207                 /* The 8042 is translating for us; use AT codes. */
  208                 cmd[0] = KBC_SETTABLE;
  209                 cmd[1] = 2;
  210                 res = pckbport_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0);
  211                 if (res) {
  212                         u_char cmd[1];
  213 #ifdef DEBUG
  214                         printf("pckbd: error setting scanset 2\n");
  215 #endif
  216                         /*
  217                          * XXX at least one keyboard is reported to lock up
  218                          * if a "set table" is attempted, thus the "reset".
  219                          * XXX ignore errors, scanset 2 should be
  220                          * default anyway.
  221                          */
  222                         cmd[0] = KBC_RESET;
  223                         (void)pckbport_poll_cmd(kbctag, kbcslot, cmd, 1, 1, 0, 1);
  224                         pckbport_flush(kbctag, kbcslot);
  225                         res = 0;
  226                 }
  227         } else {
  228                 /* Stupid 8042; set keyboard to XT codes. */
  229                 cmd[0] = KBC_SETTABLE;
  230                 cmd[1] = 1;
  231                 res = pckbport_poll_cmd(kbctag, kbcslot, cmd, 2, 0, 0, 0);
  232 #ifdef DEBUG
  233                 if (res)
  234                         printf("pckbd: error setting scanset 1\n");
  235 #endif
  236         }
  237         return res;
  238 }
  239 
  240 static int
  241 pckbd_is_console(pckbport_tag_t tag, pckbport_slot_t slot)
  242 {
  243 
  244         return pckbd_consdata.t_isconsole &&
  245             tag == pckbd_consdata.t_kbctag && slot == pckbd_consdata.t_kbcslot;
  246 }
  247 
  248 /*
  249  * these are both bad jokes
  250  */
  251 int
  252 pckbdprobe(struct device *parent, struct cfdata *cf, void *aux)
  253 {
  254         struct pckbport_attach_args *pa = aux;
  255         int res;
  256         u_char cmd[1], resp[1];
  257 
  258         /*
  259          * XXX There are rumours that a keyboard can be connected
  260          * to the aux port as well. For me, this didn't work.
  261          * For further experiments, allow it if explicitly
  262          * wired in the config file.
  263          */
  264         if ((pa->pa_slot != PCKBPORT_KBD_SLOT) &&
  265             (cf->cf_loc[PCKBPORTCF_SLOT] == PCKBPORTCF_SLOT_DEFAULT))
  266                 return 0;
  267 
  268         /* Flush any garbage. */
  269         pckbport_flush(pa->pa_tag, pa->pa_slot);
  270 
  271         /* Reset the keyboard. */
  272         cmd[0] = KBC_RESET;
  273         res = pckbport_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 1, resp, 1);
  274         if (res) {
  275 #ifdef DEBUG
  276                 printf("pckbdprobe: reset error %d\n", res);
  277 #endif
  278                 /*
  279                  * There is probably no keyboard connected.
  280                  * Let the probe succeed if the keyboard is used
  281                  * as console input - it can be connected later.
  282                  */
  283                 return pckbd_is_console(pa->pa_tag, pa->pa_slot) ? 1 : 0;
  284         }
  285         if (resp[0] != KBR_RSTDONE) {
  286                 printf("pckbdprobe: reset response 0x%x\n", resp[0]);
  287                 return 0;
  288         }
  289 
  290         /*
  291          * Some keyboards seem to leave a second ack byte after the reset.
  292          * This is kind of stupid, but we account for them anyway by just
  293          * flushing the buffer.
  294          */
  295         pckbport_flush(pa->pa_tag, pa->pa_slot);
  296 
  297         if (pckbd_set_xtscancode(pa->pa_tag, pa->pa_slot))
  298                 return 0;
  299 
  300         return 2;
  301 }
  302 
  303 void
  304 pckbdattach(struct device *parent, struct device *self, void *aux)
  305 {
  306         struct pckbd_softc *sc = (void *)self;
  307         struct pckbport_attach_args *pa = aux;
  308         struct wskbddev_attach_args a;
  309         int isconsole;
  310         u_char cmd[1];
  311 
  312         printf("\n");
  313 
  314         isconsole = pckbd_is_console(pa->pa_tag, pa->pa_slot);
  315 
  316         if (isconsole) {
  317                 sc->id = &pckbd_consdata;
  318 
  319                 /* 
  320                  * Some keyboards are not enabled after a reset, 
  321                  * so make sure it is enabled now.
  322                  */
  323                 cmd[0] = KBC_ENABLE;
  324                 (void) pckbport_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  325                                       cmd, 1, 0, 0, 0);
  326                 sc->sc_enabled = 1;
  327         } else {
  328                 sc->id = malloc(sizeof(struct pckbd_internal),
  329                                 M_DEVBUF, M_WAITOK);
  330                 (void) pckbd_init(sc->id, pa->pa_tag, pa->pa_slot, 0);
  331 
  332                 /* no interrupts until enabled */
  333                 cmd[0] = KBC_DISABLE;
  334                 (void) pckbport_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  335                                       cmd, 1, 0, 0, 0);
  336                 sc->sc_enabled = 0;
  337         }
  338 
  339         sc->id->t_sc = sc;
  340 
  341         pckbport_set_inputhandler(sc->id->t_kbctag, sc->id->t_kbcslot,
  342                                pckbd_input, sc, sc->sc_dev.dv_xname);
  343 
  344         a.console = isconsole;
  345 
  346         a.keymap = &pckbd_keymapdata;
  347 
  348         a.accessops = &pckbd_accessops;
  349         a.accesscookie = sc;
  350 
  351         /*
  352          * Attach the wskbd, saving a handle to it.
  353          * XXX XXX XXX
  354          */
  355         sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
  356 }
  357 
  358 int
  359 pckbd_enable(void *v, int on)
  360 {
  361         struct pckbd_softc *sc = v;
  362         int res;
  363         u_char cmd[1];
  364 
  365         if (on) {
  366                 if (sc->sc_enabled) {
  367 #ifdef DIAGNOSTIC
  368                         printf("pckbd_enable: bad enable\n");
  369 #endif
  370                         return EBUSY;
  371                 }
  372 
  373                 pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 1);
  374 
  375                 cmd[0] = KBC_ENABLE;
  376                 res = pckbport_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  377                                         cmd, 1, 0, NULL, 0);
  378                 if (res) {
  379                         printf("pckbd_enable: command error\n");
  380                         return (res);
  381                 }
  382 
  383                 res = pckbd_set_xtscancode(sc->id->t_kbctag,
  384                                            sc->id->t_kbcslot);
  385                 if (res)
  386                         return res;
  387 
  388                 sc->sc_enabled = 1;
  389         } else {
  390                 if (sc->id->t_isconsole)
  391                         return EBUSY;
  392 
  393                 cmd[0] = KBC_DISABLE;
  394                 res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  395                                         cmd, 1, 0, 1, 0);
  396                 if (res) {
  397                         printf("pckbd_disable: command error\n");
  398                         return res;
  399                 }
  400 
  401                 pckbport_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 0);
  402 
  403                 sc->sc_enabled = 0;
  404         }
  405 
  406         return 0;
  407 }
  408 
  409 static int
  410 pckbd_decode(struct pckbd_internal *id, int datain, u_int *type, int *dataout)
  411 {
  412         int key;
  413 
  414         if (datain == KBR_EXTENDED0) {
  415                 id->t_extended0 = 1;
  416                 return 0;
  417         } else if (datain == KBR_EXTENDED1) {
  418                 id->t_extended1 = 2;
  419                 return 0;
  420         }
  421 
  422         /* map extended keys to (unused) codes 128-254 */
  423         key = (datain & 0x7f) | (id->t_extended0 ? 0x80 : 0);
  424         id->t_extended0 = 0;
  425 
  426         /*
  427          * process PAUSE (also break) key (EXT1 1D 45  EXT1 9D C5):
  428          * map to (unused) code 7F
  429          */
  430         if (id->t_extended1 == 2 && (datain == 0x1d || datain == 0x9d)) {
  431                 id->t_extended1 = 1;
  432                 return 0;
  433         } else if (id->t_extended1 == 1 &&
  434                    (datain == 0x45 || datain == 0xc5)) {
  435                 id->t_extended1 = 0;
  436                 key = 0x7f;
  437         } else if (id->t_extended1 > 0) {
  438                 id->t_extended1 = 0;
  439         }
  440 
  441         if (datain & 0x80) {
  442                 id->t_lastchar = 0;
  443                 *type = WSCONS_EVENT_KEY_UP;
  444         } else {
  445                 /* Always ignore typematic keys */
  446                 if (key == id->t_lastchar)
  447                         return 0;
  448                 id->t_lastchar = key;
  449                 *type = WSCONS_EVENT_KEY_DOWN;
  450         }
  451 
  452         *dataout = key;
  453         return 1;
  454 }
  455 
  456 int
  457 pckbd_init(struct pckbd_internal *t, pckbport_tag_t kbctag,
  458     pckbport_slot_t kbcslot, int console)
  459 {
  460 
  461         memset(t, 0, sizeof(struct pckbd_internal));
  462 
  463         t->t_isconsole = console;
  464         t->t_kbctag = kbctag;
  465         t->t_kbcslot = kbcslot;
  466 
  467         return pckbd_set_xtscancode(kbctag, kbcslot);
  468 }
  469 
  470 static int
  471 pckbd_led_encode(int led)
  472 {
  473         int res;
  474 
  475         res = 0;
  476 
  477         if (led & WSKBD_LED_SCROLL)
  478                 res |= 0x01;
  479         if (led & WSKBD_LED_NUM)
  480                 res |= 0x02;
  481         if (led & WSKBD_LED_CAPS)
  482                 res |= 0x04;
  483         return res;
  484 }
  485 
  486 static int
  487 pckbd_led_decode(int led)
  488 {
  489         int res;
  490 
  491         res = 0;
  492         if (led & 0x01)
  493                 res |= WSKBD_LED_SCROLL;
  494         if (led & 0x02)
  495                 res |= WSKBD_LED_NUM;
  496         if (led & 0x04)
  497                 res |= WSKBD_LED_CAPS;
  498         return res;
  499 }
  500 
  501 void
  502 pckbd_set_leds(void *v, int leds)
  503 {
  504         struct pckbd_softc *sc = v;
  505         u_char cmd[2];
  506 
  507         cmd[0] = KBC_MODEIND;
  508         cmd[1] = pckbd_led_encode(leds);
  509         sc->sc_ledstate = cmd[1];
  510 
  511         (void)pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  512                                  cmd, 2, 0, 0, 0);
  513 }
  514 
  515 /*
  516  * Got a console receive interrupt -
  517  * the console processor wants to give us a character.
  518  */
  519 void
  520 pckbd_input(void *vsc, int data)
  521 {
  522         struct pckbd_softc *sc = vsc;
  523         int key;
  524         u_int type;
  525 
  526 #ifdef WSDISPLAY_COMPAT_RAWKBD
  527         if (sc->rawkbd) {
  528                 u_char d = data;
  529                 wskbd_rawinput(sc->sc_wskbddev, &d, 1);
  530                 return;
  531         }
  532 #endif
  533         if (pckbd_decode(sc->id, data, &type, &key))
  534                 wskbd_input(sc->sc_wskbddev, type, key);
  535 }
  536 
  537 int
  538 pckbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
  539 {
  540         struct pckbd_softc *sc = v;
  541 
  542         switch (cmd) {
  543         case WSKBDIO_GTYPE:
  544                 *(int *)data = WSKBD_TYPE_PC_XT;
  545                 return 0;
  546         case WSKBDIO_SETLEDS:
  547         {
  548                 int res;
  549                 u_char cmd[2];
  550 
  551                 cmd[0] = KBC_MODEIND;
  552                 cmd[1] = pckbd_led_encode(*(int *)data);
  553                 sc->sc_ledstate = cmd[1];
  554                 res = pckbport_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
  555                                         cmd, 2, 0, 1, 0);
  556                 return res;
  557         }
  558         case WSKBDIO_GETLEDS:
  559                 *(int *)data = pckbd_led_decode(sc->sc_ledstate);
  560                 return 0;
  561         case WSKBDIO_COMPLEXBELL:
  562 #define d ((struct wskbd_bell_data *)data)
  563                 /*
  564                  * Keyboard can't beep directly; we have an
  565                  * externally-provided global hook to do this.
  566                  */
  567                 pckbd_bell(d->pitch, d->period, d->volume, 0);
  568 #undef d
  569                 return 0;
  570 #ifdef WSDISPLAY_COMPAT_RAWKBD
  571         case WSKBDIO_SETMODE:
  572                 sc->rawkbd = (*(int *)data == WSKBD_RAW);
  573                 return 0;
  574 #endif
  575         }
  576         return EPASSTHROUGH;
  577 }
  578 
  579 void
  580 pckbd_bell(u_int pitch, u_int period, u_int volume, int poll)
  581 {
  582 
  583         if (pckbd_bell_fn != NULL)
  584                 (*pckbd_bell_fn)(pckbd_bell_fn_arg, pitch, period,
  585                     volume, poll);
  586 }
  587 
  588 void
  589 pckbd_hookup_bell(void (*fn)(void *, u_int, u_int, u_int, int), void *arg)
  590 {
  591 
  592         if (pckbd_bell_fn == NULL) {
  593                 pckbd_bell_fn = fn;
  594                 pckbd_bell_fn_arg = arg;
  595         }
  596 }
  597 
  598 int
  599 pckbd_cnattach(pckbport_tag_t kbctag, int kbcslot)
  600 {
  601         int res;
  602         u_char cmd[1];
  603 
  604         res = pckbd_init(&pckbd_consdata, kbctag, kbcslot, 1);
  605 #if 0 /* we allow the console to be attached if no keyboard is present */
  606         if (res)
  607                 return res;
  608 #endif
  609 
  610         /* Just to be sure. */
  611         cmd[0] = KBC_ENABLE;
  612         res = pckbport_poll_cmd(kbctag, kbcslot, cmd, 1, 0, 0, 0);
  613 
  614 #if 0
  615         if (res)
  616                 return res;
  617 #endif
  618 
  619         wskbd_cnattach(&pckbd_consops, &pckbd_consdata, &pckbd_keymapdata);
  620 
  621         return 0;
  622 }
  623 
  624 /* ARGSUSED */
  625 void
  626 pckbd_cngetc(void *v, u_int *type, int *data)
  627 {
  628         struct pckbd_internal *t = v;
  629         int val;
  630 
  631         for (;;) {
  632                 val = pckbport_poll_data(t->t_kbctag, t->t_kbcslot);
  633                 if ((val != -1) && pckbd_decode(t, val, type, data))
  634                         return;
  635         }
  636 }
  637 
  638 void
  639 pckbd_cnpollc(void *v, int on)
  640 {
  641         struct pckbd_internal *t = v;
  642 
  643         pckbport_set_poll(t->t_kbctag, t->t_kbcslot, on);
  644 }
  645 
  646 void
  647 pckbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
  648 {
  649 
  650         pckbd_bell(pitch, period, volume, 1);
  651 }

Cache object: 1266dc86cc20ecf25bc0b4b91c6533d7


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