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