1 /*- 2 * vkbd.c 3 * 4 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com> 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 * $Id: vkbd.c,v 1.20 2004/11/15 23:53:30 max Exp $ 29 * $FreeBSD$ 30 */ 31 32 #include "opt_kbd.h" 33 34 #include <sys/param.h> 35 #include <sys/conf.h> 36 #include <sys/fcntl.h> 37 #include <sys/kbio.h> 38 #include <sys/kernel.h> 39 #include <sys/limits.h> 40 #include <sys/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/module.h> 43 #include <sys/mutex.h> 44 #include <sys/poll.h> 45 #include <sys/proc.h> 46 #include <sys/queue.h> 47 #include <sys/selinfo.h> 48 #include <sys/systm.h> 49 #include <sys/taskqueue.h> 50 #include <sys/uio.h> 51 #include <dev/kbd/kbdreg.h> 52 #include <dev/kbd/kbdtables.h> 53 #include <dev/vkbd/vkbd_var.h> 54 55 #define DEVICE_NAME "vkbdctl" 56 #define KEYBOARD_NAME "vkbd" 57 58 MALLOC_DECLARE(M_VKBD); 59 MALLOC_DEFINE(M_VKBD, KEYBOARD_NAME, "Virtual AT keyboard"); 60 61 /***************************************************************************** 62 ***************************************************************************** 63 ** Keyboard state 64 ***************************************************************************** 65 *****************************************************************************/ 66 67 #define VKBD_LOCK_DECL struct mtx ks_lock 68 #define VKBD_LOCK_INIT(s) mtx_init(&(s)->ks_lock, "vkbd_lock", NULL, MTX_DEF|MTX_RECURSE) 69 #define VKBD_LOCK_DESTROY(s) mtx_destroy(&(s)->ks_lock) 70 #define VKBD_LOCK(s) mtx_lock(&(s)->ks_lock) 71 #define VKBD_UNLOCK(s) mtx_unlock(&(s)->ks_lock) 72 #define VKBD_LOCK_ASSERT(s, w) mtx_assert(&(s)->ks_lock, w) 73 #define VKBD_SLEEP(s, f, d, t) \ 74 msleep(&(s)->f, &(s)->ks_lock, PCATCH | (PZERO + 1), d, t) 75 76 #define VKBD_KEYBOARD(d) \ 77 kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, dev2unit(d))) 78 79 /* vkbd queue */ 80 struct vkbd_queue 81 { 82 int q[VKBD_Q_SIZE]; /* queue */ 83 int head; /* index of the first code */ 84 int tail; /* index of the last code */ 85 int cc; /* number of codes in queue */ 86 }; 87 88 typedef struct vkbd_queue vkbd_queue_t; 89 90 /* vkbd state */ 91 struct vkbd_state 92 { 93 struct cdev *ks_dev; /* control device */ 94 95 struct selinfo ks_rsel; /* select(2) */ 96 struct selinfo ks_wsel; 97 98 vkbd_queue_t ks_inq; /* input key codes queue */ 99 struct task ks_task; /* interrupt task */ 100 101 int ks_flags; /* flags */ 102 #define OPEN (1 << 0) /* control device is open */ 103 #define COMPOSE (1 << 1) /* compose flag */ 104 #define STATUS (1 << 2) /* status has changed */ 105 #define TASK (1 << 3) /* interrupt task queued */ 106 #define READ (1 << 4) /* read pending */ 107 #define WRITE (1 << 5) /* write pending */ 108 109 int ks_mode; /* K_XLATE, K_RAW, K_CODE */ 110 int ks_polling; /* polling flag */ 111 int ks_state; /* shift/lock key state */ 112 int ks_accents; /* accent key index (> 0) */ 113 u_int ks_composed_char; /* composed char code */ 114 u_char ks_prefix; /* AT scan code prefix */ 115 116 VKBD_LOCK_DECL; 117 }; 118 119 typedef struct vkbd_state vkbd_state_t; 120 121 /***************************************************************************** 122 ***************************************************************************** 123 ** Character device 124 ***************************************************************************** 125 *****************************************************************************/ 126 127 static void vkbd_dev_clone(void *, struct ucred *, char *, int, 128 struct cdev **); 129 static d_open_t vkbd_dev_open; 130 static d_close_t vkbd_dev_close; 131 static d_read_t vkbd_dev_read; 132 static d_write_t vkbd_dev_write; 133 static d_ioctl_t vkbd_dev_ioctl; 134 static d_poll_t vkbd_dev_poll; 135 static void vkbd_dev_intr(void *, int); 136 static void vkbd_status_changed(vkbd_state_t *); 137 static int vkbd_data_ready(vkbd_state_t *); 138 static int vkbd_data_read(vkbd_state_t *, int); 139 140 static struct cdevsw vkbd_dev_cdevsw = { 141 .d_version = D_VERSION, 142 .d_flags = D_PSEUDO | D_NEEDGIANT, 143 .d_open = vkbd_dev_open, 144 .d_close = vkbd_dev_close, 145 .d_read = vkbd_dev_read, 146 .d_write = vkbd_dev_write, 147 .d_ioctl = vkbd_dev_ioctl, 148 .d_poll = vkbd_dev_poll, 149 .d_name = DEVICE_NAME, 150 }; 151 152 static struct clonedevs *vkbd_dev_clones = NULL; 153 154 /* Clone device */ 155 static void 156 vkbd_dev_clone(void *arg, struct ucred *cred, char *name, int namelen, 157 struct cdev **dev) 158 { 159 int unit; 160 161 if (*dev != NULL) 162 return; 163 164 if (strcmp(name, DEVICE_NAME) == 0) 165 unit = -1; 166 else if (dev_stdclone(name, NULL, DEVICE_NAME, &unit) != 1) 167 return; /* don't recognize the name */ 168 169 /* find any existing device, or allocate new unit number */ 170 if (clone_create(&vkbd_dev_clones, &vkbd_dev_cdevsw, &unit, dev, 0)) { 171 *dev = make_dev(&vkbd_dev_cdevsw, unit2minor(unit), 172 UID_ROOT, GID_WHEEL, 0600, DEVICE_NAME "%d", unit); 173 if (*dev != NULL) { 174 dev_ref(*dev); 175 (*dev)->si_flags |= SI_CHEAPCLONE; 176 } 177 } 178 } 179 180 /* Open device */ 181 static int 182 vkbd_dev_open(struct cdev *dev, int flag, int mode, struct thread *td) 183 { 184 int unit = dev2unit(dev), error; 185 keyboard_switch_t *sw = NULL; 186 keyboard_t *kbd = NULL; 187 vkbd_state_t *state = (vkbd_state_t *) dev->si_drv1; 188 189 /* XXX FIXME: dev->si_drv1 locking */ 190 if (state == NULL) { 191 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) 192 return (ENXIO); 193 194 if ((error = (*sw->probe)(unit, NULL, 0)) != 0 || 195 (error = (*sw->init)(unit, &kbd, NULL, 0)) != 0) 196 return (error); 197 198 state = (vkbd_state_t *) kbd->kb_data; 199 200 if ((error = (*sw->enable)(kbd)) != 0) { 201 (*sw->term)(kbd); 202 return (error); 203 } 204 205 #ifdef KBD_INSTALL_CDEV 206 if ((error = kbd_attach(kbd)) != 0) { 207 (*sw->disable)(kbd); 208 (*sw->term)(kbd); 209 return (error); 210 } 211 #endif /* def KBD_INSTALL_CDEV */ 212 213 dev->si_drv1 = kbd->kb_data; 214 } 215 216 VKBD_LOCK(state); 217 218 if (state->ks_flags & OPEN) { 219 VKBD_UNLOCK(state); 220 return (EBUSY); 221 } 222 223 state->ks_flags |= OPEN; 224 state->ks_dev = dev; 225 226 VKBD_UNLOCK(state); 227 228 return (0); 229 } 230 231 /* Close device */ 232 static int 233 vkbd_dev_close(struct cdev *dev, int foo, int bar, struct thread *td) 234 { 235 keyboard_t *kbd = VKBD_KEYBOARD(dev); 236 vkbd_state_t *state = NULL; 237 238 if (kbd == NULL) 239 return (ENXIO); 240 241 if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1) 242 panic("%s: kbd->kb_data != dev->si_drv1\n", __func__); 243 244 state = (vkbd_state_t *) kbd->kb_data; 245 246 VKBD_LOCK(state); 247 248 /* wait for interrupt task */ 249 while (state->ks_flags & TASK) 250 VKBD_SLEEP(state, ks_task, "vkbdc", 0); 251 252 /* wakeup poll()ers */ 253 selwakeuppri(&state->ks_rsel, PZERO + 1); 254 selwakeuppri(&state->ks_wsel, PZERO + 1); 255 256 state->ks_flags &= ~OPEN; 257 state->ks_dev = NULL; 258 state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0; 259 260 VKBD_UNLOCK(state); 261 262 (*kbdsw[kbd->kb_index]->disable)(kbd); 263 #ifdef KBD_INSTALL_CDEV 264 kbd_detach(kbd); 265 #endif /* def KBD_INSTALL_CDEV */ 266 (*kbdsw[kbd->kb_index]->term)(kbd); 267 268 /* XXX FIXME: dev->si_drv1 locking */ 269 dev->si_drv1 = NULL; 270 271 return (0); 272 } 273 274 /* Read status */ 275 static int 276 vkbd_dev_read(struct cdev *dev, struct uio *uio, int flag) 277 { 278 keyboard_t *kbd = VKBD_KEYBOARD(dev); 279 vkbd_state_t *state = NULL; 280 vkbd_status_t status; 281 int error; 282 283 if (kbd == NULL) 284 return (ENXIO); 285 286 if (uio->uio_resid != sizeof(status)) 287 return (EINVAL); 288 289 if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1) 290 panic("%s: kbd->kb_data != dev->si_drv1\n", __func__); 291 292 state = (vkbd_state_t *) kbd->kb_data; 293 294 VKBD_LOCK(state); 295 296 if (state->ks_flags & READ) { 297 VKBD_UNLOCK(state); 298 return (EALREADY); 299 } 300 301 state->ks_flags |= READ; 302 again: 303 if (state->ks_flags & STATUS) { 304 state->ks_flags &= ~STATUS; 305 306 status.mode = state->ks_mode; 307 status.leds = KBD_LED_VAL(kbd); 308 status.lock = state->ks_state & LOCK_MASK; 309 status.delay = kbd->kb_delay1; 310 status.rate = kbd->kb_delay2; 311 bzero(status.reserved, sizeof(status.reserved)); 312 313 error = uiomove(&status, sizeof(status), uio); 314 } else { 315 if (flag & O_NONBLOCK) { 316 error = EWOULDBLOCK; 317 goto done; 318 } 319 320 error = VKBD_SLEEP(state, ks_flags, "vkbdr", 0); 321 if (error != 0) 322 goto done; 323 324 goto again; 325 } 326 done: 327 state->ks_flags &= ~READ; 328 329 VKBD_UNLOCK(state); 330 331 return (error); 332 } 333 334 /* Write scancodes */ 335 static int 336 vkbd_dev_write(struct cdev *dev, struct uio *uio, int flag) 337 { 338 keyboard_t *kbd = VKBD_KEYBOARD(dev); 339 vkbd_state_t *state = NULL; 340 vkbd_queue_t *q = NULL; 341 int error, avail, bytes; 342 343 if (kbd == NULL) 344 return (ENXIO); 345 346 if (uio->uio_resid <= 0) 347 return (EINVAL); 348 349 if (kbd->kb_data == NULL || kbd->kb_data != dev->si_drv1) 350 panic("%s: kbd->kb_data != dev->si_drv1\n", __func__); 351 352 state = (vkbd_state_t *) kbd->kb_data; 353 354 VKBD_LOCK(state); 355 356 if (state->ks_flags & WRITE) { 357 VKBD_UNLOCK(state); 358 return (EALREADY); 359 } 360 361 state->ks_flags |= WRITE; 362 error = 0; 363 q = &state->ks_inq; 364 365 while (uio->uio_resid >= sizeof(q->q[0])) { 366 if (q->head == q->tail) { 367 if (q->cc == 0) 368 avail = sizeof(q->q)/sizeof(q->q[0]) - q->head; 369 else 370 avail = 0; /* queue must be full */ 371 } else if (q->head < q->tail) 372 avail = sizeof(q->q)/sizeof(q->q[0]) - q->tail; 373 else 374 avail = q->head - q->tail; 375 376 if (avail == 0) { 377 if (flag & O_NONBLOCK) { 378 error = EWOULDBLOCK; 379 break; 380 } 381 382 error = VKBD_SLEEP(state, ks_inq, "vkbdw", 0); 383 if (error != 0) 384 break; 385 } else { 386 bytes = avail * sizeof(q->q[0]); 387 if (bytes > uio->uio_resid) { 388 avail = uio->uio_resid / sizeof(q->q[0]); 389 bytes = avail * sizeof(q->q[0]); 390 } 391 392 error = uiomove((void *) &q->q[q->tail], bytes, uio); 393 if (error != 0) 394 break; 395 396 q->cc += avail; 397 q->tail += avail; 398 if (q->tail == sizeof(q->q)/sizeof(q->q[0])) 399 q->tail = 0; 400 401 /* queue interrupt task if needed */ 402 if (!(state->ks_flags & TASK) && 403 taskqueue_enqueue(taskqueue_swi_giant, &state->ks_task) == 0) 404 state->ks_flags |= TASK; 405 } 406 } 407 408 state->ks_flags &= ~WRITE; 409 410 VKBD_UNLOCK(state); 411 412 return (error); 413 } 414 415 /* Process ioctl */ 416 static int 417 vkbd_dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag, struct thread *td) 418 { 419 keyboard_t *kbd = VKBD_KEYBOARD(dev); 420 421 return ((kbd == NULL)? ENXIO : 422 (*kbdsw[kbd->kb_index]->ioctl)(kbd, cmd, data)); 423 } 424 425 /* Poll device */ 426 static int 427 vkbd_dev_poll(struct cdev *dev, int events, struct thread *td) 428 { 429 vkbd_state_t *state = (vkbd_state_t *) dev->si_drv1; 430 vkbd_queue_t *q = NULL; 431 int revents = 0; 432 433 if (state == NULL) 434 return (ENXIO); 435 436 VKBD_LOCK(state); 437 438 q = &state->ks_inq; 439 440 if (events & (POLLIN | POLLRDNORM)) { 441 if (state->ks_flags & STATUS) 442 revents |= events & (POLLIN | POLLRDNORM); 443 else 444 selrecord(td, &state->ks_rsel); 445 } 446 447 if (events & (POLLOUT | POLLWRNORM)) { 448 if (q->cc < sizeof(q->q)/sizeof(q->q[0])) 449 revents |= events & (POLLOUT | POLLWRNORM); 450 else 451 selrecord(td, &state->ks_wsel); 452 } 453 454 VKBD_UNLOCK(state); 455 456 return (revents); 457 } 458 459 /* Interrupt handler */ 460 void 461 vkbd_dev_intr(void *xkbd, int pending) 462 { 463 keyboard_t *kbd = (keyboard_t *) xkbd; 464 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 465 466 (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); 467 468 VKBD_LOCK(state); 469 470 state->ks_flags &= ~TASK; 471 wakeup(&state->ks_task); 472 473 VKBD_UNLOCK(state); 474 } 475 476 /* Set status change flags */ 477 static void 478 vkbd_status_changed(vkbd_state_t *state) 479 { 480 VKBD_LOCK_ASSERT(state, MA_OWNED); 481 482 if (!(state->ks_flags & STATUS)) { 483 state->ks_flags |= STATUS; 484 selwakeuppri(&state->ks_rsel, PZERO + 1); 485 wakeup(&state->ks_flags); 486 } 487 } 488 489 /* Check if we have data in the input queue */ 490 static int 491 vkbd_data_ready(vkbd_state_t *state) 492 { 493 VKBD_LOCK_ASSERT(state, MA_OWNED); 494 495 return (state->ks_inq.cc > 0); 496 } 497 498 /* Read one code from the input queue */ 499 static int 500 vkbd_data_read(vkbd_state_t *state, int wait) 501 { 502 vkbd_queue_t *q = &state->ks_inq; 503 int c; 504 505 VKBD_LOCK_ASSERT(state, MA_OWNED); 506 507 if (q->cc == 0) 508 return (-1); 509 510 /* get first code from the queue */ 511 q->cc --; 512 c = q->q[q->head ++]; 513 if (q->head == sizeof(q->q)/sizeof(q->q[0])) 514 q->head = 0; 515 516 /* wakeup ks_inq writers/poll()ers */ 517 selwakeuppri(&state->ks_wsel, PZERO + 1); 518 wakeup(q); 519 520 return (c); 521 } 522 523 /**************************************************************************** 524 **************************************************************************** 525 ** Keyboard driver 526 **************************************************************************** 527 ****************************************************************************/ 528 529 static int vkbd_configure(int flags); 530 static kbd_probe_t vkbd_probe; 531 static kbd_init_t vkbd_init; 532 static kbd_term_t vkbd_term; 533 static kbd_intr_t vkbd_intr; 534 static kbd_test_if_t vkbd_test_if; 535 static kbd_enable_t vkbd_enable; 536 static kbd_disable_t vkbd_disable; 537 static kbd_read_t vkbd_read; 538 static kbd_check_t vkbd_check; 539 static kbd_read_char_t vkbd_read_char; 540 static kbd_check_char_t vkbd_check_char; 541 static kbd_ioctl_t vkbd_ioctl; 542 static kbd_lock_t vkbd_lock; 543 static void vkbd_clear_state_locked(vkbd_state_t *state); 544 static kbd_clear_state_t vkbd_clear_state; 545 static kbd_get_state_t vkbd_get_state; 546 static kbd_set_state_t vkbd_set_state; 547 static kbd_poll_mode_t vkbd_poll; 548 549 static keyboard_switch_t vkbdsw = { 550 .probe = vkbd_probe, 551 .init = vkbd_init, 552 .term = vkbd_term, 553 .intr = vkbd_intr, 554 .test_if = vkbd_test_if, 555 .enable = vkbd_enable, 556 .disable = vkbd_disable, 557 .read = vkbd_read, 558 .check = vkbd_check, 559 .read_char = vkbd_read_char, 560 .check_char = vkbd_check_char, 561 .ioctl = vkbd_ioctl, 562 .lock = vkbd_lock, 563 .clear_state = vkbd_clear_state, 564 .get_state = vkbd_get_state, 565 .set_state = vkbd_set_state, 566 .get_fkeystr = genkbd_get_fkeystr, 567 .poll = vkbd_poll, 568 .diag = genkbd_diag, 569 }; 570 571 static int typematic(int delay, int rate); 572 static int typematic_delay(int delay); 573 static int typematic_rate(int rate); 574 575 /* Return the number of found keyboards */ 576 static int 577 vkbd_configure(int flags) 578 { 579 return (1); 580 } 581 582 /* Detect a keyboard */ 583 static int 584 vkbd_probe(int unit, void *arg, int flags) 585 { 586 return (0); 587 } 588 589 /* Reset and initialize the keyboard (stolen from atkbd.c) */ 590 static int 591 vkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) 592 { 593 keyboard_t *kbd = NULL; 594 vkbd_state_t *state = NULL; 595 keymap_t *keymap = NULL; 596 accentmap_t *accmap = NULL; 597 fkeytab_t *fkeymap = NULL; 598 int fkeymap_size, delay[2]; 599 int error, needfree; 600 601 if (*kbdp == NULL) { 602 *kbdp = kbd = malloc(sizeof(*kbd), M_VKBD, M_NOWAIT | M_ZERO); 603 state = malloc(sizeof(*state), M_VKBD, M_NOWAIT | M_ZERO); 604 keymap = malloc(sizeof(key_map), M_VKBD, M_NOWAIT); 605 accmap = malloc(sizeof(accent_map), M_VKBD, M_NOWAIT); 606 fkeymap = malloc(sizeof(fkey_tab), M_VKBD, M_NOWAIT); 607 fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]); 608 needfree = 1; 609 if ((kbd == NULL) || (state == NULL) || (keymap == NULL) || 610 (accmap == NULL) || (fkeymap == NULL)) { 611 error = ENOMEM; 612 goto bad; 613 } 614 615 VKBD_LOCK_INIT(state); 616 state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0; 617 TASK_INIT(&state->ks_task, 0, vkbd_dev_intr, (void *) kbd); 618 } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) { 619 return (0); 620 } else { 621 kbd = *kbdp; 622 state = (vkbd_state_t *) kbd->kb_data; 623 keymap = kbd->kb_keymap; 624 accmap = kbd->kb_accentmap; 625 fkeymap = kbd->kb_fkeytab; 626 fkeymap_size = kbd->kb_fkeytab_size; 627 needfree = 0; 628 } 629 630 if (!KBD_IS_PROBED(kbd)) { 631 kbd_init_struct(kbd, KEYBOARD_NAME, KB_OTHER, unit, flags, 0, 0); 632 bcopy(&key_map, keymap, sizeof(key_map)); 633 bcopy(&accent_map, accmap, sizeof(accent_map)); 634 bcopy(fkey_tab, fkeymap, 635 imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); 636 kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); 637 kbd->kb_data = (void *)state; 638 639 KBD_FOUND_DEVICE(kbd); 640 KBD_PROBE_DONE(kbd); 641 642 VKBD_LOCK(state); 643 vkbd_clear_state_locked(state); 644 state->ks_mode = K_XLATE; 645 /* FIXME: set the initial value for lock keys in ks_state */ 646 VKBD_UNLOCK(state); 647 } 648 if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { 649 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY; 650 651 vkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); 652 delay[0] = kbd->kb_delay1; 653 delay[1] = kbd->kb_delay2; 654 vkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); 655 656 KBD_INIT_DONE(kbd); 657 } 658 if (!KBD_IS_CONFIGURED(kbd)) { 659 if (kbd_register(kbd) < 0) { 660 error = ENXIO; 661 goto bad; 662 } 663 KBD_CONFIG_DONE(kbd); 664 } 665 666 return (0); 667 bad: 668 if (needfree) { 669 if (state != NULL) 670 free(state, M_VKBD); 671 if (keymap != NULL) 672 free(keymap, M_VKBD); 673 if (accmap != NULL) 674 free(accmap, M_VKBD); 675 if (fkeymap != NULL) 676 free(fkeymap, M_VKBD); 677 if (kbd != NULL) { 678 free(kbd, M_VKBD); 679 *kbdp = NULL; /* insure ref doesn't leak to caller */ 680 } 681 } 682 return (error); 683 } 684 685 /* Finish using this keyboard */ 686 static int 687 vkbd_term(keyboard_t *kbd) 688 { 689 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 690 691 kbd_unregister(kbd); 692 693 VKBD_LOCK_DESTROY(state); 694 bzero(state, sizeof(*state)); 695 free(state, M_VKBD); 696 697 free(kbd->kb_keymap, M_VKBD); 698 free(kbd->kb_accentmap, M_VKBD); 699 free(kbd->kb_fkeytab, M_VKBD); 700 free(kbd, M_VKBD); 701 702 return (0); 703 } 704 705 /* Keyboard interrupt routine */ 706 static int 707 vkbd_intr(keyboard_t *kbd, void *arg) 708 { 709 int c; 710 711 if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { 712 /* let the callback function to process the input */ 713 (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, 714 kbd->kb_callback.kc_arg); 715 } else { 716 /* read and discard the input; no one is waiting for input */ 717 do { 718 c = vkbd_read_char(kbd, FALSE); 719 } while (c != NOKEY); 720 } 721 722 return (0); 723 } 724 725 /* Test the interface to the device */ 726 static int 727 vkbd_test_if(keyboard_t *kbd) 728 { 729 return (0); 730 } 731 732 /* 733 * Enable the access to the device; until this function is called, 734 * the client cannot read from the keyboard. 735 */ 736 737 static int 738 vkbd_enable(keyboard_t *kbd) 739 { 740 KBD_ACTIVATE(kbd); 741 return (0); 742 } 743 744 /* Disallow the access to the device */ 745 static int 746 vkbd_disable(keyboard_t *kbd) 747 { 748 KBD_DEACTIVATE(kbd); 749 return (0); 750 } 751 752 /* Read one byte from the keyboard if it's allowed */ 753 static int 754 vkbd_read(keyboard_t *kbd, int wait) 755 { 756 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 757 int c; 758 759 VKBD_LOCK(state); 760 c = vkbd_data_read(state, wait); 761 VKBD_UNLOCK(state); 762 763 if (c != -1) 764 kbd->kb_count ++; 765 766 return (KBD_IS_ACTIVE(kbd)? c : -1); 767 } 768 769 /* Check if data is waiting */ 770 static int 771 vkbd_check(keyboard_t *kbd) 772 { 773 vkbd_state_t *state = NULL; 774 int ready; 775 776 if (!KBD_IS_ACTIVE(kbd)) 777 return (FALSE); 778 779 state = (vkbd_state_t *) kbd->kb_data; 780 781 VKBD_LOCK(state); 782 ready = vkbd_data_ready(state); 783 VKBD_UNLOCK(state); 784 785 return (ready); 786 } 787 788 /* Read char from the keyboard (stolen from atkbd.c) */ 789 static u_int 790 vkbd_read_char(keyboard_t *kbd, int wait) 791 { 792 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 793 u_int action; 794 int scancode, keycode; 795 796 VKBD_LOCK(state); 797 798 next_code: 799 800 /* do we have a composed char to return? */ 801 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) { 802 action = state->ks_composed_char; 803 state->ks_composed_char = 0; 804 if (action > UCHAR_MAX) { 805 VKBD_UNLOCK(state); 806 return (ERRKEY); 807 } 808 809 VKBD_UNLOCK(state); 810 return (action); 811 } 812 813 /* see if there is something in the keyboard port */ 814 scancode = vkbd_data_read(state, wait); 815 if (scancode == -1) { 816 VKBD_UNLOCK(state); 817 return (NOKEY); 818 } 819 /* XXX FIXME: check for -1 if wait == 1! */ 820 821 kbd->kb_count ++; 822 823 /* return the byte as is for the K_RAW mode */ 824 if (state->ks_mode == K_RAW) { 825 VKBD_UNLOCK(state); 826 return (scancode); 827 } 828 829 /* translate the scan code into a keycode */ 830 keycode = scancode & 0x7F; 831 switch (state->ks_prefix) { 832 case 0x00: /* normal scancode */ 833 switch(scancode) { 834 case 0xB8: /* left alt (compose key) released */ 835 if (state->ks_flags & COMPOSE) { 836 state->ks_flags &= ~COMPOSE; 837 if (state->ks_composed_char > UCHAR_MAX) 838 state->ks_composed_char = 0; 839 } 840 break; 841 case 0x38: /* left alt (compose key) pressed */ 842 if (!(state->ks_flags & COMPOSE)) { 843 state->ks_flags |= COMPOSE; 844 state->ks_composed_char = 0; 845 } 846 break; 847 case 0xE0: 848 case 0xE1: 849 state->ks_prefix = scancode; 850 goto next_code; 851 } 852 break; 853 case 0xE0: /* 0xE0 prefix */ 854 state->ks_prefix = 0; 855 switch (keycode) { 856 case 0x1C: /* right enter key */ 857 keycode = 0x59; 858 break; 859 case 0x1D: /* right ctrl key */ 860 keycode = 0x5A; 861 break; 862 case 0x35: /* keypad divide key */ 863 keycode = 0x5B; 864 break; 865 case 0x37: /* print scrn key */ 866 keycode = 0x5C; 867 break; 868 case 0x38: /* right alt key (alt gr) */ 869 keycode = 0x5D; 870 break; 871 case 0x46: /* ctrl-pause/break on AT 101 (see below) */ 872 keycode = 0x68; 873 break; 874 case 0x47: /* grey home key */ 875 keycode = 0x5E; 876 break; 877 case 0x48: /* grey up arrow key */ 878 keycode = 0x5F; 879 break; 880 case 0x49: /* grey page up key */ 881 keycode = 0x60; 882 break; 883 case 0x4B: /* grey left arrow key */ 884 keycode = 0x61; 885 break; 886 case 0x4D: /* grey right arrow key */ 887 keycode = 0x62; 888 break; 889 case 0x4F: /* grey end key */ 890 keycode = 0x63; 891 break; 892 case 0x50: /* grey down arrow key */ 893 keycode = 0x64; 894 break; 895 case 0x51: /* grey page down key */ 896 keycode = 0x65; 897 break; 898 case 0x52: /* grey insert key */ 899 keycode = 0x66; 900 break; 901 case 0x53: /* grey delete key */ 902 keycode = 0x67; 903 break; 904 /* the following 3 are only used on the MS "Natural" keyboard */ 905 case 0x5b: /* left Window key */ 906 keycode = 0x69; 907 break; 908 case 0x5c: /* right Window key */ 909 keycode = 0x6a; 910 break; 911 case 0x5d: /* menu key */ 912 keycode = 0x6b; 913 break; 914 case 0x5e: /* power key */ 915 keycode = 0x6d; 916 break; 917 case 0x5f: /* sleep key */ 918 keycode = 0x6e; 919 break; 920 case 0x63: /* wake key */ 921 keycode = 0x6f; 922 break; 923 default: /* ignore everything else */ 924 goto next_code; 925 } 926 break; 927 case 0xE1: /* 0xE1 prefix */ 928 /* 929 * The pause/break key on the 101 keyboard produces: 930 * E1-1D-45 E1-9D-C5 931 * Ctrl-pause/break produces: 932 * E0-46 E0-C6 (See above.) 933 */ 934 state->ks_prefix = 0; 935 if (keycode == 0x1D) 936 state->ks_prefix = 0x1D; 937 goto next_code; 938 /* NOT REACHED */ 939 case 0x1D: /* pause / break */ 940 state->ks_prefix = 0; 941 if (keycode != 0x45) 942 goto next_code; 943 keycode = 0x68; 944 break; 945 } 946 947 if (kbd->kb_type == KB_84) { 948 switch (keycode) { 949 case 0x37: /* *(numpad)/print screen */ 950 if (state->ks_flags & SHIFTS) 951 keycode = 0x5c; /* print screen */ 952 break; 953 case 0x45: /* num lock/pause */ 954 if (state->ks_flags & CTLS) 955 keycode = 0x68; /* pause */ 956 break; 957 case 0x46: /* scroll lock/break */ 958 if (state->ks_flags & CTLS) 959 keycode = 0x6c; /* break */ 960 break; 961 } 962 } else if (kbd->kb_type == KB_101) { 963 switch (keycode) { 964 case 0x5c: /* print screen */ 965 if (state->ks_flags & ALTS) 966 keycode = 0x54; /* sysrq */ 967 break; 968 case 0x68: /* pause/break */ 969 if (state->ks_flags & CTLS) 970 keycode = 0x6c; /* break */ 971 break; 972 } 973 } 974 975 /* return the key code in the K_CODE mode */ 976 if (state->ks_mode == K_CODE) { 977 VKBD_UNLOCK(state); 978 return (keycode | (scancode & 0x80)); 979 } 980 981 /* compose a character code */ 982 if (state->ks_flags & COMPOSE) { 983 switch (keycode | (scancode & 0x80)) { 984 /* key pressed, process it */ 985 case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ 986 state->ks_composed_char *= 10; 987 state->ks_composed_char += keycode - 0x40; 988 if (state->ks_composed_char > UCHAR_MAX) { 989 VKBD_UNLOCK(state); 990 return (ERRKEY); 991 } 992 goto next_code; 993 case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ 994 state->ks_composed_char *= 10; 995 state->ks_composed_char += keycode - 0x47; 996 if (state->ks_composed_char > UCHAR_MAX) { 997 VKBD_UNLOCK(state); 998 return (ERRKEY); 999 } 1000 goto next_code; 1001 case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ 1002 state->ks_composed_char *= 10; 1003 state->ks_composed_char += keycode - 0x4E; 1004 if (state->ks_composed_char > UCHAR_MAX) { 1005 VKBD_UNLOCK(state); 1006 return (ERRKEY); 1007 } 1008 goto next_code; 1009 case 0x52: /* keypad 0 */ 1010 state->ks_composed_char *= 10; 1011 if (state->ks_composed_char > UCHAR_MAX) { 1012 VKBD_UNLOCK(state); 1013 return (ERRKEY); 1014 } 1015 goto next_code; 1016 1017 /* key released, no interest here */ 1018 case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ 1019 case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ 1020 case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ 1021 case 0xD2: /* keypad 0 */ 1022 goto next_code; 1023 1024 case 0x38: /* left alt key */ 1025 break; 1026 1027 default: 1028 if (state->ks_composed_char > 0) { 1029 state->ks_flags &= ~COMPOSE; 1030 state->ks_composed_char = 0; 1031 VKBD_UNLOCK(state); 1032 return (ERRKEY); 1033 } 1034 break; 1035 } 1036 } 1037 1038 /* keycode to key action */ 1039 action = genkbd_keyaction(kbd, keycode, scancode & 0x80, 1040 &state->ks_state, &state->ks_accents); 1041 if (action == NOKEY) 1042 goto next_code; 1043 1044 VKBD_UNLOCK(state); 1045 1046 return (action); 1047 } 1048 1049 /* Check if char is waiting */ 1050 static int 1051 vkbd_check_char(keyboard_t *kbd) 1052 { 1053 vkbd_state_t *state = NULL; 1054 int ready; 1055 1056 if (!KBD_IS_ACTIVE(kbd)) 1057 return (FALSE); 1058 1059 state = (vkbd_state_t *) kbd->kb_data; 1060 1061 VKBD_LOCK(state); 1062 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) 1063 ready = TRUE; 1064 else 1065 ready = vkbd_data_ready(state); 1066 VKBD_UNLOCK(state); 1067 1068 return (ready); 1069 } 1070 1071 /* Some useful control functions (stolen from atkbd.c) */ 1072 static int 1073 vkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) 1074 { 1075 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 1076 int i; 1077 1078 VKBD_LOCK(state); 1079 1080 switch (cmd) { 1081 case KDGKBMODE: /* get keyboard mode */ 1082 *(int *)arg = state->ks_mode; 1083 break; 1084 1085 case KDSKBMODE: /* set keyboard mode */ 1086 switch (*(int *)arg) { 1087 case K_XLATE: 1088 if (state->ks_mode != K_XLATE) { 1089 /* make lock key state and LED state match */ 1090 state->ks_state &= ~LOCK_MASK; 1091 state->ks_state |= KBD_LED_VAL(kbd); 1092 vkbd_status_changed(state); 1093 } 1094 /* FALLTHROUGH */ 1095 1096 case K_RAW: 1097 case K_CODE: 1098 if (state->ks_mode != *(int *)arg) { 1099 vkbd_clear_state_locked(state); 1100 state->ks_mode = *(int *)arg; 1101 vkbd_status_changed(state); 1102 } 1103 break; 1104 1105 default: 1106 VKBD_UNLOCK(state); 1107 return (EINVAL); 1108 } 1109 break; 1110 1111 case KDGETLED: /* get keyboard LED */ 1112 *(int *)arg = KBD_LED_VAL(kbd); 1113 break; 1114 1115 case KDSETLED: /* set keyboard LED */ 1116 /* NOTE: lock key state in ks_state won't be changed */ 1117 if (*(int *)arg & ~LOCK_MASK) { 1118 VKBD_UNLOCK(state); 1119 return (EINVAL); 1120 } 1121 1122 i = *(int *)arg; 1123 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ 1124 if (state->ks_mode == K_XLATE && 1125 kbd->kb_keymap->n_keys > ALTGR_OFFSET) { 1126 if (i & ALKED) 1127 i |= CLKED; 1128 else 1129 i &= ~CLKED; 1130 } 1131 1132 KBD_LED_VAL(kbd) = *(int *)arg; 1133 vkbd_status_changed(state); 1134 break; 1135 1136 case KDGKBSTATE: /* get lock key state */ 1137 *(int *)arg = state->ks_state & LOCK_MASK; 1138 break; 1139 1140 case KDSKBSTATE: /* set lock key state */ 1141 if (*(int *)arg & ~LOCK_MASK) { 1142 VKBD_UNLOCK(state); 1143 return (EINVAL); 1144 } 1145 state->ks_state &= ~LOCK_MASK; 1146 state->ks_state |= *(int *)arg; 1147 vkbd_status_changed(state); 1148 VKBD_UNLOCK(state); 1149 /* set LEDs and quit */ 1150 return (vkbd_ioctl(kbd, KDSETLED, arg)); 1151 1152 case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ 1153 i = typematic(((int *)arg)[0], ((int *)arg)[1]); 1154 kbd->kb_delay1 = typematic_delay(i); 1155 kbd->kb_delay2 = typematic_rate(i); 1156 vkbd_status_changed(state); 1157 break; 1158 1159 case KDSETRAD: /* set keyboard repeat rate (old interface) */ 1160 kbd->kb_delay1 = typematic_delay(*(int *)arg); 1161 kbd->kb_delay2 = typematic_rate(*(int *)arg); 1162 vkbd_status_changed(state); 1163 break; 1164 1165 case PIO_KEYMAP: /* set keyboard translation table */ 1166 case PIO_KEYMAPENT: /* set keyboard translation table entry */ 1167 case PIO_DEADKEYMAP: /* set accent key translation table */ 1168 state->ks_accents = 0; 1169 /* FALLTHROUGH */ 1170 1171 default: 1172 VKBD_UNLOCK(state); 1173 return (genkbd_commonioctl(kbd, cmd, arg)); 1174 } 1175 1176 VKBD_UNLOCK(state); 1177 1178 return (0); 1179 } 1180 1181 /* Lock the access to the keyboard */ 1182 static int 1183 vkbd_lock(keyboard_t *kbd, int lock) 1184 { 1185 return (1); /* XXX */ 1186 } 1187 1188 /* Clear the internal state of the keyboard */ 1189 static void 1190 vkbd_clear_state_locked(vkbd_state_t *state) 1191 { 1192 VKBD_LOCK_ASSERT(state, MA_OWNED); 1193 1194 state->ks_flags &= ~COMPOSE; 1195 state->ks_polling = 0; 1196 state->ks_state &= LOCK_MASK; /* preserve locking key state */ 1197 state->ks_accents = 0; 1198 state->ks_composed_char = 0; 1199 /* state->ks_prefix = 0; XXX */ 1200 1201 /* flush ks_inq and wakeup writers/poll()ers */ 1202 state->ks_inq.head = state->ks_inq.tail = state->ks_inq.cc = 0; 1203 selwakeuppri(&state->ks_wsel, PZERO + 1); 1204 wakeup(&state->ks_inq); 1205 } 1206 1207 static void 1208 vkbd_clear_state(keyboard_t *kbd) 1209 { 1210 vkbd_state_t *state = (vkbd_state_t *) kbd->kb_data; 1211 1212 VKBD_LOCK(state); 1213 vkbd_clear_state_locked(state); 1214 VKBD_UNLOCK(state); 1215 } 1216 1217 /* Save the internal state */ 1218 static int 1219 vkbd_get_state(keyboard_t *kbd, void *buf, size_t len) 1220 { 1221 if (len == 0) 1222 return (sizeof(vkbd_state_t)); 1223 if (len < sizeof(vkbd_state_t)) 1224 return (-1); 1225 bcopy(kbd->kb_data, buf, sizeof(vkbd_state_t)); /* XXX locking? */ 1226 return (0); 1227 } 1228 1229 /* Set the internal state */ 1230 static int 1231 vkbd_set_state(keyboard_t *kbd, void *buf, size_t len) 1232 { 1233 if (len < sizeof(vkbd_state_t)) 1234 return (ENOMEM); 1235 bcopy(buf, kbd->kb_data, sizeof(vkbd_state_t)); /* XXX locking? */ 1236 return (0); 1237 } 1238 1239 /* Set polling */ 1240 static int 1241 vkbd_poll(keyboard_t *kbd, int on) 1242 { 1243 vkbd_state_t *state = NULL; 1244 1245 state = (vkbd_state_t *) kbd->kb_data; 1246 1247 VKBD_LOCK(state); 1248 1249 if (on) 1250 state->ks_polling ++; 1251 else 1252 state->ks_polling --; 1253 1254 VKBD_UNLOCK(state); 1255 1256 return (0); 1257 } 1258 1259 /* 1260 * Local functions 1261 */ 1262 1263 static int delays[] = { 250, 500, 750, 1000 }; 1264 static int rates[] = { 34, 38, 42, 46, 50, 55, 59, 63, 1265 68, 76, 84, 92, 100, 110, 118, 126, 1266 136, 152, 168, 184, 200, 220, 236, 252, 1267 272, 304, 336, 368, 400, 440, 472, 504 }; 1268 1269 static int 1270 typematic_delay(int i) 1271 { 1272 return (delays[(i >> 5) & 3]); 1273 } 1274 1275 static int 1276 typematic_rate(int i) 1277 { 1278 return (rates[i & 0x1f]); 1279 } 1280 1281 static int 1282 typematic(int delay, int rate) 1283 { 1284 int value; 1285 int i; 1286 1287 for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --) { 1288 if (delay >= delays[i]) 1289 break; 1290 } 1291 value = i << 5; 1292 for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --) { 1293 if (rate >= rates[i]) 1294 break; 1295 } 1296 value |= i; 1297 return (value); 1298 } 1299 1300 /***************************************************************************** 1301 ***************************************************************************** 1302 ** Module 1303 ***************************************************************************** 1304 *****************************************************************************/ 1305 1306 KEYBOARD_DRIVER(vkbd, vkbdsw, vkbd_configure); 1307 1308 static int 1309 vkbd_modevent(module_t mod, int type, void *data) 1310 { 1311 static eventhandler_tag tag; 1312 1313 switch (type) { 1314 case MOD_LOAD: 1315 clone_setup(&vkbd_dev_clones); 1316 tag = EVENTHANDLER_REGISTER(dev_clone, vkbd_dev_clone, 0, 1000); 1317 if (tag == NULL) { 1318 clone_cleanup(&vkbd_dev_clones); 1319 return (ENOMEM); 1320 } 1321 kbd_add_driver(&vkbd_kbd_driver); 1322 break; 1323 1324 case MOD_UNLOAD: 1325 kbd_delete_driver(&vkbd_kbd_driver); 1326 EVENTHANDLER_DEREGISTER(dev_clone, tag); 1327 clone_cleanup(&vkbd_dev_clones); 1328 break; 1329 1330 default: 1331 return (EOPNOTSUPP); 1332 } 1333 1334 return (0); 1335 } 1336 1337 DEV_MODULE(vkbd, vkbd_modevent, NULL); 1338 1339