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