root/dev/pckbc/pckbd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pckbd_set_xtscancode
  2. pckbd_is_console
  3. pckbdprobe
  4. pckbdattach
  5. pckbd_enable
  6. pckbd_decode
  7. pckbd_init
  8. pckbd_led_encode
  9. pckbd_led_decode
  10. pckbd_set_leds
  11. pckbd_input
  12. pckbd_ioctl
  13. pckbd_bell
  14. pckbd_hookup_bell
  15. pckbd_cnattach
  16. pckbd_cngetc
  17. pckbd_cnpollc
  18. pckbd_cnbell

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

/* [<][>][^][v][top][bottom][index][help] */