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