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