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