1 /*- 2 * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org> 3 * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 * $FreeBSD$ 28 */ 29 30 #include "opt_evdev.h" 31 32 #include <sys/types.h> 33 #include <sys/module.h> 34 #include <sys/devfs.h> 35 36 #include <sys/param.h> 37 #include <sys/caps.h> 38 #include <sys/conf.h> 39 #include <sys/filio.h> 40 #include <sys/fcntl.h> 41 #include <sys/kernel.h> 42 #include <sys/malloc.h> 43 #include <sys/poll.h> 44 #include <sys/proc.h> 45 #include <sys/systm.h> 46 #include <sys/time.h> 47 #include <sys/vnode.h> /* IO_NDELAY in read() */ 48 #include <sys/uio.h> 49 50 #include <sys/errno.h> 51 52 #include <sys/device.h> 53 #include <sys/bus.h> 54 55 /* Use FreeBSD bitstring locally. */ 56 #include "freebsd-bitstring.h" 57 58 #include <dev/misc/evdev/evdev.h> 59 #include <dev/misc/evdev/evdev_private.h> 60 #include <dev/misc/evdev/input.h> 61 62 #ifdef EVDEV_DEBUG 63 #define debugf(client, fmt, args...) kprintf("evdev cdev: "fmt"\n", ##args) 64 #else 65 #define debugf(client, fmt, args...) 66 #endif 67 68 #define DEF_RING_REPORTS 8 69 70 static d_open_t evdev_open; 71 static d_read_t evdev_read; 72 static d_write_t evdev_write; 73 static d_ioctl_t evdev_ioctl; 74 static d_kqfilter_t evdev_kqfilter; 75 static d_priv_dtor_t evdev_dtor; 76 77 static int evdev_kqread(struct knote *kn, long hint); 78 static void evdev_kqdetach(struct knote *kn); 79 static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t); 80 static void evdev_client_filter_queue(struct evdev_client *, uint16_t); 81 82 static struct dev_ops evdev_cdevsw = { 83 { "evdev", 0, 0 }, 84 .d_open = evdev_open, 85 .d_read = evdev_read, 86 .d_write = evdev_write, 87 .d_ioctl = evdev_ioctl, 88 .d_kqfilter = evdev_kqfilter, 89 }; 90 91 static struct filterops evdev_cdev_filterops = { 92 .f_flags = FILTEROP_ISFD, 93 .f_attach = NULL, 94 .f_detach = evdev_kqdetach, 95 .f_event = evdev_kqread, 96 }; 97 98 static int 99 evdev_open(struct dev_open_args *ap) 100 { 101 cdev_t dev = ap->a_head.a_dev; 102 struct evdev_dev *evdev = dev->si_drv1; 103 struct evdev_client *client; 104 size_t buffer_size; 105 int ret; 106 107 /* 108 * Disallow access to disk volumes if RESTRICTEDROOT 109 */ 110 if (caps_priv_check_self(SYSCAP_RESTRICTEDROOT)) 111 return (EPERM); 112 113 if (evdev == NULL) 114 return (ENODEV); 115 116 /* Initialize client structure */ 117 buffer_size = evdev->ev_report_size * DEF_RING_REPORTS; 118 client = kmalloc(offsetof(struct evdev_client, ec_buffer) + 119 sizeof(struct input_event) * buffer_size, 120 M_EVDEV, M_WAITOK | M_ZERO); 121 122 /* Initialize ring buffer */ 123 client->ec_buffer_size = buffer_size; 124 client->ec_buffer_head = 0; 125 client->ec_buffer_tail = 0; 126 client->ec_buffer_ready = 0; 127 128 client->ec_evdev = evdev; 129 lockinit(&client->ec_buffer_mtx, "evclient", 0, LK_CANRECURSE); 130 131 /* Avoid race with evdev_unregister */ 132 EVDEV_LOCK(evdev); 133 if (dev->si_drv1 == NULL) 134 ret = ENODEV; 135 else 136 ret = evdev_register_client(evdev, client); 137 138 if (ret != 0) 139 evdev_revoke_client(client); 140 /* 141 * Unlock evdev here because non-sleepable lock held 142 * while calling devfs_set_cdevpriv upsets WITNESS 143 */ 144 EVDEV_UNLOCK(evdev); 145 146 if (ret == 0) { 147 struct file *fp; 148 149 fp = (ap->a_fpp) ? *ap->a_fpp : NULL; 150 ret = devfs_set_cdevpriv(fp, client, &evdev_dtor); 151 } 152 153 if (ret != 0) { 154 debugf(client, "cannot register evdev client"); 155 } 156 157 return (ret); 158 } 159 160 static void 161 evdev_dtor(void *data) 162 { 163 struct evdev_client *client = (struct evdev_client *)data; 164 165 EVDEV_LOCK(client->ec_evdev); 166 if (!client->ec_revoked) 167 evdev_dispose_client(client->ec_evdev, client); 168 EVDEV_UNLOCK(client->ec_evdev); 169 170 funsetown(&client->ec_sigio); 171 lockuninit(&client->ec_buffer_mtx); 172 kfree(client, M_EVDEV); 173 } 174 175 static int 176 evdev_read(struct dev_read_args *ap) 177 { 178 struct uio *uio = ap->a_uio; 179 int ioflag = ap->a_ioflag; 180 struct evdev_client *client; 181 struct input_event event; 182 int ret = 0; 183 int remaining; 184 185 ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client); 186 if (ret != 0) 187 return (ret); 188 189 debugf(client, "read %zd bytes by thread %d", uio->uio_resid, 0); 190 191 if (client->ec_revoked) 192 return (ENODEV); 193 194 /* Zero-sized reads are allowed for error checking */ 195 if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event)) 196 return (EINVAL); 197 198 remaining = uio->uio_resid / sizeof(struct input_event); 199 200 EVDEV_CLIENT_LOCKQ(client); 201 202 if (EVDEV_CLIENT_EMPTYQ(client)) { 203 if (ioflag & IO_NDELAY) { 204 ret = EWOULDBLOCK; 205 } else { 206 if (remaining != 0) { 207 client->ec_blocked = true; 208 ret = lksleep(client, &client->ec_buffer_mtx, 209 PCATCH, "evread", 0); 210 if (ret == 0 && client->ec_revoked) 211 ret = ENODEV; 212 } 213 } 214 } 215 216 while (ret == 0 && !EVDEV_CLIENT_EMPTYQ(client) && remaining > 0) { 217 memcpy(&event, &client->ec_buffer[client->ec_buffer_head], 218 sizeof(struct input_event)); 219 client->ec_buffer_head = 220 (client->ec_buffer_head + 1) % client->ec_buffer_size; 221 remaining--; 222 223 EVDEV_CLIENT_UNLOCKQ(client); 224 ret = uiomove((void *)&event, sizeof(struct input_event), uio); 225 EVDEV_CLIENT_LOCKQ(client); 226 } 227 228 EVDEV_CLIENT_UNLOCKQ(client); 229 230 return (ret); 231 } 232 233 static int 234 evdev_write(struct dev_write_args *ap) 235 { 236 cdev_t dev = ap->a_head.a_dev; 237 struct uio *uio = ap->a_uio; 238 struct evdev_dev *evdev = dev->si_drv1; 239 struct evdev_client *client; 240 struct input_event event; 241 int ret = 0; 242 243 ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client); 244 if (ret != 0) 245 return (ret); 246 247 debugf(client, "write %zd bytes by thread %d", uio->uio_resid, 0); 248 249 if (client->ec_revoked || evdev == NULL) 250 return (ENODEV); 251 252 if (uio->uio_resid % sizeof(struct input_event) != 0) { 253 debugf(client, "write size not multiple of input_event size"); 254 return (EINVAL); 255 } 256 257 while (uio->uio_resid > 0 && ret == 0) { 258 ret = uiomove((void *)&event, sizeof(struct input_event), uio); 259 if (ret == 0) 260 ret = evdev_inject_event(evdev, event.type, event.code, 261 event.value); 262 } 263 264 return (ret); 265 } 266 267 static int 268 evdev_kqfilter(struct dev_kqfilter_args *ap) 269 { 270 struct knote *kn = ap->a_kn; 271 struct klist *klist; 272 struct evdev_client *client; 273 int ret; 274 275 ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client); 276 if (ret != 0) 277 return (ret); 278 279 if (client->ec_revoked) 280 return (ENODEV); 281 282 switch(kn->kn_filter) { 283 case EVFILT_READ: 284 kn->kn_fop = &evdev_cdev_filterops; 285 break; 286 default: 287 return(EINVAL); 288 } 289 kn->kn_hook = (caddr_t)client; 290 291 klist = &client->kqinfo.ki_note; 292 knote_insert(klist, kn); 293 return (0); 294 } 295 296 static int 297 evdev_kqread(struct knote *kn, long hint) 298 { 299 struct evdev_client *client; 300 int ret; 301 int locked = 0; 302 303 client = (struct evdev_client *)kn->kn_hook; 304 305 /* NOTE on DragonFly v FreeBSD. 306 * FreeBSD locks the klist when calling f_event, i.e. evdev_kqread(). 307 * That's why the plain assertion EVDEV_CLIENT_LOCKQ_ASSERT(client) 308 * fails on DragonFly: DragonFly does not ensure the lock associated 309 * with the klist is locked. 310 * To mimic FreeBSD's behavior, we will lock ec_buffer_mtx if 311 * it was not locked, and unlock when leaving. 312 */ 313 locked = lockowned(&(client)->ec_buffer_mtx); 314 if (!locked) 315 EVDEV_CLIENT_LOCKQ(client); 316 317 EVDEV_CLIENT_LOCKQ_ASSERT(client); 318 319 if (client->ec_revoked) { 320 kn->kn_flags |= EV_EOF; 321 ret = 1; 322 } else { 323 kn->kn_data = EVDEV_CLIENT_SIZEQ(client) * 324 sizeof(struct input_event); 325 ret = !EVDEV_CLIENT_EMPTYQ(client); 326 } 327 328 /* Unlock if ec_buffer_mtx was not locked. */ 329 if (!locked) { 330 EVDEV_CLIENT_UNLOCKQ(client); 331 } 332 333 return (ret); 334 } 335 336 static void 337 evdev_kqdetach(struct knote *kn) 338 { 339 struct evdev_client *client; 340 341 client = (struct evdev_client *)kn->kn_hook; 342 knote_remove(&client->kqinfo.ki_note, kn); 343 } 344 345 static int 346 evdev_ioctl(struct dev_ioctl_args *ap) 347 { 348 cdev_t dev = ap->a_head.a_dev; 349 u_long cmd = ap->a_cmd; 350 caddr_t data = ap->a_data; 351 struct evdev_dev *evdev = dev->si_drv1; 352 struct evdev_client *client; 353 struct input_keymap_entry *ke; 354 int ret, len, limit, type_num; 355 uint32_t code; 356 size_t nvalues; 357 358 ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client); 359 if (ret != 0) 360 return (ret); 361 362 if (client->ec_revoked || evdev == NULL) 363 return (ENODEV); 364 365 /* file I/O ioctl handling */ 366 switch (cmd) { 367 case FIOSETOWN: 368 return (fsetown(*(int *)data, &client->ec_sigio)); 369 370 case FIOGETOWN: 371 *(int *)data = fgetown(&client->ec_sigio); 372 return (0); 373 374 case FIONBIO: 375 return (0); 376 377 case FIOASYNC: 378 if (*(int *)data) 379 client->ec_async = true; 380 else 381 client->ec_async = false; 382 383 return (0); 384 385 case FIONREAD: 386 EVDEV_CLIENT_LOCKQ(client); 387 *(int *)data = 388 EVDEV_CLIENT_SIZEQ(client) * sizeof(struct input_event); 389 EVDEV_CLIENT_UNLOCKQ(client); 390 return (0); 391 } 392 393 len = IOCPARM_LEN(cmd); 394 debugf(client, "ioctl called: cmd=0x%08lx, data=%p", cmd, data); 395 396 /* evdev fixed-length ioctls handling */ 397 switch (cmd) { 398 case EVIOCGVERSION: 399 *(int *)data = EV_VERSION; 400 return (0); 401 402 case EVIOCGID: 403 debugf(client, "EVIOCGID: bus=%d vendor=0x%04x product=0x%04x", 404 evdev->ev_id.bustype, evdev->ev_id.vendor, 405 evdev->ev_id.product); 406 memcpy(data, &evdev->ev_id, sizeof(struct input_id)); 407 return (0); 408 409 case EVIOCGREP: 410 if (!evdev_event_supported(evdev, EV_REP)) 411 return (ENOTSUP); 412 413 memcpy(data, evdev->ev_rep, sizeof(evdev->ev_rep)); 414 return (0); 415 416 case EVIOCSREP: 417 if (!evdev_event_supported(evdev, EV_REP)) 418 return (ENOTSUP); 419 420 evdev_inject_event(evdev, EV_REP, REP_DELAY, ((int *)data)[0]); 421 evdev_inject_event(evdev, EV_REP, REP_PERIOD, 422 ((int *)data)[1]); 423 return (0); 424 425 case EVIOCGKEYCODE: 426 /* Fake unsupported ioctl */ 427 return (0); 428 429 case EVIOCGKEYCODE_V2: 430 if (evdev->ev_methods == NULL || 431 evdev->ev_methods->ev_get_keycode == NULL) 432 return (ENOTSUP); 433 434 ke = (struct input_keymap_entry *)data; 435 evdev->ev_methods->ev_get_keycode(evdev, ke); 436 return (0); 437 438 case EVIOCSKEYCODE: 439 /* Fake unsupported ioctl */ 440 return (0); 441 442 case EVIOCSKEYCODE_V2: 443 if (evdev->ev_methods == NULL || 444 evdev->ev_methods->ev_set_keycode == NULL) 445 return (ENOTSUP); 446 447 ke = (struct input_keymap_entry *)data; 448 evdev->ev_methods->ev_set_keycode(evdev, ke); 449 return (0); 450 451 case EVIOCGABS(0) ... EVIOCGABS(ABS_MAX): 452 if (evdev->ev_absinfo == NULL) 453 return (EINVAL); 454 455 memcpy(data, &evdev->ev_absinfo[cmd - EVIOCGABS(0)], 456 sizeof(struct input_absinfo)); 457 return (0); 458 459 case EVIOCSABS(0) ... EVIOCSABS(ABS_MAX): 460 if (evdev->ev_absinfo == NULL) 461 return (EINVAL); 462 463 code = cmd - EVIOCSABS(0); 464 /* mt-slot number can not be changed */ 465 if (code == ABS_MT_SLOT) 466 return (EINVAL); 467 468 EVDEV_LOCK(evdev); 469 evdev_set_absinfo(evdev, code, (struct input_absinfo *)data); 470 EVDEV_UNLOCK(evdev); 471 return (0); 472 473 case EVIOCSFF: 474 case EVIOCRMFF: 475 case EVIOCGEFFECTS: 476 /* Fake unsupported ioctls */ 477 return (0); 478 479 case EVIOCGRAB: 480 EVDEV_LOCK(evdev); 481 if (*(int *)data) 482 ret = evdev_grab_client(evdev, client); 483 else 484 ret = evdev_release_client(evdev, client); 485 EVDEV_UNLOCK(evdev); 486 return (ret); 487 488 case EVIOCREVOKE: 489 if (*(int *)data != 0) 490 return (EINVAL); 491 492 EVDEV_LOCK(evdev); 493 if (dev->si_drv1 != NULL && !client->ec_revoked) { 494 evdev_dispose_client(evdev, client); 495 evdev_revoke_client(client); 496 } 497 EVDEV_UNLOCK(evdev); 498 return (0); 499 500 case EVIOCSCLOCKID: 501 switch (*(int *)data) { 502 case CLOCK_REALTIME: 503 client->ec_clock_id = EV_CLOCK_REALTIME; 504 return (0); 505 case CLOCK_MONOTONIC: 506 client->ec_clock_id = EV_CLOCK_MONOTONIC; 507 return (0); 508 default: 509 return (EINVAL); 510 } 511 } 512 513 /* evdev variable-length ioctls handling */ 514 switch (IOCBASECMD(cmd)) { 515 case EVIOCGNAME(0): 516 strlcpy(data, evdev->ev_name, len); 517 return (0); 518 519 case EVIOCGPHYS(0): 520 if (evdev->ev_shortname[0] == 0) 521 return (ENOENT); 522 523 strlcpy(data, evdev->ev_shortname, len); 524 return (0); 525 526 case EVIOCGUNIQ(0): 527 if (evdev->ev_serial[0] == 0) 528 return (ENOENT); 529 530 strlcpy(data, evdev->ev_serial, len); 531 return (0); 532 533 case EVIOCGPROP(0): 534 limit = MIN(len, bitstr_size(INPUT_PROP_CNT)); 535 memcpy(data, evdev->ev_prop_flags, limit); 536 return (0); 537 538 case EVIOCGMTSLOTS(0): 539 if (evdev->ev_mt == NULL) 540 return (EINVAL); 541 if (len < sizeof(uint32_t)) 542 return (EINVAL); 543 code = *(uint32_t *)data; 544 if (!ABS_IS_MT(code)) 545 return (EINVAL); 546 547 nvalues = 548 MIN(len / sizeof(int32_t) - 1, MAXIMAL_MT_SLOT(evdev) + 1); 549 for (int i = 0; i < nvalues; i++) 550 ((int32_t *)data)[i + 1] = 551 evdev_mt_get_value(evdev, i, code); 552 return (0); 553 554 case EVIOCGKEY(0): 555 limit = MIN(len, bitstr_size(KEY_CNT)); 556 EVDEV_LOCK(evdev); 557 evdev_client_filter_queue(client, EV_KEY); 558 memcpy(data, evdev->ev_key_states, limit); 559 EVDEV_UNLOCK(evdev); 560 return (0); 561 562 case EVIOCGLED(0): 563 limit = MIN(len, bitstr_size(LED_CNT)); 564 EVDEV_LOCK(evdev); 565 evdev_client_filter_queue(client, EV_LED); 566 memcpy(data, evdev->ev_led_states, limit); 567 EVDEV_UNLOCK(evdev); 568 return (0); 569 570 case EVIOCGSND(0): 571 limit = MIN(len, bitstr_size(SND_CNT)); 572 EVDEV_LOCK(evdev); 573 evdev_client_filter_queue(client, EV_SND); 574 memcpy(data, evdev->ev_snd_states, limit); 575 EVDEV_UNLOCK(evdev); 576 return (0); 577 578 case EVIOCGSW(0): 579 limit = MIN(len, bitstr_size(SW_CNT)); 580 EVDEV_LOCK(evdev); 581 evdev_client_filter_queue(client, EV_SW); 582 memcpy(data, evdev->ev_sw_states, limit); 583 EVDEV_UNLOCK(evdev); 584 return (0); 585 586 case EVIOCGBIT(0, 0) ... EVIOCGBIT(EV_MAX, 0): 587 type_num = IOCBASECMD(cmd) - EVIOCGBIT(0, 0); 588 debugf(client, "EVIOCGBIT(%d): data=%p, len=%d", type_num, 589 data, len); 590 return (evdev_ioctl_eviocgbit(evdev, type_num, len, data)); 591 } 592 593 return (EINVAL); 594 } 595 596 static int 597 evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data) 598 { 599 /* 600 * We will use freebsd-bitstring.h locally. This ensures bitmap 601 * is of type (unsigned long *). DragonFly's original bitmap 602 * is (unsigned char *). 603 */ 604 unsigned long *bitmap; 605 int limit; 606 607 switch (type) { 608 case 0: 609 bitmap = evdev->ev_type_flags; 610 limit = EV_CNT; 611 break; 612 case EV_KEY: 613 bitmap = evdev->ev_key_flags; 614 limit = KEY_CNT; 615 break; 616 case EV_REL: 617 bitmap = evdev->ev_rel_flags; 618 limit = REL_CNT; 619 break; 620 case EV_ABS: 621 bitmap = evdev->ev_abs_flags; 622 limit = ABS_CNT; 623 break; 624 case EV_MSC: 625 bitmap = evdev->ev_msc_flags; 626 limit = MSC_CNT; 627 break; 628 case EV_LED: 629 bitmap = evdev->ev_led_flags; 630 limit = LED_CNT; 631 break; 632 case EV_SND: 633 bitmap = evdev->ev_snd_flags; 634 limit = SND_CNT; 635 break; 636 case EV_SW: 637 bitmap = evdev->ev_sw_flags; 638 limit = SW_CNT; 639 break; 640 case EV_FF: 641 /* 642 * We don't support EV_FF now, so let's 643 * just fake it returning only zeros. 644 */ 645 bzero(data, len); 646 return (0); 647 default: 648 return (ENOTTY); 649 } 650 651 /* 652 * Clear ioctl data buffer in case it's bigger than 653 * bitmap size 654 */ 655 bzero(data, len); 656 657 limit = bitstr_size(limit); 658 len = MIN(limit, len); 659 memcpy(data, bitmap, len); 660 return (0); 661 } 662 663 void 664 evdev_revoke_client(struct evdev_client *client) 665 { 666 667 EVDEV_LOCK_ASSERT(client->ec_evdev); 668 669 client->ec_revoked = true; 670 } 671 672 void 673 evdev_notify_event(struct evdev_client *client) 674 { 675 676 EVDEV_CLIENT_LOCKQ_ASSERT(client); 677 678 if (client->ec_blocked) { 679 client->ec_blocked = false; 680 wakeup(client); 681 } 682 if (client->ec_selected) { 683 client->ec_selected = false; 684 wakeup(&client->kqinfo); 685 } 686 687 KNOTE(&client->kqinfo.ki_note, 0); 688 689 if (client->ec_async && client->ec_sigio != NULL) 690 pgsigio(client->ec_sigio, SIGIO, 0); 691 } 692 693 int 694 evdev_cdev_create(struct evdev_dev *evdev) 695 { 696 cdev_t dev; 697 int ret, unit; 698 699 /* 700 * Iterate over devices input/eventX until we find a non-existing 701 * one and record its number in unit. 702 */ 703 unit = 0; 704 while (devfs_find_device_by_name("input/event%d", unit) != NULL) { 705 unit++; 706 } 707 708 /* 709 * Put unit as minor. Minor and major will determine st_rdev of 710 * eventX. Ensuring that all eventX have different major and minor 711 * will make st_rdev unique. This is needed by libinput, which 712 * determines eventX from st_rdev. 713 */ 714 dev = make_dev(&evdev_cdevsw, unit, UID_ROOT, GID_WHEEL, 0600, 715 "input/event%d", unit); 716 717 if (dev != NULL) { 718 dev->si_drv1 = evdev; 719 evdev->ev_cdev = dev; 720 evdev->ev_unit = unit; 721 ret = 0; 722 } else { 723 ret = ENODEV; 724 goto err; 725 } 726 727 reference_dev(evdev->ev_cdev); 728 729 err: 730 return (ret); 731 } 732 733 int 734 evdev_cdev_destroy(struct evdev_dev *evdev) 735 { 736 737 if (evdev->ev_cdev) { 738 dev_ops_remove_minor(&evdev_cdevsw, evdev->ev_unit); 739 } 740 741 return (0); 742 } 743 744 static void 745 evdev_client_gettime(struct evdev_client *client, struct timeval *tv) 746 { 747 748 switch (client->ec_clock_id) { 749 case EV_CLOCK_BOOTTIME: 750 /* 751 * XXX: FreeBSD does not support true POSIX monotonic clock. 752 * So aliase EV_CLOCK_BOOTTIME to EV_CLOCK_MONOTONIC. 753 */ 754 case EV_CLOCK_MONOTONIC: 755 microuptime(tv); 756 break; 757 758 case EV_CLOCK_REALTIME: 759 default: 760 microtime(tv); 761 break; 762 } 763 } 764 765 void 766 evdev_client_push(struct evdev_client *client, uint16_t type, uint16_t code, 767 int32_t value) 768 { 769 struct timeval time; 770 size_t count, head, tail, ready; 771 772 EVDEV_CLIENT_LOCKQ_ASSERT(client); 773 head = client->ec_buffer_head; 774 tail = client->ec_buffer_tail; 775 ready = client->ec_buffer_ready; 776 count = client->ec_buffer_size; 777 778 /* If queue is full drop its content and place SYN_DROPPED event */ 779 if ((tail + 1) % count == head) { 780 debugf(client, "client %p: buffer overflow", client); 781 782 head = (tail + count - 1) % count; 783 client->ec_buffer[head] = (struct input_event) { 784 .type = EV_SYN, 785 .code = SYN_DROPPED, 786 .value = 0 787 }; 788 /* 789 * XXX: Here is a small race window from now till the end of 790 * report. The queue is empty but client has been already 791 * notified of data readyness. Can be fixed in two ways: 792 * 1. Implement bulk insert so queue lock would not be dropped 793 * till the SYN_REPORT event. 794 * 2. Insert SYN_REPORT just now and skip remaining events 795 */ 796 client->ec_buffer_head = head; 797 client->ec_buffer_ready = head; 798 } 799 800 client->ec_buffer[tail].type = type; 801 client->ec_buffer[tail].code = code; 802 client->ec_buffer[tail].value = value; 803 client->ec_buffer_tail = (tail + 1) % count; 804 805 /* Allow users to read events only after report has been completed */ 806 if (type == EV_SYN && code == SYN_REPORT) { 807 evdev_client_gettime(client, &time); 808 for (; ready != client->ec_buffer_tail; 809 ready = (ready + 1) % count) 810 client->ec_buffer[ready].time = time; 811 client->ec_buffer_ready = client->ec_buffer_tail; 812 } 813 } 814 815 void 816 evdev_client_dumpqueue(struct evdev_client *client) 817 { 818 struct input_event *event; 819 size_t i, head, tail, ready, size; 820 821 head = client->ec_buffer_head; 822 tail = client->ec_buffer_tail; 823 ready = client->ec_buffer_ready; 824 size = client->ec_buffer_size; 825 826 kprintf("evdev client: %p\n", client); 827 kprintf("event queue: head=%zu ready=%zu tail=%zu size=%zu\n", 828 head, ready, tail, size); 829 830 kprintf("queue contents:\n"); 831 832 for (i = 0; i < size; i++) { 833 event = &client->ec_buffer[i]; 834 kprintf("%zu: ", i); 835 836 if (i < head || i > tail) 837 kprintf("unused\n"); 838 else 839 kprintf("type=%d code=%d value=%d ", event->type, 840 event->code, event->value); 841 842 if (i == head) 843 kprintf("<- head\n"); 844 else if (i == tail) 845 kprintf("<- tail\n"); 846 else if (i == ready) 847 kprintf("<- ready\n"); 848 else 849 kprintf("\n"); 850 } 851 } 852 853 static void 854 evdev_client_filter_queue(struct evdev_client *client, uint16_t type) 855 { 856 struct input_event *event; 857 size_t head, tail, count, i; 858 bool last_was_syn = false; 859 860 EVDEV_CLIENT_LOCKQ(client); 861 862 i = head = client->ec_buffer_head; 863 tail = client->ec_buffer_tail; 864 count = client->ec_buffer_size; 865 client->ec_buffer_ready = client->ec_buffer_tail; 866 867 while (i != client->ec_buffer_tail) { 868 event = &client->ec_buffer[i]; 869 i = (i + 1) % count; 870 871 /* Skip event of given type */ 872 if (event->type == type) 873 continue; 874 875 /* Remove empty SYN_REPORT events */ 876 if (event->type == EV_SYN && event->code == SYN_REPORT) { 877 if (last_was_syn) 878 continue; 879 else 880 client->ec_buffer_ready = (tail + 1) % count; 881 } 882 883 /* Rewrite entry */ 884 memcpy(&client->ec_buffer[tail], event, 885 sizeof(struct input_event)); 886 887 last_was_syn = (event->type == EV_SYN && 888 event->code == SYN_REPORT); 889 890 tail = (tail + 1) % count; 891 } 892 893 client->ec_buffer_head = i; 894 client->ec_buffer_tail = tail; 895 896 EVDEV_CLIENT_UNLOCKQ(client); 897 } 898