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