xref: /illumos-gate/usr/src/cmd/bhyve/pci_virtio_input.c (revision 32640292339b07090f10ce34d455f98711077343)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer
12  *    in this position and unchanged.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 /*
31  * virtio input device emulation.
32  */
33 
34 #include <sys/cdefs.h>
35 
36 #include <sys/param.h>
37 #ifndef WITHOUT_CAPSICUM
38 #include <sys/capsicum.h>
39 
40 #include <capsicum_helpers.h>
41 #endif
42 #include <sys/ioctl.h>
43 #include <sys/linker_set.h>
44 #include <sys/uio.h>
45 
46 #include <dev/evdev/input.h>
47 
48 #include <assert.h>
49 #include <err.h>
50 #include <errno.h>
51 #include <fcntl.h>
52 #include <pthread.h>
53 #include <stddef.h>
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <string.h>
57 #include <sysexits.h>
58 #include <unistd.h>
59 
60 #include "bhyverun.h"
61 #include "config.h"
62 #include "debug.h"
63 #include "mevent.h"
64 #include "pci_emul.h"
65 #include "virtio.h"
66 
67 #define VTINPUT_RINGSZ 64
68 
69 #define VTINPUT_MAX_PKT_LEN 10
70 
71 /*
72  * Queue definitions.
73  */
74 #define VTINPUT_EVENTQ 0
75 #define VTINPUT_STATUSQ 1
76 
77 #define VTINPUT_MAXQ 2
78 
79 static int pci_vtinput_debug;
80 #define DPRINTF(params)        \
81 	if (pci_vtinput_debug) \
82 	PRINTLN params
83 #define WPRINTF(params) PRINTLN params
84 
85 enum vtinput_config_select {
86 	VTINPUT_CFG_UNSET = 0x00,
87 	VTINPUT_CFG_ID_NAME = 0x01,
88 	VTINPUT_CFG_ID_SERIAL = 0x02,
89 	VTINPUT_CFG_ID_DEVIDS = 0x03,
90 	VTINPUT_CFG_PROP_BITS = 0x10,
91 	VTINPUT_CFG_EV_BITS = 0x11,
92 	VTINPUT_CFG_ABS_INFO = 0x12
93 };
94 
95 struct vtinput_absinfo {
96 	uint32_t min;
97 	uint32_t max;
98 	uint32_t fuzz;
99 	uint32_t flat;
100 	uint32_t res;
101 } __packed;
102 
103 struct vtinput_devids {
104 	uint16_t bustype;
105 	uint16_t vendor;
106 	uint16_t product;
107 	uint16_t version;
108 } __packed;
109 
110 struct vtinput_config {
111 	uint8_t select;
112 	uint8_t subsel;
113 	uint8_t size;
114 	uint8_t reserved[5];
115 	union {
116 		char string[128];
117 		uint8_t bitmap[128];
118 		struct vtinput_absinfo abs;
119 		struct vtinput_devids ids;
120 	} u;
121 } __packed;
122 
123 struct vtinput_event {
124 	uint16_t type;
125 	uint16_t code;
126 	uint32_t value;
127 } __packed;
128 
129 struct vtinput_event_elem {
130 	struct vtinput_event event;
131 	struct iovec iov;
132 	uint16_t idx;
133 };
134 
135 struct vtinput_eventqueue {
136 	struct vtinput_event_elem *events;
137 	uint32_t size;
138 	uint32_t idx;
139 };
140 
141 /*
142  * Per-device softc
143  */
144 struct pci_vtinput_softc {
145 	struct virtio_softc vsc_vs;
146 	struct vqueue_info vsc_queues[VTINPUT_MAXQ];
147 	pthread_mutex_t vsc_mtx;
148 	const char *vsc_evdev;
149 	int vsc_fd;
150 	struct vtinput_config vsc_config;
151 	int vsc_config_valid;
152 	struct mevent *vsc_evp;
153 	struct vtinput_eventqueue vsc_eventqueue;
154 };
155 
156 static void pci_vtinput_reset(void *);
157 static int pci_vtinput_cfgread(void *, int, int, uint32_t *);
158 static int pci_vtinput_cfgwrite(void *, int, int, uint32_t);
159 
160 static struct virtio_consts vtinput_vi_consts = {
161 	.vc_name =	"vtinput",
162 	.vc_nvq =	VTINPUT_MAXQ,
163 	.vc_cfgsize =	sizeof(struct vtinput_config),
164 	.vc_reset =	pci_vtinput_reset,
165 	.vc_cfgread =	pci_vtinput_cfgread,
166 	.vc_cfgwrite =	pci_vtinput_cfgwrite,
167 	.vc_hv_caps =	0,
168 };
169 
170 static void
pci_vtinput_reset(void * vsc)171 pci_vtinput_reset(void *vsc)
172 {
173 	struct pci_vtinput_softc *sc = vsc;
174 
175 	DPRINTF(("%s: device reset requested", __func__));
176 	vi_reset_dev(&sc->vsc_vs);
177 }
178 
179 static void
pci_vtinput_notify_eventq(void * vsc __unused,struct vqueue_info * vq __unused)180 pci_vtinput_notify_eventq(void *vsc __unused, struct vqueue_info *vq __unused)
181 {
182 	DPRINTF(("%s", __func__));
183 }
184 
185 static void
pci_vtinput_notify_statusq(void * vsc,struct vqueue_info * vq)186 pci_vtinput_notify_statusq(void *vsc, struct vqueue_info *vq)
187 {
188 	struct pci_vtinput_softc *sc = vsc;
189 
190 	while (vq_has_descs(vq)) {
191 		/* get descriptor chain */
192 		struct iovec iov;
193 		struct vi_req req;
194 		const int n = vq_getchain(vq, &iov, 1, &req);
195 		if (n <= 0) {
196 			WPRINTF(("%s: invalid descriptor: %d", __func__, n));
197 			return;
198 		}
199 
200 		/* get event */
201 		struct vtinput_event event;
202 		memcpy(&event, iov.iov_base, sizeof(event));
203 
204 		/*
205 		 * on multi touch devices:
206 		 * - host send EV_MSC to guest
207 		 * - guest sends EV_MSC back to host
208 		 * - host writes EV_MSC to evdev
209 		 * - evdev saves EV_MSC in it's event buffer
210 		 * - host receives an extra EV_MSC by reading the evdev event
211 		 *   buffer
212 		 * - frames become larger and larger
213 		 * avoid endless loops by ignoring EV_MSC
214 		 */
215 		if (event.type == EV_MSC) {
216 			vq_relchain(vq, req.idx, sizeof(event));
217 			continue;
218 		}
219 
220 		/* send event to evdev */
221 		struct input_event host_event;
222 		host_event.type = event.type;
223 		host_event.code = event.code;
224 		host_event.value = event.value;
225 		if (gettimeofday(&host_event.time, NULL) != 0) {
226 			WPRINTF(("%s: failed gettimeofday", __func__));
227 		}
228 		if (write(sc->vsc_fd, &host_event, sizeof(host_event)) == -1) {
229 			WPRINTF(("%s: failed to write host_event", __func__));
230 		}
231 
232 		vq_relchain(vq, req.idx, sizeof(event));
233 	}
234 	vq_endchains(vq, 1);
235 }
236 
237 static int
pci_vtinput_get_bitmap(struct pci_vtinput_softc * sc,int cmd,int count)238 pci_vtinput_get_bitmap(struct pci_vtinput_softc *sc, int cmd, int count)
239 {
240 	if (count <= 0 || !sc) {
241 		return (-1);
242 	}
243 
244 	/* query bitmap */
245 	memset(sc->vsc_config.u.bitmap, 0, sizeof(sc->vsc_config.u.bitmap));
246 	if (ioctl(sc->vsc_fd, cmd, sc->vsc_config.u.bitmap) < 0) {
247 		return (-1);
248 	}
249 
250 	/* get number of set bytes in bitmap */
251 	for (int i = count - 1; i >= 0; i--) {
252 		if (sc->vsc_config.u.bitmap[i]) {
253 			return i + 1;
254 		}
255 	}
256 
257 	return (-1);
258 }
259 
260 static int
pci_vtinput_read_config_id_name(struct pci_vtinput_softc * sc)261 pci_vtinput_read_config_id_name(struct pci_vtinput_softc *sc)
262 {
263 	char name[128];
264 	if (ioctl(sc->vsc_fd, EVIOCGNAME(sizeof(name) - 1), name) < 0) {
265 		return (1);
266 	}
267 
268 	memcpy(sc->vsc_config.u.string, name, sizeof(name));
269 	sc->vsc_config.size = strnlen(name, sizeof(name));
270 
271 	return (0);
272 }
273 
274 static int
pci_vtinput_read_config_id_serial(struct pci_vtinput_softc * sc)275 pci_vtinput_read_config_id_serial(struct pci_vtinput_softc *sc)
276 {
277 	/* serial isn't supported */
278 	sc->vsc_config.size = 0;
279 
280 	return (0);
281 }
282 
283 static int
pci_vtinput_read_config_id_devids(struct pci_vtinput_softc * sc)284 pci_vtinput_read_config_id_devids(struct pci_vtinput_softc *sc)
285 {
286 	struct input_id devids;
287 	if (ioctl(sc->vsc_fd, EVIOCGID, &devids)) {
288 		return (1);
289 	}
290 
291 	sc->vsc_config.u.ids.bustype = devids.bustype;
292 	sc->vsc_config.u.ids.vendor = devids.vendor;
293 	sc->vsc_config.u.ids.product = devids.product;
294 	sc->vsc_config.u.ids.version = devids.version;
295 	sc->vsc_config.size = sizeof(struct vtinput_devids);
296 
297 	return (0);
298 }
299 
300 static int
pci_vtinput_read_config_prop_bits(struct pci_vtinput_softc * sc)301 pci_vtinput_read_config_prop_bits(struct pci_vtinput_softc *sc)
302 {
303 	/*
304 	 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
305 	 * are arrays of longs instead of chars. Calculate how many longs are
306 	 * required for evdev bitmap. Multiply that with sizeof(long) to get the
307 	 * number of elements.
308 	 */
309 	const int count = howmany(INPUT_PROP_CNT, sizeof(long) * 8) *
310 	    sizeof(long);
311 	const unsigned int cmd = EVIOCGPROP(count);
312 	const int size = pci_vtinput_get_bitmap(sc, cmd, count);
313 	if (size <= 0) {
314 		return (1);
315 	}
316 
317 	sc->vsc_config.size = size;
318 
319 	return (0);
320 }
321 
322 static int
pci_vtinput_read_config_ev_bits(struct pci_vtinput_softc * sc,uint8_t type)323 pci_vtinput_read_config_ev_bits(struct pci_vtinput_softc *sc, uint8_t type)
324 {
325 	int count;
326 
327 	switch (type) {
328 	case EV_KEY:
329 		count = KEY_CNT;
330 		break;
331 	case EV_REL:
332 		count = REL_CNT;
333 		break;
334 	case EV_ABS:
335 		count = ABS_CNT;
336 		break;
337 	case EV_MSC:
338 		count = MSC_CNT;
339 		break;
340 	case EV_SW:
341 		count = SW_CNT;
342 		break;
343 	case EV_LED:
344 		count = LED_CNT;
345 		break;
346 	default:
347 		return (1);
348 	}
349 
350 	/*
351 	 * Evdev bitmap countains 1 bit per count. Additionally evdev bitmaps
352 	 * are arrays of longs instead of chars. Calculate how many longs are
353 	 * required for evdev bitmap. Multiply that with sizeof(long) to get the
354 	 * number of elements.
355 	 */
356 	count = howmany(count, sizeof(long) * 8) * sizeof(long);
357 	const unsigned int cmd = EVIOCGBIT(sc->vsc_config.subsel, count);
358 	const int size = pci_vtinput_get_bitmap(sc, cmd, count);
359 	if (size <= 0) {
360 		return (1);
361 	}
362 
363 	sc->vsc_config.size = size;
364 
365 	return (0);
366 }
367 
368 static int
pci_vtinput_read_config_abs_info(struct pci_vtinput_softc * sc)369 pci_vtinput_read_config_abs_info(struct pci_vtinput_softc *sc)
370 {
371 	/* check if evdev has EV_ABS */
372 	if (!pci_vtinput_read_config_ev_bits(sc, EV_ABS)) {
373 		return (1);
374 	}
375 
376 	/* get abs information */
377 	struct input_absinfo abs;
378 	if (ioctl(sc->vsc_fd, EVIOCGABS(sc->vsc_config.subsel), &abs) < 0) {
379 		return (1);
380 	}
381 
382 	/* save abs information */
383 	sc->vsc_config.u.abs.min = abs.minimum;
384 	sc->vsc_config.u.abs.max = abs.maximum;
385 	sc->vsc_config.u.abs.fuzz = abs.fuzz;
386 	sc->vsc_config.u.abs.flat = abs.flat;
387 	sc->vsc_config.u.abs.res = abs.resolution;
388 	sc->vsc_config.size = sizeof(struct vtinput_absinfo);
389 
390 	return (0);
391 }
392 
393 static int
pci_vtinput_read_config(struct pci_vtinput_softc * sc)394 pci_vtinput_read_config(struct pci_vtinput_softc *sc)
395 {
396 	switch (sc->vsc_config.select) {
397 	case VTINPUT_CFG_UNSET:
398 		return (0);
399 	case VTINPUT_CFG_ID_NAME:
400 		return pci_vtinput_read_config_id_name(sc);
401 	case VTINPUT_CFG_ID_SERIAL:
402 		return pci_vtinput_read_config_id_serial(sc);
403 	case VTINPUT_CFG_ID_DEVIDS:
404 		return pci_vtinput_read_config_id_devids(sc);
405 	case VTINPUT_CFG_PROP_BITS:
406 		return pci_vtinput_read_config_prop_bits(sc);
407 	case VTINPUT_CFG_EV_BITS:
408 		return pci_vtinput_read_config_ev_bits(
409 		    sc, sc->vsc_config.subsel);
410 	case VTINPUT_CFG_ABS_INFO:
411 		return pci_vtinput_read_config_abs_info(sc);
412 	default:
413 		return (1);
414 	}
415 }
416 
417 static int
pci_vtinput_cfgread(void * vsc,int offset,int size,uint32_t * retval)418 pci_vtinput_cfgread(void *vsc, int offset, int size, uint32_t *retval)
419 {
420 	struct pci_vtinput_softc *sc = vsc;
421 
422 	/* check for valid offset and size */
423 	if (offset + size > (int)sizeof(struct vtinput_config)) {
424 		WPRINTF(("%s: read to invalid offset/size %d/%d", __func__,
425 		    offset, size));
426 		memset(retval, 0, size);
427 		return (0);
428 	}
429 
430 	/* read new config values, if select and subsel changed. */
431 	if (!sc->vsc_config_valid) {
432 		if (pci_vtinput_read_config(sc) != 0) {
433 			DPRINTF(("%s: could not read config %d/%d", __func__,
434 			    sc->vsc_config.select, sc->vsc_config.subsel));
435 			memset(retval, 0, size);
436 			return (0);
437 		}
438 		sc->vsc_config_valid = 1;
439 	}
440 
441 	uint8_t *ptr = (uint8_t *)&sc->vsc_config;
442 	memcpy(retval, ptr + offset, size);
443 
444 	return (0);
445 }
446 
447 static int
pci_vtinput_cfgwrite(void * vsc,int offset,int size,uint32_t value)448 pci_vtinput_cfgwrite(void *vsc, int offset, int size, uint32_t value)
449 {
450 	struct pci_vtinput_softc *sc = vsc;
451 
452 	/* guest can only write to select and subsel fields */
453 	if (offset + size > 2) {
454 		WPRINTF(("%s: write to readonly reg %d", __func__, offset));
455 		return (1);
456 	}
457 
458 	/* copy value into config */
459 	uint8_t *ptr = (uint8_t *)&sc->vsc_config;
460 	memcpy(ptr + offset, &value, size);
461 
462 	/* select/subsel changed, query new config on next cfgread */
463 	sc->vsc_config_valid = 0;
464 
465 	return (0);
466 }
467 
468 static int
vtinput_eventqueue_add_event(struct vtinput_eventqueue * queue,struct input_event * e)469 vtinput_eventqueue_add_event(
470     struct vtinput_eventqueue *queue, struct input_event *e)
471 {
472 	/* check if queue is full */
473 	if (queue->idx >= queue->size) {
474 		/* alloc new elements for queue */
475 		const uint32_t newSize = queue->idx;
476 		void *newPtr = realloc(queue->events,
477 		    queue->size * sizeof(struct vtinput_event_elem));
478 		if (newPtr == NULL) {
479 			WPRINTF(("%s: realloc memory for eventqueue failed!",
480 			    __func__));
481 			return (1);
482 		}
483 		queue->events = newPtr;
484 		queue->size = newSize;
485 	}
486 
487 	/* save event */
488 	struct vtinput_event *event = &queue->events[queue->idx].event;
489 	event->type = e->type;
490 	event->code = e->code;
491 	event->value = e->value;
492 	queue->idx++;
493 
494 	return (0);
495 }
496 
497 static void
vtinput_eventqueue_clear(struct vtinput_eventqueue * queue)498 vtinput_eventqueue_clear(struct vtinput_eventqueue *queue)
499 {
500 	/* just reset index to clear queue */
501 	queue->idx = 0;
502 }
503 
504 static void
vtinput_eventqueue_send_events(struct vtinput_eventqueue * queue,struct vqueue_info * vq)505 vtinput_eventqueue_send_events(
506     struct vtinput_eventqueue *queue, struct vqueue_info *vq)
507 {
508 	/*
509 	 * First iteration through eventqueue:
510 	 *   Get descriptor chains.
511 	 */
512 	for (uint32_t i = 0; i < queue->idx; ++i) {
513 		/* get descriptor */
514 		if (!vq_has_descs(vq)) {
515 			/*
516 			 * We don't have enough descriptors for all events.
517 			 * Return chains back to guest.
518 			 */
519 			vq_retchains(vq, i);
520 			WPRINTF((
521 			    "%s: not enough available descriptors, dropping %d events",
522 			    __func__, queue->idx));
523 			goto done;
524 		}
525 
526 		/* get descriptor chain */
527 		struct iovec iov;
528 		struct vi_req req;
529 		const int n = vq_getchain(vq, &iov, 1, &req);
530 		if (n <= 0) {
531 			WPRINTF(("%s: invalid descriptor: %d", __func__, n));
532 			return;
533 		}
534 		if (n != 1) {
535 			WPRINTF(
536 			    ("%s: invalid number of descriptors in chain: %d",
537 				__func__, n));
538 			/* release invalid chain */
539 			vq_relchain(vq, req.idx, 0);
540 			return;
541 		}
542 		if (iov.iov_len < sizeof(struct vtinput_event)) {
543 			WPRINTF(("%s: invalid descriptor length: %lu", __func__,
544 			    iov.iov_len));
545 			/* release invalid chain */
546 			vq_relchain(vq, req.idx, 0);
547 			return;
548 		}
549 
550 		/* save descriptor */
551 		queue->events[i].iov = iov;
552 		queue->events[i].idx = req.idx;
553 	}
554 
555 	/*
556 	 * Second iteration through eventqueue:
557 	 *   Send events to guest by releasing chains
558 	 */
559 	for (uint32_t i = 0; i < queue->idx; ++i) {
560 		struct vtinput_event_elem event = queue->events[i];
561 		memcpy(event.iov.iov_base, &event.event,
562 		    sizeof(struct vtinput_event));
563 		vq_relchain(vq, event.idx, sizeof(struct vtinput_event));
564 	}
565 done:
566 	/* clear queue and send interrupt to guest */
567 	vtinput_eventqueue_clear(queue);
568 	vq_endchains(vq, 1);
569 }
570 
571 static int
vtinput_read_event_from_host(int fd,struct input_event * event)572 vtinput_read_event_from_host(int fd, struct input_event *event)
573 {
574 	const int len = read(fd, event, sizeof(struct input_event));
575 	if (len != sizeof(struct input_event)) {
576 		if (len == -1 && errno != EAGAIN) {
577 			WPRINTF(("%s: event read failed! len = %d, errno = %d",
578 			    __func__, len, errno));
579 		}
580 
581 		/* host doesn't have more events for us */
582 		return (1);
583 	}
584 
585 	return (0);
586 }
587 
588 static void
vtinput_read_event(int fd __attribute ((unused)),enum ev_type t,void * arg)589 vtinput_read_event(int fd __attribute((unused)),
590     enum ev_type t __attribute__((unused)), void *arg __attribute__((unused)))
591 {
592 	struct pci_vtinput_softc *sc = arg;
593 
594 	/* skip if driver isn't ready */
595 	if (!(sc->vsc_vs.vs_status & VIRTIO_CONFIG_STATUS_DRIVER_OK))
596 		return;
597 
598 	/* read all events from host */
599 	struct input_event event;
600 	while (vtinput_read_event_from_host(sc->vsc_fd, &event) == 0) {
601 		/* add events to our queue */
602 		vtinput_eventqueue_add_event(&sc->vsc_eventqueue, &event);
603 
604 		/* only send events to guest on EV_SYN or SYN_REPORT */
605 		if (event.type != EV_SYN || event.type != SYN_REPORT) {
606 			continue;
607 		}
608 
609 		/* send host events to guest */
610 		vtinput_eventqueue_send_events(
611 		    &sc->vsc_eventqueue, &sc->vsc_queues[VTINPUT_EVENTQ]);
612 	}
613 }
614 
615 static int
pci_vtinput_legacy_config(nvlist_t * nvl,const char * opts)616 pci_vtinput_legacy_config(nvlist_t *nvl, const char *opts)
617 {
618 	if (opts == NULL)
619 		return (-1);
620 
621 	/*
622 	 * parse opts:
623 	 *   virtio-input,/dev/input/eventX
624 	 */
625 	char *cp = strchr(opts, ',');
626 	if (cp == NULL) {
627 		set_config_value_node(nvl, "path", opts);
628 		return (0);
629 	}
630 	char *path = strndup(opts, cp - opts);
631 	set_config_value_node(nvl, "path", path);
632 	free(path);
633 
634 	return (pci_parse_legacy_config(nvl, cp + 1));
635 }
636 
637 static int
pci_vtinput_init(struct pci_devinst * pi,nvlist_t * nvl)638 pci_vtinput_init(struct pci_devinst *pi, nvlist_t *nvl)
639 {
640 	struct pci_vtinput_softc *sc;
641 
642 	/*
643 	 * Keep it here.
644 	 * Else it's possible to access it uninitialized by jumping to failed.
645 	 */
646 	pthread_mutexattr_t mtx_attr = NULL;
647 
648 	sc = calloc(1, sizeof(struct pci_vtinput_softc));
649 
650 	sc->vsc_evdev = get_config_value_node(nvl, "path");
651 	if (sc->vsc_evdev == NULL) {
652 		WPRINTF(("%s: missing required path config value", __func__));
653 		goto failed;
654 	}
655 
656 	/*
657 	 * open evdev by using non blocking I/O:
658 	 *   read from /dev/input/eventX would block our thread otherwise
659 	 */
660 	sc->vsc_fd = open(sc->vsc_evdev, O_RDWR | O_NONBLOCK);
661 	if (sc->vsc_fd < 0) {
662 		WPRINTF(("%s: failed to open %s", __func__, sc->vsc_evdev));
663 		goto failed;
664 	}
665 
666 	/* check if evdev is really a evdev */
667 	int evversion;
668 	int error = ioctl(sc->vsc_fd, EVIOCGVERSION, &evversion);
669 	if (error < 0) {
670 		WPRINTF(("%s: %s is no evdev", __func__, sc->vsc_evdev));
671 		goto failed;
672 	}
673 
674 	/* gain exclusive access to evdev */
675 	error = ioctl(sc->vsc_fd, EVIOCGRAB, 1);
676 	if (error < 0) {
677 		WPRINTF(("%s: failed to grab %s", __func__, sc->vsc_evdev));
678 		goto failed;
679 	}
680 
681 	if (pthread_mutexattr_init(&mtx_attr)) {
682 		WPRINTF(("%s: init mutexattr failed", __func__));
683 		goto failed;
684 	}
685 	if (pthread_mutexattr_settype(&mtx_attr, PTHREAD_MUTEX_RECURSIVE)) {
686 		WPRINTF(("%s: settype mutexattr failed", __func__));
687 		goto failed;
688 	}
689 	if (pthread_mutex_init(&sc->vsc_mtx, &mtx_attr)) {
690 		WPRINTF(("%s: init mutex failed", __func__));
691 		goto failed;
692 	}
693 
694 	/* init softc */
695 	sc->vsc_eventqueue.idx = 0;
696 	sc->vsc_eventqueue.size = VTINPUT_MAX_PKT_LEN;
697 	sc->vsc_eventqueue.events = calloc(
698 	    sc->vsc_eventqueue.size, sizeof(struct vtinput_event_elem));
699 	sc->vsc_config_valid = 0;
700 	if (sc->vsc_eventqueue.events == NULL) {
701 		WPRINTF(("%s: failed to alloc eventqueue", __func__));
702 		goto failed;
703 	}
704 
705 	/* register event handler */
706 	sc->vsc_evp = mevent_add(sc->vsc_fd, EVF_READ, vtinput_read_event, sc);
707 	if (sc->vsc_evp == NULL) {
708 		WPRINTF(("%s: could not register mevent", __func__));
709 		goto failed;
710 	}
711 
712 #ifndef WITHOUT_CAPSICUM
713 	cap_rights_t rights;
714 	cap_rights_init(&rights, CAP_EVENT, CAP_IOCTL, CAP_READ, CAP_WRITE);
715 	if (caph_rights_limit(sc->vsc_fd, &rights) == -1) {
716 		errx(EX_OSERR, "Unable to apply rights for sandbox");
717 	}
718 #endif
719 
720 	/* link virtio to softc */
721 	vi_softc_linkup(
722 	    &sc->vsc_vs, &vtinput_vi_consts, sc, pi, sc->vsc_queues);
723 	sc->vsc_vs.vs_mtx = &sc->vsc_mtx;
724 
725 	/* init virtio queues */
726 	sc->vsc_queues[VTINPUT_EVENTQ].vq_qsize = VTINPUT_RINGSZ;
727 	sc->vsc_queues[VTINPUT_EVENTQ].vq_notify = pci_vtinput_notify_eventq;
728 	sc->vsc_queues[VTINPUT_STATUSQ].vq_qsize = VTINPUT_RINGSZ;
729 	sc->vsc_queues[VTINPUT_STATUSQ].vq_notify = pci_vtinput_notify_statusq;
730 
731 	/* initialize config space */
732 	pci_set_cfgdata16(pi, PCIR_DEVICE, VIRTIO_DEV_INPUT);
733 	pci_set_cfgdata16(pi, PCIR_VENDOR, VIRTIO_VENDOR);
734 	pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_INPUTDEV);
735 	pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_INPUTDEV_OTHER);
736 	pci_set_cfgdata8(pi, PCIR_REVID, VIRTIO_REV_INPUT);
737 	pci_set_cfgdata16(pi, PCIR_SUBDEV_0, VIRTIO_SUBDEV_INPUT);
738 	pci_set_cfgdata16(pi, PCIR_SUBVEND_0, VIRTIO_SUBVEN_INPUT);
739 
740 	/* add MSI-X table BAR */
741 	if (vi_intr_init(&sc->vsc_vs, 1, fbsdrun_virtio_msix()))
742 		goto failed;
743 	/* add virtio register */
744 	vi_set_io_bar(&sc->vsc_vs, 0);
745 
746 	return (0);
747 
748 failed:
749 	if (sc == NULL) {
750 		return (-1);
751 	}
752 
753 	if (sc->vsc_evp)
754 		mevent_delete(sc->vsc_evp);
755 	if (sc->vsc_eventqueue.events)
756 		free(sc->vsc_eventqueue.events);
757 	if (sc->vsc_mtx)
758 		pthread_mutex_destroy(&sc->vsc_mtx);
759 	if (mtx_attr)
760 		pthread_mutexattr_destroy(&mtx_attr);
761 	if (sc->vsc_fd)
762 		close(sc->vsc_fd);
763 
764 	free(sc);
765 
766 	return (-1);
767 }
768 
769 static const struct pci_devemu pci_de_vinput = {
770 	.pe_emu = "virtio-input",
771 	.pe_init = pci_vtinput_init,
772 	.pe_legacy_config = pci_vtinput_legacy_config,
773 	.pe_barwrite = vi_pci_write,
774 	.pe_barread = vi_pci_read,
775 };
776 PCI_EMUL_SET(pci_de_vinput);
777