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