xref: /freebsd/sys/dev/evdev/uinput.c (revision 36138969847b231cd98f48272e2bdf88a8dc08dd)
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 
28 #include "opt_evdev.h"
29 
30 #include <sys/param.h>
31 #include <sys/conf.h>
32 #include <sys/fcntl.h>
33 #include <sys/kernel.h>
34 #include <sys/lock.h>
35 #include <sys/malloc.h>
36 #include <sys/module.h>
37 #include <sys/poll.h>
38 #include <sys/proc.h>
39 #include <sys/selinfo.h>
40 #include <sys/systm.h>
41 #include <sys/sx.h>
42 #include <sys/uio.h>
43 
44 #include <dev/evdev/evdev.h>
45 #include <dev/evdev/evdev_private.h>
46 #include <dev/evdev/input.h>
47 #include <dev/evdev/uinput.h>
48 
49 #ifdef UINPUT_DEBUG
50 #define	debugf(state, fmt, args...)	printf("uinput: " fmt "\n", ##args)
51 #else
52 #define	debugf(state, fmt, args...)
53 #endif
54 
55 #define	UINPUT_BUFFER_SIZE	16
56 
57 #define	UINPUT_LOCK(state)		sx_xlock(&(state)->ucs_lock)
58 #define	UINPUT_UNLOCK(state)		sx_unlock(&(state)->ucs_lock)
59 #define	UINPUT_LOCK_ASSERT(state)	sx_assert(&(state)->ucs_lock, SA_LOCKED)
60 #define UINPUT_EMPTYQ(state) \
61     ((state)->ucs_buffer_head == (state)->ucs_buffer_tail)
62 
63 enum uinput_state
64 {
65 	UINPUT_NEW = 0,
66 	UINPUT_CONFIGURED,
67 	UINPUT_RUNNING
68 };
69 
70 static evdev_event_t	uinput_ev_event;
71 
72 static d_open_t		uinput_open;
73 static d_read_t		uinput_read;
74 static d_write_t	uinput_write;
75 static d_ioctl_t	uinput_ioctl;
76 static d_poll_t		uinput_poll;
77 static d_kqfilter_t	uinput_kqfilter;
78 static void uinput_dtor(void *);
79 
80 static int uinput_kqread(struct knote *kn, long hint);
81 static void uinput_kqdetach(struct knote *kn);
82 
83 static struct cdevsw uinput_cdevsw = {
84 	.d_version = D_VERSION,
85 	.d_open = uinput_open,
86 	.d_read = uinput_read,
87 	.d_write = uinput_write,
88 	.d_ioctl = uinput_ioctl,
89 	.d_poll = uinput_poll,
90 	.d_kqfilter = uinput_kqfilter,
91 	.d_name = "uinput",
92 };
93 
94 static struct cdev *uinput_cdev;
95 
96 static const struct evdev_methods uinput_ev_methods = {
97 	.ev_open = NULL,
98 	.ev_close = NULL,
99 	.ev_event = uinput_ev_event,
100 };
101 
102 static const struct filterops uinput_filterops = {
103 	.f_isfd = 1,
104 	.f_attach = NULL,
105 	.f_detach = uinput_kqdetach,
106 	.f_event = uinput_kqread,
107 	.f_copy = knote_triv_copy,
108 };
109 
110 struct uinput_cdev_state
111 {
112 	enum uinput_state	ucs_state;
113 	struct evdev_dev *	ucs_evdev;
114 	struct sx		ucs_lock;
115 	size_t			ucs_buffer_head;
116 	size_t			ucs_buffer_tail;
117 	struct selinfo		ucs_selp;
118 	bool			ucs_blocked;
119 	bool			ucs_selected;
120 	struct input_event      ucs_buffer[UINPUT_BUFFER_SIZE];
121 };
122 
123 static void uinput_enqueue_event(struct uinput_cdev_state *, uint16_t,
124     uint16_t, int32_t);
125 static int uinput_setup_provider(struct uinput_cdev_state *,
126     struct uinput_user_dev *);
127 static int uinput_cdev_create(void);
128 static void uinput_notify(struct uinput_cdev_state *);
129 
130 static void
uinput_knllock(void * arg)131 uinput_knllock(void *arg)
132 {
133 	struct sx *sx = arg;
134 
135 	sx_xlock(sx);
136 }
137 
138 static void
uinput_knlunlock(void * arg)139 uinput_knlunlock(void *arg)
140 {
141 	struct sx *sx = arg;
142 
143 	sx_unlock(sx);
144 }
145 
146 static void
uinput_knl_assert_lock(void * arg,int what)147 uinput_knl_assert_lock(void *arg, int what)
148 {
149 
150 	if (what == LA_LOCKED)
151 		sx_assert((struct sx*)arg, SA_XLOCKED);
152 	else
153 		sx_assert((struct sx*)arg, SA_UNLOCKED);
154 }
155 
156 static void
uinput_ev_event(struct evdev_dev * evdev,uint16_t type,uint16_t code,int32_t value)157 uinput_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
158     int32_t value)
159 {
160 	struct uinput_cdev_state *state = evdev_get_softc(evdev);
161 
162 	if (type == EV_LED)
163 		evdev_push_event(evdev, type, code, value);
164 
165 	UINPUT_LOCK(state);
166 	if (state->ucs_state == UINPUT_RUNNING) {
167 		uinput_enqueue_event(state, type, code, value);
168 		uinput_notify(state);
169 	}
170 	UINPUT_UNLOCK(state);
171 }
172 
173 static void
uinput_enqueue_event(struct uinput_cdev_state * state,uint16_t type,uint16_t code,int32_t value)174 uinput_enqueue_event(struct uinput_cdev_state *state, uint16_t type,
175     uint16_t code, int32_t value)
176 {
177 	size_t head, tail;
178 
179 	UINPUT_LOCK_ASSERT(state);
180 
181 	head = state->ucs_buffer_head;
182 	tail = (state->ucs_buffer_tail + 1) % UINPUT_BUFFER_SIZE;
183 
184 	microtime(&state->ucs_buffer[tail].time);
185 	state->ucs_buffer[tail].type = type;
186 	state->ucs_buffer[tail].code = code;
187 	state->ucs_buffer[tail].value = value;
188 	state->ucs_buffer_tail = tail;
189 
190 	/* If queue is full remove oldest event */
191 	if (tail == head) {
192 		debugf(state, "state %p: buffer overflow", state);
193 
194 		head = (head + 1) % UINPUT_BUFFER_SIZE;
195 		state->ucs_buffer_head = head;
196 	}
197 }
198 
199 static int
uinput_open(struct cdev * dev,int oflags,int devtype,struct thread * td)200 uinput_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
201 {
202 	struct uinput_cdev_state *state;
203 
204 	state = malloc(sizeof(struct uinput_cdev_state), M_EVDEV,
205 	    M_WAITOK | M_ZERO);
206 	state->ucs_evdev = evdev_alloc();
207 
208 	sx_init(&state->ucs_lock, "uinput");
209 	knlist_init(&state->ucs_selp.si_note, &state->ucs_lock, uinput_knllock,
210 	    uinput_knlunlock, uinput_knl_assert_lock);
211 
212 	devfs_set_cdevpriv(state, uinput_dtor);
213 	return (0);
214 }
215 
216 static void
uinput_dtor(void * data)217 uinput_dtor(void *data)
218 {
219 	struct uinput_cdev_state *state = (struct uinput_cdev_state *)data;
220 
221 	evdev_free(state->ucs_evdev);
222 
223 	knlist_clear(&state->ucs_selp.si_note, 0);
224 	seldrain(&state->ucs_selp);
225 	knlist_destroy(&state->ucs_selp.si_note);
226 	sx_destroy(&state->ucs_lock);
227 	free(data, M_EVDEV);
228 }
229 
230 static int
uinput_read(struct cdev * dev,struct uio * uio,int ioflag)231 uinput_read(struct cdev *dev, struct uio *uio, int ioflag)
232 {
233 	struct uinput_cdev_state *state;
234 	struct input_event *event;
235 	int remaining, ret;
236 
237 	ret = devfs_get_cdevpriv((void **)&state);
238 	if (ret != 0)
239 		return (ret);
240 
241 	debugf(state, "read %zd bytes by thread %d", uio->uio_resid,
242 	    uio->uio_td->td_tid);
243 
244 	/* Zero-sized reads are allowed for error checking */
245 	if (uio->uio_resid != 0 && uio->uio_resid < sizeof(struct input_event))
246 		return (EINVAL);
247 
248 	remaining = uio->uio_resid / sizeof(struct input_event);
249 
250 	UINPUT_LOCK(state);
251 
252 	if (state->ucs_state != UINPUT_RUNNING)
253 		ret = EINVAL;
254 
255 	if (ret == 0 && UINPUT_EMPTYQ(state)) {
256 		if (ioflag & O_NONBLOCK)
257 			ret = EWOULDBLOCK;
258 		else {
259 			if (remaining != 0) {
260 				state->ucs_blocked = true;
261 				ret = sx_sleep(state, &state->ucs_lock,
262 				    PCATCH, "uiread", 0);
263 			}
264 		}
265 	}
266 
267 	while (ret == 0 && !UINPUT_EMPTYQ(state) && remaining > 0) {
268 		event = &state->ucs_buffer[state->ucs_buffer_head];
269 		state->ucs_buffer_head = (state->ucs_buffer_head + 1) %
270 		    UINPUT_BUFFER_SIZE;
271 		remaining--;
272 		ret = uiomove(event, sizeof(struct input_event), uio);
273 	}
274 
275 	UINPUT_UNLOCK(state);
276 
277 	return (ret);
278 }
279 
280 static int
uinput_write(struct cdev * dev,struct uio * uio,int ioflag)281 uinput_write(struct cdev *dev, struct uio *uio, int ioflag)
282 {
283 	struct uinput_cdev_state *state;
284 	struct uinput_user_dev userdev;
285 	struct input_event event;
286 	int ret = 0;
287 
288 	ret = devfs_get_cdevpriv((void **)&state);
289 	if (ret != 0)
290 		return (ret);
291 
292 	debugf(state, "write %zd bytes by thread %d", uio->uio_resid,
293 	    uio->uio_td->td_tid);
294 
295 	UINPUT_LOCK(state);
296 
297 	if (state->ucs_state != UINPUT_RUNNING) {
298 		/* Process written struct uinput_user_dev */
299 		if (uio->uio_resid != sizeof(struct uinput_user_dev)) {
300 			debugf(state, "write size not multiple of "
301 			    "struct uinput_user_dev size");
302 			ret = EINVAL;
303 		} else {
304 			ret = uiomove(&userdev, sizeof(struct uinput_user_dev),
305 			    uio);
306 			if (ret == 0)
307 				uinput_setup_provider(state, &userdev);
308 		}
309 	} else {
310 		/* Process written event */
311 		if (uio->uio_resid % sizeof(struct input_event) != 0) {
312 			debugf(state, "write size not multiple of "
313 			    "struct input_event size");
314 			ret = EINVAL;
315 		}
316 
317 		while (ret == 0 && uio->uio_resid > 0) {
318 			uiomove(&event, sizeof(struct input_event), uio);
319 			ret = evdev_push_event(state->ucs_evdev, event.type,
320 			    event.code, event.value);
321 		}
322 	}
323 
324 	UINPUT_UNLOCK(state);
325 
326 	return (ret);
327 }
328 
329 static int
uinput_setup_dev(struct uinput_cdev_state * state,struct input_id * id,char * name,uint32_t ff_effects_max)330 uinput_setup_dev(struct uinput_cdev_state *state, struct input_id *id,
331     char *name, uint32_t ff_effects_max)
332 {
333 
334 	if (name[0] == 0)
335 		return (EINVAL);
336 
337 	evdev_set_name(state->ucs_evdev, name);
338 	evdev_set_id(state->ucs_evdev, id->bustype, id->vendor, id->product,
339 	    id->version);
340 	state->ucs_state = UINPUT_CONFIGURED;
341 
342 	return (0);
343 }
344 
345 static int
uinput_setup_provider(struct uinput_cdev_state * state,struct uinput_user_dev * udev)346 uinput_setup_provider(struct uinput_cdev_state *state,
347     struct uinput_user_dev *udev)
348 {
349 	struct input_absinfo absinfo;
350 	int i, ret;
351 
352 	debugf(state, "setup_provider called, udev=%p", udev);
353 
354 	ret = uinput_setup_dev(state, &udev->id, udev->name,
355 	    udev->ff_effects_max);
356 	if (ret)
357 		return (ret);
358 
359 	bzero(&absinfo, sizeof(struct input_absinfo));
360 	for (i = 0; i < ABS_CNT; i++) {
361 		if (!bit_test(state->ucs_evdev->ev_abs_flags, i))
362 			continue;
363 
364 		absinfo.minimum = udev->absmin[i];
365 		absinfo.maximum = udev->absmax[i];
366 		absinfo.fuzz = udev->absfuzz[i];
367 		absinfo.flat = udev->absflat[i];
368 		evdev_set_absinfo(state->ucs_evdev, i, &absinfo);
369 	}
370 
371 	return (0);
372 }
373 
374 static int
uinput_poll(struct cdev * dev,int events,struct thread * td)375 uinput_poll(struct cdev *dev, int events, struct thread *td)
376 {
377 	struct uinput_cdev_state *state;
378 	int revents = 0;
379 
380 	if (devfs_get_cdevpriv((void **)&state) != 0)
381 		return (POLLNVAL);
382 
383 	debugf(state, "poll by thread %d", td->td_tid);
384 
385 	/* Always allow write */
386 	if (events & (POLLOUT | POLLWRNORM))
387 		revents |= (events & (POLLOUT | POLLWRNORM));
388 
389 	if (events & (POLLIN | POLLRDNORM)) {
390 		UINPUT_LOCK(state);
391 		if (!UINPUT_EMPTYQ(state))
392 			revents = events & (POLLIN | POLLRDNORM);
393 		else {
394 			state->ucs_selected = true;
395 			selrecord(td, &state->ucs_selp);
396 		}
397 		UINPUT_UNLOCK(state);
398 	}
399 
400 	return (revents);
401 }
402 
403 static int
uinput_kqfilter(struct cdev * dev,struct knote * kn)404 uinput_kqfilter(struct cdev *dev, struct knote *kn)
405 {
406 	struct uinput_cdev_state *state;
407 	int ret;
408 
409 	ret = devfs_get_cdevpriv((void **)&state);
410 	if (ret != 0)
411 		return (ret);
412 
413 	switch(kn->kn_filter) {
414 	case EVFILT_READ:
415 		kn->kn_fop = &uinput_filterops;
416 		break;
417 	default:
418 		return(EINVAL);
419 	}
420 	kn->kn_hook = (caddr_t)state;
421 
422 	knlist_add(&state->ucs_selp.si_note, kn, 0);
423 	return (0);
424 }
425 
426 static int
uinput_kqread(struct knote * kn,long hint)427 uinput_kqread(struct knote *kn, long hint)
428 {
429 	struct uinput_cdev_state *state;
430 	int ret;
431 
432 	state = (struct uinput_cdev_state *)kn->kn_hook;
433 
434 	UINPUT_LOCK_ASSERT(state);
435 
436 	ret = !UINPUT_EMPTYQ(state);
437 	return (ret);
438 }
439 
440 static void
uinput_kqdetach(struct knote * kn)441 uinput_kqdetach(struct knote *kn)
442 {
443 	struct uinput_cdev_state *state;
444 
445 	state = (struct uinput_cdev_state *)kn->kn_hook;
446 	knlist_remove(&state->ucs_selp.si_note, kn, 0);
447 }
448 
449 static void
uinput_notify(struct uinput_cdev_state * state)450 uinput_notify(struct uinput_cdev_state *state)
451 {
452 
453 	UINPUT_LOCK_ASSERT(state);
454 
455 	if (state->ucs_blocked) {
456 		state->ucs_blocked = false;
457 		wakeup(state);
458 	}
459 	if (state->ucs_selected) {
460 		state->ucs_selected = false;
461 		selwakeup(&state->ucs_selp);
462 	}
463 	KNOTE_LOCKED(&state->ucs_selp.si_note, 0);
464 }
465 
466 static int
uinput_ioctl_sub(struct uinput_cdev_state * state,u_long cmd,caddr_t data)467 uinput_ioctl_sub(struct uinput_cdev_state *state, u_long cmd, caddr_t data)
468 {
469 	struct uinput_setup *us;
470 	struct uinput_abs_setup *uabs;
471 	int ret, len, intdata;
472 	char buf[NAMELEN];
473 
474 	UINPUT_LOCK_ASSERT(state);
475 
476 	len = IOCPARM_LEN(cmd);
477 	if ((cmd & IOC_DIRMASK) == IOC_VOID && len == sizeof(int))
478 		intdata = *(int *)data;
479 
480 	switch (IOCBASECMD(cmd)) {
481 	case UI_GET_SYSNAME(0):
482 		if (state->ucs_state != UINPUT_RUNNING)
483 			return (ENOENT);
484 		if (len == 0)
485 			return (EINVAL);
486 		snprintf(data, len, "event%d", state->ucs_evdev->ev_unit);
487 		return (0);
488 	}
489 
490 	switch (cmd) {
491 	case UI_DEV_CREATE:
492 		if (state->ucs_state != UINPUT_CONFIGURED)
493 			return (EINVAL);
494 
495 		evdev_set_methods(state->ucs_evdev, state, &uinput_ev_methods);
496 		evdev_set_flag(state->ucs_evdev, EVDEV_FLAG_SOFTREPEAT);
497 		evdev_set_flag(state->ucs_evdev, EVDEV_FLAG_MT_KEEPID);
498 		ret = evdev_register(state->ucs_evdev);
499 		if (ret == 0)
500 			state->ucs_state = UINPUT_RUNNING;
501 		return (ret);
502 
503 	case UI_DEV_DESTROY:
504 		if (state->ucs_state != UINPUT_RUNNING)
505 			return (0);
506 
507 		evdev_unregister(state->ucs_evdev);
508 		bzero(state->ucs_evdev, sizeof(struct evdev_dev));
509 		state->ucs_state = UINPUT_NEW;
510 		return (0);
511 
512 	case UI_DEV_SETUP:
513 		if (state->ucs_state == UINPUT_RUNNING)
514 			return (EINVAL);
515 
516 		us = (struct uinput_setup *)data;
517 		return (uinput_setup_dev(state, &us->id, us->name,
518 		    us->ff_effects_max));
519 
520 	case UI_ABS_SETUP:
521 		if (state->ucs_state == UINPUT_RUNNING)
522 			return (EINVAL);
523 
524 		uabs = (struct uinput_abs_setup *)data;
525 		if (uabs->code > ABS_MAX)
526 			return (EINVAL);
527 
528 		evdev_set_abs_bit(state->ucs_evdev, uabs->code);
529 		evdev_set_absinfo(state->ucs_evdev, uabs->code,
530 		    &uabs->absinfo);
531 		return (0);
532 
533 	case UI_SET_EVBIT:
534 		if (state->ucs_state == UINPUT_RUNNING ||
535 		    intdata > EV_MAX || intdata < 0)
536 			return (EINVAL);
537 		evdev_support_event(state->ucs_evdev, intdata);
538 		return (0);
539 
540 	case UI_SET_KEYBIT:
541 		if (state->ucs_state == UINPUT_RUNNING ||
542 		    intdata > KEY_MAX || intdata < 0)
543 			return (EINVAL);
544 		evdev_support_key(state->ucs_evdev, intdata);
545 		return (0);
546 
547 	case UI_SET_RELBIT:
548 		if (state->ucs_state == UINPUT_RUNNING ||
549 		    intdata > REL_MAX || intdata < 0)
550 			return (EINVAL);
551 		evdev_support_rel(state->ucs_evdev, intdata);
552 		return (0);
553 
554 	case UI_SET_ABSBIT:
555 		if (state->ucs_state == UINPUT_RUNNING ||
556 		    intdata > ABS_MAX || intdata < 0)
557 			return (EINVAL);
558 		evdev_set_abs_bit(state->ucs_evdev, intdata);
559 		return (0);
560 
561 	case UI_SET_MSCBIT:
562 		if (state->ucs_state == UINPUT_RUNNING ||
563 		    intdata > MSC_MAX || intdata < 0)
564 			return (EINVAL);
565 		evdev_support_msc(state->ucs_evdev, intdata);
566 		return (0);
567 
568 	case UI_SET_LEDBIT:
569 		if (state->ucs_state == UINPUT_RUNNING ||
570 		    intdata > LED_MAX || intdata < 0)
571 			return (EINVAL);
572 		evdev_support_led(state->ucs_evdev, intdata);
573 		return (0);
574 
575 	case UI_SET_SNDBIT:
576 		if (state->ucs_state == UINPUT_RUNNING ||
577 		    intdata > SND_MAX || intdata < 0)
578 			return (EINVAL);
579 		evdev_support_snd(state->ucs_evdev, intdata);
580 		return (0);
581 
582 	case UI_SET_FFBIT:
583 		if (state->ucs_state == UINPUT_RUNNING ||
584 		    intdata > FF_MAX || intdata < 0)
585 			return (EINVAL);
586 		/* Fake unsupported ioctl */
587 		return (0);
588 
589 	case UI_SET_PHYS:
590 		if (state->ucs_state == UINPUT_RUNNING)
591 			return (EINVAL);
592 		ret = copyinstr(*(void **)data, buf, sizeof(buf), NULL);
593 		/* Linux returns EINVAL when string does not fit the buffer */
594 		if (ret == ENAMETOOLONG)
595 			ret = EINVAL;
596 		if (ret != 0)
597 			return (ret);
598 		evdev_set_phys(state->ucs_evdev, buf);
599 		return (0);
600 
601 	case UI_SET_BSDUNIQ:
602 		if (state->ucs_state == UINPUT_RUNNING)
603 			return (EINVAL);
604 		ret = copyinstr(*(void **)data, buf, sizeof(buf), NULL);
605 		if (ret != 0)
606 			return (ret);
607 		evdev_set_serial(state->ucs_evdev, buf);
608 		return (0);
609 
610 	case UI_SET_SWBIT:
611 		if (state->ucs_state == UINPUT_RUNNING ||
612 		    intdata > SW_MAX || intdata < 0)
613 			return (EINVAL);
614 		evdev_support_sw(state->ucs_evdev, intdata);
615 		return (0);
616 
617 	case UI_SET_PROPBIT:
618 		if (state->ucs_state == UINPUT_RUNNING ||
619 		    intdata > INPUT_PROP_MAX || intdata < 0)
620 			return (EINVAL);
621 		evdev_support_prop(state->ucs_evdev, intdata);
622 		return (0);
623 
624 	case UI_BEGIN_FF_UPLOAD:
625 	case UI_END_FF_UPLOAD:
626 	case UI_BEGIN_FF_ERASE:
627 	case UI_END_FF_ERASE:
628 		if (state->ucs_state == UINPUT_RUNNING)
629 			return (EINVAL);
630 		/* Fake unsupported ioctl */
631 		return (0);
632 
633 	case UI_GET_VERSION:
634 		*(unsigned int *)data = UINPUT_VERSION;
635 		return (0);
636 	}
637 
638 	return (EINVAL);
639 }
640 
641 static int
uinput_ioctl(struct cdev * dev,u_long cmd,caddr_t data,int fflag,struct thread * td)642 uinput_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
643     struct thread *td)
644 {
645 	struct uinput_cdev_state *state;
646 	int ret;
647 
648 	ret = devfs_get_cdevpriv((void **)&state);
649 	if (ret != 0)
650 		return (ret);
651 
652 	debugf(state, "ioctl called: cmd=0x%08lx, data=%p", cmd, data);
653 
654 	UINPUT_LOCK(state);
655 	ret = uinput_ioctl_sub(state, cmd, data);
656 	UINPUT_UNLOCK(state);
657 
658 	return (ret);
659 }
660 
661 static int
uinput_cdev_create(void)662 uinput_cdev_create(void)
663 {
664 	struct make_dev_args mda;
665 	int ret;
666 
667 	make_dev_args_init(&mda);
668 	mda.mda_flags = MAKEDEV_WAITOK | MAKEDEV_CHECKNAME;
669 	mda.mda_devsw = &uinput_cdevsw;
670 	mda.mda_uid = UID_ROOT;
671 	mda.mda_gid = GID_WHEEL;
672 	mda.mda_mode = 0600;
673 
674 	ret = make_dev_s(&mda, &uinput_cdev, "uinput");
675 
676 	return (ret);
677 }
678 
679 static int
uinput_cdev_destroy(void)680 uinput_cdev_destroy(void)
681 {
682 
683 	destroy_dev(uinput_cdev);
684 
685 	return (0);
686 }
687 
688 static int
uinput_modevent(module_t mod __unused,int cmd,void * data)689 uinput_modevent(module_t mod __unused, int cmd, void *data)
690 {
691 	int ret = 0;
692 
693 	switch (cmd) {
694 	case MOD_LOAD:
695 		ret = uinput_cdev_create();
696 		break;
697 
698 	case MOD_UNLOAD:
699 		ret = uinput_cdev_destroy();
700 		break;
701 
702 	case MOD_SHUTDOWN:
703 		break;
704 
705 	default:
706 		ret = EINVAL;
707 		break;
708 	}
709 
710 	return (ret);
711 }
712 
713 DEV_MODULE(uinput, uinput_modevent, NULL);
714 MODULE_VERSION(uinput, 1);
715 MODULE_DEPEND(uinput, evdev, 1, 1, 1);
716