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