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