[BACK]Return to gsckbd.c CVS log [TXT][DIR] Up to [local] / sys / arch / hppa / gsc

Annotation of sys/arch/hppa/gsc/gsckbd.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: gsckbd.c,v 1.7 2006/12/17 21:26:53 miod Exp $ */
        !             2: /*
        !             3:  * Copyright (c) 2003, Miodrag Vallat.
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * Redistribution and use in source and binary forms, with or without
        !             7:  * modification, are permitted provided that the following conditions
        !             8:  * are met:
        !             9:  * 1. Redistributions of source code must retain the above copyright
        !            10:  *    notice, this list of conditions and the following disclaimer.
        !            11:  * 2. Redistributions in binary form must reproduce the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer in the
        !            13:  *    documentation and/or other materials provided with the distribution.
        !            14:  *
        !            15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            18:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            19:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            20:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            23:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            24:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            25:  * POSSIBILITY OF SUCH DAMAGE.
        !            26:  *
        !            27:  */
        !            28:
        !            29: /*
        !            30:  * Derived from /sys/dev/pckbc/pckbd.c under the following terms:
        !            31:  * OpenBSD: pckbd.c,v 1.4 2002/03/14 01:27:00 millert Exp
        !            32:  * NetBSD: pckbd.c,v 1.24 2000/06/05 22:20:57 sommerfeld Exp
        !            33:  */
        !            34: /*-
        !            35:  * Copyright (c) 1998 The NetBSD Foundation, Inc.
        !            36:  * All rights reserved.
        !            37:  *
        !            38:  * This code is derived from software contributed to The NetBSD Foundation
        !            39:  * by Charles M. Hannum.
        !            40:  *
        !            41:  * Redistribution and use in source and binary forms, with or without
        !            42:  * modification, are permitted provided that the following conditions
        !            43:  * are met:
        !            44:  * 1. Redistributions of source code must retain the above copyright
        !            45:  *    notice, this list of conditions and the following disclaimer.
        !            46:  * 2. Redistributions in binary form must reproduce the above copyright
        !            47:  *    notice, this list of conditions and the following disclaimer in the
        !            48:  *    documentation and/or other materials provided with the distribution.
        !            49:  * 3. All advertising materials mentioning features or use of this software
        !            50:  *    must display the following acknowledgement:
        !            51:  *        This product includes software developed by the NetBSD
        !            52:  *        Foundation, Inc. and its contributors.
        !            53:  * 4. Neither the name of The NetBSD Foundation nor the names of its
        !            54:  *    contributors may be used to endorse or promote products derived
        !            55:  *    from this software without specific prior written permission.
        !            56:  *
        !            57:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            58:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            59:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            60:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            61:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            62:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            63:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            64:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            65:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            66:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            67:  * POSSIBILITY OF SUCH DAMAGE.
        !            68:  */
        !            69:
        !            70: /*-
        !            71:  * Copyright (c) 1990 The Regents of the University of California.
        !            72:  * All rights reserved.
        !            73:  *
        !            74:  * This code is derived from software contributed to Berkeley by
        !            75:  * William Jolitz and Don Ahn.
        !            76:  *
        !            77:  * Redistribution and use in source and binary forms, with or without
        !            78:  * modification, are permitted provided that the following conditions
        !            79:  * are met:
        !            80:  * 1. Redistributions of source code must retain the above copyright
        !            81:  *    notice, this list of conditions and the following disclaimer.
        !            82:  * 2. Redistributions in binary form must reproduce the above copyright
        !            83:  *    notice, this list of conditions and the following disclaimer in the
        !            84:  *    documentation and/or other materials provided with the distribution.
        !            85:  * 3. Neither the name of the University nor the names of its contributors
        !            86:  *    may be used to endorse or promote products derived from this software
        !            87:  *    without specific prior written permission.
        !            88:  *
        !            89:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            90:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            91:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            92:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            93:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            94:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            95:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            96:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            97:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            98:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            99:  * SUCH DAMAGE.
        !           100:  *
        !           101:  *     @(#)pccons.c    5.11 (Berkeley) 5/21/91
        !           102:  */
        !           103:
        !           104: /*
        !           105:  * A pckbd-like driver for the GSC keyboards found on various HP workstations.
        !           106:  */
        !           107:
        !           108: #include <sys/param.h>
        !           109: #include <sys/systm.h>
        !           110: #include <sys/device.h>
        !           111: #include <sys/malloc.h>
        !           112: #include <sys/ioctl.h>
        !           113:
        !           114: #include <machine/bus.h>
        !           115:
        !           116: #include <dev/ic/pckbcvar.h>
        !           117:
        !           118: #include <dev/pckbc/pckbdreg.h>
        !           119: #include <hppa/gsc/gsckbdvar.h>
        !           120: #include <hppa/gsc/gsckbdmap.h>
        !           121:
        !           122: #include <dev/wscons/wsconsio.h>
        !           123: #include <dev/wscons/wskbdvar.h>
        !           124: #include <dev/wscons/wsksymdef.h>
        !           125: #include <dev/wscons/wsksymvar.h>
        !           126:
        !           127: struct gsckbd_internal {
        !           128:        int t_isconsole;
        !           129:        pckbc_tag_t t_kbctag;
        !           130:        pckbc_slot_t t_kbcslot;
        !           131:
        !           132:        int t_lastchar;
        !           133:        int t_extended;
        !           134:        int t_releasing;
        !           135:        int t_extended1;
        !           136:
        !           137:        struct gsckbd_softc *t_sc; /* back pointer */
        !           138: };
        !           139:
        !           140: struct gsckbd_softc {
        !           141:         struct  device sc_dev;
        !           142:
        !           143:        struct gsckbd_internal *id;
        !           144:        int sc_enabled;
        !           145:
        !           146:        int sc_ledstate;
        !           147:
        !           148:        struct device *sc_wskbddev;
        !           149: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           150:        int rawkbd;
        !           151: #endif
        !           152: };
        !           153:
        !           154: int gsckbd_is_console(pckbc_tag_t, pckbc_slot_t);
        !           155:
        !           156: int gsckbdprobe(struct device *, void *, void *);
        !           157: void gsckbdattach(struct device *, struct device *, void *);
        !           158:
        !           159: struct cfdriver gsckbd_cd = {
        !           160:        NULL, "gsckbd", DV_DULL
        !           161: };
        !           162:
        !           163: struct cfattach gsckbd_ca = {
        !           164:        sizeof(struct gsckbd_softc), gsckbdprobe, gsckbdattach,
        !           165: };
        !           166:
        !           167: int    gsckbd_enable(void *, int);
        !           168: void   gsckbd_set_leds(void *, int);
        !           169: int    gsckbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
        !           170:
        !           171: const struct wskbd_accessops gsckbd_accessops = {
        !           172:        gsckbd_enable,
        !           173:        gsckbd_set_leds,
        !           174:        gsckbd_ioctl,
        !           175: };
        !           176:
        !           177: void   gsckbd_cngetc(void *, u_int *, int *);
        !           178: void   gsckbd_cnpollc(void *, int);
        !           179:
        !           180: const struct wskbd_consops gsckbd_consops = {
        !           181:        gsckbd_cngetc,
        !           182:        gsckbd_cnpollc,
        !           183:        NULL
        !           184: };
        !           185:
        !           186: const struct wskbd_mapdata gsckbd_keymapdata = {
        !           187:        gsckbd_keydesctab,      /* XXX */
        !           188: #ifdef GSCKBD_LAYOUT
        !           189:        GSCKBD_LAYOUT,
        !           190: #else
        !           191:        KB_US,
        !           192: #endif
        !           193: };
        !           194:
        !           195: int    gsckbd_init(struct gsckbd_internal *, pckbc_tag_t, pckbc_slot_t,
        !           196:                        int);
        !           197: void   gsckbd_input(void *, int);
        !           198:
        !           199: static int     gsckbd_decode(struct gsckbd_internal *, int,
        !           200:                                  u_int *, int *);
        !           201: static int     gsckbd_led_encode(int);
        !           202: static int     gsckbd_led_decode(int);
        !           203:
        !           204: struct gsckbd_internal gsckbd_consdata;
        !           205:
        !           206: int
        !           207: gsckbd_is_console(tag, slot)
        !           208:        pckbc_tag_t tag;
        !           209:        pckbc_slot_t slot;
        !           210: {
        !           211:        return (gsckbd_consdata.t_isconsole &&
        !           212:                (tag == gsckbd_consdata.t_kbctag) &&
        !           213:                (slot == gsckbd_consdata.t_kbcslot));
        !           214: }
        !           215:
        !           216: /*
        !           217:  * these are both EXTREMELY bad jokes
        !           218:  */
        !           219: int
        !           220: gsckbdprobe(parent, match, aux)
        !           221:        struct device *parent;
        !           222:        void *match;
        !           223:        void *aux;
        !           224: {
        !           225:        struct cfdata *cf = match;
        !           226:        struct pckbc_attach_args *pa = aux;
        !           227:        u_char cmd[1], resp[1];
        !           228:        int res;
        !           229:
        !           230:        /*
        !           231:         * XXX There are rumours that a keyboard can be connected
        !           232:         * to the aux port as well. For me, this didn't work.
        !           233:         * For further experiments, allow it if explicitly
        !           234:         * wired in the config file.
        !           235:         */
        !           236:        if ((pa->pa_slot != PCKBC_KBD_SLOT) &&
        !           237:            (cf->cf_loc[PCKBCCF_SLOT] == PCKBCCF_SLOT_DEFAULT))
        !           238:                return (0);
        !           239:
        !           240:        /* Flush any garbage. */
        !           241:        pckbc_flush(pa->pa_tag, pa->pa_slot);
        !           242:
        !           243:        /* Reset the keyboard. */
        !           244:        cmd[0] = KBC_RESET;
        !           245:        res = pckbc_poll_cmd(pa->pa_tag, pa->pa_slot, cmd, 1, 1, resp, 1);
        !           246:        if (res) {
        !           247: #ifdef DEBUG
        !           248:                printf("gsckbdprobe: reset error %d\n", res);
        !           249: #endif
        !           250:                /*
        !           251:                 * There is probably no keyboard connected.
        !           252:                 * Let the probe succeed if the keyboard is used
        !           253:                 * as console input - it can be connected later.
        !           254:                 */
        !           255:                return (gsckbd_is_console(pa->pa_tag, pa->pa_slot) ? 1 : 0);
        !           256:        }
        !           257:        if (resp[0] != KBR_RSTDONE) {
        !           258:                printf("gsckbdprobe: reset response 0x%x\n", resp[0]);
        !           259:                return (0);
        !           260:        }
        !           261:
        !           262:        /*
        !           263:         * Some keyboards seem to leave a second ack byte after the reset.
        !           264:         * This is kind of stupid, but we account for them anyway by just
        !           265:         * flushing the buffer.
        !           266:         */
        !           267:        pckbc_flush(pa->pa_tag, pa->pa_slot);
        !           268:
        !           269:        return (2);
        !           270: }
        !           271:
        !           272: void
        !           273: gsckbdattach(parent, self, aux)
        !           274:        struct device *parent, *self;
        !           275:        void *aux;
        !           276: {
        !           277:        struct gsckbd_softc *sc = (void *)self;
        !           278:        struct pckbc_attach_args *pa = aux;
        !           279:        int isconsole;
        !           280:        struct wskbddev_attach_args a;
        !           281:        u_char cmd[1];
        !           282:
        !           283:        printf("\n");
        !           284:
        !           285:        isconsole = gsckbd_is_console(pa->pa_tag, pa->pa_slot);
        !           286:
        !           287:        if (isconsole) {
        !           288:                sc->id = &gsckbd_consdata;
        !           289:                /*
        !           290:                 * Some keyboards are not enabled after a reset,
        !           291:                 * so make sure it is enabled now.
        !           292:                 */
        !           293:                cmd[0] = KBC_ENABLE;
        !           294:                (void) pckbc_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           295:                    cmd, 1, 0, 0, 0);
        !           296:                sc->sc_enabled = 1;
        !           297:        } else {
        !           298:                sc->id = malloc(sizeof(struct gsckbd_internal),
        !           299:                                M_DEVBUF, M_WAITOK);
        !           300:                (void) gsckbd_init(sc->id, pa->pa_tag, pa->pa_slot, 0);
        !           301:
        !           302:                /* no interrupts until enabled */
        !           303:                cmd[0] = KBC_DISABLE;
        !           304:                (void) pckbc_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           305:                                      cmd, 1, 0, 0, 0);
        !           306:                sc->sc_enabled = 0;
        !           307:        }
        !           308:
        !           309:        sc->id->t_sc = sc;
        !           310:
        !           311:        pckbc_set_inputhandler(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           312:                               gsckbd_input, sc, sc->sc_dev.dv_xname);
        !           313:
        !           314:        a.console = isconsole;
        !           315:
        !           316:        a.keymap = &gsckbd_keymapdata;
        !           317:
        !           318:        a.accessops = &gsckbd_accessops;
        !           319:        a.accesscookie = sc;
        !           320:
        !           321:        /*
        !           322:         * Attach the wskbd, saving a handle to it.
        !           323:         * XXX XXX XXX
        !           324:         */
        !           325:        sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
        !           326: }
        !           327:
        !           328: int
        !           329: gsckbd_enable(v, on)
        !           330:        void *v;
        !           331:        int on;
        !           332: {
        !           333:        struct gsckbd_softc *sc = v;
        !           334:        u_char cmd[1];
        !           335:        int res;
        !           336:
        !           337:        if (on) {
        !           338:                if (sc->sc_enabled && !sc->id->t_isconsole)
        !           339:                        return (EBUSY);
        !           340:
        !           341:                pckbc_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 1);
        !           342:
        !           343:                cmd[0] = KBC_ENABLE;
        !           344:                res = pckbc_poll_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           345:                    cmd, 1, 0, NULL, 0);
        !           346:                if (res) {
        !           347:                        printf("gsckbd_enable: command error\n");
        !           348:                        return (res);
        !           349:                }
        !           350:
        !           351:                sc->sc_enabled = 1;
        !           352:        } else {
        !           353:                if (sc->id->t_isconsole)
        !           354:                        return (EBUSY);
        !           355:
        !           356:                cmd[0] = KBC_DISABLE;
        !           357:                res = pckbc_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           358:                                        cmd, 1, 0, 1, 0);
        !           359:                if (res) {
        !           360:                        printf("gsckbd_disable: command error\n");
        !           361:                        return (res);
        !           362:                }
        !           363:
        !           364:                pckbc_slot_enable(sc->id->t_kbctag, sc->id->t_kbcslot, 0);
        !           365:
        !           366:                sc->sc_enabled = 0;
        !           367:        }
        !           368:
        !           369:        return (0);
        !           370: }
        !           371:
        !           372: static int
        !           373: gsckbd_decode(id, datain, type, dataout)
        !           374:        struct gsckbd_internal *id;
        !           375:        int datain;
        !           376:        u_int *type;
        !           377:        int *dataout;
        !           378: {
        !           379:        int key;
        !           380:
        !           381:        if (datain == KBR_BREAK) {
        !           382:                id->t_releasing = 1;    /* next keycode is a release */
        !           383:                return 0;
        !           384:        }
        !           385:
        !           386:        if (datain == KBR_EXTENDED0) {
        !           387:                id->t_extended = 0x80;
        !           388:                return 0;
        !           389:        } else if (datain == KBR_EXTENDED1) {
        !           390:                id->t_extended1 = 2;
        !           391:                return 0;
        !           392:        }
        !           393:
        !           394:        /*
        !           395:         * Map extended keys to codes 128-254
        !           396:         * Note that we do not use (datain & 0x7f) because function key
        !           397:         * F7 produces non-extended 0x83 code. Sucker.
        !           398:         */
        !           399:        key = datain | id->t_extended;
        !           400:        id->t_extended = 0;
        !           401:
        !           402:        /*
        !           403:         * process BREAK sequence (EXT1 14 77):
        !           404:         * map to (unused) code 7F
        !           405:         */
        !           406:        if (id->t_extended1 == 2 && datain == 0x14) {
        !           407:                id->t_extended1 = 1;
        !           408:                return 0;
        !           409:        } else if (id->t_extended1 == 1 && datain == 0x77) {
        !           410:                id->t_extended1 = 0;
        !           411:                key = 0x7f;
        !           412:        } else if (id->t_extended1 > 0) {
        !           413:                id->t_extended1 = 0;
        !           414:        }
        !           415:
        !           416:        if (id->t_releasing) {
        !           417:                id->t_releasing = 0;
        !           418:                *type = WSCONS_EVENT_KEY_UP;
        !           419:                *dataout = key;
        !           420:                id->t_lastchar = 0;
        !           421:        } else {
        !           422:                /* Always ignore typematic keys */
        !           423:                if (key == id->t_lastchar)
        !           424:                        return 0;
        !           425:                *dataout = id->t_lastchar = key;
        !           426:                *type = WSCONS_EVENT_KEY_DOWN;
        !           427:        }
        !           428:
        !           429:        return 1;
        !           430: }
        !           431:
        !           432: int
        !           433: gsckbd_init(t, kbctag, kbcslot, console)
        !           434:        struct gsckbd_internal *t;
        !           435:        pckbc_tag_t kbctag;
        !           436:        pckbc_slot_t kbcslot;
        !           437:        int console;
        !           438: {
        !           439:        bzero(t, sizeof(struct gsckbd_internal));
        !           440:
        !           441:        t->t_isconsole = console;
        !           442:        t->t_kbctag = kbctag;
        !           443:        t->t_kbcslot = kbcslot;
        !           444:
        !           445:        return (0);
        !           446: }
        !           447:
        !           448: static int
        !           449: gsckbd_led_encode(led)
        !           450:        int led;
        !           451: {
        !           452:        int res;
        !           453:
        !           454:        res = 0;
        !           455:
        !           456:        if (led & WSKBD_LED_SCROLL)
        !           457:                res |= 0x01;
        !           458:        if (led & WSKBD_LED_NUM)
        !           459:                res |= 0x02;
        !           460:        if (led & WSKBD_LED_CAPS)
        !           461:                res |= 0x04;
        !           462:        return(res);
        !           463: }
        !           464:
        !           465: static int
        !           466: gsckbd_led_decode(led)
        !           467:        int led;
        !           468: {
        !           469:        int res;
        !           470:
        !           471:        res = 0;
        !           472:        if (led & 0x01)
        !           473:                res |= WSKBD_LED_SCROLL;
        !           474:        if (led & 0x02)
        !           475:                res |= WSKBD_LED_NUM;
        !           476:        if (led & 0x04)
        !           477:                res |= WSKBD_LED_CAPS;
        !           478:        return(res);
        !           479: }
        !           480:
        !           481: void
        !           482: gsckbd_set_leds(v, leds)
        !           483:        void *v;
        !           484:        int leds;
        !           485: {
        !           486:        struct gsckbd_softc *sc = v;
        !           487:        u_char cmd[2];
        !           488:
        !           489:        cmd[0] = KBC_MODEIND;
        !           490:        cmd[1] = gsckbd_led_encode(leds);
        !           491:        sc->sc_ledstate = cmd[1];
        !           492:
        !           493:        pckbc_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           494:            cmd, 2, 0, 0, 0);
        !           495: }
        !           496:
        !           497: /*
        !           498:  * Got a console receive interrupt -
        !           499:  * the console processor wants to give us a character.
        !           500:  */
        !           501: void
        !           502: gsckbd_input(vsc, data)
        !           503:        void *vsc;
        !           504:        int data;
        !           505: {
        !           506:        struct gsckbd_softc *sc = vsc;
        !           507:        int type, key;
        !           508:
        !           509: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           510:        if (sc->rawkbd) {
        !           511:                char d = data;
        !           512:                wskbd_rawinput(sc->sc_wskbddev, &d, 1);
        !           513:                return;
        !           514:        }
        !           515: #endif
        !           516:        if (gsckbd_decode(sc->id, data, &type, &key))
        !           517:                wskbd_input(sc->sc_wskbddev, type, key);
        !           518: }
        !           519:
        !           520: int
        !           521: gsckbd_ioctl(v, cmd, data, flag, p)
        !           522:        void *v;
        !           523:        u_long cmd;
        !           524:        caddr_t data;
        !           525:        int flag;
        !           526:        struct proc *p;
        !           527: {
        !           528:        struct gsckbd_softc *sc = v;
        !           529:
        !           530:        switch (cmd) {
        !           531:        case WSKBDIO_GTYPE:
        !           532:                *(int *)data = WSKBD_TYPE_GSC;
        !           533:                return 0;
        !           534:        case WSKBDIO_SETLEDS:
        !           535:        {
        !           536:                char cmd[2];
        !           537:                int res;
        !           538:                cmd[0] = KBC_MODEIND;
        !           539:                cmd[1] = gsckbd_led_encode(*(int *)data);
        !           540:                sc->sc_ledstate = cmd[1];
        !           541:                res = pckbc_enqueue_cmd(sc->id->t_kbctag, sc->id->t_kbcslot,
        !           542:                    cmd, 2, 0, 1, 0);
        !           543:                return (res);
        !           544:        }
        !           545:        case WSKBDIO_GETLEDS:
        !           546:                *(int *)data = gsckbd_led_decode(sc->sc_ledstate);
        !           547:                return (0);
        !           548: #ifdef WSDISPLAY_COMPAT_RAWKBD
        !           549:        case WSKBDIO_SETMODE:
        !           550:                sc->rawkbd = (*(int *)data == WSKBD_RAW);
        !           551:                return (0);
        !           552: #endif
        !           553:        }
        !           554:        return -1;
        !           555: }
        !           556:
        !           557: int
        !           558: gsckbd_cnattach(kbctag, kbcslot)
        !           559:        pckbc_tag_t kbctag;
        !           560:        int kbcslot;
        !           561: {
        !           562:        char cmd[1];
        !           563:        int res;
        !           564:
        !           565:        res = gsckbd_init(&gsckbd_consdata, kbctag, kbcslot, 1);
        !           566: #if 0 /* we allow the console to be attached if no keyboard is present */
        !           567:        if (res)
        !           568:                return (res);
        !           569: #endif
        !           570:
        !           571:        /* Just to be sure. */
        !           572:        cmd[0] = KBC_ENABLE;
        !           573:        res = pckbc_poll_cmd(kbctag, kbcslot, cmd, 1, 0, 0, 0);
        !           574: #if 0
        !           575:        if (res)
        !           576:                return (res);
        !           577: #endif
        !           578:
        !           579:        wskbd_cnattach(&gsckbd_consops, &gsckbd_consdata, &gsckbd_keymapdata);
        !           580:
        !           581:        return (0);
        !           582: }
        !           583:
        !           584: /* ARGSUSED */
        !           585: void
        !           586: gsckbd_cngetc(v, type, data)
        !           587:        void *v;
        !           588:        u_int *type;
        !           589:        int *data;
        !           590: {
        !           591:         struct gsckbd_internal *t = v;
        !           592:        int val;
        !           593:
        !           594:        for (;;) {
        !           595:                val = pckbc_poll_data(t->t_kbctag, t->t_kbcslot);
        !           596:                if ((val != -1) && gsckbd_decode(t, val, type, data))
        !           597:                        return;
        !           598:        }
        !           599: }
        !           600:
        !           601: void
        !           602: gsckbd_cnpollc(v, on)
        !           603:        void *v;
        !           604:         int on;
        !           605: {
        !           606:        struct gsckbd_internal *t = v;
        !           607:
        !           608:        pckbc_set_poll(t->t_kbctag, t->t_kbcslot, on);
        !           609: }

CVSweb