2 * Copyright (c) 2014 Jakub Wojciech Klama <jceel@FreeBSD.org>
3 * Copyright (c) 2015-2016 Vladimir Kondratyev <wulf@cicgroup.ru>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
30 #include "opt_evdev.h"
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>
41 #include <sys/filio.h>
42 #include <sys/fcntl.h>
43 #include <sys/selinfo.h>
44 #include <sys/malloc.h>
47 #include <dev/evdev/input.h>
48 #include <dev/evdev/evdev.h>
49 #include <dev/evdev/evdev_private.h>
52 #define debugf(client, fmt, args...) printf("evdev cdev: "fmt"\n", ##args)
54 #define debugf(client, fmt, args...)
57 #define DEF_RING_REPORTS 8
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;
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);
72 static struct cdevsw evdev_cdevsw = {
73 .d_version = D_VERSION,
76 .d_write = evdev_write,
77 .d_ioctl = evdev_ioctl,
79 .d_kqfilter = evdev_kqfilter,
83 static struct filterops evdev_cdev_filterops = {
86 .f_detach = evdev_kqdetach,
87 .f_event = evdev_kqread,
91 evdev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
93 struct evdev_dev *evdev = dev->si_drv1;
94 struct evdev_client *client;
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);
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;
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);
117 /* Avoid race with evdev_unregister */
119 if (dev->si_drv1 == NULL)
122 ret = evdev_register_client(evdev, client);
125 evdev_revoke_client(client);
127 * Unlock evdev here because non-sleepable lock held
128 * while calling devfs_set_cdevpriv upsets WITNESS
133 ret = devfs_set_cdevpriv(client, evdev_dtor);
136 debugf(client, "cannot register evdev client");
144 evdev_dtor(void *data)
146 struct evdev_client *client = (struct evdev_client *)data;
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);
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);
162 evdev_read(struct cdev *dev, struct uio *uio, int ioflag)
164 struct evdev_client *client;
165 struct input_event event;
169 ret = devfs_get_cdevpriv((void **)&client);
173 debugf(client, "read %zd bytes by thread %d", uio->uio_resid,
174 uio->uio_td->td_tid);
176 if (client->ec_revoked)
179 /* Zero-sized reads are allowed for error checking */
180 if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event))
183 remaining = uio->uio_resid / sizeof(struct input_event);
185 EVDEV_CLIENT_LOCKQ(client);
187 if (EVDEV_CLIENT_EMPTYQ(client)) {
188 if (ioflag & O_NONBLOCK)
191 if (remaining != 0) {
192 client->ec_blocked = true;
193 ret = mtx_sleep(client, &client->ec_buffer_mtx,
194 PCATCH, "evread", 0);
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;
206 EVDEV_CLIENT_UNLOCKQ(client);
207 ret = uiomove(&event, sizeof(struct input_event), uio);
208 EVDEV_CLIENT_LOCKQ(client);
211 EVDEV_CLIENT_UNLOCKQ(client);
217 evdev_write(struct cdev *dev, struct uio *uio, int ioflag)
219 struct evdev_dev *evdev = dev->si_drv1;
220 struct evdev_client *client;
221 struct input_event event;
224 ret = devfs_get_cdevpriv((void **)&client);
228 debugf(client, "write %zd bytes by thread %d", uio->uio_resid,
229 uio->uio_td->td_tid);
231 if (client->ec_revoked || evdev == NULL)
234 if (uio->uio_resid % sizeof(struct input_event) != 0) {
235 debugf(client, "write size not multiple of input_event size");
239 while (uio->uio_resid > 0 && ret == 0) {
240 ret = uiomove(&event, sizeof(struct input_event), uio);
242 ret = evdev_inject_event(evdev, event.type, event.code,
250 evdev_poll(struct cdev *dev, int events, struct thread *td)
252 struct evdev_client *client;
256 ret = devfs_get_cdevpriv((void **)&client);
260 debugf(client, "poll by thread %d", td->td_tid);
262 if (client->ec_revoked)
265 if (events & (POLLIN | POLLRDNORM)) {
266 EVDEV_CLIENT_LOCKQ(client);
267 if (!EVDEV_CLIENT_EMPTYQ(client))
268 revents = events & (POLLIN | POLLRDNORM);
270 client->ec_selected = true;
271 selrecord(td, &client->ec_selp);
273 EVDEV_CLIENT_UNLOCKQ(client);
280 evdev_kqfilter(struct cdev *dev, struct knote *kn)
282 struct evdev_client *client;
285 ret = devfs_get_cdevpriv((void **)&client);
289 if (client->ec_revoked)
292 switch(kn->kn_filter) {
294 kn->kn_fop = &evdev_cdev_filterops;
299 kn->kn_hook = (caddr_t)client;
301 knlist_add(&client->ec_selp.si_note, kn, 0);
306 evdev_kqread(struct knote *kn, long hint)
308 struct evdev_client *client;
311 client = (struct evdev_client *)kn->kn_hook;
313 EVDEV_CLIENT_LOCKQ_ASSERT(client);
315 if (client->ec_revoked) {
316 kn->kn_flags |= EV_EOF;
319 kn->kn_data = EVDEV_CLIENT_SIZEQ(client) *
320 sizeof(struct input_event);
321 ret = !EVDEV_CLIENT_EMPTYQ(client);
327 evdev_kqdetach(struct knote *kn)
329 struct evdev_client *client;
331 client = (struct evdev_client *)kn->kn_hook;
332 knlist_remove(&client->ec_selp.si_note, kn, 0);
336 evdev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
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;
346 ret = devfs_get_cdevpriv((void **)&client);
350 if (client->ec_revoked || evdev == NULL)
353 /* file I/O ioctl handling */
356 return (fsetown(*(int *)data, &client->ec_sigio));
359 *(int *)data = fgetown(&client->ec_sigio);
367 client->ec_async = true;
369 client->ec_async = false;
374 EVDEV_CLIENT_LOCKQ(client);
376 EVDEV_CLIENT_SIZEQ(client) * sizeof(struct input_event);
377 EVDEV_CLIENT_UNLOCKQ(client);
381 len = IOCPARM_LEN(cmd);
382 debugf(client, "ioctl called: cmd=0x%08lx, data=%p", cmd, data);
384 /* evdev fixed-length ioctls handling */
387 *(int *)data = EV_VERSION;
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));
398 if (!evdev_event_supported(evdev, EV_REP))
401 memcpy(data, evdev->ev_rep, sizeof(evdev->ev_rep));
405 if (!evdev_event_supported(evdev, EV_REP))
408 evdev_inject_event(evdev, EV_REP, REP_DELAY, ((int *)data)[0]);
409 evdev_inject_event(evdev, EV_REP, REP_PERIOD,
414 /* Fake unsupported ioctl */
417 case EVIOCGKEYCODE_V2:
418 if (evdev->ev_methods == NULL ||
419 evdev->ev_methods->ev_get_keycode == NULL)
422 ke = (struct input_keymap_entry *)data;
423 evdev->ev_methods->ev_get_keycode(evdev, evdev->ev_softc, ke);
427 /* Fake unsupported ioctl */
430 case EVIOCSKEYCODE_V2:
431 if (evdev->ev_methods == NULL ||
432 evdev->ev_methods->ev_set_keycode == NULL)
435 ke = (struct input_keymap_entry *)data;
436 evdev->ev_methods->ev_set_keycode(evdev, evdev->ev_softc, ke);
439 case EVIOCGABS(0) ... EVIOCGABS(ABS_MAX):
440 if (evdev->ev_absinfo == NULL)
443 memcpy(data, &evdev->ev_absinfo[cmd - EVIOCGABS(0)],
444 sizeof(struct input_absinfo));
447 case EVIOCSABS(0) ... EVIOCSABS(ABS_MAX):
448 if (evdev->ev_absinfo == NULL)
451 code = cmd - EVIOCSABS(0);
452 /* mt-slot number can not be changed */
453 if (code == ABS_MT_SLOT)
457 evdev_set_absinfo(evdev, code, (struct input_absinfo *)data);
464 /* Fake unsupported ioctls */
470 ret = evdev_grab_client(evdev, client);
472 ret = evdev_release_client(evdev, client);
477 if (*(int *)data != 0)
481 if (dev->si_drv1 != NULL && !client->ec_revoked) {
482 evdev_dispose_client(evdev, client);
483 evdev_revoke_client(client);
489 switch (*(int *)data) {
491 client->ec_clock_id = EV_CLOCK_REALTIME;
493 case CLOCK_MONOTONIC:
494 client->ec_clock_id = EV_CLOCK_MONOTONIC;
501 /* evdev variable-length ioctls handling */
502 switch (IOCBASECMD(cmd)) {
504 strlcpy(data, evdev->ev_name, len);
508 if (evdev->ev_shortname[0] == 0)
511 strlcpy(data, evdev->ev_shortname, len);
515 if (evdev->ev_serial[0] == 0)
518 strlcpy(data, evdev->ev_serial, len);
522 limit = MIN(len, bitstr_size(INPUT_PROP_CNT));
523 memcpy(data, evdev->ev_prop_flags, limit);
526 case EVIOCGMTSLOTS(0):
527 if (evdev->ev_mt == NULL)
529 if (len < sizeof(uint32_t))
531 code = *(uint32_t *)data;
532 if (!ABS_IS_MT(code))
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);
543 limit = MIN(len, bitstr_size(KEY_CNT));
545 evdev_client_filter_queue(client, EV_KEY);
546 memcpy(data, evdev->ev_key_states, limit);
551 limit = MIN(len, bitstr_size(LED_CNT));
553 evdev_client_filter_queue(client, EV_LED);
554 memcpy(data, evdev->ev_led_states, limit);
559 limit = MIN(len, bitstr_size(SND_CNT));
561 evdev_client_filter_queue(client, EV_SND);
562 memcpy(data, evdev->ev_snd_states, limit);
567 limit = MIN(len, bitstr_size(SW_CNT));
569 evdev_client_filter_queue(client, EV_SW);
570 memcpy(data, evdev->ev_sw_states, limit);
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,
578 return (evdev_ioctl_eviocgbit(evdev, type_num, len, data));
585 evdev_ioctl_eviocgbit(struct evdev_dev *evdev, int type, int len, caddr_t data)
587 unsigned long *bitmap;
592 bitmap = evdev->ev_type_flags;
596 bitmap = evdev->ev_key_flags;
600 bitmap = evdev->ev_rel_flags;
604 bitmap = evdev->ev_abs_flags;
608 bitmap = evdev->ev_msc_flags;
612 bitmap = evdev->ev_led_flags;
616 bitmap = evdev->ev_snd_flags;
620 bitmap = evdev->ev_sw_flags;
625 * We don't support EV_FF now, so let's
626 * just fake it returning only zeros.
635 * Clear ioctl data buffer in case it's bigger than
640 limit = bitstr_size(limit);
641 len = MIN(limit, len);
642 memcpy(data, bitmap, len);
647 evdev_revoke_client(struct evdev_client *client)
650 EVDEV_LOCK_ASSERT(client->ec_evdev);
652 client->ec_revoked = true;
656 evdev_notify_event(struct evdev_client *client)
659 EVDEV_CLIENT_LOCKQ_ASSERT(client);
661 if (client->ec_blocked) {
662 client->ec_blocked = false;
665 if (client->ec_selected) {
666 client->ec_selected = false;
667 selwakeup(&client->ec_selp);
669 KNOTE_LOCKED(&client->ec_selp.si_note, 0);
671 if (client->ec_async && client->ec_sigio != NULL)
672 pgsigio(&client->ec_sigio, SIGIO, 0);
676 evdev_cdev_create(struct evdev_dev *evdev)
678 struct make_dev_args mda;
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;
687 mda.mda_si_drv1 = evdev;
689 /* Try to coexist with cuse-backed input/event devices */
690 while ((ret = make_dev_s(&mda, &evdev->ev_cdev, "input/event%d", unit))
695 evdev->ev_unit = unit;
701 evdev_cdev_destroy(struct evdev_dev *evdev)
704 destroy_dev(evdev->ev_cdev);
709 evdev_client_gettime(struct evdev_client *client, struct timeval *tv)
712 switch (client->ec_clock_id) {
713 case EV_CLOCK_BOOTTIME:
715 * XXX: FreeBSD does not support true POSIX monotonic clock.
716 * So aliase EV_CLOCK_BOOTTIME to EV_CLOCK_MONOTONIC.
718 case EV_CLOCK_MONOTONIC:
722 case EV_CLOCK_REALTIME:
730 evdev_client_push(struct evdev_client *client, uint16_t type, uint16_t code,
734 size_t count, head, tail, ready;
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;
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);
746 head = (tail + count - 1) % count;
747 client->ec_buffer[head] = (struct input_event) {
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
760 client->ec_buffer_head = head;
761 client->ec_buffer_ready = head;
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;
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;
780 evdev_client_dumpqueue(struct evdev_client *client)
782 struct input_event *event;
783 size_t i, head, tail, ready, size;
785 head = client->ec_buffer_head;
786 tail = client->ec_buffer_tail;
787 ready = client->ec_buffer_ready;
788 size = client->ec_buffer_size;
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);
794 printf("queue contents:\n");
796 for (i = 0; i < size; i++) {
797 event = &client->ec_buffer[i];
800 if (i < head || i > tail)
803 printf("type=%d code=%d value=%d ", event->type,
804 event->code, event->value);
811 printf("<- ready\n");
818 evdev_client_filter_queue(struct evdev_client *client, uint16_t type)
820 struct input_event *event;
821 size_t head, tail, count, i;
822 bool last_was_syn = false;
824 EVDEV_CLIENT_LOCKQ(client);
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;
831 while (i != client->ec_buffer_tail) {
832 event = &client->ec_buffer[i];
835 /* Skip event of given type */
836 if (event->type == type)
839 /* Remove empty SYN_REPORT events */
840 if (event->type == EV_SYN && event->code == SYN_REPORT) {
844 client->ec_buffer_ready = (tail + 1) % count;
848 memcpy(&client->ec_buffer[tail], event,
849 sizeof(struct input_event));
851 last_was_syn = (event->type == EV_SYN &&
852 event->code == SYN_REPORT);
854 tail = (tail + 1) % count;
857 client->ec_buffer_head = i;
858 client->ec_buffer_tail = tail;
860 EVDEV_CLIENT_UNLOCKQ(client);