[BACK]Return to akbd.c CVS log [TXT][DIR] Up to [local] / sys / dev / adb

Annotation of sys/dev/adb/akbd.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: akbd.c,v 1.6 2007/03/13 20:56:56 miod Exp $   */
                      2: /*     $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $    */
                      3:
                      4: /*
                      5:  * Copyright (C) 1998  Colin Wood
                      6:  * All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by Colin Wood.
                     19:  * 4. The name of the author may not be used to endorse or promote products
                     20:  *    derived from this software without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     23:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     24:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     25:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     26:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     27:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     28:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     29:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     30:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     31:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32:  */
                     33:
                     34: #include <sys/param.h>
                     35: #include <sys/timeout.h>
                     36: #include <sys/kernel.h>
                     37: #include <sys/device.h>
                     38: #include <sys/systm.h>
                     39:
                     40: #include <dev/wscons/wsconsio.h>
                     41: #include <dev/wscons/wskbdvar.h>
                     42: #include <dev/wscons/wsksymdef.h>
                     43: #include <dev/wscons/wsksymvar.h>
                     44:
                     45: #include <machine/autoconf.h>
                     46: #include <machine/cpu.h>
                     47:
                     48: #include <dev/adb/adb.h>
                     49: #include <dev/adb/akbdmap.h>
                     50: #include <dev/adb/akbdvar.h>
                     51:
                     52: #ifdef WSDISPLAY_COMPAT_RAWKBD
                     53: #define KEYBOARD_ARRAY
                     54: #endif
                     55: #include <dev/adb/keyboard.h>
                     56:
                     57: /*
                     58:  * Function declarations.
                     59:  */
                     60: int    akbdmatch(struct device *, void *, void *);
                     61: void   akbdattach(struct device *, struct device *, void *);
                     62:
                     63: /* Driver definition. */
                     64: struct cfattach akbd_ca = {
                     65:        sizeof(struct akbd_softc), akbdmatch, akbdattach
                     66: };
                     67: struct cfdriver akbd_cd = {
                     68:        NULL, "akbd", DV_DULL
                     69: };
                     70:
                     71: int    akbd_enable(void *, int);
                     72: void   akbd_set_leds(void *, int);
                     73: int    akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
                     74:
                     75:
                     76: struct wskbd_accessops akbd_accessops = {
                     77:        akbd_enable,
                     78:        akbd_set_leds,
                     79:        akbd_ioctl,
                     80: };
                     81:
                     82: struct wskbd_mapdata akbd_keymapdata = {
                     83:        akbd_keydesctab,
                     84: #ifdef AKBD_LAYOUT
                     85:        AKBD_LAYOUT,
                     86: #else
                     87:        KB_US,
                     88: #endif
                     89: };
                     90:
                     91: void   akbd_adbcomplete(caddr_t, caddr_t, int);
                     92: void   akbd_capslockwrapper(struct akbd_softc *, int);
                     93: void   akbd_input(struct akbd_softc *, int);
                     94: void   akbd_processevent(struct akbd_softc *, adb_event_t *);
                     95: void   akbd_rawrepeat(void *v);
                     96: #ifdef notyet
                     97: u_char getleds(int);
                     98: int    setleds(struct akbd_softc *, u_char);
                     99: void   blinkleds(struct akbd_softc *);
                    100: #endif
                    101:
                    102: int
                    103: akbdmatch(struct device *parent, void *vcf, void *aux)
                    104: {
                    105:        struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
                    106:
                    107:        if (aa_args->origaddr == ADBADDR_KBD)
                    108:                return (1);
                    109:        else
                    110:                return (0);
                    111: }
                    112:
                    113: void
                    114: akbdattach(struct device *parent, struct device *self, void *aux)
                    115: {
                    116:        ADBSetInfoBlock adbinfo;
                    117:        struct akbd_softc *sc = (struct akbd_softc *)self;
                    118:        struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
                    119:        int error, kbd_done;
                    120:        short cmd;
                    121:        u_char buffer[9];
                    122:        struct wskbddev_attach_args a;
                    123:        static int akbd_console_initted;
                    124:        int wskbd_eligible = 1;
                    125:
                    126:        sc->origaddr = aa_args->origaddr;
                    127:        sc->adbaddr = aa_args->adbaddr;
                    128:        sc->handler_id = aa_args->handler_id;
                    129:
                    130:        sc->sc_leds = (u_int8_t)0x00;   /* initially off */
                    131:        sc->sc_caps = 0;
                    132:
                    133:        adbinfo.siServiceRtPtr = (Ptr)akbd_adbcomplete;
                    134:        adbinfo.siDataAreaAddr = (caddr_t)sc;
                    135:
                    136:        printf(": ");
                    137:        switch (sc->handler_id) {
                    138:        case ADB_STDKBD:
                    139:                printf("standard keyboard\n");
                    140:                break;
                    141:        case ADB_ISOKBD:
                    142:                printf("standard keyboard (ISO layout)\n");
                    143:                break;
                    144:        case ADB_EXTKBD:
                    145:                cmd = ADBTALK(sc->adbaddr, 1);
                    146:                kbd_done =
                    147:                    (adb_op_sync((Ptr)buffer, cmd) == 0);
                    148:
                    149:                /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
                    150:                if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
                    151:                        printf("Mouseman (non-EMP) pseudo keyboard\n");
                    152:                        adbinfo.siServiceRtPtr = (Ptr)0;
                    153:                        adbinfo.siDataAreaAddr = (Ptr)0;
                    154:                        wskbd_eligible = 0;
                    155:                } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
                    156:                        printf("Trackman (non-EMP) pseudo keyboard\n");
                    157:                        adbinfo.siServiceRtPtr = (Ptr)0;
                    158:                        adbinfo.siDataAreaAddr = (Ptr)0;
                    159:                        wskbd_eligible = 0;
                    160:                } else {
                    161:                        printf("extended keyboard\n");
                    162: #ifdef notyet
                    163:                        blinkleds(sc);
                    164: #endif
                    165:                }
                    166:                break;
                    167:        case ADB_EXTISOKBD:
                    168:                printf("extended keyboard (ISO layout)\n");
                    169: #ifdef notyet
                    170:                blinkleds(sc);
                    171: #endif
                    172:                break;
                    173:        case ADB_KBDII:
                    174:                printf("keyboard II\n");
                    175:                break;
                    176:        case ADB_ISOKBDII:
                    177:                printf("keyboard II (ISO layout)\n");
                    178:                break;
                    179:        case ADB_PBKBD:
                    180:                printf("PowerBook keyboard\n");
                    181:                break;
                    182:        case ADB_PBISOKBD:
                    183:                printf("PowerBook keyboard (ISO layout)\n");
                    184:                break;
                    185:        case ADB_ADJKPD:
                    186:                printf("adjustable keypad\n");
                    187:                wskbd_eligible = 0;
                    188:                break;
                    189:        case ADB_ADJKBD:
                    190:                printf("adjustable keyboard\n");
                    191:                break;
                    192:        case ADB_ADJISOKBD:
                    193:                printf("adjustable keyboard (ISO layout)\n");
                    194:                break;
                    195:        case ADB_ADJJAPKBD:
                    196:                printf("adjustable keyboard (Japanese layout)\n");
                    197:                break;
                    198:        case ADB_PBEXTISOKBD:
                    199:                printf("PowerBook extended keyboard (ISO layout)\n");
                    200:                break;
                    201:        case ADB_PBEXTJAPKBD:
                    202:                printf("PowerBook extended keyboard (Japanese layout)\n");
                    203:                break;
                    204:        case ADB_JPKBDII:
                    205:                printf("keyboard II (Japanese layout)\n");
                    206:                break;
                    207:        case ADB_PBEXTKBD:
                    208:                printf("PowerBook extended keyboard\n");
                    209:                break;
                    210:        case ADB_DESIGNKBD:
                    211:                printf("extended keyboard\n");
                    212: #ifdef notyet
                    213:                blinkleds(sc);
                    214: #endif
                    215:                break;
                    216:        case ADB_PBJPKBD:
                    217:                printf("PowerBook keyboard (Japanese layout)\n");
                    218:                break;
                    219:        case ADB_PBG3JPKBD:
                    220:                printf("PowerBook G3 keyboard (Japanese layout)\n");
                    221:                break;
                    222:        case ADB_PBG4KBD:
                    223:                printf("PowerBook G4 keyboard (Inverted T)\n");
                    224:                break;
                    225:        case ADB_IBITISOKBD:
                    226:                printf("iBook keyboard with inverted T (ISO layout)\n");
                    227:                break;
                    228:        default:
                    229:                printf("mapped device (%d)\n", sc->handler_id);
                    230: #if 0
                    231:                wskbd_eligible = 0;
                    232: #endif
                    233:                break;
                    234:        }
                    235:        error = set_adb_info(&adbinfo, sc->adbaddr);
                    236: #ifdef ADB_DEBUG
                    237:        if (adb_debug)
                    238:                printf("akbd: returned %d from set_adb_info\n", error);
                    239: #endif
                    240:
                    241: #ifdef WSDISPLAY_COMPAT_RAWKBD
                    242:        timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc);
                    243: #endif
                    244:
                    245:        if (akbd_is_console() && wskbd_eligible)
                    246:                a.console = (++akbd_console_initted == 1);
                    247:        else
                    248:                a.console = 0;
                    249:        a.keymap = &akbd_keymapdata;
                    250:        a.accessops = &akbd_accessops;
                    251:        a.accesscookie = sc;
                    252:
                    253:        sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
                    254: }
                    255:
                    256:
                    257: /*
                    258:  * Handle putting the keyboard data received from the ADB into
                    259:  * an ADB event record.
                    260:  */
                    261: void
                    262: akbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
                    263: {
                    264:        adb_event_t event;
                    265:        struct akbd_softc *sc;
                    266:        int adbaddr;
                    267: #ifdef ADB_DEBUG
                    268:        int i;
                    269:
                    270:        if (adb_debug)
                    271:                printf("adb: transaction completion\n");
                    272: #endif
                    273:
                    274:        adbaddr = ADB_CMDADDR(adb_command);
                    275:        sc = (struct akbd_softc *)data_area;
                    276:
                    277:        event.byte_count = buffer[0];
                    278:        memcpy(event.bytes, buffer + 1, event.byte_count);
                    279:
                    280: #ifdef ADB_DEBUG
                    281:        if (adb_debug) {
                    282:                printf("akbd: from %d at %d (org %d) %d:", adbaddr,
                    283:                    sc->handler_id, sc->origaddr, buffer[0]);
                    284:                for (i = 1; i <= buffer[0]; i++)
                    285:                        printf(" %x", buffer[i]);
                    286:                printf("\n");
                    287:        }
                    288: #endif
                    289:
                    290:        if (sc->sc_wskbddev != NULL)
                    291:                akbd_processevent(sc, &event);
                    292: }
                    293:
                    294: #ifdef notyet
                    295: /*
                    296:  * Get the actual hardware LED state and convert it to softc format.
                    297:  */
                    298: u_char
                    299: getleds(int addr)
                    300: {
                    301:        short cmd;
                    302:        u_char buffer[9], leds;
                    303:
                    304:        leds = 0x00;    /* all off */
                    305:        buffer[0] = 0;
                    306:
                    307:        cmd = ADBTALK(addr, 2);
                    308:        if (adb_op_sync((Ptr)buffer, cmd) == 0 &&
                    309:            buffer[0] > 0)
                    310:                leds = ~(buffer[2]) & 0x07;
                    311:
                    312:        return (leds);
                    313: }
                    314:
                    315: /*
                    316:  * Set the keyboard LED's.
                    317:  *
                    318:  * Automatically translates from ioctl/softc format to the
                    319:  * actual keyboard register format
                    320:  */
                    321: int
                    322: setleds(struct akbd_softc *sc, u_char leds)
                    323: {
                    324:        int addr;
                    325:        short cmd;
                    326:        u_char buffer[9];
                    327:
                    328:        addr = sc->adbaddr;
                    329:        buffer[0] = 0;
                    330:
                    331:        cmd = ADBTALK(addr, 2);
                    332:        if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
                    333:                return (EIO);
                    334:
                    335:        leds = ~leds & 0x07;
                    336:        buffer[2] &= 0xf8;
                    337:        buffer[2] |= leds;
                    338:
                    339:        cmd = ADBLISTEN(addr, 2);
                    340:        adb_op_sync((Ptr)buffer, cmd);
                    341:
                    342:        /* talk R2 */
                    343:        cmd = ADBTALK(addr, 2);
                    344:        if (adb_op_sync((Ptr)buffer, cmd) || buffer[0] == 0)
                    345:                return (EIO);
                    346:
                    347:        if ((buffer[2] & 0xf8) != leds)
                    348:                return (EIO);
                    349:        else
                    350:                return (0);
                    351: }
                    352:
                    353: /*
                    354:  * Toggle all of the LED's on and off, just for show.
                    355:  */
                    356: void
                    357: blinkleds(struct akbd_softc *sc)
                    358: {
                    359:        u_char origleds;
                    360:
                    361:        origleds = getleds(sc->adbaddr);
                    362:        setleds(sc, LED_NUMLOCK | LED_CAPSLOCK | LED_SCROLL_LOCK);
                    363:        delay(400000);
                    364:        setleds(sc, origleds);
                    365:
                    366:        if (origleds & LED_NUMLOCK)
                    367:                sc->sc_leds |= WSKBD_LED_NUM;
                    368:        if (origleds & LED_CAPSLOCK)
                    369:                sc->sc_leds |= WSKBD_LED_CAPS;
                    370:        if (origleds & LED_SCROLL_LOCK)
                    371:                sc->sc_leds |= WSKBD_LED_SCROLL;
                    372: }
                    373: #endif
                    374:
                    375: int
                    376: akbd_enable(void *v, int on)
                    377: {
                    378:        return 0;
                    379: }
                    380:
                    381: void
                    382: akbd_set_leds(void *v, int on)
                    383: {
                    384: #ifdef notyet
                    385:        struct akbd_softc *sc = v;
                    386:        int leds;
                    387:
                    388:        if (sc->sc_extended) {
                    389:                if (sc->sc_leds == on)
                    390:                        return;
                    391:
                    392:                leds = 0;
                    393:                if (on & WSKBD_LED_NUM)
                    394:                        leds |= LED_NUMLOCK;
                    395:                if (on & WSKBD_LED_CAPS)
                    396:                        leds |= LED_CAPSLOCK;
                    397:                if (on & WSKBD_LED_SCROLL)
                    398:                        leds |= LED_SCROLL_LOCK;
                    399:
                    400:                setleds(sc, leds);
                    401:        }
                    402: #endif
                    403: }
                    404:
                    405: int
                    406: akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
                    407: {
                    408:        struct akbd_softc *sc = v;
                    409:
                    410:        switch (cmd) {
                    411:
                    412:        case WSKBDIO_GTYPE:
                    413:                *(int *)data = WSKBD_TYPE_ADB;
                    414:                return 0;
                    415:        case WSKBDIO_SETLEDS:
                    416:                akbd_set_leds(v, *(int *)data);
                    417:                return 0;
                    418:        case WSKBDIO_GETLEDS:
                    419:                *(int *)data = sc->sc_leds;
                    420:                return 0;
                    421: #ifdef WSDISPLAY_COMPAT_RAWKBD
                    422:        case WSKBDIO_SETMODE:
                    423:                sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
                    424:                timeout_del(&sc->sc_rawrepeat_ch);
                    425:                return (0);
                    426: #endif
                    427:
                    428: #ifdef mac68k  /* XXX not worth creating akbd_machdep_ioctl() */
                    429:        case WSKBDIO_BELL:
                    430:        case WSKBDIO_COMPLEXBELL:
                    431: #define d ((struct wskbd_bell_data *)data)
                    432:                mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
                    433: #undef d
                    434:                return (0);
                    435: #endif
                    436:
                    437:        default:
                    438:                return (-1);
                    439:        }
                    440: }
                    441:
                    442: #ifdef WSDISPLAY_COMPAT_RAWKBD
                    443: void
                    444: akbd_rawrepeat(void *v)
                    445: {
                    446:        struct akbd_softc *sc = v;
                    447:        int s;
                    448:
                    449:        s = spltty();
                    450:        wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
                    451:        splx(s);
                    452:        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
                    453: }
                    454: #endif
                    455:
                    456: /*
                    457:  * The ``caps lock'' key is special: since on earlier keyboards, the physical
                    458:  * key stays down when pressed, we will get a notification of the key press,
                    459:  * but not of the key release. Then, when it is pressed again, we will not get
                    460:  * a notification of the key press, but will see the key release.
                    461:  *
                    462:  * This is not exactly true. We see the missing release and press events both
                    463:  * as the release of the power (reset) key.
                    464:  *
                    465:  * To avoid confusing them with real power key presses, we maintain two
                    466:  * states for the caps lock key: logically down (from wscons' point of view),
                    467:  * and ``physically'' down (from the adb messages point of view), to ignore
                    468:  * the power key. But since one may press the power key while the caps lock
                    469:  * is held down, we also have to remember the state of the power key... this
                    470:  * is quite messy.
                    471:  */
                    472:
                    473: /*
                    474:  * Values for caps lock state machine
                    475:  */
                    476: #define        CL_DOWN_ADB     0x01
                    477: #define        CL_DOWN_LOGICAL 0x02
                    478: #define        CL_DOWN_RESET   0x04
                    479:
                    480: /*
                    481:  * Given a keyboard ADB event, decode the keycodes and pass them to wskbd.
                    482:  */
                    483: void
                    484: akbd_processevent(struct akbd_softc *sc, adb_event_t *event)
                    485: {
                    486:        switch (event->byte_count) {
                    487:        case 1:
                    488:                akbd_capslockwrapper(sc, event->bytes[0]);
                    489:                break;
                    490:        case 2:
                    491:                /*
                    492:                 * The reset (or power) key sends 0x7f7f on press and
                    493:                 * 0xffff on release, and we ignore it.
                    494:                 */
                    495:                if (event->bytes[0] == event->bytes[1] &&
                    496:                    ADBK_KEYVAL(event->bytes[0]) == ADBK_RESET) {
                    497:                        if (event->bytes[0] == ADBK_KEYDOWN(ADBK_RESET))
                    498:                                SET(sc->sc_caps, CL_DOWN_RESET);
                    499:                        else {
                    500:                                if (ISSET(sc->sc_caps, CL_DOWN_RESET))
                    501:                                        CLR(sc->sc_caps, CL_DOWN_RESET);
                    502:                                else if (ISSET(sc->sc_caps, CL_DOWN_ADB)) {
                    503:                                        akbd_input(sc, ISSET(sc->sc_caps,
                    504:                                            CL_DOWN_LOGICAL) ?
                    505:                                              ADBK_KEYDOWN(ADBK_CAPSLOCK) :
                    506:                                              ADBK_KEYUP(ADBK_CAPSLOCK));
                    507:                                        sc->sc_caps ^= CL_DOWN_LOGICAL;
                    508:                                }
                    509:                        }
                    510:                } else {
                    511:                        akbd_capslockwrapper(sc, event->bytes[0]);
                    512:                        akbd_capslockwrapper(sc, event->bytes[1]);
                    513:                }
                    514:                break;
                    515:        default:
                    516: #ifdef DIAGNOSTIC
                    517:                printf("%s: unexpected message length %d\n",
                    518:                    sc->sc_dev.dv_xname, event->byte_count);
                    519: #endif
                    520:                break;
                    521:        }
                    522:
                    523: }
                    524:
                    525: void
                    526: akbd_capslockwrapper(struct akbd_softc *sc, int key)
                    527: {
                    528:        if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
                    529:                sc->sc_caps ^= CL_DOWN_ADB;
                    530:
                    531:        if (key != 0xff)
                    532:                akbd_input(sc, key);
                    533: }
                    534:
                    535: int adb_polledkey;
                    536: void
                    537: akbd_input(struct akbd_softc *sc, int key)
                    538: {
                    539:        int press, val;
                    540:        int type;
                    541:
                    542:        press = ADBK_PRESS(key);
                    543:        val = ADBK_KEYVAL(key);
                    544:
                    545:        type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
                    546:
                    547:        if (adb_polling) {
                    548:                adb_polledkey = key;
                    549: #ifdef WSDISPLAY_COMPAT_RAWKBD
                    550:        } else if (sc->sc_rawkbd) {
                    551:                char cbuf[MAXKEYS *2];
                    552:                int c, j, s;
                    553:                int npress;
                    554:
                    555:                j = npress = 0;
                    556:
                    557:                c = keyboard[val];
                    558:                if (c == 0) {
                    559:                        return; /* XXX */
                    560:                }
                    561:                if (c & 0x80)
                    562:                        cbuf[j++] = 0xe0;
                    563:                cbuf[j] = c & 0x7f;
                    564:                if (type == WSCONS_EVENT_KEY_UP) {
                    565:                        cbuf[j] |= 0x80;
                    566:                } else {
                    567:                        /* this only records last key pressed */
                    568:                        if (c & 0x80)
                    569:                                sc->sc_rep[npress++] = 0xe0;
                    570:                        sc->sc_rep[npress++] = c & 0x7f;
                    571:                }
                    572:                j++;
                    573:                s = spltty();
                    574:                wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
                    575:                splx(s);
                    576:                timeout_del(&sc->sc_rawrepeat_ch);
                    577:                sc->sc_nrep = npress;
                    578:                if (npress != 0)
                    579:                        timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
                    580: #endif
                    581:        } else {
                    582:                wskbd_input(sc->sc_wskbddev, type, val);
                    583:        }
                    584: }

CVSweb