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 EVDEV_DEBUG
51 #define debugf(client, fmt, args...) printf("evdev cdev: "fmt"\n", ##args)
52 #else
53 #define debugf(client, fmt, args...)
54 #endif
55
56 #define DEF_RING_REPORTS 8
57
58 static d_open_t evdev_open;
59 static d_read_t evdev_read;
60 static d_write_t evdev_write;
61 static d_ioctl_t evdev_ioctl;
62 static d_poll_t evdev_poll;
63 static d_kqfilter_t evdev_kqfilter;
64
65 static int evdev_kqread(struct knote *kn, long hint);
66 static void evdev_kqdetach(struct knote *kn);
67 static void evdev_dtor(void *);
68 static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t);
69 static void evdev_client_filter_queue(struct evdev_client *, uint16_t);
70
71 static struct cdevsw evdev_cdevsw = {
72 .d_version = D_VERSION,
73 .d_open = evdev_open,
74 .d_read = evdev_read,
75 .d_write = evdev_write,
76 .d_ioctl = evdev_ioctl,
77 .d_poll = evdev_poll,
78 .d_kqfilter = evdev_kqfilter,
79 .d_name = "evdev",
80 };
81
82 static struct filterops evdev_cdev_filterops = {
83 .f_isfd = 1,
84 .f_attach = NULL,
85 .f_detach = evdev_kqdetach,
86 .f_event = evdev_kqread,
87 };
88
89 static int
evdev_open(struct cdev * dev,int oflags,int devtype,struct thread * td)90 evdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
91 {
92 struct evdev_dev *evdev = dev->si_drv1;
93 struct evdev_client *client;
94 size_t buffer_size;
95 int ret;
96
97 if (evdev == NULL)
98 return (ENODEV);
99
100 /* Initialize client structure */
101 buffer_size = evdev->ev_report_size * DEF_RING_REPORTS;
102 client = malloc(offsetof(struct evdev_client, ec_buffer) +
103 sizeof(struct input_event) * buffer_size,
104 M_EVDEV, M_WAITOK | M_ZERO);
105
106 /* Initialize ring buffer */
107 client->ec_buffer_size = buffer_size;
108 client->ec_buffer_head = 0;
109 client->ec_buffer_tail = 0;
110 client->ec_buffer_ready = 0;
111
112 client->ec_evdev = evdev;
113 mtx_init(&client->ec_buffer_mtx, "evclient", "evdev", MTX_DEF);
114 knlist_init_mtx(&client->ec_selp.si_note, &client->ec_buffer_mtx);
115
116 /* Avoid race with evdev_unregister */
117 EVDEV_LOCK(evdev);
118 if (dev->si_drv1 == NULL)
119 ret = ENODEV;
120 else
121 ret = evdev_register_client(evdev, client);
122
123 if (ret != 0)
124 evdev_revoke_client(client);
125 /*
126 * Unlock evdev here because non-sleepable lock held
127 * while calling devfs_set_cdevpriv upsets WITNESS
128 */
129 EVDEV_UNLOCK(evdev);
130
131 if (!ret)
132 ret = devfs_set_cdevpriv(client, evdev_dtor);
133
134 if (ret != 0) {
135 debugf(client, "cannot register evdev client");
136 evdev_dtor(client);
137 }
138
139 return (ret);
140 }
141
142 static void
evdev_dtor(void * data)143 evdev_dtor(void *data)
144 {
145 struct evdev_client *client = (struct evdev_client *)data;
146
147 EVDEV_LOCK(client->ec_evdev);
148 if (!client->ec_revoked)
149 evdev_dispose_client(client->ec_evdev, client);
150 EVDEV_UNLOCK(client->ec_evdev);
151
152 knlist_clear(&client->ec_selp.si_note, 0);
153 seldrain(&client->ec_selp);
154 knlist_destroy(&client->ec_selp.si_note);
155 funsetown(&client->ec_sigio);
156 mtx_destroy(&client->ec_buffer_mtx);
157 free(client, M_EVDEV);
158 }
159
160 static int
evdev_read(struct cdev * dev,struct uio * uio,int ioflag)161 evdev_read(struct cdev *dev, struct uio *uio, int ioflag)
162 {
163 struct evdev_client *client;
164 struct input_event event;
165 int ret = 0;
166 int remaining;
167
168 ret = devfs_get_cdevpriv((void **)&client);
169 if (ret != 0)
170 return (ret);
171
172 debugf(client, "read %zd bytes by thread %d", uio->uio_resid,
173 uio->uio_td->td_tid);
174
175 if (client->ec_revoked)
176 return (ENODEV);
177
178 /* Zero-sized reads are allowed for error checking */
179 if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event))
180 return (EINVAL);
181
182 remaining = uio->uio_resid / sizeof(struct input_event);
183
184 EVDEV_CLIENT_LOCKQ(client);
185
186 if (EVDEV_CLIENT_EMPTYQ(client)) {
187 if (ioflag & O_NONBLOCK)
188 ret = EWOULDBLOCK;
189 else {
190 if (remaining != 0) {
191 client->ec_blocked = true;
192 ret = mtx_sleep(client, &client->ec_buffer_mtx,
193 PCATCH, "evread", 0);
194 }
195 }
196 }
197
198 while (ret == 0 && !EVDEV_CLIENT_EMPTYQ(client) && remaining > 0) {
199 memcpy(&event, &client->ec_buffer[client->ec_buffer_head],
200 sizeof(struct input_event));
201 client->ec_buffer_head =
202 (client->ec_buffer_head + 1) % client->ec_buffer_size;
203 remaining--;
204
205 EVDEV_CLIENT_UNLOCKQ(client);
206 ret = uiomove(&event, sizeof(struct input_event), uio);
207 EVDEV_CLIENT_LOCKQ(client);
208 }
209
210 EVDEV_CLIENT_UNLOCKQ(client);
211
212 return (ret);
213 }
214
215 static int
evdev_write(struct cdev * dev,struct uio * uio,int ioflag)216 evdev_write(struct cdev *dev, struct uio *uio, int ioflag)
217 {
218 struct evdev_dev *evdev = dev->si_drv1;
219 struct evdev_client *client;
220 struct input_event event;
221 int ret = 0;
222
223 ret = devfs_get_cdevpriv((void **)&client);
224 if (ret != 0)
225 return (ret);
226
227 debugf(client, "write %zd bytes by thread %d", uio->uio_resid,
228 uio->uio_td->td_tid);
229
230 if (client->ec_revoked || evdev == NULL)
231 return (ENODEV);
232
233 if (uio->uio_resid % sizeof(struct input_event) != 0) {
234 debugf(client, "write size not multiple of input_event size");
235 return (EINVAL);
236 }
237
238 while (uio->uio_resid > 0 && ret == 0) {
239 ret = uiomove(&event, sizeof(struct input_event), uio);
240 if (ret == 0)
241 ret = evdev_inject_event(evdev, event.type, event.code,
242 event.value);
243 }
244
245 return (ret);
246 }
247
248 static int
evdev_poll(struct cdev * dev,int events,struct thread * td)249 evdev_poll(struct cdev *dev, int events, struct thread *td)
250 {
251 struct evdev_client *client;
252 int ret;
253 int revents = 0;
254
255 ret = devfs_get_cdevpriv((void **)&client);
256 if (ret != 0)
257 return (POLLNVAL);
258
259 debugf(client, "poll by thread %d", td->td_tid);
260
261 if (client->ec_revoked)
262 return (POLLHUP);
263
264 if (events & (POLLIN | POLLRDNORM)) {
265 EVDEV_CLIENT_LOCKQ(client);
266 if (!EVDEV_CLIENT_EMPTYQ(client))
267 revents = events & (POLLIN | POLLRDNORM);
268 else {
269 client->ec_selected = true;
270 selrecord(td, &client->ec_selp);
271 }
272 EVDEV_CLIENT_UNLOCKQ(client);
273 }
274
275 return (revents);
276 }
277
278 static int
evdev_kqfilter(struct cdev * dev,struct knote * kn)279 evdev_kqfilter(struct cdev *dev, struct knote *kn)
280 {
281 struct evdev_client *client;
282 int ret;
283
284 ret = devfs_get_cdevpriv((void **)&client);
285 if (ret != 0)
286 return (ret);
287
288 if (client->ec_revoked)
289 return (ENODEV);
290
291 switch(kn->kn_filter) {
292 case EVFILT_READ:
293 kn->kn_fop = &evdev_cdev_filterops;
294 break;
295 default:
296 return(EINVAL);
297 }
298 kn->kn_hook = (caddr_t)client;
299
300 knlist_add(&client->ec_selp.si_note, kn, 0);
301 return (0);
302 }
303
304 static int
evdev_kqread(struct knote * kn,long hint)305 evdev_kqread(struct knote *kn, long hint)
306 {
307 struct evdev_client *client;
308 int ret;
309
310 client = (struct evdev_client *)kn->kn_hook;
311
312 EVDEV_CLIENT_LOCKQ_ASSERT(client);
313
314 if (client->ec_revoked) {
315 kn->kn_flags |= EV_EOF;
316 ret = 1;
317 } else {
318 kn->kn_data = EVDEV_CLIENT_SIZEQ(client) *
319 sizeof(struct input_event);
320 ret = !EVDEV_CLIENT_EMPTYQ(client);
321 }
322 return (ret);
323 }
324
325 static void
evdev_kqdetach(struct knote * kn)326 evdev_kqdetach(struct knote *kn)
327 {
328 struct evdev_client *client;
329
330 client = (struct evdev_client *)kn->kn_hook;
331 knlist_remove(&client->ec_selp.si_note, kn, 0);
332 }
333
334 static int
evdev_ioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)335 evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
336 struct thread *td)
337 {
338 struct evdev_dev *evdev = dev->si_drv1;
339 struct evdev_client *client;
340 struct input_keymap_entry *ke;
341 int ret, len, limit, type_num;
342 uint32_t code;
343 size_t nvalues;
344
345 ret = devfs_get_cdevpriv((void **)&client);
346 if (ret != 0)
347 return (ret);
348
349 if (client->ec_revoked || evdev == NULL)
350 return (ENODEV);
351
352 /*
353 * Fix evdev state corrupted with discarding of kdb events.
354 * EVIOCGKEY and EVIOCGLED ioctls can suffer from this.
355 */
356 if (evdev->ev_kdb_active) {
357 EVDEV_LOCK(evdev);
358 if (evdev->ev_kdb_active) {
359 evdev->ev_kdb_active = false;
360 evdev_restore_after_kdb(evdev);
361 }
362 EVDEV_UNLOCK(evdev);
363 }
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_get_mt_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
evdev_ioctl_eviocgbit(struct evdev_dev * evdev,int type,int len,caddr_t data)597 evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data)
598 {
599 unsigned long *bitmap;
600 int limit;
601
602 switch (type) {
603 case 0:
604 bitmap = evdev->ev_type_flags;
605 limit = EV_CNT;
606 break;
607 case EV_KEY:
608 bitmap = evdev->ev_key_flags;
609 limit = KEY_CNT;
610 break;
611 case EV_REL:
612 bitmap = evdev->ev_rel_flags;
613 limit = REL_CNT;
614 break;
615 case EV_ABS:
616 bitmap = evdev->ev_abs_flags;
617 limit = ABS_CNT;
618 break;
619 case EV_MSC:
620 bitmap = evdev->ev_msc_flags;
621 limit = MSC_CNT;
622 break;
623 case EV_LED:
624 bitmap = evdev->ev_led_flags;
625 limit = LED_CNT;
626 break;
627 case EV_SND:
628 bitmap = evdev->ev_snd_flags;
629 limit = SND_CNT;
630 break;
631 case EV_SW:
632 bitmap = evdev->ev_sw_flags;
633 limit = SW_CNT;
634 break;
635 case EV_FF:
636 /*
637 * We don't support EV_FF now, so let's
638 * just fake it returning only zeros.
639 */
640 bzero(data, len);
641 return (0);
642 default:
643 return (ENOTTY);
644 }
645
646 /*
647 * Clear ioctl data buffer in case it's bigger than
648 * bitmap size
649 */
650 bzero(data, len);
651
652 limit = bitstr_size(limit);
653 len = MIN(limit, len);
654 memcpy(data, bitmap, len);
655 return (0);
656 }
657
658 void
evdev_revoke_client(struct evdev_client * client)659 evdev_revoke_client(struct evdev_client *client)
660 {
661
662 EVDEV_LOCK_ASSERT(client->ec_evdev);
663
664 client->ec_revoked = true;
665 }
666
667 void
evdev_notify_event(struct evdev_client * client)668 evdev_notify_event(struct evdev_client *client)
669 {
670
671 EVDEV_CLIENT_LOCKQ_ASSERT(client);
672
673 if (client->ec_blocked) {
674 client->ec_blocked = false;
675 wakeup(client);
676 }
677 if (client->ec_selected) {
678 client->ec_selected = false;
679 selwakeup(&client->ec_selp);
680 }
681 KNOTE_LOCKED(&client->ec_selp.si_note, 0);
682
683 if (client->ec_async && client->ec_sigio != NULL)
684 pgsigio(&client->ec_sigio, SIGIO, 0);
685 }
686
687 int
evdev_cdev_create(struct evdev_dev * evdev)688 evdev_cdev_create(struct evdev_dev *evdev)
689 {
690 struct make_dev_args mda;
691 int ret, unit = 0;
692
693 make_dev_args_init(&mda);
694 mda.mda_flags = MAKEDEV_WAITOK | MAKEDEV_CHECKNAME;
695 mda.mda_devsw = &evdev_cdevsw;
696 mda.mda_uid = UID_ROOT;
697 mda.mda_gid = GID_WHEEL;
698 mda.mda_mode = 0600;
699 mda.mda_si_drv1 = evdev;
700
701 /* Try to coexist with cuse-backed input/event devices */
702 while ((ret = make_dev_s(&mda, &evdev->ev_cdev, "input/event%d", unit))
703 == EEXIST)
704 unit++;
705
706 if (ret == 0)
707 evdev->ev_unit = unit;
708
709 return (ret);
710 }
711
712 int
evdev_cdev_destroy(struct evdev_dev * evdev)713 evdev_cdev_destroy(struct evdev_dev *evdev)
714 {
715
716 destroy_dev(evdev->ev_cdev);
717 return (0);
718 }
719
720 static void
evdev_client_gettime(struct evdev_client * client,struct timeval * tv)721 evdev_client_gettime(struct evdev_client *client, struct timeval *tv)
722 {
723
724 switch (client->ec_clock_id) {
725 case EV_CLOCK_BOOTTIME:
726 /*
727 * XXX: FreeBSD does not support true POSIX monotonic clock.
728 * So aliase EV_CLOCK_BOOTTIME to EV_CLOCK_MONOTONIC.
729 */
730 case EV_CLOCK_MONOTONIC:
731 microuptime(tv);
732 break;
733
734 case EV_CLOCK_REALTIME:
735 default:
736 microtime(tv);
737 break;
738 }
739 }
740
741 void
evdev_client_push(struct evdev_client * client,uint16_t type,uint16_t code,int32_t value)742 evdev_client_push(struct evdev_client *client, uint16_t type, uint16_t code,
743 int32_t value)
744 {
745 struct timeval time;
746 size_t count, head, tail, ready;
747
748 EVDEV_CLIENT_LOCKQ_ASSERT(client);
749 head = client->ec_buffer_head;
750 tail = client->ec_buffer_tail;
751 ready = client->ec_buffer_ready;
752 count = client->ec_buffer_size;
753
754 /* If queue is full drop its content and place SYN_DROPPED event */
755 if ((tail + 1) % count == head) {
756 debugf(client, "client %p: buffer overflow", client);
757
758 head = (tail + count - 1) % count;
759 client->ec_buffer[head] = (struct input_event) {
760 .type = EV_SYN,
761 .code = SYN_DROPPED,
762 .value = 0
763 };
764 /*
765 * XXX: Here is a small race window from now till the end of
766 * report. The queue is empty but client has been already
767 * notified of data readyness. Can be fixed in two ways:
768 * 1. Implement bulk insert so queue lock would not be dropped
769 * till the SYN_REPORT event.
770 * 2. Insert SYN_REPORT just now and skip remaining events
771 */
772 client->ec_buffer_head = head;
773 client->ec_buffer_ready = head;
774 }
775
776 client->ec_buffer[tail].type = type;
777 client->ec_buffer[tail].code = code;
778 client->ec_buffer[tail].value = value;
779 client->ec_buffer_tail = (tail + 1) % count;
780
781 /* Allow users to read events only after report has been completed */
782 if (type == EV_SYN && code == SYN_REPORT) {
783 evdev_client_gettime(client, &time);
784 for (; ready != client->ec_buffer_tail;
785 ready = (ready + 1) % count)
786 client->ec_buffer[ready].time = time;
787 client->ec_buffer_ready = client->ec_buffer_tail;
788 }
789 }
790
791 void
evdev_client_dumpqueue(struct evdev_client * client)792 evdev_client_dumpqueue(struct evdev_client *client)
793 {
794 struct input_event *event;
795 size_t i, head, tail, ready, size;
796
797 head = client->ec_buffer_head;
798 tail = client->ec_buffer_tail;
799 ready = client->ec_buffer_ready;
800 size = client->ec_buffer_size;
801
802 printf("evdev client: %p\n", client);
803 printf("event queue: head=%zu ready=%zu tail=%zu size=%zu\n",
804 head, ready, tail, size);
805
806 printf("queue contents:\n");
807
808 for (i = 0; i < size; i++) {
809 event = &client->ec_buffer[i];
810 printf("%zu: ", i);
811
812 if (i < head || i > tail)
813 printf("unused\n");
814 else
815 printf("type=%d code=%d value=%d ", event->type,
816 event->code, event->value);
817
818 if (i == head)
819 printf("<- head\n");
820 else if (i == tail)
821 printf("<- tail\n");
822 else if (i == ready)
823 printf("<- ready\n");
824 else
825 printf("\n");
826 }
827 }
828
829 static void
evdev_client_filter_queue(struct evdev_client * client,uint16_t type)830 evdev_client_filter_queue(struct evdev_client *client, uint16_t type)
831 {
832 struct input_event *event;
833 size_t head, tail, count, i;
834 bool last_was_syn = false;
835
836 EVDEV_CLIENT_LOCKQ(client);
837
838 i = head = client->ec_buffer_head;
839 tail = client->ec_buffer_tail;
840 count = client->ec_buffer_size;
841 client->ec_buffer_ready = client->ec_buffer_tail;
842
843 while (i != client->ec_buffer_tail) {
844 event = &client->ec_buffer[i];
845 i = (i + 1) % count;
846
847 /* Skip event of given type */
848 if (event->type == type)
849 continue;
850
851 /* Remove empty SYN_REPORT events */
852 if (event->type == EV_SYN && event->code == SYN_REPORT) {
853 if (last_was_syn)
854 continue;
855 else
856 client->ec_buffer_ready = (tail + 1) % count;
857 }
858
859 /* Rewrite entry */
860 memcpy(&client->ec_buffer[tail], event,
861 sizeof(struct input_event));
862
863 last_was_syn = (event->type == EV_SYN &&
864 event->code == SYN_REPORT);
865
866 tail = (tail + 1) % count;
867 }
868
869 client->ec_buffer_head = i;
870 client->ec_buffer_tail = tail;
871
872 EVDEV_CLIENT_UNLOCKQ(client);
873 }
874