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