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