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