1190d69f6429c25df54da670919590f73f264677
[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 #define GID_INPUT               107     /* input group */
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_kqfilter_t     evdev_kqfilter;
75
76 static int evdev_kqread(struct knote *kn, long hint);
77 static void evdev_kqdetach(struct knote *kn);
78 static void evdev_dtor(void *);
79 static int evdev_ioctl_eviocgbit(struct evdev_dev *, int, int, caddr_t);
80 static void evdev_client_filter_queue(struct evdev_client *, uint16_t);
81
82 static struct dev_ops evdev_cdevsw = {
83         { "evdev", 0, 0 },
84         .d_open = evdev_open,
85         .d_read = evdev_read,
86         .d_write = evdev_write,
87         .d_ioctl = evdev_ioctl,
88         .d_kqfilter = evdev_kqfilter,
89 };
90
91 static struct filterops evdev_cdev_filterops = {
92         .f_flags = FILTEROP_ISFD,
93         .f_attach = NULL,
94         .f_detach = evdev_kqdetach,
95         .f_event = evdev_kqread,
96 };
97
98 static int
99 evdev_open(struct dev_open_args *ap)
100 {
101         cdev_t dev = ap->a_head.a_dev;
102         struct evdev_dev *evdev = dev->si_drv1;
103         struct evdev_client *client;
104         size_t buffer_size;
105         int ret;
106
107         if (evdev == NULL)
108                 return (ENODEV);
109
110         /* Initialize client structure */
111         buffer_size = evdev->ev_report_size * DEF_RING_REPORTS;
112         client = kmalloc(offsetof(struct evdev_client, ec_buffer) +
113             sizeof(struct input_event) * buffer_size,
114             M_EVDEV, M_WAITOK | M_ZERO);
115
116         /* Initialize ring buffer */
117         client->ec_buffer_size = buffer_size;
118         client->ec_buffer_head = 0;
119         client->ec_buffer_tail = 0;
120         client->ec_buffer_ready = 0;
121
122         client->ec_evdev = evdev;
123         lockinit(&client->ec_buffer_mtx, "evclient", 0, LK_CANRECURSE);
124
125         /* Avoid race with evdev_unregister */
126         EVDEV_LOCK(evdev);
127         if (dev->si_drv1 == NULL)
128                 ret = ENODEV;
129         else
130                 ret = evdev_register_client(evdev, client);
131
132         if (ret != 0)
133                 evdev_revoke_client(client);
134         /*
135          * Unlock evdev here because non-sleepable lock held
136          * while calling devfs_set_cdevpriv upsets WITNESS
137          */
138         EVDEV_UNLOCK(evdev);
139
140         if (!ret)
141                 ret = devfs_set_cdevpriv(ap->a_fp, client, &evdev_dtor);
142
143         if (ret != 0) {
144                 debugf(client, "cannot register evdev client");
145         }
146
147         return (ret);
148 }
149
150 static void
151 evdev_dtor(void *data)
152 {
153         struct evdev_client *client = (struct evdev_client *)data;
154
155         EVDEV_LOCK(client->ec_evdev);
156         if (!client->ec_revoked)
157                 evdev_dispose_client(client->ec_evdev, client);
158         EVDEV_UNLOCK(client->ec_evdev);
159
160         funsetown(&client->ec_sigio);
161         lockuninit(&client->ec_buffer_mtx);
162         kfree(client, M_EVDEV);
163 }
164
165 static int
166 evdev_read(struct dev_read_args *ap)
167 {
168         struct uio *uio = ap->a_uio;
169         int ioflag = ap->a_ioflag;
170         struct evdev_client *client;
171         struct input_event event;
172         int ret = 0;
173         int remaining;
174
175         ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client);
176         if (ret != 0)
177                 return (ret);
178
179         debugf(client, "read %zd bytes by thread %d", uio->uio_resid, 0);
180
181         if (client->ec_revoked)
182                 return (ENODEV);
183
184         /* Zero-sized reads are allowed for error checking */
185         if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event))
186                 return (EINVAL);
187
188         remaining = uio->uio_resid / sizeof(struct input_event);
189
190         EVDEV_CLIENT_LOCKQ(client);
191
192         if (EVDEV_CLIENT_EMPTYQ(client)) {
193                 if (ioflag & IO_NDELAY) {
194                         ret = EWOULDBLOCK;
195                 } else {
196                         if (remaining != 0) {
197                                 client->ec_blocked = true;
198                                 ret = lksleep(client, &client->ec_buffer_mtx,
199                                     PCATCH, "evread", 0);
200                         }
201                 }
202         }
203
204         while (ret == 0 && !EVDEV_CLIENT_EMPTYQ(client) && remaining > 0) {
205                 memcpy(&event, &client->ec_buffer[client->ec_buffer_head],
206                     sizeof(struct input_event));
207                 client->ec_buffer_head =
208                     (client->ec_buffer_head + 1) % client->ec_buffer_size;
209                 remaining--;
210
211                 EVDEV_CLIENT_UNLOCKQ(client);
212                 ret = uiomove((void *)&event, sizeof(struct input_event), uio);
213                 EVDEV_CLIENT_LOCKQ(client);
214         }
215
216         EVDEV_CLIENT_UNLOCKQ(client);
217
218         return (ret);
219 }
220
221 static int
222 evdev_write(struct dev_write_args *ap)
223 {
224         cdev_t dev = ap->a_head.a_dev;
225         struct uio *uio = ap->a_uio;
226         struct evdev_dev *evdev = dev->si_drv1;
227         struct evdev_client *client;
228         struct input_event event;
229         int ret = 0;
230
231         ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client);
232         if (ret != 0)
233                 return (ret);
234
235         debugf(client, "write %zd bytes by thread %d", uio->uio_resid, 0);
236
237         if (client->ec_revoked || evdev == NULL)
238                 return (ENODEV);
239
240         if (uio->uio_resid % sizeof(struct input_event) != 0) {
241                 debugf(client, "write size not multiple of input_event size");
242                 return (EINVAL);
243         }
244
245         while (uio->uio_resid > 0 && ret == 0) {
246                 ret = uiomove((void *)&event, sizeof(struct input_event), uio);
247                 if (ret == 0)
248                         ret = evdev_inject_event(evdev, event.type, event.code,
249                             event.value);
250         }
251
252         return (ret);
253 }
254
255 static int
256 evdev_kqfilter(struct dev_kqfilter_args *ap)
257 {
258         struct knote *kn = ap->a_kn;
259         struct klist *klist;
260         struct evdev_client *client;
261         int ret;
262
263         ret = devfs_get_cdevpriv(ap->a_fp, (void **)&client);
264         if (ret != 0)
265                 return (ret);
266
267         if (client->ec_revoked)
268                 return (ENODEV);
269
270         switch(kn->kn_filter) {
271         case EVFILT_READ:
272                 kn->kn_fop = &evdev_cdev_filterops;
273                 break;
274         default:
275                 return(EINVAL);
276         }
277         kn->kn_hook = (caddr_t)client;
278
279         klist = &client->kqinfo.ki_note;
280         knote_insert(klist, kn);
281         return (0);
282 }
283
284 static int
285 evdev_kqread(struct knote *kn, long hint)
286 {
287         struct evdev_client *client;
288         int ret;
289         int locked = 0;
290
291         client = (struct evdev_client *)kn->kn_hook;
292
293         /* NOTE on DragonFly v FreeBSD.
294          * FreeBSD locks the klist when calling f_event, i.e. evdev_kqread().
295          * That's why the plain assertion EVDEV_CLIENT_LOCKQ_ASSERT(client)
296          * fails on DragonFly: DragonFly does not ensure the lock associated
297          * with the klist is locked.
298          * To mimic FreeBSD's behavior, we will lock ec_buffer_mtx if
299          * it was not locked, and unlock when leaving.
300          */
301         locked = lockowned(&(client)->ec_buffer_mtx);
302         if (!locked)
303                 EVDEV_CLIENT_LOCKQ(client);
304
305         EVDEV_CLIENT_LOCKQ_ASSERT(client);
306
307         if (client->ec_revoked) {
308                 kn->kn_flags |= EV_EOF;
309                 ret = 1;
310         } else {
311                 kn->kn_data = EVDEV_CLIENT_SIZEQ(client) *
312                     sizeof(struct input_event);
313                 ret = !EVDEV_CLIENT_EMPTYQ(client);
314         }
315
316         /* Unlock if ec_buffer_mtx was not locked. */
317         if (!locked) {
318                 EVDEV_CLIENT_UNLOCKQ(client);
319         }
320
321         return (ret);
322 }
323
324 static void
325 evdev_kqdetach(struct knote *kn)
326 {
327         struct evdev_client *client;
328
329         client = (struct evdev_client *)kn->kn_hook;
330         knote_remove(&client->kqinfo.ki_note, kn);
331 }
332
333 static int
334 evdev_ioctl(struct dev_ioctl_args *ap)
335 {
336         cdev_t dev = ap->a_head.a_dev;
337         u_long cmd = ap->a_cmd;
338         caddr_t data = ap->a_data;
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(ap->a_fp, (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         /*
588          * We will use freebsd-bitstring.h locally. This ensures bitmap
589          * is of type (unsigned long *). DragonFly's original bitmap
590          * is (unsigned char *).
591          */
592         unsigned long *bitmap;
593         int limit;
594
595         switch (type) {
596         case 0:
597                 bitmap = evdev->ev_type_flags;
598                 limit = EV_CNT;
599                 break;
600         case EV_KEY:
601                 bitmap = evdev->ev_key_flags;
602                 limit = KEY_CNT;
603                 break;
604         case EV_REL:
605                 bitmap = evdev->ev_rel_flags;
606                 limit = REL_CNT;
607                 break;
608         case EV_ABS:
609                 bitmap = evdev->ev_abs_flags;
610                 limit = ABS_CNT;
611                 break;
612         case EV_MSC:
613                 bitmap = evdev->ev_msc_flags;
614                 limit = MSC_CNT;
615                 break;
616         case EV_LED:
617                 bitmap = evdev->ev_led_flags;
618                 limit = LED_CNT;
619                 break;
620         case EV_SND:
621                 bitmap = evdev->ev_snd_flags;
622                 limit = SND_CNT;
623                 break;
624         case EV_SW:
625                 bitmap = evdev->ev_sw_flags;
626                 limit = SW_CNT;
627                 break;
628         case EV_FF:
629                 /*
630                  * We don't support EV_FF now, so let's
631                  * just fake it returning only zeros.
632                  */
633                 bzero(data, len);
634                 return (0);
635         default:
636                 return (ENOTTY);
637         }
638
639         /*
640          * Clear ioctl data buffer in case it's bigger than
641          * bitmap size
642          */
643         bzero(data, len);
644
645         limit = bitstr_size(limit);
646         len = MIN(limit, len);
647         memcpy(data, bitmap, len);
648         return (0);
649 }
650
651 void
652 evdev_revoke_client(struct evdev_client *client)
653 {
654
655         EVDEV_LOCK_ASSERT(client->ec_evdev);
656
657         client->ec_revoked = true;
658 }
659
660 void
661 evdev_notify_event(struct evdev_client *client)
662 {
663
664         EVDEV_CLIENT_LOCKQ_ASSERT(client);
665
666         if (client->ec_blocked) {
667                 client->ec_blocked = false;
668                 wakeup(client);
669         }
670         if (client->ec_selected) {
671                 client->ec_selected = false;
672                 wakeup(&client->kqinfo);
673         }
674
675         KNOTE(&client->kqinfo.ki_note, 0);
676
677         if (client->ec_async && client->ec_sigio != NULL)
678                 pgsigio(client->ec_sigio, SIGIO, 0);
679 }
680
681 int
682 evdev_cdev_create(struct evdev_dev *evdev)
683 {
684         cdev_t dev;
685         int ret, unit;
686
687         /*
688          * Iterate over devices input/eventX until we find a non-existing
689          * one and record its number in unit.
690          */
691         unit = 0;
692         while (devfs_find_device_by_name("input/event%d", unit) != NULL) {
693             unit++;
694         }
695
696         /*
697          * Put unit as minor. Minor and major will determine st_rdev of
698          * eventX. Ensuring that all eventX have different major and minor
699          * will make st_rdev unique. This is needed by libinput, which
700          * determines eventX from st_rdev.
701          */
702         dev = make_dev(&evdev_cdevsw, unit, UID_ROOT, GID_INPUT,
703                                   0660, "input/event%d", unit);
704
705         if (dev != NULL) {
706                 dev->si_drv1 = evdev;
707                 evdev->ev_cdev = dev;
708                 evdev->ev_unit = unit;
709                 ret = 0;
710         } else {
711                 ret = ENODEV;
712                 goto err;
713         }
714
715         reference_dev(evdev->ev_cdev);
716
717 err:
718         return (ret);
719 }
720
721 int
722 evdev_cdev_destroy(struct evdev_dev *evdev)
723 {
724
725         if (evdev->ev_cdev) {
726                 dev_ops_remove_minor(&evdev_cdevsw, evdev->ev_unit);
727         }
728
729         return (0);
730 }
731
732 static void
733 evdev_client_gettime(struct evdev_client *client, struct timeval *tv)
734 {
735
736         switch (client->ec_clock_id) {
737         case EV_CLOCK_BOOTTIME:
738                 /*
739                  * XXX: FreeBSD does not support true POSIX monotonic clock.
740                  *      So aliase EV_CLOCK_BOOTTIME to EV_CLOCK_MONOTONIC.
741                  */
742         case EV_CLOCK_MONOTONIC:
743                 microuptime(tv);
744                 break;
745
746         case EV_CLOCK_REALTIME:
747         default:
748                 microtime(tv);
749                 break;
750         }
751 }
752
753 void
754 evdev_client_push(struct evdev_client *client, uint16_t type, uint16_t code,
755     int32_t value)
756 {
757         struct timeval time;
758         size_t count, head, tail, ready;
759
760         EVDEV_CLIENT_LOCKQ_ASSERT(client);
761         head = client->ec_buffer_head;
762         tail = client->ec_buffer_tail;
763         ready = client->ec_buffer_ready;
764         count = client->ec_buffer_size;
765
766         /* If queue is full drop its content and place SYN_DROPPED event */
767         if ((tail + 1) % count == head) {
768                 debugf(client, "client %p: buffer overflow", client);
769
770                 head = (tail + count - 1) % count;
771                 client->ec_buffer[head] = (struct input_event) {
772                         .type = EV_SYN,
773                         .code = SYN_DROPPED,
774                         .value = 0
775                 };
776                 /*
777                  * XXX: Here is a small race window from now till the end of
778                  *      report. The queue is empty but client has been already
779                  *      notified of data readyness. Can be fixed in two ways:
780                  * 1. Implement bulk insert so queue lock would not be dropped
781                  *    till the SYN_REPORT event.
782                  * 2. Insert SYN_REPORT just now and skip remaining events
783                  */
784                 client->ec_buffer_head = head;
785                 client->ec_buffer_ready = head;
786         }
787
788         client->ec_buffer[tail].type = type;
789         client->ec_buffer[tail].code = code;
790         client->ec_buffer[tail].value = value;
791         client->ec_buffer_tail = (tail + 1) % count;
792
793         /* Allow users to read events only after report has been completed */
794         if (type == EV_SYN && code == SYN_REPORT) {
795                 evdev_client_gettime(client, &time);
796                 for (; ready != client->ec_buffer_tail;
797                     ready = (ready + 1) % count)
798                         client->ec_buffer[ready].time = time;
799                 client->ec_buffer_ready = client->ec_buffer_tail;
800         }
801 }
802
803 void
804 evdev_client_dumpqueue(struct evdev_client *client)
805 {
806         struct input_event *event;
807         size_t i, head, tail, ready, size;
808
809         head = client->ec_buffer_head;
810         tail = client->ec_buffer_tail;
811         ready = client->ec_buffer_ready;
812         size = client->ec_buffer_size;
813
814         kprintf("evdev client: %p\n", client);
815         kprintf("event queue: head=%zu ready=%zu tail=%zu size=%zu\n",
816             head, ready, tail, size);
817
818         kprintf("queue contents:\n");
819
820         for (i = 0; i < size; i++) {
821                 event = &client->ec_buffer[i];
822                 kprintf("%zu: ", i);
823
824                 if (i < head || i > tail)
825                         kprintf("unused\n");
826                 else
827                         kprintf("type=%d code=%d value=%d ", event->type,
828                             event->code, event->value);
829
830                 if (i == head)
831                         kprintf("<- head\n");
832                 else if (i == tail)
833                         kprintf("<- tail\n");
834                 else if (i == ready)
835                         kprintf("<- ready\n");
836                 else
837                         kprintf("\n");
838         }
839 }
840
841 static void
842 evdev_client_filter_queue(struct evdev_client *client, uint16_t type)
843 {
844         struct input_event *event;
845         size_t head, tail, count, i;
846         bool last_was_syn = false;
847
848         EVDEV_CLIENT_LOCKQ(client);
849
850         i = head = client->ec_buffer_head;
851         tail = client->ec_buffer_tail;
852         count = client->ec_buffer_size;
853         client->ec_buffer_ready = client->ec_buffer_tail;
854
855         while (i != client->ec_buffer_tail) {
856                 event = &client->ec_buffer[i];
857                 i = (i + 1) % count;
858
859                 /* Skip event of given type */
860                 if (event->type == type)
861                         continue;
862
863                 /* Remove empty SYN_REPORT events */
864                 if (event->type == EV_SYN && event->code == SYN_REPORT) {
865                         if (last_was_syn)
866                                 continue;
867                         else
868                                 client->ec_buffer_ready = (tail + 1) % count;
869                 }
870
871                 /* Rewrite entry */
872                 memcpy(&client->ec_buffer[tail], event,
873                     sizeof(struct input_event));
874
875                 last_was_syn = (event->type == EV_SYN &&
876                     event->code == SYN_REPORT);
877
878                 tail = (tail + 1) % count;
879         }
880
881         client->ec_buffer_head = i;
882         client->ec_buffer_tail = tail;
883
884         EVDEV_CLIENT_UNLOCKQ(client);
885 }