Home | History | Annotate | Line # | Download | only in dev
kbd.c revision 1.35.8.2
      1 /*	$NetBSD: kbd.c,v 1.35.8.2 2002/04/01 07:38:59 nathanw Exp $ */
      2 
      3 /*
      4  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  *
     35  *	kbd.c
     36  */
     37 
     38 #include <sys/cdefs.h>
     39 __KERNEL_RCSID(0, "$NetBSD: kbd.c,v 1.35.8.2 2002/04/01 07:38:59 nathanw Exp $");
     40 
     41 #include <sys/param.h>
     42 #include <sys/systm.h>
     43 #include <sys/device.h>
     44 #include <sys/ioctl.h>
     45 #include <sys/tty.h>
     46 #include <sys/proc.h>
     47 #include <sys/file.h>
     48 #include <sys/kernel.h>
     49 #include <sys/syslog.h>
     50 #include <sys/signalvar.h>
     51 #include <dev/cons.h>
     52 #include <machine/cpu.h>
     53 #include <amiga/amiga/device.h>
     54 #include <amiga/amiga/custom.h>
     55 #ifdef DRACO
     56 #include <m68k/asm_single.h>
     57 #include <amiga/amiga/drcustom.h>
     58 #endif
     59 #include <amiga/amiga/cia.h>
     60 #include <amiga/dev/itevar.h>
     61 #include <amiga/dev/kbdreg.h>
     62 #include <amiga/dev/kbdmap.h>
     63 #include <amiga/dev/event_var.h>
     64 #include <amiga/dev/vuid_event.h>
     65 
     66 #include "kbd.h"
     67 #include "ite.h"
     68 
     69 /* WSKBD */
     70 
     71 /*
     72  * If NWSKBD>0 we try to attach an wskbd device to us. What follows
     73  * is definitions of callback functions and structures that are passed
     74  * to wscons when initializing.
     75  */
     76 
     77 /*
     78  * Now with wscons this driver exhibits some weird behaviour.
     79  * It may act both as a driver of its own and the md part of the
     80  * wskbd driver. Therefore it can be accessed through /dev/kbd
     81  * and /dev/wskbd0 both.
     82  *
     83  * The data from they keyboard may end up in at least four different
     84  * places:
     85  * - If this driver has been opened (/dev/kbd) and the
     86  *   direct mode (TIOCDIRECT) has been set, data goes to
     87  *   the process who opened the device. Data will transmit itself
     88  *   as described by the firm_event structure.
     89  * - If wskbd support is compiled in and a wskbd driver has been
     90  *   attached then the data is sent to it. Wskbd in turn may
     91  *   - Send the data in the wscons_event form to a process that
     92  *     has opened /dev/wskbd0
     93  *   - Feed the data to a virtual terminal.
     94  * - If an ite is present the data may be fed to it.
     95  */
     96 
     97 #include "wskbd.h"
     98 
     99 #if NWSKBD>0
    100 #include <dev/wscons/wsconsio.h>
    101 #include <dev/wscons/wskbdvar.h>
    102 #include <dev/wscons/wsksymdef.h>
    103 #include <dev/wscons/wsksymvar.h>
    104 #include <amiga/dev/wskbdmap_amiga.h>
    105 
    106 /* accessops */
    107 int     kbd_enable(void *, int);
    108 void    kbd_set_leds(void *, int);
    109 int     kbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
    110 
    111 /* console ops */
    112 void    kbd_getc(void *, u_int *, int *);
    113 void    kbd_pollc(void *, int);
    114 void    kbd_bell(void *, u_int, u_int, u_int);
    115 
    116 static struct wskbd_accessops kbd_accessops = {
    117 	kbd_enable,
    118 	kbd_set_leds,
    119 	kbd_ioctl
    120 };
    121 
    122 static struct wskbd_consops kbd_consops = {
    123 	kbd_getc,
    124 	kbd_pollc,
    125 	kbd_bell
    126 };
    127 
    128 /*
    129  * Pointer to keymaps. They are defined in wskbdmap_amiga.c.
    130  */
    131 static struct wskbd_mapdata kbd_mapdata = {
    132 	amigakbd_keydesctab,
    133 	KB_US
    134 };
    135 
    136 #endif /* WSKBD */
    137 
    138 
    139 #include <sys/conf.h>
    140 #include <machine/conf.h>
    141 
    142 struct kbd_softc {
    143 	int k_event_mode;	/* if true, collect events, else pass to ite */
    144 	struct evvar k_events;	/* event queue state */
    145 #ifdef DRACO
    146 	u_char k_rlprfx;	/* MF-II rel. prefix has been seen */
    147 	u_char k_mf2;
    148 #endif
    149 
    150 #if NWSKBD>0
    151 	struct device *k_wskbddev; /* pointer to wskbd for sending strokes */
    152 	int k_pollingmode;         /* polling mode on? whatever it isss... */
    153 #endif
    154 };
    155 struct kbd_softc kbd_softc;
    156 
    157 int kbdmatch(struct device *, struct cfdata *, void *);
    158 void kbdattach(struct device *, struct device *, void *);
    159 void kbdintr(int);
    160 void kbdstuffchar(u_char);
    161 
    162 int drkbdgetc(void);
    163 int drkbdrputc(u_int8_t);
    164 int drkbdputc(u_int8_t);
    165 int drkbdputc2(u_int8_t, u_int8_t);
    166 int drkbdwaitfor(int);
    167 
    168 struct cfattach kbd_ca = {
    169 	sizeof(struct device), kbdmatch, kbdattach
    170 };
    171 
    172 /*ARGSUSED*/
    173 int
    174 kbdmatch(struct device *pdp, struct cfdata *cfp, void *auxp)
    175 {
    176 
    177 	if (matchname((char *)auxp, "kbd"))
    178 		return(1);
    179 	return(0);
    180 }
    181 
    182 /*ARGSUSED*/
    183 void
    184 kbdattach(struct device *pdp, struct device *dp, void *auxp)
    185 {
    186 #ifdef DRACO
    187 	kbdenable();
    188 	if (kbd_softc.k_mf2)
    189 		printf(": QuickLogic type MF-II\n");
    190 	else
    191 		printf(": CIA A type Amiga\n");
    192 #else
    193 	printf(": CIA A type Amiga\n");
    194 #endif
    195 
    196 #if NWSKBD>0
    197 	if (dp != NULL) {
    198 		/*
    199 		 * Try to attach the wskbd.
    200 		 */
    201 		struct wskbddev_attach_args waa;
    202 
    203 		/* Maybe should be done before this?... */
    204 		wskbd_cnattach(&kbd_consops, NULL, &kbd_mapdata);
    205 
    206 		waa.console = 1;
    207 		waa.keymap = &kbd_mapdata;
    208 		waa.accessops = &kbd_accessops;
    209 		waa.accesscookie = NULL;
    210 		kbd_softc.k_wskbddev = config_found(dp, &waa, wskbddevprint);
    211 
    212 		kbd_softc.k_pollingmode = 0;
    213 	}
    214 	kbdenable();
    215 #endif /* WSKBD */
    216 }
    217 
    218 /* definitions for amiga keyboard encoding. */
    219 #define KEY_CODE(c)  ((c) & 0x7f)
    220 #define KEY_UP(c)    ((c) & 0x80)
    221 
    222 #define DATLO single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDDATOUT)
    223 #define DATHI single_inst_bset_b(draco_ioct->io_control, DRCNTRL_KBDDATOUT)
    224 
    225 #define CLKLO single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDCLKOUT)
    226 #define CLKHI single_inst_bset_b(draco_ioct->io_control, DRCNTRL_KBDCLKOUT)
    227 
    228 void
    229 kbdenable(void)
    230 {
    231 	static int kbd_inited = 0;
    232 
    233 	int s;
    234 
    235 #ifdef DRACO
    236 	int id;
    237 #endif
    238 	/*
    239 	 * collides with external ints from SCSI, watch out for this when
    240 	 * enabling/disabling interrupts there !!
    241 	 */
    242 	s = splhigh();	/* don't lower; might be called from early ddb */
    243 	if (kbd_inited) {
    244 		splx(s);
    245 		return;
    246 	}
    247 	kbd_inited = 1;
    248 #ifdef DRACO
    249 	if (is_draco()) {
    250 
    251 		CLKLO;
    252 		delay(5000);
    253 		draco_ioct->io_kbdrst = 0;
    254 
    255 		if (drkbdputc(0xf2))
    256 			goto LnoMFII;
    257 
    258 		id = drkbdgetc() << 8;
    259 		id |= drkbdgetc();
    260 
    261 		if (id != 0xab83)
    262 			goto LnoMFII;
    263 
    264 		if (drkbdputc2(0xf0, 3))	/* mode 3 */
    265 			goto LnoMFII;
    266 
    267 		if (drkbdputc(0xf8))		/* make/break, no typematic */
    268 			goto LnoMFII;
    269 
    270 		if (drkbdputc(0xf4))		/* enable */
    271 			goto LnoMFII;
    272 		kbd_softc.k_mf2 = 1;
    273 		single_inst_bclr_b(draco_ioct->io_control, DRCNTRL_KBDINTENA);
    274 
    275 		ciaa.icr = CIA_ICR_SP;  /* CIA SP interrupt disable */
    276 		ciaa.cra &= ~(1<<6);	/* serial line == input */
    277 		splx(s);
    278 		return;
    279 
    280 	LnoMFII:
    281 		kbd_softc.k_mf2 = 0;
    282 		single_inst_bset_b(*draco_intena, DRIRQ_INT2);
    283 		ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_SP;
    284 					/* SP interrupt enable */
    285 		ciaa.cra &= ~(1<<6);	/* serial line == input */
    286 		splx(s);
    287 		return;
    288 
    289 	} else {
    290 #endif
    291 	custom.intena = INTF_SETCLR | INTF_PORTS;
    292 	ciaa.icr = CIA_ICR_IR_SC | CIA_ICR_SP;  /* SP interrupt enable */
    293 	ciaa.cra &= ~(1<<6);		/* serial line == input */
    294 #ifdef DRACO
    295 	}
    296 #endif
    297 	kbd_softc.k_event_mode = 0;
    298 	kbd_softc.k_events.ev_io = 0;
    299 	splx(s);
    300 }
    301 
    302 #ifdef DRACO
    303 /*
    304  * call this with kbd interupt blocked
    305  */
    306 
    307 int
    308 drkbdgetc(void)
    309 {
    310 	u_int8_t in;
    311 
    312 	while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0);
    313 	in = draco_ioct->io_kbddata;
    314 	draco_ioct->io_kbdrst = 0;
    315 
    316 	return in;
    317 }
    318 
    319 #define WAIT0 if (drkbdwaitfor(0)) goto Ltimeout
    320 #define WAIT1 if (drkbdwaitfor(DRSTAT_KBDCLKIN)) goto Ltimeout
    321 
    322 int
    323 drkbdwaitfor(int bit)
    324 {
    325 	int i;
    326 
    327 
    328 
    329 	i = 60000;	/* about 50 ms max */
    330 
    331 	do {
    332 		if ((draco_ioct->io_status & DRSTAT_KBDCLKIN) == bit)
    333 			return 0;
    334 
    335 	} while (--i >= 0);
    336 
    337 	return 1;
    338 }
    339 
    340 /*
    341  * Output a raw byte to the keyboard (+ parity and stop bit).
    342  * return 0 on success, 1 on timeout.
    343  */
    344 int
    345 drkbdrputc(u_int8_t c)
    346 {
    347 	u_int8_t parity;
    348 	int bitcnt;
    349 
    350 	DATLO; CLKHI; WAIT1;
    351 	parity = 0;
    352 
    353 	for (bitcnt=7; bitcnt >= 0; bitcnt--) {
    354 		WAIT0;
    355 		if (c & 1) {
    356 			DATHI;
    357 		} else {
    358 			++parity;
    359 			DATLO;
    360 		}
    361 		c >>= 1;
    362 		WAIT1;
    363 	}
    364 	WAIT0;
    365 	/* parity bit */
    366 	if (parity & 1) {
    367 		DATLO;
    368 	} else {
    369 		DATHI;
    370 	}
    371 	WAIT1;
    372 	/* stop bit */
    373 	WAIT0; DATHI; WAIT1;
    374 
    375 	WAIT0; /* XXX should check the ack bit here... */
    376 	WAIT1;
    377 	draco_ioct->io_kbdrst = 0;
    378 	return 0;
    379 
    380 Ltimeout:
    381 	DATHI;
    382 	draco_ioct->io_kbdrst = 0;
    383 	return 1;
    384 }
    385 
    386 /*
    387  * Output one cooked byte to the keyboard, with wait for ACK or RESEND,
    388  * and retry if necessary. 0 == success, 1 == timeout
    389  */
    390 int
    391 drkbdputc(u_int8_t c)
    392 {
    393 	int rc;
    394 
    395 	do {
    396 		if (drkbdrputc(c))
    397 			return(-1);
    398 
    399 		rc = drkbdgetc();
    400 	} while (rc == 0xfe);
    401 	return (!(rc == 0xfa));
    402 }
    403 
    404 /*
    405  * same for twobyte sequence
    406  */
    407 
    408 int
    409 drkbdputc2(u_int8_t c1, u_int8_t c2)
    410 {
    411 	int rc;
    412 
    413 	do {
    414 		do {
    415 			if (drkbdrputc(c1))
    416 				return(-1);
    417 
    418 			rc = drkbdgetc();
    419 		} while (rc == 0xfe);
    420 		if (rc != 0xfa)
    421 			return (-1);
    422 
    423 		if (drkbdrputc(c2))
    424 			return(-1);
    425 
    426 		rc = drkbdgetc();
    427 	} while (rc == 0xfe);
    428 	return (!(rc == 0xfa));
    429 }
    430 #endif
    431 
    432 int
    433 kbdopen(dev_t dev, int flags, int mode, struct proc *p)
    434 {
    435 
    436 	kbdenable();
    437 	if (kbd_softc.k_events.ev_io)
    438 		return EBUSY;
    439 
    440 	kbd_softc.k_events.ev_io = p;
    441 	ev_init(&kbd_softc.k_events);
    442 	return (0);
    443 }
    444 
    445 int
    446 kbdclose(dev_t dev, int flags, int mode, struct proc *p)
    447 {
    448 
    449 	/* Turn off event mode, dump the queue */
    450 	kbd_softc.k_event_mode = 0;
    451 	ev_fini(&kbd_softc.k_events);
    452 	kbd_softc.k_events.ev_io = NULL;
    453 	return (0);
    454 }
    455 
    456 int
    457 kbdread(dev_t dev, struct uio *uio, int flags)
    458 {
    459 	return ev_read (&kbd_softc.k_events, uio, flags);
    460 }
    461 
    462 int
    463 kbdioctl(dev_t dev, u_long cmd, register caddr_t data, int flag,
    464          struct proc *p)
    465 {
    466 	register struct kbd_softc *k = &kbd_softc;
    467 
    468 	switch (cmd) {
    469 		case KIOCTRANS:
    470 			if (*(int *)data == TR_UNTRANS_EVENT)
    471 				return 0;
    472 			break;
    473 
    474 		case KIOCGTRANS:
    475 			/* Get translation mode */
    476 			*(int *)data = TR_UNTRANS_EVENT;
    477 			return 0;
    478 
    479 		case KIOCSDIRECT:
    480 			k->k_event_mode = *(int *)data;
    481 			return 0;
    482 
    483 		case FIONBIO:	/* we will remove this someday (soon???) */
    484 			return 0;
    485 
    486 		case FIOASYNC:
    487 			k->k_events.ev_async = *(int *)data != 0;
    488 			return 0;
    489 
    490 		case TIOCSPGRP:
    491 			if (*(int *)data != k->k_events.ev_io->p_pgid)
    492 				return EPERM;
    493 			return 0;
    494 
    495 		default:
    496 			return ENOTTY;
    497 	}
    498 
    499 	/* We identified the ioctl, but we do not handle it. */
    500 	return EOPNOTSUPP;	/* misuse, but what the heck */
    501 }
    502 
    503 int
    504 kbdpoll(dev_t dev, int events, struct proc *p)
    505 {
    506 	return ev_poll (&kbd_softc.k_events, events, p);
    507 }
    508 
    509 
    510 void
    511 kbdintr(int mask)
    512 {
    513 	u_char c;
    514 #ifdef KBDRESET
    515 	static int reset_warn;
    516 #endif
    517 
    518 	/*
    519 	 * now only invoked from generic CIA interrupt handler if there *is*
    520 	 * a keyboard interrupt pending
    521 	 */
    522 
    523 	c = ~ciaa.sdr;	/* keyboard data is inverted */
    524 	/* ack */
    525 	ciaa.cra |= (1 << 6);	/* serial line output */
    526 #ifdef KBDRESET
    527 	if (reset_warn && c == 0xf0) {
    528 #ifdef DEBUG
    529 		printf ("kbdintr: !!!! Reset Warning !!!!\n");
    530 #endif
    531 		bootsync();
    532 		reset_warn = 0;
    533 		DELAY(30000000);
    534 	}
    535 #endif
    536 	/* wait 200 microseconds (for bloody Cherry keyboards..) */
    537 	DELAY(2000);			/* fudge delay a bit for some keyboards */
    538 	ciaa.cra &= ~(1 << 6);
    539 
    540 	/* process the character */
    541 	c = (c >> 1) | (c << 7);	/* rotate right once */
    542 
    543 #ifdef KBDRESET
    544 	if (c == 0x78) {
    545 #ifdef DEBUG
    546 		printf ("kbdintr: Reset Warning started\n");
    547 #endif
    548 		++reset_warn;
    549 		return;
    550 	}
    551 #endif
    552 	kbdstuffchar(c);
    553 }
    554 
    555 #ifdef DRACO
    556 /* maps MF-II keycodes to Amiga keycodes */
    557 
    558 const u_char drkbdtab[] = {
    559 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50,
    560 	0x45, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0x51,
    561 
    562 	0xff, 0x64, 0x60, 0x30, 0x63, 0x10, 0x01, 0x52,
    563 	0xff, 0x66, 0x31, 0x21, 0x20, 0x11, 0x02, 0x53,
    564 
    565 	0xff, 0x33, 0x32, 0x22, 0x12, 0x04, 0x03, 0x54,
    566 	0xff, 0x40, 0x34, 0x23, 0x14, 0x13, 0x05, 0x55,
    567 
    568 	0xff, 0x36, 0x35, 0x25, 0x24, 0x15, 0x06, 0x56,
    569 	0xff, 0x67, 0x37, 0x26, 0x16, 0x07, 0x08, 0x57,
    570 	/* --- */
    571 	0xff, 0x38, 0x27, 0x17, 0x18, 0x0a, 0x09, 0x58,
    572 	0xff, 0x39, 0x3a, 0x28, 0x29, 0x19, 0x0b, 0x59,
    573 
    574 	0xff, 0xff, 0x2a, 0x2b, 0x1a, 0x0c, 0x4b, 0xff,
    575 	0x65, 0x61, 0x44, 0x1b, 0xff, 0xff, 0x6f, 0xff,
    576 
    577 	0x4d, 0x4f, 0xff, 0x4c, 0x0d, 0xff, 0x41, 0x46,
    578 	0xff, 0x1d, 0x4e, 0x2d, 0x3d, 0x4a, 0x5f, 0x62,
    579 
    580 	0x0f, 0x3c, 0x1e, 0x2e, 0x2f, 0x3e, 0x5a, 0x5b,
    581 	0xff, 0x43, 0x1f, 0xff, 0x5e, 0x3f, 0x5c, 0xff,
    582 	/* --- */
    583 	0xff, 0xff, 0xff, 0xff, 0x5d
    584 };
    585 #endif
    586 
    587 
    588 int
    589 kbdgetcn(void)
    590 {
    591 	int s;
    592 	u_char ints, mask, c, in;
    593 
    594 #ifdef DRACO
    595 	if (is_draco() && kbd_softc.k_mf2) {
    596 		do {
    597 			c = 0;
    598 			s = spltty ();
    599 			while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0);
    600 			in = draco_ioct->io_kbddata;
    601 			draco_ioct->io_kbdrst = 0;
    602 			if (in == 0xF0) { /* release prefix */
    603 				c = 0x80;
    604 				while ((draco_ioct->io_status &
    605 				    DRSTAT_KBDRECV) == 0);
    606 				in = draco_ioct->io_kbddata;
    607 				draco_ioct->io_kbdrst = 0;
    608 			}
    609 			splx(s);
    610 #ifdef DRACORAWKEYDEBUG
    611 			printf("<%02x>", in);
    612 #endif
    613 			c |= in>=sizeof(drkbdtab) ? 0xff : drkbdtab[in];
    614 		} while (c == 0xff);
    615 		return (c);
    616 	}
    617 #endif
    618 	s = spltty();
    619 	for (ints = 0; ! ((mask = ciaa.icr) & CIA_ICR_SP);
    620 	    ints |= mask) ;
    621 
    622 	in = ciaa.sdr;
    623 	c = ~in;
    624 
    625 	/* ack */
    626 	ciaa.cra |= (1 << 6);	/* serial line output */
    627 	ciaa.sdr = 0xff;	/* ack */
    628 	/* wait 200 microseconds */
    629 	DELAY(2000);	/* XXXX only works as long as DELAY doesn't
    630 			 * use a timer and waits.. */
    631 	ciaa.cra &= ~(1 << 6);
    632 	ciaa.sdr = in;
    633 
    634 	splx (s);
    635 	c = (c >> 1) | (c << 7);
    636 
    637 	/* take care that no CIA-interrupts are lost */
    638 	if (ints)
    639 		dispatch_cia_ints (0, ints);
    640 
    641 	return c;
    642 }
    643 
    644 void
    645 kbdstuffchar(u_char c)
    646 {
    647 	struct firm_event *fe;
    648 	struct kbd_softc *k = &kbd_softc;
    649 	int put;
    650 
    651 #if NWSKBD>0
    652 	/*
    653 	 * If we have attached a wskbd and not in polling mode and
    654 	 * nobody has opened us directly, then send the keystroke
    655 	 * to the wskbd.
    656 	 */
    657 
    658 	if (kbd_softc.k_pollingmode == 0
    659 	    && kbd_softc.k_wskbddev != NULL
    660 	    && k->k_event_mode == 0) {
    661 		wskbd_input(kbd_softc.k_wskbddev,
    662 			    KEY_UP(c) ?
    663 			    WSCONS_EVENT_KEY_UP :
    664 			    WSCONS_EVENT_KEY_DOWN,
    665 			    KEY_CODE(c));
    666 		return;
    667 	}
    668 
    669 #endif /* NWSKBD */
    670 
    671 	/*
    672 	 * If not in event mode, deliver straight to ite to process
    673 	 * key stroke
    674 	 */
    675 
    676 	if (! k->k_event_mode) {
    677 #if NITE>0
    678 		ite_filter (c, ITEFILT_TTY);
    679 #endif
    680 		return;
    681 	}
    682 
    683 	/*
    684 	 * Keyboard is generating events. Turn this keystroke into an
    685 	 * event and put it in the queue. If the queue is full, the
    686 	 * keystroke is lost (sorry!).
    687 	 */
    688 
    689 	put = k->k_events.ev_put;
    690 	fe = &k->k_events.ev_q[put];
    691 	put = (put + 1) % EV_QSIZE;
    692 	if (put == k->k_events.ev_get) {
    693 		log(LOG_WARNING, "keyboard event queue overflow\n");
    694 			/* ??? */
    695 		return;
    696 	}
    697 	fe->id = KEY_CODE(c);
    698 	fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
    699 	fe->time = time;
    700 	k->k_events.ev_put = put;
    701 	EV_WAKEUP(&k->k_events);
    702 }
    703 
    704 
    705 #ifdef DRACO
    706 void
    707 drkbdintr(void)
    708 {
    709 	u_char in;
    710 	struct kbd_softc *k = &kbd_softc;
    711 
    712 	in = draco_ioct->io_kbddata;
    713 	draco_ioct->io_kbdrst = 0;
    714 
    715 	if (in == 0xF0)
    716 		k->k_rlprfx = 0x80;
    717 	else {
    718 		kbdstuffchar(in>=sizeof(drkbdtab) ? 0xff :
    719 		    drkbdtab[in] | k->k_rlprfx);
    720 		k->k_rlprfx = 0;
    721 	}
    722 }
    723 
    724 #endif
    725 
    726 
    727 #if NWSKBD>0
    728 /*
    729  * These are the callback functions that are passed to wscons.
    730  * They really don't do anything worth noting, just call the
    731  * other functions above.
    732  */
    733 
    734 int
    735 kbd_enable(void *c, int on)
    736 {
    737 	/* Wonder what this is supposed to do... */
    738 	return (0);
    739 }
    740 
    741 void
    742 kbd_set_leds(void *c, int leds)
    743 {
    744 }
    745 
    746 int
    747 kbd_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc *p)
    748 {
    749 	switch (cmd)
    750 	{
    751 	case WSKBDIO_COMPLEXBELL:
    752 		return 0;
    753 	case WSKBDIO_SETLEDS:
    754 		return 0;
    755 	case WSKBDIO_GETLEDS:
    756 		*(int*)data = 0;
    757 		return 0;
    758 	case WSKBDIO_GTYPE:
    759 		*(u_int*)data = WSKBD_TYPE_AMIGA;
    760 		return 0;
    761 	}
    762 
    763 	/*
    764 	 * We are supposed to return EPASSTHROUGH to wscons if we didn't
    765 	 * understand.
    766 	 */
    767 	return (EPASSTHROUGH);
    768 }
    769 
    770 void
    771 kbd_getc(void *c, u_int *type, int *data)
    772 {
    773 	int key;
    774 
    775 	key = kbdgetcn();
    776 
    777 	*data = KEY_CODE(key);
    778 	*type = KEY_UP(key) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
    779 }
    780 
    781 void
    782 kbd_pollc(void *c, int on)
    783 {
    784 	kbd_softc.k_pollingmode = on;
    785 }
    786 
    787 void
    788 kbd_bell(void *c, u_int x, u_int y, u_int z)
    789 {
    790 }
    791 #endif /* WSKBD */
    792