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