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