1 /* $NetBSD: kbd.c,v 1.46 2003/09/21 19:16:48 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. 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.46 2003/09/21 19:16:48 jdolecek 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 FIOSETOWN: 495 if (-*(int *)data != k->k_events.ev_io->p_pgid 496 && *(int *)data != k->k_events.ev_io->p_pid) 497 return EPERM; 498 return 0; 499 500 case TIOCSPGRP: 501 if (*(int *)data != k->k_events.ev_io->p_pgid) 502 return EPERM; 503 return 0; 504 505 default: 506 return ENOTTY; 507 } 508 509 /* We identified the ioctl, but we do not handle it. */ 510 return EOPNOTSUPP; /* misuse, but what the heck */ 511 } 512 513 int 514 kbdpoll(dev_t dev, int events, struct proc *p) 515 { 516 return ev_poll (&kbd_softc.k_events, events, p); 517 } 518 519 int 520 kbdkqfilter(dev, kn) 521 dev_t dev; 522 struct knote *kn; 523 { 524 525 return (ev_kqfilter(&kbd_softc.k_events, kn)); 526 } 527 528 void 529 kbdintr(int mask) 530 { 531 u_char c; 532 #ifdef KBDRESET 533 static int reset_warn; 534 #endif 535 536 /* 537 * now only invoked from generic CIA interrupt handler if there *is* 538 * a keyboard interrupt pending 539 */ 540 541 c = ~ciaa.sdr; /* keyboard data is inverted */ 542 /* ack */ 543 ciaa.cra |= (1 << 6); /* serial line output */ 544 #ifdef KBDRESET 545 if (reset_warn && c == 0xf0) { 546 #ifdef DEBUG 547 printf ("kbdintr: !!!! Reset Warning !!!!\n"); 548 #endif 549 bootsync(); 550 reset_warn = 0; 551 DELAY(30000000); 552 } 553 #endif 554 /* wait 200 microseconds (for bloody Cherry keyboards..) */ 555 DELAY(2000); /* fudge delay a bit for some keyboards */ 556 ciaa.cra &= ~(1 << 6); 557 558 /* process the character */ 559 c = (c >> 1) | (c << 7); /* rotate right once */ 560 561 #ifdef KBDRESET 562 if (c == 0x78) { 563 #ifdef DEBUG 564 printf ("kbdintr: Reset Warning started\n"); 565 #endif 566 ++reset_warn; 567 return; 568 } 569 #endif 570 kbdstuffchar(c); 571 } 572 573 #ifdef DRACO 574 /* maps MF-II keycodes to Amiga keycodes */ 575 576 const u_char drkbdtab[] = { 577 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x50, 578 0x45, 0xff, 0xff, 0xff, 0xff, 0x42, 0x00, 0x51, 579 580 0xff, 0x64, 0x60, 0x30, 0x63, 0x10, 0x01, 0x52, 581 0xff, 0x66, 0x31, 0x21, 0x20, 0x11, 0x02, 0x53, 582 583 0xff, 0x33, 0x32, 0x22, 0x12, 0x04, 0x03, 0x54, 584 0xff, 0x40, 0x34, 0x23, 0x14, 0x13, 0x05, 0x55, 585 586 0xff, 0x36, 0x35, 0x25, 0x24, 0x15, 0x06, 0x56, 587 0xff, 0x67, 0x37, 0x26, 0x16, 0x07, 0x08, 0x57, 588 /* --- */ 589 0xff, 0x38, 0x27, 0x17, 0x18, 0x0a, 0x09, 0x58, 590 0xff, 0x39, 0x3a, 0x28, 0x29, 0x19, 0x0b, 0x59, 591 592 0xff, 0xff, 0x2a, 0x2b, 0x1a, 0x0c, 0x4b, 0xff, 593 0x65, 0x61, 0x44, 0x1b, 0xff, 0xff, 0x6f, 0xff, 594 595 0x4d, 0x4f, 0xff, 0x4c, 0x0d, 0xff, 0x41, 0x46, 596 0xff, 0x1d, 0x4e, 0x2d, 0x3d, 0x4a, 0x5f, 0x62, 597 598 0x0f, 0x3c, 0x1e, 0x2e, 0x2f, 0x3e, 0x5a, 0x5b, 599 0xff, 0x43, 0x1f, 0xff, 0x5e, 0x3f, 0x5c, 0xff, 600 /* --- */ 601 0xff, 0xff, 0xff, 0xff, 0x5d 602 }; 603 #endif 604 605 606 int 607 kbdgetcn(void) 608 { 609 int s; 610 u_char ints, mask, c, in; 611 612 #ifdef DRACO 613 if (is_draco() && kbd_softc.k_mf2) { 614 do { 615 c = 0; 616 s = spltty (); 617 while ((draco_ioct->io_status & DRSTAT_KBDRECV) == 0); 618 in = draco_ioct->io_kbddata; 619 draco_ioct->io_kbdrst = 0; 620 if (in == 0xF0) { /* release prefix */ 621 c = 0x80; 622 while ((draco_ioct->io_status & 623 DRSTAT_KBDRECV) == 0); 624 in = draco_ioct->io_kbddata; 625 draco_ioct->io_kbdrst = 0; 626 } 627 splx(s); 628 #ifdef DRACORAWKEYDEBUG 629 printf("<%02x>", in); 630 #endif 631 c |= in>=sizeof(drkbdtab) ? 0xff : drkbdtab[in]; 632 } while (c == 0xff); 633 return (c); 634 } 635 #endif 636 s = spltty(); 637 for (ints = 0; ! ((mask = ciaa.icr) & CIA_ICR_SP); 638 ints |= mask) ; 639 640 in = ciaa.sdr; 641 c = ~in; 642 643 /* ack */ 644 ciaa.cra |= (1 << 6); /* serial line output */ 645 ciaa.sdr = 0xff; /* ack */ 646 /* wait 200 microseconds */ 647 DELAY(2000); /* XXXX only works as long as DELAY doesn't 648 * use a timer and waits.. */ 649 ciaa.cra &= ~(1 << 6); 650 ciaa.sdr = in; 651 652 splx (s); 653 c = (c >> 1) | (c << 7); 654 655 /* take care that no CIA-interrupts are lost */ 656 if (ints) 657 dispatch_cia_ints (0, ints); 658 659 return c; 660 } 661 662 void 663 kbdstuffchar(u_char c) 664 { 665 struct firm_event *fe; 666 struct kbd_softc *k = &kbd_softc; 667 int put; 668 669 #if NWSKBD>0 670 /* 671 * If we have attached a wskbd and not in polling mode and 672 * nobody has opened us directly, then send the keystroke 673 * to the wskbd. 674 */ 675 676 if (kbd_softc.k_pollingmode == 0 677 && kbd_softc.k_wskbddev != NULL 678 && k->k_event_mode == 0) { 679 wskbd_input(kbd_softc.k_wskbddev, 680 KEY_UP(c) ? 681 WSCONS_EVENT_KEY_UP : 682 WSCONS_EVENT_KEY_DOWN, 683 KEY_CODE(c)); 684 return; 685 } 686 687 #endif /* NWSKBD */ 688 689 /* 690 * If not in event mode, deliver straight to ite to process 691 * key stroke 692 */ 693 694 if (! k->k_event_mode) { 695 #if NITE>0 696 ite_filter (c, ITEFILT_TTY); 697 #endif 698 return; 699 } 700 701 /* 702 * Keyboard is generating events. Turn this keystroke into an 703 * event and put it in the queue. If the queue is full, the 704 * keystroke is lost (sorry!). 705 */ 706 707 put = k->k_events.ev_put; 708 fe = &k->k_events.ev_q[put]; 709 put = (put + 1) % EV_QSIZE; 710 if (put == k->k_events.ev_get) { 711 log(LOG_WARNING, "keyboard event queue overflow\n"); 712 /* ??? */ 713 return; 714 } 715 fe->id = KEY_CODE(c); 716 fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; 717 fe->time = time; 718 k->k_events.ev_put = put; 719 EV_WAKEUP(&k->k_events); 720 } 721 722 723 #ifdef DRACO 724 void 725 drkbdintr(void) 726 { 727 u_char in; 728 struct kbd_softc *k = &kbd_softc; 729 730 in = draco_ioct->io_kbddata; 731 draco_ioct->io_kbdrst = 0; 732 733 if (in == 0xF0) 734 k->k_rlprfx = 0x80; 735 else { 736 kbdstuffchar(in>=sizeof(drkbdtab) ? 0xff : 737 drkbdtab[in] | k->k_rlprfx); 738 k->k_rlprfx = 0; 739 } 740 } 741 742 #endif 743 744 745 #if NWSKBD>0 746 /* 747 * These are the callback functions that are passed to wscons. 748 * They really don't do anything worth noting, just call the 749 * other functions above. 750 */ 751 752 int 753 kbd_enable(void *c, int on) 754 { 755 /* Wonder what this is supposed to do... */ 756 return (0); 757 } 758 759 void 760 kbd_set_leds(void *c, int leds) 761 { 762 } 763 764 int 765 kbd_ioctl(void *c, u_long cmd, caddr_t data, int flag, struct proc *p) 766 { 767 switch (cmd) 768 { 769 case WSKBDIO_COMPLEXBELL: 770 return 0; 771 case WSKBDIO_SETLEDS: 772 return 0; 773 case WSKBDIO_GETLEDS: 774 *(int*)data = 0; 775 return 0; 776 case WSKBDIO_GTYPE: 777 *(u_int*)data = WSKBD_TYPE_AMIGA; 778 return 0; 779 } 780 781 /* 782 * We are supposed to return EPASSTHROUGH to wscons if we didn't 783 * understand. 784 */ 785 return (EPASSTHROUGH); 786 } 787 788 void 789 kbd_getc(void *c, u_int *type, int *data) 790 { 791 int key; 792 793 key = kbdgetcn(); 794 795 *data = KEY_CODE(key); 796 *type = KEY_UP(key) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 797 } 798 799 void 800 kbd_pollc(void *c, int on) 801 { 802 kbd_softc.k_pollingmode = on; 803 } 804 805 void 806 kbd_bell(void *c, u_int x, u_int y, u_int z) 807 { 808 } 809 #endif /* WSKBD */ 810