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