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