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