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