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