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 77 static int pci_vtinput_debug; 78 #define DPRINTF(params) \ 79 if (pci_vtinput_debug) \ 80 PRINTLN params 81 #define WPRINTF(params) PRINTLN params 82 83 enum 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 93 struct 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 101 struct vtinput_devids { 102 uint16_t bustype; 103 uint16_t vendor; 104 uint16_t product; 105 uint16_t version; 106 } __packed; 107 108 struct 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 121 struct vtinput_event { 122 uint16_t type; 123 uint16_t code; 124 uint32_t value; 125 } __packed; 126 127 struct vtinput_event_elem { 128 struct vtinput_event event; 129 struct iovec iov; 130 uint16_t idx; 131 }; 132 133 struct vtinput_eventqueue { 134 struct vtinput_event_elem *events; 135 uint32_t size; 136 uint32_t idx; 137 }; 138 139 /* 140 * Per-device softc 141 */ 142 struct 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 154 static void pci_vtinput_reset(void *); 155 static int pci_vtinput_cfgread(void *, int, int, uint32_t *); 156 static int pci_vtinput_cfgwrite(void *, int, int, uint32_t); 157 158 static 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 168 static void 169 pci_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 177 static void 178 pci_vtinput_notify_eventq(void *vsc __unused, struct vqueue_info *vq __unused) 179 { 180 DPRINTF(("%s", __func__)); 181 } 182 183 static void 184 pci_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 235 static int 236 pci_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 258 static int 259 pci_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 272 static int 273 pci_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 281 static int 282 pci_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 298 static int 299 pci_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 320 static int 321 pci_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 366 static int 367 pci_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 391 static int 392 pci_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 415 static int 416 pci_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 445 static int 446 pci_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 466 static int 467 vtinput_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 495 static void 496 vtinput_eventqueue_clear(struct vtinput_eventqueue *queue) 497 { 498 /* just reset index to clear queue */ 499 queue->idx = 0; 500 } 501 502 static void 503 vtinput_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 } 563 done: 564 /* clear queue and send interrupt to guest */ 565 vtinput_eventqueue_clear(queue); 566 vq_endchains(vq, 1); 567 } 568 569 static int 570 vtinput_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 586 static void 587 vtinput_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 613 static int 614 pci_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 635 static int 636 pci_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 746 failed: 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 767 static 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 }; 774 PCI_EMUL_SET(pci_de_vinput); 775