Set virtqueues in virtio_child_attach_finish The number of virtqueue maybe change in a part of VirtIO devices (e.g. vioif(4)). And it is fixed after negotiation of features. So the configuration is moved into the function.diff -r1.102 -r1.103 src/sys/dev/pci/if_vioif.c
(yamaguchi)
--- src/sys/dev/pci/if_vioif.c 2023/03/23 03:02:17 1.102
+++ src/sys/dev/pci/if_vioif.c 2023/03/23 03:27:48 1.103
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $ */ | 1 | /* $NetBSD: if_vioif.c,v 1.103 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | |
5 | * Copyright (c) 2010 Minoura Makoto. | 5 | * Copyright (c) 2010 Minoura Makoto. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * Redistribution and use in source and binary forms, with or without | 8 | * Redistribution and use in source and binary forms, with or without | |
9 | * modification, are permitted provided that the following conditions | 9 | * modification, are permitted provided that the following conditions | |
10 | * are met: | 10 | * are met: | |
11 | * 1. Redistributions of source code must retain the above copyright | 11 | * 1. Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | 12 | * notice, this list of conditions and the following disclaimer. | |
13 | * 2. Redistributions in binary form must reproduce the above copyright | 13 | * 2. Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in the | 14 | * notice, this list of conditions and the following disclaimer in the | |
@@ -17,27 +17,27 @@ | @@ -17,27 +17,27 @@ | |||
17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | */ | 27 | */ | |
28 | 28 | |||
29 | #include <sys/cdefs.h> | 29 | #include <sys/cdefs.h> | |
30 | __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.102 2023/03/23 03:02:17 yamaguchi Exp $"); | 30 | __KERNEL_RCSID(0, "$NetBSD: if_vioif.c,v 1.103 2023/03/23 03:27:48 yamaguchi Exp $"); | |
31 | 31 | |||
32 | #ifdef _KERNEL_OPT | 32 | #ifdef _KERNEL_OPT | |
33 | #include "opt_net_mpsafe.h" | 33 | #include "opt_net_mpsafe.h" | |
34 | #endif | 34 | #endif | |
35 | 35 | |||
36 | #include <sys/param.h> | 36 | #include <sys/param.h> | |
37 | #include <sys/systm.h> | 37 | #include <sys/systm.h> | |
38 | #include <sys/kernel.h> | 38 | #include <sys/kernel.h> | |
39 | #include <sys/atomic.h> | 39 | #include <sys/atomic.h> | |
40 | #include <sys/bus.h> | 40 | #include <sys/bus.h> | |
41 | #include <sys/condvar.h> | 41 | #include <sys/condvar.h> | |
42 | #include <sys/device.h> | 42 | #include <sys/device.h> | |
43 | #include <sys/evcnt.h> | 43 | #include <sys/evcnt.h> | |
@@ -455,27 +455,27 @@ vioif_match(device_t parent, cfdata_t ma | @@ -455,27 +455,27 @@ vioif_match(device_t parent, cfdata_t ma | |||
455 | 455 | |||
456 | static void | 456 | static void | |
457 | vioif_attach(device_t parent, device_t self, void *aux) | 457 | vioif_attach(device_t parent, device_t self, void *aux) | |
458 | { | 458 | { | |
459 | struct vioif_softc *sc = device_private(self); | 459 | struct vioif_softc *sc = device_private(self); | |
460 | struct virtio_softc *vsc = device_private(parent); | 460 | struct virtio_softc *vsc = device_private(parent); | |
461 | struct vioif_netqueue *txq0; | 461 | struct vioif_netqueue *txq0; | |
462 | struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq; | 462 | struct vioif_ctrlqueue *ctrlq = &sc->sc_ctrlq; | |
463 | uint64_t features, req_features; | 463 | uint64_t features, req_features; | |
464 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | 464 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; | |
465 | u_int softint_flags; | 465 | u_int softint_flags; | |
466 | int r, i, req_flags; | 466 | int r, i, req_flags; | |
467 | char xnamebuf[MAXCOMLEN]; | 467 | char xnamebuf[MAXCOMLEN]; | |
468 | size_t netq_num; | 468 | size_t nvqs; | |
469 | 469 | |||
470 | if (virtio_child(vsc) != NULL) { | 470 | if (virtio_child(vsc) != NULL) { | |
471 | aprint_normal(": child already attached for %s; " | 471 | aprint_normal(": child already attached for %s; " | |
472 | "something wrong...\n", device_xname(parent)); | 472 | "something wrong...\n", device_xname(parent)); | |
473 | return; | 473 | return; | |
474 | } | 474 | } | |
475 | 475 | |||
476 | sc->sc_dev = self; | 476 | sc->sc_dev = self; | |
477 | sc->sc_virtio = vsc; | 477 | sc->sc_virtio = vsc; | |
478 | sc->sc_link_state = LINK_STATE_UNKNOWN; | 478 | sc->sc_link_state = LINK_STATE_UNKNOWN; | |
479 | 479 | |||
480 | sc->sc_max_nvq_pairs = 1; | 480 | sc->sc_max_nvq_pairs = 1; | |
481 | sc->sc_req_nvq_pairs = 1; | 481 | sc->sc_req_nvq_pairs = 1; | |
@@ -499,31 +499,31 @@ vioif_attach(device_t parent, device_t s | @@ -499,31 +499,31 @@ vioif_attach(device_t parent, device_t s | |||
499 | #ifdef VIOIF_MPSAFE | 499 | #ifdef VIOIF_MPSAFE | |
500 | req_flags |= VIRTIO_F_INTR_MPSAFE; | 500 | req_flags |= VIRTIO_F_INTR_MPSAFE; | |
501 | #endif | 501 | #endif | |
502 | req_flags |= VIRTIO_F_INTR_MSIX; | 502 | req_flags |= VIRTIO_F_INTR_MSIX; | |
503 | 503 | |||
504 | req_features = | 504 | req_features = | |
505 | VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ | | 505 | VIRTIO_NET_F_MAC | VIRTIO_NET_F_STATUS | VIRTIO_NET_F_CTRL_VQ | | |
506 | VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY; | 506 | VIRTIO_NET_F_CTRL_RX | VIRTIO_F_NOTIFY_ON_EMPTY; | |
507 | req_features |= VIRTIO_F_RING_EVENT_IDX; | 507 | req_features |= VIRTIO_F_RING_EVENT_IDX; | |
508 | req_features |= VIRTIO_NET_F_CTRL_MAC_ADDR; | 508 | req_features |= VIRTIO_NET_F_CTRL_MAC_ADDR; | |
509 | #ifdef VIOIF_MULTIQ | 509 | #ifdef VIOIF_MULTIQ | |
510 | req_features |= VIRTIO_NET_F_MQ; | 510 | req_features |= VIRTIO_NET_F_MQ; | |
511 | #endif | 511 | #endif | |
512 | virtio_child_attach_start(vsc, self, IPL_NET, NULL, | |||
513 | vioif_config_change, virtio_vq_intrhand, req_flags, | |||
514 | req_features, VIRTIO_NET_FLAG_BITS); | |||
515 | 512 | |||
513 | virtio_child_attach_start(vsc, self, IPL_NET, | |||
514 | req_features, VIRTIO_NET_FLAG_BITS); | |||
516 | features = virtio_features(vsc); | 515 | features = virtio_features(vsc); | |
516 | ||||
517 | if (features == 0) | 517 | if (features == 0) | |
518 | goto err; | 518 | goto err; | |
519 | 519 | |||
520 | if (features & VIRTIO_NET_F_MAC) { | 520 | if (features & VIRTIO_NET_F_MAC) { | |
521 | for (i = 0; i < __arraycount(sc->sc_mac); i++) { | 521 | for (i = 0; i < __arraycount(sc->sc_mac); i++) { | |
522 | sc->sc_mac[i] = virtio_read_device_config_1(vsc, | 522 | sc->sc_mac[i] = virtio_read_device_config_1(vsc, | |
523 | VIRTIO_NET_CONFIG_MAC + i); | 523 | VIRTIO_NET_CONFIG_MAC + i); | |
524 | } | 524 | } | |
525 | } else { | 525 | } else { | |
526 | /* code stolen from sys/net/if_tap.c */ | 526 | /* code stolen from sys/net/if_tap.c */ | |
527 | struct timeval tv; | 527 | struct timeval tv; | |
528 | uint32_t ui; | 528 | uint32_t ui; | |
529 | getmicrouptime(&tv); | 529 | getmicrouptime(&tv); | |
@@ -555,49 +555,53 @@ vioif_attach(device_t parent, device_t s | @@ -555,49 +555,53 @@ vioif_attach(device_t parent, device_t s | |||
555 | } else { | 555 | } else { | |
556 | sc->sc_has_ctrl = false; | 556 | sc->sc_has_ctrl = false; | |
557 | } | 557 | } | |
558 | 558 | |||
559 | if (sc->sc_has_ctrl && (features & VIRTIO_NET_F_MQ)) { | 559 | if (sc->sc_has_ctrl && (features & VIRTIO_NET_F_MQ)) { | |
560 | sc->sc_max_nvq_pairs = virtio_read_device_config_2(vsc, | 560 | sc->sc_max_nvq_pairs = virtio_read_device_config_2(vsc, | |
561 | VIRTIO_NET_CONFIG_MAX_VQ_PAIRS); | 561 | VIRTIO_NET_CONFIG_MAX_VQ_PAIRS); | |
562 | 562 | |||
563 | if (sc->sc_max_nvq_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX) | 563 | if (sc->sc_max_nvq_pairs > VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX) | |
564 | goto err; | 564 | goto err; | |
565 | 565 | |||
566 | /* Limit the number of queue pairs to use */ | 566 | /* Limit the number of queue pairs to use */ | |
567 | sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu); | 567 | sc->sc_req_nvq_pairs = MIN(sc->sc_max_nvq_pairs, ncpu); | |
568 | ||||
569 | if (sc->sc_max_nvq_pairs > 1) | |||
570 | req_flags |= VIRTIO_F_INTR_PERVQ; | |||
568 | } | 571 | } | |
569 | 572 | |||
570 | vioif_alloc_queues(sc); | 573 | vioif_alloc_queues(sc); | |
571 | virtio_child_attach_set_vqs(vsc, sc->sc_vqs, sc->sc_req_nvq_pairs); | |||
572 | 574 | |||
573 | #ifdef VIOIF_MPSAFE | 575 | #ifdef VIOIF_MPSAFE | |
574 | softint_flags = SOFTINT_NET | SOFTINT_MPSAFE; | 576 | softint_flags = SOFTINT_NET | SOFTINT_MPSAFE; | |
575 | #else | 577 | #else | |
576 | softint_flags = SOFTINT_NET; | 578 | softint_flags = SOFTINT_NET; | |
577 | #endif | 579 | #endif | |
578 | 580 | |||
579 | /* | 581 | /* | |
580 | * Initialize network queues | 582 | * Initialize network queues | |
581 | */ | 583 | */ | |
582 | netq_num = sc->sc_max_nvq_pairs * 2; | 584 | nvqs = sc->sc_max_nvq_pairs * 2; | |
583 | for (i = 0; i < netq_num; i++) { | 585 | for (i = 0; i < nvqs; i++) { | |
584 | r = vioif_netqueue_init(sc, vsc, i, softint_flags); | 586 | r = vioif_netqueue_init(sc, vsc, i, softint_flags); | |
585 | if (r != 0) | 587 | if (r != 0) | |
586 | goto err; | 588 | goto err; | |
587 | } | 589 | } | |
588 | 590 | |||
589 | if (sc->sc_has_ctrl) { | 591 | if (sc->sc_has_ctrl) { | |
590 | int ctrlq_idx = sc->sc_max_nvq_pairs * 2; | 592 | int ctrlq_idx = nvqs; | |
593 | ||||
594 | nvqs++; | |||
591 | /* | 595 | /* | |
592 | * Allocating a virtqueue for control channel | 596 | * Allocating a virtqueue for control channel | |
593 | */ | 597 | */ | |
594 | sc->sc_ctrlq.ctrlq_vq = &sc->sc_vqs[ctrlq_idx]; | 598 | sc->sc_ctrlq.ctrlq_vq = &sc->sc_vqs[ctrlq_idx]; | |
595 | r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, ctrlq_idx, | 599 | r = virtio_alloc_vq(vsc, ctrlq->ctrlq_vq, ctrlq_idx, | |
596 | NBPG, 1, "control"); | 600 | NBPG, 1, "control"); | |
597 | if (r != 0) { | 601 | if (r != 0) { | |
598 | aprint_error_dev(self, "failed to allocate " | 602 | aprint_error_dev(self, "failed to allocate " | |
599 | "a virtqueue for control channel, error code %d\n", | 603 | "a virtqueue for control channel, error code %d\n", | |
600 | r); | 604 | r); | |
601 | 605 | |||
602 | sc->sc_has_ctrl = false; | 606 | sc->sc_has_ctrl = false; | |
603 | cv_destroy(&ctrlq->ctrlq_wait); | 607 | cv_destroy(&ctrlq->ctrlq_wait); | |
@@ -608,27 +612,29 @@ vioif_attach(device_t parent, device_t s | @@ -608,27 +612,29 @@ vioif_attach(device_t parent, device_t s | |||
608 | } | 612 | } | |
609 | } | 613 | } | |
610 | 614 | |||
611 | sc->sc_cfg_softint = softint_establish(softint_flags, | 615 | sc->sc_cfg_softint = softint_establish(softint_flags, | |
612 | vioif_cfg_softint, sc); | 616 | vioif_cfg_softint, sc); | |
613 | if (sc->sc_cfg_softint == NULL) { | 617 | if (sc->sc_cfg_softint == NULL) { | |
614 | aprint_error_dev(self, "cannot establish ctl softint\n"); | 618 | aprint_error_dev(self, "cannot establish ctl softint\n"); | |
615 | goto err; | 619 | goto err; | |
616 | } | 620 | } | |
617 | 621 | |||
618 | if (vioif_alloc_mems(sc) < 0) | 622 | if (vioif_alloc_mems(sc) < 0) | |
619 | goto err; | 623 | goto err; | |
620 | 624 | |||
621 | if (virtio_child_attach_finish(vsc) != 0) | 625 | r = virtio_child_attach_finish(vsc, sc->sc_vqs, nvqs, | |
626 | vioif_config_change, virtio_vq_intrhand, req_flags); | |||
627 | if (r != 0) | |||
622 | goto err; | 628 | goto err; | |
623 | 629 | |||
624 | if (vioif_setup_sysctl(sc) != 0) { | 630 | if (vioif_setup_sysctl(sc) != 0) { | |
625 | aprint_error_dev(self, "unable to create sysctl node\n"); | 631 | aprint_error_dev(self, "unable to create sysctl node\n"); | |
626 | /* continue */ | 632 | /* continue */ | |
627 | } | 633 | } | |
628 | 634 | |||
629 | vioif_setup_stats(sc); | 635 | vioif_setup_stats(sc); | |
630 | 636 | |||
631 | strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); | 637 | strlcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); | |
632 | ifp->if_softc = sc; | 638 | ifp->if_softc = sc; | |
633 | ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; | 639 | ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; | |
634 | #ifdef VIOIF_MPSAFE | 640 | #ifdef VIOIF_MPSAFE | |
@@ -646,28 +652,28 @@ vioif_attach(device_t parent, device_t s | @@ -646,28 +652,28 @@ vioif_attach(device_t parent, device_t s | |||
646 | IFQ_SET_MAXLEN(&ifp->if_snd, MAX(txq0->netq_vq->vq_num, IFQ_MAXLEN)); | 652 | IFQ_SET_MAXLEN(&ifp->if_snd, MAX(txq0->netq_vq->vq_num, IFQ_MAXLEN)); | |
647 | IFQ_SET_READY(&ifp->if_snd); | 653 | IFQ_SET_READY(&ifp->if_snd); | |
648 | 654 | |||
649 | sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; | 655 | sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; | |
650 | 656 | |||
651 | if_attach(ifp); | 657 | if_attach(ifp); | |
652 | if_deferred_start_init(ifp, NULL); | 658 | if_deferred_start_init(ifp, NULL); | |
653 | ether_ifattach(ifp, sc->sc_mac); | 659 | ether_ifattach(ifp, sc->sc_mac); | |
654 | ether_set_ifflags_cb(&sc->sc_ethercom, vioif_ifflags_cb); | 660 | ether_set_ifflags_cb(&sc->sc_ethercom, vioif_ifflags_cb); | |
655 | 661 | |||
656 | return; | 662 | return; | |
657 | 663 | |||
658 | err: | 664 | err: | |
659 | netq_num = sc->sc_max_nvq_pairs * 2; | 665 | nvqs = sc->sc_max_nvq_pairs * 2; | |
660 | for (i = 0; i < netq_num; i++) { | 666 | for (i = 0; i < nvqs; i++) { | |
661 | vioif_netqueue_teardown(sc, vsc, i); | 667 | vioif_netqueue_teardown(sc, vsc, i); | |
662 | } | 668 | } | |
663 | 669 | |||
664 | if (sc->sc_has_ctrl) { | 670 | if (sc->sc_has_ctrl) { | |
665 | cv_destroy(&ctrlq->ctrlq_wait); | 671 | cv_destroy(&ctrlq->ctrlq_wait); | |
666 | mutex_destroy(&ctrlq->ctrlq_wait_lock); | 672 | mutex_destroy(&ctrlq->ctrlq_wait_lock); | |
667 | virtio_free_vq(vsc, ctrlq->ctrlq_vq); | 673 | virtio_free_vq(vsc, ctrlq->ctrlq_vq); | |
668 | ctrlq->ctrlq_vq = NULL; | 674 | ctrlq->ctrlq_vq = NULL; | |
669 | } | 675 | } | |
670 | 676 | |||
671 | vioif_free_queues(sc); | 677 | vioif_free_queues(sc); | |
672 | mutex_destroy(&sc->sc_lock); | 678 | mutex_destroy(&sc->sc_lock); | |
673 | virtio_child_attach_failed(vsc); | 679 | virtio_child_attach_failed(vsc); |
--- src/sys/dev/pci/ld_virtio.c 2022/04/13 10:42:12 1.30
+++ src/sys/dev/pci/ld_virtio.c 2023/03/23 03:27:48 1.31
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: ld_virtio.c,v 1.30 2022/04/13 10:42:12 uwe Exp $ */ | 1 | /* $NetBSD: ld_virtio.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Minoura Makoto. | 4 | * Copyright (c) 2010 Minoura Makoto. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -16,27 +16,27 @@ | @@ -16,27 +16,27 @@ | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | __KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.30 2022/04/13 10:42:12 uwe Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: ld_virtio.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $"); | |
30 | 30 | |||
31 | #include <sys/param.h> | 31 | #include <sys/param.h> | |
32 | #include <sys/systm.h> | 32 | #include <sys/systm.h> | |
33 | #include <sys/kernel.h> | 33 | #include <sys/kernel.h> | |
34 | #include <sys/buf.h> | 34 | #include <sys/buf.h> | |
35 | #include <sys/bufq.h> | 35 | #include <sys/bufq.h> | |
36 | #include <sys/bus.h> | 36 | #include <sys/bus.h> | |
37 | #include <sys/device.h> | 37 | #include <sys/device.h> | |
38 | #include <sys/disk.h> | 38 | #include <sys/disk.h> | |
39 | #include <sys/mutex.h> | 39 | #include <sys/mutex.h> | |
40 | #include <sys/module.h> | 40 | #include <sys/module.h> | |
41 | 41 | |||
42 | #include <dev/ldvar.h> | 42 | #include <dev/ldvar.h> | |
@@ -265,28 +265,27 @@ ld_virtio_attach(device_t parent, device | @@ -265,28 +265,27 @@ ld_virtio_attach(device_t parent, device | |||
265 | struct virtio_softc *vsc = device_private(parent); | 265 | struct virtio_softc *vsc = device_private(parent); | |
266 | uint64_t features; | 266 | uint64_t features; | |
267 | int qsize, maxxfersize, maxnsegs; | 267 | int qsize, maxxfersize, maxnsegs; | |
268 | 268 | |||
269 | if (virtio_child(vsc) != NULL) { | 269 | if (virtio_child(vsc) != NULL) { | |
270 | aprint_normal(": child already attached for %s; " | 270 | aprint_normal(": child already attached for %s; " | |
271 | "something wrong...\n", device_xname(parent)); | 271 | "something wrong...\n", device_xname(parent)); | |
272 | return; | 272 | return; | |
273 | } | 273 | } | |
274 | 274 | |||
275 | sc->sc_dev = self; | 275 | sc->sc_dev = self; | |
276 | sc->sc_virtio = vsc; | 276 | sc->sc_virtio = vsc; | |
277 | 277 | |||
278 | virtio_child_attach_start(vsc, self, IPL_BIO, &sc->sc_vq, | 278 | virtio_child_attach_start(vsc, self, IPL_BIO, | |
279 | NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX, | |||
280 | (VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX | | 279 | (VIRTIO_BLK_F_SIZE_MAX | VIRTIO_BLK_F_SEG_MAX | | |
281 | VIRTIO_BLK_F_GEOMETRY | VIRTIO_BLK_F_RO | VIRTIO_BLK_F_BLK_SIZE | | 280 | VIRTIO_BLK_F_GEOMETRY | VIRTIO_BLK_F_RO | VIRTIO_BLK_F_BLK_SIZE | | |
282 | VIRTIO_BLK_F_FLUSH | VIRTIO_BLK_F_CONFIG_WCE), | 281 | VIRTIO_BLK_F_FLUSH | VIRTIO_BLK_F_CONFIG_WCE), | |
283 | VIRTIO_BLK_FLAG_BITS); | 282 | VIRTIO_BLK_FLAG_BITS); | |
284 | 283 | |||
285 | features = virtio_features(vsc); | 284 | features = virtio_features(vsc); | |
286 | if (features == 0) | 285 | if (features == 0) | |
287 | goto err; | 286 | goto err; | |
288 | 287 | |||
289 | if (features & VIRTIO_BLK_F_RO) | 288 | if (features & VIRTIO_BLK_F_RO) | |
290 | sc->sc_readonly = 1; | 289 | sc->sc_readonly = 1; | |
291 | else | 290 | else | |
292 | sc->sc_readonly = 0; | 291 | sc->sc_readonly = 0; | |
@@ -330,27 +329,28 @@ ld_virtio_attach(device_t parent, device | @@ -330,27 +329,28 @@ ld_virtio_attach(device_t parent, device | |||
330 | } else | 329 | } else | |
331 | maxnsegs = maxxfersize / NBPG; | 330 | maxnsegs = maxxfersize / NBPG; | |
332 | 331 | |||
333 | /* 2 for the minimum size */ | 332 | /* 2 for the minimum size */ | |
334 | maxnsegs += VIRTIO_BLK_MIN_SEGMENTS; | 333 | maxnsegs += VIRTIO_BLK_MIN_SEGMENTS; | |
335 | 334 | |||
336 | if (virtio_alloc_vq(vsc, &sc->sc_vq, 0, maxxfersize, maxnsegs, | 335 | if (virtio_alloc_vq(vsc, &sc->sc_vq, 0, maxxfersize, maxnsegs, | |
337 | "I/O request") != 0) { | 336 | "I/O request") != 0) { | |
338 | goto err; | 337 | goto err; | |
339 | } | 338 | } | |
340 | qsize = sc->sc_vq.vq_num; | 339 | qsize = sc->sc_vq.vq_num; | |
341 | sc->sc_vq.vq_done = ld_virtio_vq_done; | 340 | sc->sc_vq.vq_done = ld_virtio_vq_done; | |
342 | 341 | |||
343 | if (virtio_child_attach_finish(vsc) != 0) | 342 | if (virtio_child_attach_finish(vsc, &sc->sc_vq, 1, | |
343 | NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX) != 0) | |||
344 | goto err; | 344 | goto err; | |
345 | 345 | |||
346 | ld->sc_dv = self; | 346 | ld->sc_dv = self; | |
347 | ld->sc_secperunit = virtio_read_device_config_8(vsc, | 347 | ld->sc_secperunit = virtio_read_device_config_8(vsc, | |
348 | VIRTIO_BLK_CONFIG_CAPACITY) / (ld->sc_secsize / VIRTIO_BLK_BSIZE); | 348 | VIRTIO_BLK_CONFIG_CAPACITY) / (ld->sc_secsize / VIRTIO_BLK_BSIZE); | |
349 | ld->sc_maxxfer = maxxfersize; | 349 | ld->sc_maxxfer = maxxfersize; | |
350 | if (features & VIRTIO_BLK_F_GEOMETRY) { | 350 | if (features & VIRTIO_BLK_F_GEOMETRY) { | |
351 | ld->sc_ncylinders = virtio_read_device_config_2(vsc, | 351 | ld->sc_ncylinders = virtio_read_device_config_2(vsc, | |
352 | VIRTIO_BLK_CONFIG_GEOMETRY_C); | 352 | VIRTIO_BLK_CONFIG_GEOMETRY_C); | |
353 | ld->sc_nheads = virtio_read_device_config_1(vsc, | 353 | ld->sc_nheads = virtio_read_device_config_1(vsc, | |
354 | VIRTIO_BLK_CONFIG_GEOMETRY_H); | 354 | VIRTIO_BLK_CONFIG_GEOMETRY_H); | |
355 | ld->sc_nsectors = virtio_read_device_config_1(vsc, | 355 | ld->sc_nsectors = virtio_read_device_config_1(vsc, | |
356 | VIRTIO_BLK_CONFIG_GEOMETRY_S); | 356 | VIRTIO_BLK_CONFIG_GEOMETRY_S); |
--- src/sys/dev/pci/vioscsi.c 2022/10/11 22:03:37 1.30
+++ src/sys/dev/pci/vioscsi.c 2023/03/23 03:27:48 1.31
@@ -1,34 +1,34 @@ | @@ -1,34 +1,34 @@ | |||
1 | /* $NetBSD: vioscsi.c,v 1.30 2022/10/11 22:03:37 andvar Exp $ */ | 1 | /* $NetBSD: vioscsi.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | /* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ | 2 | /* $OpenBSD: vioscsi.c,v 1.3 2015/03/14 03:38:49 jsg Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2013 Google Inc. | 5 | * Copyright (c) 2013 Google Inc. | |
6 | * | 6 | * | |
7 | * Permission to use, copy, modify, and distribute this software for any | 7 | * Permission to use, copy, modify, and distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | 9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | 10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
18 | */ | 18 | */ | |
19 | 19 | |||
20 | #include <sys/cdefs.h> | 20 | #include <sys/cdefs.h> | |
21 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.30 2022/10/11 22:03:37 andvar Exp $"); | 21 | __KERNEL_RCSID(0, "$NetBSD: vioscsi.c,v 1.31 2023/03/23 03:27:48 yamaguchi Exp $"); | |
22 | 22 | |||
23 | #include <sys/param.h> | 23 | #include <sys/param.h> | |
24 | #include <sys/systm.h> | 24 | #include <sys/systm.h> | |
25 | #include <sys/device.h> | 25 | #include <sys/device.h> | |
26 | #include <sys/bus.h> | 26 | #include <sys/bus.h> | |
27 | #include <sys/buf.h> | 27 | #include <sys/buf.h> | |
28 | #include <sys/module.h> | 28 | #include <sys/module.h> | |
29 | 29 | |||
30 | #include <dev/pci/vioscsireg.h> | 30 | #include <dev/pci/vioscsireg.h> | |
31 | #include <dev/pci/virtiovar.h> | 31 | #include <dev/pci/virtiovar.h> | |
32 | 32 | |||
33 | #include <dev/scsipi/scsi_all.h> | 33 | #include <dev/scsipi/scsi_all.h> | |
34 | #include <dev/scsipi/scsiconf.h> | 34 | #include <dev/scsipi/scsiconf.h> | |
@@ -118,28 +118,27 @@ vioscsi_attach(device_t parent, device_t | @@ -118,28 +118,27 @@ vioscsi_attach(device_t parent, device_t | |||
118 | struct scsipi_adapter *adapt = &sc->sc_adapter; | 118 | struct scsipi_adapter *adapt = &sc->sc_adapter; | |
119 | struct scsipi_channel *chan = &sc->sc_channel; | 119 | struct scsipi_channel *chan = &sc->sc_channel; | |
120 | int rv, qsize = 0, i = 0; | 120 | int rv, qsize = 0, i = 0; | |
121 | int ipl = IPL_BIO; | 121 | int ipl = IPL_BIO; | |
122 | 122 | |||
123 | if (virtio_child(vsc) != NULL) { | 123 | if (virtio_child(vsc) != NULL) { | |
124 | aprint_error(": parent %s already has a child\n", | 124 | aprint_error(": parent %s already has a child\n", | |
125 | device_xname(parent)); | 125 | device_xname(parent)); | |
126 | return; | 126 | return; | |
127 | } | 127 | } | |
128 | 128 | |||
129 | sc->sc_dev = self; | 129 | sc->sc_dev = self; | |
130 | 130 | |||
131 | virtio_child_attach_start(vsc, self, ipl, sc->sc_vqs, | 131 | virtio_child_attach_start(vsc, self, ipl, | |
132 | NULL, virtio_vq_intr, VIRTIO_F_INTR_MSIX, | |||
133 | 0, VIRTIO_COMMON_FLAG_BITS); | 132 | 0, VIRTIO_COMMON_FLAG_BITS); | |
134 | 133 | |||
135 | mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, ipl); | 134 | mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, ipl); | |
136 | 135 | |||
137 | uint32_t cmd_per_lun = virtio_read_device_config_4(vsc, | 136 | uint32_t cmd_per_lun = virtio_read_device_config_4(vsc, | |
138 | VIRTIO_SCSI_CONFIG_CMD_PER_LUN); | 137 | VIRTIO_SCSI_CONFIG_CMD_PER_LUN); | |
139 | 138 | |||
140 | uint32_t seg_max = virtio_read_device_config_4(vsc, | 139 | uint32_t seg_max = virtio_read_device_config_4(vsc, | |
141 | VIRTIO_SCSI_CONFIG_SEG_MAX); | 140 | VIRTIO_SCSI_CONFIG_SEG_MAX); | |
142 | 141 | |||
143 | uint16_t max_target = virtio_read_device_config_2(vsc, | 142 | uint16_t max_target = virtio_read_device_config_2(vsc, | |
144 | VIRTIO_SCSI_CONFIG_MAX_TARGET); | 143 | VIRTIO_SCSI_CONFIG_MAX_TARGET); | |
145 | 144 | |||
@@ -161,27 +160,29 @@ vioscsi_attach(device_t parent, device_t | @@ -161,27 +160,29 @@ vioscsi_attach(device_t parent, device_t | |||
161 | if (i == VIOSCSI_VQ_REQUEST) | 160 | if (i == VIOSCSI_VQ_REQUEST) | |
162 | sc->sc_vqs[i].vq_done = vioscsi_vq_done; | 161 | sc->sc_vqs[i].vq_done = vioscsi_vq_done; | |
163 | } | 162 | } | |
164 | 163 | |||
165 | qsize = sc->sc_vqs[VIOSCSI_VQ_REQUEST].vq_num; | 164 | qsize = sc->sc_vqs[VIOSCSI_VQ_REQUEST].vq_num; | |
166 | if (vioscsi_alloc_reqs(sc, vsc, qsize)) | 165 | if (vioscsi_alloc_reqs(sc, vsc, qsize)) | |
167 | goto err; | 166 | goto err; | |
168 | 167 | |||
169 | aprint_normal_dev(sc->sc_dev, | 168 | aprint_normal_dev(sc->sc_dev, | |
170 | "cmd_per_lun %u qsize %d seg_max %u max_target %hu" | 169 | "cmd_per_lun %u qsize %d seg_max %u max_target %hu" | |
171 | " max_lun %u\n", | 170 | " max_lun %u\n", | |
172 | cmd_per_lun, qsize, seg_max, max_target, max_lun); | 171 | cmd_per_lun, qsize, seg_max, max_target, max_lun); | |
173 | 172 | |||
174 | if (virtio_child_attach_finish(vsc) != 0) | 173 | if (virtio_child_attach_finish(vsc, sc->sc_vqs, | |
174 | __arraycount(sc->sc_vqs), NULL, virtio_vq_intr, | |||
175 | VIRTIO_F_INTR_MSIX) != 0) | |||
175 | goto err; | 176 | goto err; | |
176 | 177 | |||
177 | /* | 178 | /* | |
178 | * Fill in the scsipi_adapter. | 179 | * Fill in the scsipi_adapter. | |
179 | */ | 180 | */ | |
180 | memset(adapt, 0, sizeof(*adapt)); | 181 | memset(adapt, 0, sizeof(*adapt)); | |
181 | adapt->adapt_dev = sc->sc_dev; | 182 | adapt->adapt_dev = sc->sc_dev; | |
182 | adapt->adapt_nchannels = 1; | 183 | adapt->adapt_nchannels = 1; | |
183 | adapt->adapt_openings = MIN(qsize, cmd_per_lun); | 184 | adapt->adapt_openings = MIN(qsize, cmd_per_lun); | |
184 | adapt->adapt_max_periph = adapt->adapt_openings; | 185 | adapt->adapt_max_periph = adapt->adapt_openings; | |
185 | adapt->adapt_request = vioscsi_scsipi_request; | 186 | adapt->adapt_request = vioscsi_scsipi_request; | |
186 | adapt->adapt_minphys = minphys; | 187 | adapt->adapt_minphys = minphys; | |
187 | 188 |
--- src/sys/dev/pci/vio9p.c 2022/04/20 22:08:10 1.9
+++ src/sys/dev/pci/vio9p.c 2023/03/23 03:27:48 1.10
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: vio9p.c,v 1.9 2022/04/20 22:08:10 uwe Exp $ */ | 1 | /* $NetBSD: vio9p.c,v 1.10 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2019 Internet Initiative Japan, Inc. | 4 | * Copyright (c) 2019 Internet Initiative Japan, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -16,27 +16,27 @@ | @@ -16,27 +16,27 @@ | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | __KERNEL_RCSID(0, "$NetBSD: vio9p.c,v 1.9 2022/04/20 22:08:10 uwe Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: vio9p.c,v 1.10 2023/03/23 03:27:48 yamaguchi Exp $"); | |
30 | 30 | |||
31 | #include <sys/param.h> | 31 | #include <sys/param.h> | |
32 | #include <sys/systm.h> | 32 | #include <sys/systm.h> | |
33 | #include <sys/kernel.h> | 33 | #include <sys/kernel.h> | |
34 | #include <sys/bus.h> | 34 | #include <sys/bus.h> | |
35 | #include <sys/conf.h> | 35 | #include <sys/conf.h> | |
36 | #include <sys/condvar.h> | 36 | #include <sys/condvar.h> | |
37 | #include <sys/device.h> | 37 | #include <sys/device.h> | |
38 | #include <sys/mutex.h> | 38 | #include <sys/mutex.h> | |
39 | #include <sys/sysctl.h> | 39 | #include <sys/sysctl.h> | |
40 | #include <sys/module.h> | 40 | #include <sys/module.h> | |
41 | #include <sys/syslog.h> | 41 | #include <sys/syslog.h> | |
42 | #include <sys/select.h> | 42 | #include <sys/select.h> | |
@@ -490,45 +490,40 @@ vio9p_attach(device_t parent, device_t s | @@ -490,45 +490,40 @@ vio9p_attach(device_t parent, device_t s | |||
490 | struct virtio_softc *vsc = device_private(parent); | 490 | struct virtio_softc *vsc = device_private(parent); | |
491 | uint64_t features; | 491 | uint64_t features; | |
492 | int error; | 492 | int error; | |
493 | 493 | |||
494 | if (virtio_child(vsc) != NULL) { | 494 | if (virtio_child(vsc) != NULL) { | |
495 | aprint_normal(": child already attached for %s; " | 495 | aprint_normal(": child already attached for %s; " | |
496 | "something wrong...\n", device_xname(parent)); | 496 | "something wrong...\n", device_xname(parent)); | |
497 | return; | 497 | return; | |
498 | } | 498 | } | |
499 | 499 | |||
500 | sc->sc_dev = self; | 500 | sc->sc_dev = self; | |
501 | sc->sc_virtio = vsc; | 501 | sc->sc_virtio = vsc; | |
502 | 502 | |||
503 | virtio_child_attach_start(vsc, self, IPL_VM, sc->sc_vq, | 503 | virtio_child_attach_start(vsc, self, IPL_VM, | |
504 | NULL, virtio_vq_intr, | 504 | VIO9P_F_MOUNT_TAG, VIO9P_FLAG_BITS); | |
505 | VIRTIO_F_INTR_MPSAFE | VIRTIO_F_INTR_SOFTINT, | |||
506 | VIO9P_F_MOUNT_TAG, | |||
507 | VIO9P_FLAG_BITS); | |||
508 | 505 | |||
509 | features = virtio_features(vsc); | 506 | features = virtio_features(vsc); | |
510 | if ((features & VIO9P_F_MOUNT_TAG) == 0) | 507 | if ((features & VIO9P_F_MOUNT_TAG) == 0) | |
511 | goto err_none; | 508 | goto err_none; | |
512 | 509 | |||
513 | error = virtio_alloc_vq(vsc, &sc->sc_vq[0], 0, VIO9P_MAX_REQLEN, | 510 | error = virtio_alloc_vq(vsc, &sc->sc_vq[0], 0, VIO9P_MAX_REQLEN, | |
514 | VIO9P_N_SEGMENTS * 2, "vio9p"); | 511 | VIO9P_N_SEGMENTS * 2, "vio9p"); | |
515 | if (error != 0) | 512 | if (error != 0) | |
516 | goto err_none; | 513 | goto err_none; | |
517 | 514 | |||
518 | sc->sc_vq[0].vq_done = vio9p_request_done; | 515 | sc->sc_vq[0].vq_done = vio9p_request_done; | |
519 | 516 | |||
520 | virtio_child_attach_set_vqs(vsc, sc->sc_vq, 1); | |||
521 | ||||
522 | sc->sc_buf_tx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP); | 517 | sc->sc_buf_tx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP); | |
523 | sc->sc_buf_rx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP); | 518 | sc->sc_buf_rx = kmem_alloc(VIO9P_MAX_REQLEN, KM_SLEEP); | |
524 | 519 | |||
525 | error = bus_dmamap_create(virtio_dmat(vsc), VIO9P_MAX_REQLEN, | 520 | error = bus_dmamap_create(virtio_dmat(vsc), VIO9P_MAX_REQLEN, | |
526 | VIO9P_N_SEGMENTS, VIO9P_SEGSIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap_tx); | 521 | VIO9P_N_SEGMENTS, VIO9P_SEGSIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap_tx); | |
527 | if (error != 0) { | 522 | if (error != 0) { | |
528 | aprint_error_dev(sc->sc_dev, "bus_dmamap_create failed: %d\n", | 523 | aprint_error_dev(sc->sc_dev, "bus_dmamap_create failed: %d\n", | |
529 | error); | 524 | error); | |
530 | goto err_vq; | 525 | goto err_vq; | |
531 | } | 526 | } | |
532 | error = bus_dmamap_create(virtio_dmat(vsc), VIO9P_MAX_REQLEN, | 527 | error = bus_dmamap_create(virtio_dmat(vsc), VIO9P_MAX_REQLEN, | |
533 | VIO9P_N_SEGMENTS, VIO9P_SEGSIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap_rx); | 528 | VIO9P_N_SEGMENTS, VIO9P_SEGSIZE, 0, BUS_DMA_WAITOK, &sc->sc_dmamap_rx); | |
534 | if (error != 0) { | 529 | if (error != 0) { | |
@@ -549,27 +544,29 @@ vio9p_attach(device_t parent, device_t s | @@ -549,27 +544,29 @@ vio9p_attach(device_t parent, device_t s | |||
549 | if (error != 0) { | 544 | if (error != 0) { | |
550 | aprint_error_dev(sc->sc_dev, "bus_dmamap_load failed: %d\n", | 545 | aprint_error_dev(sc->sc_dev, "bus_dmamap_load failed: %d\n", | |
551 | error); | 546 | error); | |
552 | goto err_dmamap; | 547 | goto err_dmamap; | |
553 | } | 548 | } | |
554 | 549 | |||
555 | sc->sc_state = VIO9P_S_INIT; | 550 | sc->sc_state = VIO9P_S_INIT; | |
556 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); | 551 | mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); | |
557 | cv_init(&sc->sc_wait, "vio9p"); | 552 | cv_init(&sc->sc_wait, "vio9p"); | |
558 | 553 | |||
559 | vio9p_read_config(sc); | 554 | vio9p_read_config(sc); | |
560 | aprint_normal_dev(self, "tagged as %s\n", sc->sc_tag); | 555 | aprint_normal_dev(self, "tagged as %s\n", sc->sc_tag); | |
561 | 556 | |||
562 | error = virtio_child_attach_finish(vsc); | 557 | error = virtio_child_attach_finish(vsc, sc->sc_vq, | |
558 | __arraycount(sc->sc_vq), NULL, virtio_vq_intr, | |||
559 | VIRTIO_F_INTR_MPSAFE | VIRTIO_F_INTR_SOFTINT); | |||
563 | if (error != 0) | 560 | if (error != 0) | |
564 | goto err_mutex; | 561 | goto err_mutex; | |
565 | 562 | |||
566 | return; | 563 | return; | |
567 | 564 | |||
568 | err_mutex: | 565 | err_mutex: | |
569 | cv_destroy(&sc->sc_wait); | 566 | cv_destroy(&sc->sc_wait); | |
570 | mutex_destroy(&sc->sc_lock); | 567 | mutex_destroy(&sc->sc_lock); | |
571 | err_dmamap: | 568 | err_dmamap: | |
572 | bus_dmamap_destroy(virtio_dmat(vsc), sc->sc_dmamap_tx); | 569 | bus_dmamap_destroy(virtio_dmat(vsc), sc->sc_dmamap_tx); | |
573 | bus_dmamap_destroy(virtio_dmat(vsc), sc->sc_dmamap_rx); | 570 | bus_dmamap_destroy(virtio_dmat(vsc), sc->sc_dmamap_rx); | |
574 | err_vq: | 571 | err_vq: | |
575 | virtio_free_vq(vsc, &sc->sc_vq[0]); | 572 | virtio_free_vq(vsc, &sc->sc_vq[0]); |
--- src/sys/dev/pci/viomb.c 2022/04/13 10:42:12 1.13
+++ src/sys/dev/pci/viomb.c 2023/03/23 03:27:48 1.14
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: viomb.c,v 1.13 2022/04/13 10:42:12 uwe Exp $ */ | 1 | /* $NetBSD: viomb.c,v 1.14 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Minoura Makoto. | 4 | * Copyright (c) 2010 Minoura Makoto. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -16,27 +16,27 @@ | @@ -16,27 +16,27 @@ | |||
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 17 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 18 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 19 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 20 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 21 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 22 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
26 | */ | 26 | */ | |
27 | 27 | |||
28 | #include <sys/cdefs.h> | 28 | #include <sys/cdefs.h> | |
29 | __KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.13 2022/04/13 10:42:12 uwe Exp $"); | 29 | __KERNEL_RCSID(0, "$NetBSD: viomb.c,v 1.14 2023/03/23 03:27:48 yamaguchi Exp $"); | |
30 | 30 | |||
31 | #include <sys/param.h> | 31 | #include <sys/param.h> | |
32 | #include <sys/systm.h> | 32 | #include <sys/systm.h> | |
33 | #include <sys/kernel.h> | 33 | #include <sys/kernel.h> | |
34 | #include <sys/bus.h> | 34 | #include <sys/bus.h> | |
35 | #include <sys/condvar.h> | 35 | #include <sys/condvar.h> | |
36 | #include <sys/device.h> | 36 | #include <sys/device.h> | |
37 | #include <sys/kthread.h> | 37 | #include <sys/kthread.h> | |
38 | #include <sys/mutex.h> | 38 | #include <sys/mutex.h> | |
39 | #include <sys/sysctl.h> | 39 | #include <sys/sysctl.h> | |
40 | #include <uvm/uvm_page.h> | 40 | #include <uvm/uvm_page.h> | |
41 | #include <sys/module.h> | 41 | #include <sys/module.h> | |
42 | 42 | |||
@@ -138,28 +138,27 @@ viomb_attach(device_t parent, device_t s | @@ -138,28 +138,27 @@ viomb_attach(device_t parent, device_t s | |||
138 | return; | 138 | return; | |
139 | } | 139 | } | |
140 | 140 | |||
141 | /* fail on non-4K page size archs */ | 141 | /* fail on non-4K page size archs */ | |
142 | if (VIRTIO_PAGE_SIZE != PAGE_SIZE){ | 142 | if (VIRTIO_PAGE_SIZE != PAGE_SIZE){ | |
143 | aprint_normal("non-4K page size arch found, needs %d, got %d\n", | 143 | aprint_normal("non-4K page size arch found, needs %d, got %d\n", | |
144 | VIRTIO_PAGE_SIZE, PAGE_SIZE); | 144 | VIRTIO_PAGE_SIZE, PAGE_SIZE); | |
145 | return; | 145 | return; | |
146 | } | 146 | } | |
147 | 147 | |||
148 | sc->sc_dev = self; | 148 | sc->sc_dev = self; | |
149 | sc->sc_virtio = vsc; | 149 | sc->sc_virtio = vsc; | |
150 | 150 | |||
151 | virtio_child_attach_start(vsc, self, IPL_VM, sc->sc_vq, | 151 | virtio_child_attach_start(vsc, self, IPL_VM, | |
152 | viomb_config_change, virtio_vq_intr, 0, | |||
153 | VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_FLAG_BITS); | 152 | VIRTIO_BALLOON_F_MUST_TELL_HOST, VIRTIO_BALLOON_FLAG_BITS); | |
154 | 153 | |||
155 | features = virtio_features(vsc); | 154 | features = virtio_features(vsc); | |
156 | if (features == 0) | 155 | if (features == 0) | |
157 | goto err_none; | 156 | goto err_none; | |
158 | 157 | |||
159 | viomb_read_config(sc); | 158 | viomb_read_config(sc); | |
160 | sc->sc_inflight = 0; | 159 | sc->sc_inflight = 0; | |
161 | TAILQ_INIT(&sc->sc_balloon_pages); | 160 | TAILQ_INIT(&sc->sc_balloon_pages); | |
162 | 161 | |||
163 | sc->sc_inflate_done = sc->sc_deflate_done = 0; | 162 | sc->sc_inflate_done = sc->sc_deflate_done = 0; | |
164 | mutex_init(&sc->sc_waitlock, MUTEX_DEFAULT, IPL_VM); /* spin */ | 163 | mutex_init(&sc->sc_waitlock, MUTEX_DEFAULT, IPL_VM); /* spin */ | |
165 | cv_init(&sc->sc_wait, "balloon"); | 164 | cv_init(&sc->sc_wait, "balloon"); | |
@@ -180,27 +179,28 @@ viomb_attach(device_t parent, device_t s | @@ -180,27 +179,28 @@ viomb_attach(device_t parent, device_t s | |||
180 | 1, sizeof(uint32_t)*PGS_PER_REQ, 0, | 179 | 1, sizeof(uint32_t)*PGS_PER_REQ, 0, | |
181 | BUS_DMA_NOWAIT, &sc->sc_req.bl_dmamap)) { | 180 | BUS_DMA_NOWAIT, &sc->sc_req.bl_dmamap)) { | |
182 | aprint_error_dev(sc->sc_dev, "dmamap creation failed.\n"); | 181 | aprint_error_dev(sc->sc_dev, "dmamap creation failed.\n"); | |
183 | goto err_vq; | 182 | goto err_vq; | |
184 | } | 183 | } | |
185 | if (bus_dmamap_load(virtio_dmat(vsc), sc->sc_req.bl_dmamap, | 184 | if (bus_dmamap_load(virtio_dmat(vsc), sc->sc_req.bl_dmamap, | |
186 | &sc->sc_req.bl_pages[0], | 185 | &sc->sc_req.bl_pages[0], | |
187 | sizeof(uint32_t) * PGS_PER_REQ, | 186 | sizeof(uint32_t) * PGS_PER_REQ, | |
188 | NULL, BUS_DMA_NOWAIT)) { | 187 | NULL, BUS_DMA_NOWAIT)) { | |
189 | aprint_error_dev(sc->sc_dev, "dmamap load failed.\n"); | 188 | aprint_error_dev(sc->sc_dev, "dmamap load failed.\n"); | |
190 | goto err_dmamap; | 189 | goto err_dmamap; | |
191 | } | 190 | } | |
192 | 191 | |||
193 | if (virtio_child_attach_finish(vsc) != 0) | 192 | if (virtio_child_attach_finish(vsc, sc->sc_vq, __arraycount(sc->sc_vq), | |
193 | viomb_config_change, virtio_vq_intr, 0) != 0) | |||
194 | goto err_out; | 194 | goto err_out; | |
195 | 195 | |||
196 | if (kthread_create(PRI_IDLE, KTHREAD_MPSAFE, NULL, | 196 | if (kthread_create(PRI_IDLE, KTHREAD_MPSAFE, NULL, | |
197 | viomb_thread, sc, NULL, "viomb")) { | 197 | viomb_thread, sc, NULL, "viomb")) { | |
198 | aprint_error_dev(sc->sc_dev, "cannot create kthread.\n"); | 198 | aprint_error_dev(sc->sc_dev, "cannot create kthread.\n"); | |
199 | goto err_out; | 199 | goto err_out; | |
200 | } | 200 | } | |
201 | 201 | |||
202 | sysctl_createv(NULL, 0, NULL, &node, 0, CTLTYPE_NODE, | 202 | sysctl_createv(NULL, 0, NULL, &node, 0, CTLTYPE_NODE, | |
203 | "viomb", SYSCTL_DESCR("VirtIO Balloon status"), | 203 | "viomb", SYSCTL_DESCR("VirtIO Balloon status"), | |
204 | NULL, 0, NULL, 0, | 204 | NULL, 0, NULL, 0, | |
205 | CTL_HW, CTL_CREATE, CTL_EOL); | 205 | CTL_HW, CTL_CREATE, CTL_EOL); | |
206 | sysctl_createv(NULL, 0, NULL, NULL, 0, CTLTYPE_INT, | 206 | sysctl_createv(NULL, 0, NULL, NULL, 0, CTLTYPE_INT, |
--- src/sys/dev/pci/viornd.c 2022/04/14 19:47:14 1.18
+++ src/sys/dev/pci/viornd.c 2023/03/23 03:27:48 1.19
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: viornd.c,v 1.18 2022/04/14 19:47:14 riastradh Exp $ */ | 1 | /* $NetBSD: viornd.c,v 1.19 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | /* $OpenBSD: viornd.c,v 1.1 2014/01/21 21:14:58 sf Exp $ */ | 2 | /* $OpenBSD: viornd.c,v 1.1 2014/01/21 21:14:58 sf Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | 5 | * Copyright (c) 2014 The NetBSD Foundation, Inc. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * This code is derived from software contributed to The NetBSD Foundation | 8 | * This code is derived from software contributed to The NetBSD Foundation | |
9 | * by Thor Lancelot Simon (tls@NetBSD.org). | 9 | * by Thor Lancelot Simon (tls@NetBSD.org). | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -166,40 +166,41 @@ viornd_attach(device_t parent, device_t | @@ -166,40 +166,41 @@ viornd_attach(device_t parent, device_t | |||
166 | error); | 166 | error); | |
167 | goto create_failed; | 167 | goto create_failed; | |
168 | } | 168 | } | |
169 | 169 | |||
170 | error = bus_dmamap_load(virtio_dmat(vsc), sc->sc_dmamap, | 170 | error = bus_dmamap_load(virtio_dmat(vsc), sc->sc_dmamap, | |
171 | sc->sc_buf, VIORND_BUFSIZE, NULL, | 171 | sc->sc_buf, VIORND_BUFSIZE, NULL, | |
172 | BUS_DMA_NOWAIT|BUS_DMA_READ); | 172 | BUS_DMA_NOWAIT|BUS_DMA_READ); | |
173 | if (error) { | 173 | if (error) { | |
174 | aprint_error_dev(sc->sc_dev, "can't load dmamap: %d\n", | 174 | aprint_error_dev(sc->sc_dev, "can't load dmamap: %d\n", | |
175 | error); | 175 | error); | |
176 | goto load_failed; | 176 | goto load_failed; | |
177 | } | 177 | } | |
178 | 178 | |||
179 | virtio_child_attach_start(vsc, self, IPL_NET, &sc->sc_vq, | 179 | virtio_child_attach_start(vsc, self, IPL_NET, | |
180 | NULL, virtio_vq_intr, 0, | |||
181 | 0, VIRTIO_COMMON_FLAG_BITS); | 180 | 0, VIRTIO_COMMON_FLAG_BITS); | |
182 | 181 | |||
183 | error = virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1, | 182 | error = virtio_alloc_vq(vsc, &sc->sc_vq, 0, VIORND_BUFSIZE, 1, | |
184 | "Entropy request"); | 183 | "Entropy request"); | |
185 | if (error) { | 184 | if (error) { | |
186 | aprint_error_dev(sc->sc_dev, "can't alloc virtqueue: %d\n", | 185 | aprint_error_dev(sc->sc_dev, "can't alloc virtqueue: %d\n", | |
187 | error); | 186 | error); | |
188 | goto vio_failed; | 187 | goto vio_failed; | |
189 | } | 188 | } | |
190 | sc->sc_vq.vq_done = viornd_vq_done; | 189 | sc->sc_vq.vq_done = viornd_vq_done; | |
191 | 190 | |||
192 | if (virtio_child_attach_finish(vsc) != 0) { | 191 | error = virtio_child_attach_finish(vsc, &sc->sc_vq, 1, | |
192 | NULL, virtio_vq_intr, 0); | |||
193 | if (error) { | |||
193 | virtio_free_vq(vsc, &sc->sc_vq); | 194 | virtio_free_vq(vsc, &sc->sc_vq); | |
194 | goto vio_failed; | 195 | goto vio_failed; | |
195 | } | 196 | } | |
196 | 197 | |||
197 | rndsource_setcb(&sc->sc_rndsource, viornd_get, sc); | 198 | rndsource_setcb(&sc->sc_rndsource, viornd_get, sc); | |
198 | rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev), | 199 | rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev), | |
199 | RND_TYPE_RNG, | 200 | RND_TYPE_RNG, | |
200 | RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); | 201 | RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); | |
201 | 202 | |||
202 | return; | 203 | return; | |
203 | 204 | |||
204 | vio_failed: | 205 | vio_failed: | |
205 | bus_dmamap_unload(virtio_dmat(vsc), sc->sc_dmamap); | 206 | bus_dmamap_unload(virtio_dmat(vsc), sc->sc_dmamap); |
--- src/sys/dev/pci/virtio.c 2023/01/03 19:33:31 1.65
+++ src/sys/dev/pci/virtio.c 2023/03/23 03:27:48 1.66
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: virtio.c,v 1.65 2023/01/03 19:33:31 jakllsch Exp $ */ | 1 | /* $NetBSD: virtio.c,v 1.66 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | |
5 | * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. | 5 | * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg. | |
6 | * Copyright (c) 2010 Minoura Makoto. | 6 | * Copyright (c) 2010 Minoura Makoto. | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -18,27 +18,27 @@ | @@ -18,27 +18,27 @@ | |||
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.65 2023/01/03 19:33:31 jakllsch Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.66 2023/03/23 03:27:48 yamaguchi Exp $"); | |
32 | 32 | |||
33 | #include <sys/param.h> | 33 | #include <sys/param.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/kernel.h> | 35 | #include <sys/kernel.h> | |
36 | #include <sys/atomic.h> | 36 | #include <sys/atomic.h> | |
37 | #include <sys/bus.h> | 37 | #include <sys/bus.h> | |
38 | #include <sys/device.h> | 38 | #include <sys/device.h> | |
39 | #include <sys/kmem.h> | 39 | #include <sys/kmem.h> | |
40 | #include <sys/module.h> | 40 | #include <sys/module.h> | |
41 | 41 | |||
42 | #define VIRTIO_PRIVATE | 42 | #define VIRTIO_PRIVATE | |
43 | 43 | |||
44 | #include <dev/pci/virtioreg.h> /* XXX: move to non-pci */ | 44 | #include <dev/pci/virtioreg.h> /* XXX: move to non-pci */ | |
@@ -752,29 +752,26 @@ virtio_init_vq(struct virtio_softc *sc, | @@ -752,29 +752,26 @@ virtio_init_vq(struct virtio_softc *sc, | |||
752 | } | 752 | } | |
753 | 753 | |||
754 | /* | 754 | /* | |
755 | * Allocate/free a vq. | 755 | * Allocate/free a vq. | |
756 | */ | 756 | */ | |
757 | int | 757 | int | |
758 | virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index, | 758 | virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index, | |
759 | int maxsegsize, int maxnsegs, const char *name) | 759 | int maxsegsize, int maxnsegs, const char *name) | |
760 | { | 760 | { | |
761 | int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0; | 761 | int vq_size, allocsize1, allocsize2, allocsize3, allocsize = 0; | |
762 | int rsegs, r, hdrlen; | 762 | int rsegs, r, hdrlen; | |
763 | #define VIRTQUEUE_ALIGN(n) roundup(n, VIRTIO_PAGE_SIZE) | 763 | #define VIRTQUEUE_ALIGN(n) roundup(n, VIRTIO_PAGE_SIZE) | |
764 | 764 | |||
765 | /* Make sure callers allocate vqs in order */ | |||
766 | KASSERT(sc->sc_nvqs == index); | |||
767 | ||||
768 | memset(vq, 0, sizeof(*vq)); | 765 | memset(vq, 0, sizeof(*vq)); | |
769 | 766 | |||
770 | vq_size = sc->sc_ops->read_queue_size(sc, index); | 767 | vq_size = sc->sc_ops->read_queue_size(sc, index); | |
771 | if (vq_size == 0) { | 768 | if (vq_size == 0) { | |
772 | aprint_error_dev(sc->sc_dev, | 769 | aprint_error_dev(sc->sc_dev, | |
773 | "virtqueue not exist, index %d for %s\n", | 770 | "virtqueue not exist, index %d for %s\n", | |
774 | index, name); | 771 | index, name); | |
775 | goto err; | 772 | goto err; | |
776 | } | 773 | } | |
777 | 774 | |||
778 | hdrlen = sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX ? 3 : 2; | 775 | hdrlen = sc->sc_active_features & VIRTIO_F_RING_EVENT_IDX ? 3 : 2; | |
779 | 776 | |||
780 | /* allocsize1: descriptor table + avail ring + pad */ | 777 | /* allocsize1: descriptor table + avail ring + pad */ | |
@@ -854,28 +851,26 @@ virtio_alloc_vq(struct virtio_softc *sc, | @@ -854,28 +851,26 @@ virtio_alloc_vq(struct virtio_softc *sc, | |||
854 | 851 | |||
855 | /* set the vq address */ | 852 | /* set the vq address */ | |
856 | sc->sc_ops->setup_queue(sc, index, | 853 | sc->sc_ops->setup_queue(sc, index, | |
857 | vq->vq_dmamap->dm_segs[0].ds_addr); | 854 | vq->vq_dmamap->dm_segs[0].ds_addr); | |
858 | 855 | |||
859 | aprint_verbose_dev(sc->sc_dev, | 856 | aprint_verbose_dev(sc->sc_dev, | |
860 | "allocated %u byte for virtqueue %d for %s, size %d\n", | 857 | "allocated %u byte for virtqueue %d for %s, size %d\n", | |
861 | allocsize, index, name, vq_size); | 858 | allocsize, index, name, vq_size); | |
862 | if (allocsize3 > 0) | 859 | if (allocsize3 > 0) | |
863 | aprint_verbose_dev(sc->sc_dev, | 860 | aprint_verbose_dev(sc->sc_dev, | |
864 | "using %d byte (%d entries) indirect descriptors\n", | 861 | "using %d byte (%d entries) indirect descriptors\n", | |
865 | allocsize3, maxnsegs * vq_size); | 862 | allocsize3, maxnsegs * vq_size); | |
866 | 863 | |||
867 | sc->sc_nvqs++; | |||
868 | ||||
869 | return 0; | 864 | return 0; | |
870 | 865 | |||
871 | err: | 866 | err: | |
872 | sc->sc_ops->setup_queue(sc, index, 0); | 867 | sc->sc_ops->setup_queue(sc, index, 0); | |
873 | if (vq->vq_dmamap) | 868 | if (vq->vq_dmamap) | |
874 | bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); | 869 | bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); | |
875 | if (vq->vq_vaddr) | 870 | if (vq->vq_vaddr) | |
876 | bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, allocsize); | 871 | bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, allocsize); | |
877 | if (vq->vq_segs[0].ds_addr) | 872 | if (vq->vq_segs[0].ds_addr) | |
878 | bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); | 873 | bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); | |
879 | memset(vq, 0, sizeof(*vq)); | 874 | memset(vq, 0, sizeof(*vq)); | |
880 | 875 | |||
881 | return -1; | 876 | return -1; | |
@@ -903,28 +898,26 @@ virtio_free_vq(struct virtio_softc *sc, | @@ -903,28 +898,26 @@ virtio_free_vq(struct virtio_softc *sc, | |||
903 | 898 | |||
904 | vq_sync_aring_all(sc, vq, BUS_DMASYNC_POSTWRITE); | 899 | vq_sync_aring_all(sc, vq, BUS_DMASYNC_POSTWRITE); | |
905 | 900 | |||
906 | kmem_free(vq->vq_entries, sizeof(*vq->vq_entries) * vq->vq_num); | 901 | kmem_free(vq->vq_entries, sizeof(*vq->vq_entries) * vq->vq_num); | |
907 | bus_dmamap_unload(sc->sc_dmat, vq->vq_dmamap); | 902 | bus_dmamap_unload(sc->sc_dmat, vq->vq_dmamap); | |
908 | bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); | 903 | bus_dmamap_destroy(sc->sc_dmat, vq->vq_dmamap); | |
909 | bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, vq->vq_bytesize); | 904 | bus_dmamem_unmap(sc->sc_dmat, vq->vq_vaddr, vq->vq_bytesize); | |
910 | bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); | 905 | bus_dmamem_free(sc->sc_dmat, &vq->vq_segs[0], 1); | |
911 | mutex_destroy(&vq->vq_freelist_lock); | 906 | mutex_destroy(&vq->vq_freelist_lock); | |
912 | mutex_destroy(&vq->vq_uring_lock); | 907 | mutex_destroy(&vq->vq_uring_lock); | |
913 | mutex_destroy(&vq->vq_aring_lock); | 908 | mutex_destroy(&vq->vq_aring_lock); | |
914 | memset(vq, 0, sizeof(*vq)); | 909 | memset(vq, 0, sizeof(*vq)); | |
915 | 910 | |||
916 | sc->sc_nvqs--; | |||
917 | ||||
918 | return 0; | 911 | return 0; | |
919 | } | 912 | } | |
920 | 913 | |||
921 | /* | 914 | /* | |
922 | * Free descriptor management. | 915 | * Free descriptor management. | |
923 | */ | 916 | */ | |
924 | static struct vq_entry * | 917 | static struct vq_entry * | |
925 | vq_alloc_entry(struct virtqueue *vq) | 918 | vq_alloc_entry(struct virtqueue *vq) | |
926 | { | 919 | { | |
927 | struct vq_entry *qe; | 920 | struct vq_entry *qe; | |
928 | 921 | |||
929 | mutex_enter(&vq->vq_freelist_lock); | 922 | mutex_enter(&vq->vq_freelist_lock); | |
930 | if (SIMPLEQ_EMPTY(&vq->vq_freelist)) { | 923 | if (SIMPLEQ_EMPTY(&vq->vq_freelist)) { | |
@@ -1260,65 +1253,68 @@ virtio_dequeue_commit(struct virtio_soft | @@ -1260,65 +1253,68 @@ virtio_dequeue_commit(struct virtio_soft | |||
1260 | vq_free_entry(vq, qe); | 1253 | vq_free_entry(vq, qe); | |
1261 | qe = &vq->vq_entries[s]; | 1254 | qe = &vq->vq_entries[s]; | |
1262 | } | 1255 | } | |
1263 | vq_free_entry(vq, qe); | 1256 | vq_free_entry(vq, qe); | |
1264 | 1257 | |||
1265 | return 0; | 1258 | return 0; | |
1266 | } | 1259 | } | |
1267 | 1260 | |||
1268 | /* | 1261 | /* | |
1269 | * Attach a child, fill all the members. | 1262 | * Attach a child, fill all the members. | |
1270 | */ | 1263 | */ | |
1271 | void | 1264 | void | |
1272 | virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl, | 1265 | virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl, | |
1273 | struct virtqueue *vqs, | 1266 | uint64_t req_features, const char *feat_bits) | |
1274 | virtio_callback config_change, | |||
1275 | virtio_callback intr_hand, | |||
1276 | int req_flags, int req_features, const char *feat_bits) | |||
1277 | { | 1267 | { | |
1278 | char buf[1024]; | 1268 | char buf[1024]; | |
1279 | 1269 | |||
1280 | sc->sc_child = child; | 1270 | sc->sc_child = child; | |
1281 | sc->sc_ipl = ipl; | 1271 | sc->sc_ipl = ipl; | |
1282 | sc->sc_vqs = vqs; | |||
1283 | sc->sc_config_change = config_change; | |||
1284 | sc->sc_intrhand = intr_hand; | |||
1285 | sc->sc_flags = req_flags; | |||
1286 | 1272 | |||
1287 | virtio_negotiate_features(sc, req_features); | 1273 | virtio_negotiate_features(sc, req_features); | |
1288 | snprintb(buf, sizeof(buf), feat_bits, sc->sc_active_features); | 1274 | snprintb(buf, sizeof(buf), feat_bits, sc->sc_active_features); | |
1289 | aprint_normal(": features: %s\n", buf); | 1275 | aprint_normal(": features: %s\n", buf); | |
1290 | aprint_naive("\n"); | 1276 | aprint_naive("\n"); | |
1291 | } | 1277 | } | |
1292 | 1278 | |||
1293 | void | |||
1294 | virtio_child_attach_set_vqs(struct virtio_softc *sc, | |||
1295 | struct virtqueue *vqs, int nvq_pairs) | |||
1296 | { | |||
1297 | ||||
1298 | KASSERT(nvq_pairs == 1 || | |||
1299 | (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) == 0); | |||
1300 | if (nvq_pairs > 1) | |||
1301 | sc->sc_child_mq = true; | |||
1302 | ||||
1303 | sc->sc_vqs = vqs; | |||
1304 | } | |||
1305 | ||||
1306 | int | 1279 | int | |
1307 | virtio_child_attach_finish(struct virtio_softc *sc) | 1280 | virtio_child_attach_finish(struct virtio_softc *sc, | |
1281 | struct virtqueue *vqs, size_t nvqs, | |||
1282 | virtio_callback config_change, virtio_callback intr_hand, | |||
1283 | int req_flags) | |||
1308 | { | 1284 | { | |
1309 | int r; | 1285 | int r; | |
1310 | 1286 | |||
1287 | #ifdef DIAGNOSTIC | |||
1288 | KASSERT(nvqs > 0); | |||
1289 | #define VIRTIO_ASSERT_FLAGS (VIRTIO_F_INTR_SOFTINT | VIRTIO_F_INTR_PERVQ) | |||
1290 | KASSERT((req_flags & VIRTIO_ASSERT_FLAGS) != VIRTIO_ASSERT_FLAGS); | |||
1291 | #undef VIRTIO_ASSERT_FLAGS | |||
1292 | ||||
1293 | for (size_t _i = 0; _i < nvqs; _i++){ | |||
1294 | KASSERT(vqs[_i].vq_index == _i); | |||
1295 | KASSERT((req_flags & VIRTIO_F_INTR_PERVQ) == 0 || | |||
1296 | vqs[_i].vq_intrhand != NULL); | |||
1297 | } | |||
1298 | #endif | |||
1299 | ||||
1311 | sc->sc_finished_called = true; | 1300 | sc->sc_finished_called = true; | |
1301 | ||||
1302 | sc->sc_vqs = vqs; | |||
1303 | sc->sc_nvqs = nvqs; | |||
1304 | sc->sc_config_change = config_change; | |||
1305 | sc->sc_intrhand = intr_hand; | |||
1306 | sc->sc_flags = req_flags; | |||
1307 | ||||
1312 | r = sc->sc_ops->alloc_interrupts(sc); | 1308 | r = sc->sc_ops->alloc_interrupts(sc); | |
1313 | if (r != 0) { | 1309 | if (r != 0) { | |
1314 | aprint_error_dev(sc->sc_dev, | 1310 | aprint_error_dev(sc->sc_dev, | |
1315 | "failed to allocate interrupts\n"); | 1311 | "failed to allocate interrupts\n"); | |
1316 | goto fail; | 1312 | goto fail; | |
1317 | } | 1313 | } | |
1318 | 1314 | |||
1319 | r = sc->sc_ops->setup_interrupts(sc, 0); | 1315 | r = sc->sc_ops->setup_interrupts(sc, 0); | |
1320 | if (r != 0) { | 1316 | if (r != 0) { | |
1321 | aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n"); | 1317 | aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n"); | |
1322 | goto fail; | 1318 | goto fail; | |
1323 | } | 1319 | } | |
1324 | 1320 |
--- src/sys/dev/pci/virtio_pci.c 2022/05/30 20:28:18 1.38
+++ src/sys/dev/pci/virtio_pci.c 2023/03/23 03:27:48 1.39
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: virtio_pci.c,v 1.38 2022/05/30 20:28:18 riastradh Exp $ */ | 1 | /* $NetBSD: virtio_pci.c,v 1.39 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | 4 | * Copyright (c) 2020 The NetBSD Foundation, Inc. | |
5 | * Copyright (c) 2012 Stefan Fritsch. | 5 | * Copyright (c) 2012 Stefan Fritsch. | |
6 | * Copyright (c) 2010 Minoura Makoto. | 6 | * Copyright (c) 2010 Minoura Makoto. | |
7 | * All rights reserved. | 7 | * All rights reserved. | |
8 | * | 8 | * | |
9 | * Redistribution and use in source and binary forms, with or without | 9 | * Redistribution and use in source and binary forms, with or without | |
10 | * modification, are permitted provided that the following conditions | 10 | * modification, are permitted provided that the following conditions | |
11 | * are met: | 11 | * are met: | |
12 | * 1. Redistributions of source code must retain the above copyright | 12 | * 1. Redistributions of source code must retain the above copyright | |
13 | * notice, this list of conditions and the following disclaimer. | 13 | * notice, this list of conditions and the following disclaimer. | |
14 | * 2. Redistributions in binary form must reproduce the above copyright | 14 | * 2. Redistributions in binary form must reproduce the above copyright | |
@@ -18,27 +18,27 @@ | @@ -18,27 +18,27 @@ | |||
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
28 | */ | 28 | */ | |
29 | 29 | |||
30 | #include <sys/cdefs.h> | 30 | #include <sys/cdefs.h> | |
31 | __KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.38 2022/05/30 20:28:18 riastradh Exp $"); | 31 | __KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.39 2023/03/23 03:27:48 yamaguchi Exp $"); | |
32 | 32 | |||
33 | #include <sys/param.h> | 33 | #include <sys/param.h> | |
34 | #include <sys/systm.h> | 34 | #include <sys/systm.h> | |
35 | #include <sys/kmem.h> | 35 | #include <sys/kmem.h> | |
36 | #include <sys/module.h> | 36 | #include <sys/module.h> | |
37 | #include <sys/endian.h> | 37 | #include <sys/endian.h> | |
38 | #include <sys/interrupt.h> | 38 | #include <sys/interrupt.h> | |
39 | #include <sys/syslog.h> | 39 | #include <sys/syslog.h> | |
40 | 40 | |||
41 | #include <sys/device.h> | 41 | #include <sys/device.h> | |
42 | 42 | |||
43 | #include <dev/pci/pcidevs.h> | 43 | #include <dev/pci/pcidevs.h> | |
44 | #include <dev/pci/pcireg.h> | 44 | #include <dev/pci/pcireg.h> | |
@@ -63,26 +63,27 @@ do { \ | @@ -63,26 +63,27 @@ do { \ | |||
63 | } \ | 63 | } \ | |
64 | } while(0) | 64 | } while(0) | |
65 | 65 | |||
66 | static int virtio_pci_match(device_t, cfdata_t, void *); | 66 | static int virtio_pci_match(device_t, cfdata_t, void *); | |
67 | static void virtio_pci_attach(device_t, device_t, void *); | 67 | static void virtio_pci_attach(device_t, device_t, void *); | |
68 | static int virtio_pci_rescan(device_t, const char *, const int *); | 68 | static int virtio_pci_rescan(device_t, const char *, const int *); | |
69 | static int virtio_pci_detach(device_t, int); | 69 | static int virtio_pci_detach(device_t, int); | |
70 | 70 | |||
71 | 71 | |||
72 | #define NMAPREG ((PCI_MAPREG_END - PCI_MAPREG_START) / \ | 72 | #define NMAPREG ((PCI_MAPREG_END - PCI_MAPREG_START) / \ | |
73 | sizeof(pcireg_t)) | 73 | sizeof(pcireg_t)) | |
74 | struct virtio_pci_softc { | 74 | struct virtio_pci_softc { | |
75 | struct virtio_softc sc_sc; | 75 | struct virtio_softc sc_sc; | |
76 | bool sc_intr_pervq; | |||
76 | 77 | |||
77 | /* IO space */ | 78 | /* IO space */ | |
78 | bus_space_tag_t sc_iot; | 79 | bus_space_tag_t sc_iot; | |
79 | bus_space_handle_t sc_ioh; | 80 | bus_space_handle_t sc_ioh; | |
80 | bus_size_t sc_iosize; | 81 | bus_size_t sc_iosize; | |
81 | bus_size_t sc_mapped_iosize; | 82 | bus_size_t sc_mapped_iosize; | |
82 | 83 | |||
83 | /* BARs */ | 84 | /* BARs */ | |
84 | bus_space_tag_t sc_bars_iot[NMAPREG]; | 85 | bus_space_tag_t sc_bars_iot[NMAPREG]; | |
85 | bus_space_handle_t sc_bars_ioh[NMAPREG]; | 86 | bus_space_handle_t sc_bars_ioh[NMAPREG]; | |
86 | bus_size_t sc_bars_iosize[NMAPREG]; | 87 | bus_size_t sc_bars_iosize[NMAPREG]; | |
87 | 88 | |||
88 | /* notify space */ | 89 | /* notify space */ | |
@@ -619,27 +620,27 @@ virtio_pci_read_queue_size_09(struct vir | @@ -619,27 +620,27 @@ virtio_pci_read_queue_size_09(struct vir | |||
619 | 620 | |||
620 | static void | 621 | static void | |
621 | virtio_pci_setup_queue_09(struct virtio_softc *sc, uint16_t idx, uint64_t addr) | 622 | virtio_pci_setup_queue_09(struct virtio_softc *sc, uint16_t idx, uint64_t addr) | |
622 | { | 623 | { | |
623 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | 624 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | |
624 | 625 | |||
625 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, | 626 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, | |
626 | VIRTIO_CONFIG_QUEUE_SELECT, idx); | 627 | VIRTIO_CONFIG_QUEUE_SELECT, idx); | |
627 | bus_space_write_4(psc->sc_iot, psc->sc_ioh, | 628 | bus_space_write_4(psc->sc_iot, psc->sc_ioh, | |
628 | VIRTIO_CONFIG_QUEUE_ADDRESS, addr / VIRTIO_PAGE_SIZE); | 629 | VIRTIO_CONFIG_QUEUE_ADDRESS, addr / VIRTIO_PAGE_SIZE); | |
629 | 630 | |||
630 | if (psc->sc_ihs_num > 1) { | 631 | if (psc->sc_ihs_num > 1) { | |
631 | int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 632 | int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
632 | if (sc->sc_child_mq) | 633 | if (psc->sc_intr_pervq) | |
633 | vec += idx; | 634 | vec += idx; | |
634 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, | 635 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, | |
635 | VIRTIO_CONFIG_MSI_QUEUE_VECTOR, vec); | 636 | VIRTIO_CONFIG_MSI_QUEUE_VECTOR, vec); | |
636 | } | 637 | } | |
637 | } | 638 | } | |
638 | 639 | |||
639 | static void | 640 | static void | |
640 | virtio_pci_set_status_09(struct virtio_softc *sc, int status) | 641 | virtio_pci_set_status_09(struct virtio_softc *sc, int status) | |
641 | { | 642 | { | |
642 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | 643 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | |
643 | int old = 0; | 644 | int old = 0; | |
644 | 645 | |||
645 | if (status != 0) { | 646 | if (status != 0) { | |
@@ -741,27 +742,27 @@ virtio_pci_setup_queue_10(struct virtio_ | @@ -741,27 +742,27 @@ virtio_pci_setup_queue_10(struct virtio_ | |||
741 | VIRTIO_CONFIG1_QUEUE_DESC, addr); | 742 | VIRTIO_CONFIG1_QUEUE_DESC, addr); | |
742 | virtio_pci_bus_space_write_8(iot, ioh, | 743 | virtio_pci_bus_space_write_8(iot, ioh, | |
743 | VIRTIO_CONFIG1_QUEUE_AVAIL, addr + vq->vq_availoffset); | 744 | VIRTIO_CONFIG1_QUEUE_AVAIL, addr + vq->vq_availoffset); | |
744 | virtio_pci_bus_space_write_8(iot, ioh, | 745 | virtio_pci_bus_space_write_8(iot, ioh, | |
745 | VIRTIO_CONFIG1_QUEUE_USED, addr + vq->vq_usedoffset); | 746 | VIRTIO_CONFIG1_QUEUE_USED, addr + vq->vq_usedoffset); | |
746 | bus_space_write_2(iot, ioh, | 747 | bus_space_write_2(iot, ioh, | |
747 | VIRTIO_CONFIG1_QUEUE_ENABLE, 1); | 748 | VIRTIO_CONFIG1_QUEUE_ENABLE, 1); | |
748 | vq->vq_notify_off = bus_space_read_2(iot, ioh, | 749 | vq->vq_notify_off = bus_space_read_2(iot, ioh, | |
749 | VIRTIO_CONFIG1_QUEUE_NOTIFY_OFF); | 750 | VIRTIO_CONFIG1_QUEUE_NOTIFY_OFF); | |
750 | } | 751 | } | |
751 | 752 | |||
752 | if (psc->sc_ihs_num > 1) { | 753 | if (psc->sc_ihs_num > 1) { | |
753 | int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 754 | int vec = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
754 | if (sc->sc_child_mq) | 755 | if (psc->sc_intr_pervq) | |
755 | vec += idx; | 756 | vec += idx; | |
756 | bus_space_write_2(iot, ioh, | 757 | bus_space_write_2(iot, ioh, | |
757 | VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, vec); | 758 | VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, vec); | |
758 | } | 759 | } | |
759 | } | 760 | } | |
760 | 761 | |||
761 | static void | 762 | static void | |
762 | virtio_pci_set_status_10(struct virtio_softc *sc, int status) | 763 | virtio_pci_set_status_10(struct virtio_softc *sc, int status) | |
763 | { | 764 | { | |
764 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | 765 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | |
765 | bus_space_tag_t iot = psc->sc_iot; | 766 | bus_space_tag_t iot = psc->sc_iot; | |
766 | bus_space_handle_t ioh = psc->sc_ioh; | 767 | bus_space_handle_t ioh = psc->sc_ioh; | |
767 | int old = 0; | 768 | int old = 0; | |
@@ -839,27 +840,27 @@ virtio_pci_setup_interrupts_10(struct vi | @@ -839,27 +840,27 @@ virtio_pci_setup_interrupts_10(struct vi | |||
839 | vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | 840 | vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | |
840 | bus_space_write_2(iot, ioh, | 841 | bus_space_write_2(iot, ioh, | |
841 | VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector); | 842 | VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector); | |
842 | ret = bus_space_read_2(iot, ioh, VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR); | 843 | ret = bus_space_read_2(iot, ioh, VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR); | |
843 | if (ret != vector) { | 844 | if (ret != vector) { | |
844 | VIRTIO_PCI_LOG(sc, reinit, | 845 | VIRTIO_PCI_LOG(sc, reinit, | |
845 | "can't set config msix vector\n"); | 846 | "can't set config msix vector\n"); | |
846 | return -1; | 847 | return -1; | |
847 | } | 848 | } | |
848 | 849 | |||
849 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | 850 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | |
850 | vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 851 | vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
851 | 852 | |||
852 | if (sc->sc_child_mq) | 853 | if (psc->sc_intr_pervq) | |
853 | vector += qid; | 854 | vector += qid; | |
854 | bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_SELECT, qid); | 855 | bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_SELECT, qid); | |
855 | bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, | 856 | bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, | |
856 | vector); | 857 | vector); | |
857 | ret = bus_space_read_2(iot, ioh, | 858 | ret = bus_space_read_2(iot, ioh, | |
858 | VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR); | 859 | VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR); | |
859 | if (ret != vector) { | 860 | if (ret != vector) { | |
860 | VIRTIO_PCI_LOG(sc, reinit, "can't set queue %d " | 861 | VIRTIO_PCI_LOG(sc, reinit, "can't set queue %d " | |
861 | "msix vector\n", qid); | 862 | "msix vector\n", qid); | |
862 | return -1; | 863 | return -1; | |
863 | } | 864 | } | |
864 | } | 865 | } | |
865 | 866 | |||
@@ -885,27 +886,27 @@ virtio_pci_setup_interrupts_09(struct vi | @@ -885,27 +886,27 @@ virtio_pci_setup_interrupts_09(struct vi | |||
885 | __func__, vector, ret); | 886 | __func__, vector, ret); | |
886 | VIRTIO_PCI_LOG(sc, reinit, | 887 | VIRTIO_PCI_LOG(sc, reinit, | |
887 | "can't set config msix vector\n"); | 888 | "can't set config msix vector\n"); | |
888 | return -1; | 889 | return -1; | |
889 | } | 890 | } | |
890 | 891 | |||
891 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | 892 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | |
892 | offset = VIRTIO_CONFIG_QUEUE_SELECT; | 893 | offset = VIRTIO_CONFIG_QUEUE_SELECT; | |
893 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, qid); | 894 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, qid); | |
894 | 895 | |||
895 | offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR; | 896 | offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR; | |
896 | vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 897 | vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
897 | 898 | |||
898 | if (sc->sc_child_mq) | 899 | if (psc->sc_intr_pervq) | |
899 | vector += qid; | 900 | vector += qid; | |
900 | 901 | |||
901 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector); | 902 | bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector); | |
902 | ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset); | 903 | ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset); | |
903 | if (ret != vector) { | 904 | if (ret != vector) { | |
904 | aprint_debug_dev(sc->sc_dev, "%s[qid=%d]:" | 905 | aprint_debug_dev(sc->sc_dev, "%s[qid=%d]:" | |
905 | " expected=%d, actual=%d\n", | 906 | " expected=%d, actual=%d\n", | |
906 | __func__, qid, vector, ret); | 907 | __func__, qid, vector, ret); | |
907 | VIRTIO_PCI_LOG(sc, reinit, "can't set queue %d " | 908 | VIRTIO_PCI_LOG(sc, reinit, "can't set queue %d " | |
908 | "msix vector\n", qid); | 909 | "msix vector\n", qid); | |
909 | return -1; | 910 | return -1; | |
910 | } | 911 | } | |
911 | } | 912 | } | |
@@ -931,27 +932,27 @@ virtio_pci_establish_msix_interrupts(str | @@ -931,27 +932,27 @@ virtio_pci_establish_msix_interrupts(str | |||
931 | pci_intr_setattr(pc, &psc->sc_ihp[idx], PCI_INTR_MPSAFE, true); | 932 | pci_intr_setattr(pc, &psc->sc_ihp[idx], PCI_INTR_MPSAFE, true); | |
932 | 933 | |||
933 | snprintf(intr_xname, sizeof(intr_xname), "%s config", | 934 | snprintf(intr_xname, sizeof(intr_xname), "%s config", | |
934 | device_xname(sc->sc_dev)); | 935 | device_xname(sc->sc_dev)); | |
935 | 936 | |||
936 | psc->sc_ihs[idx] = pci_intr_establish_xname(pc, psc->sc_ihp[idx], | 937 | psc->sc_ihs[idx] = pci_intr_establish_xname(pc, psc->sc_ihp[idx], | |
937 | sc->sc_ipl, virtio_pci_msix_config_intr, sc, intr_xname); | 938 | sc->sc_ipl, virtio_pci_msix_config_intr, sc, intr_xname); | |
938 | if (psc->sc_ihs[idx] == NULL) { | 939 | if (psc->sc_ihs[idx] == NULL) { | |
939 | aprint_error_dev(self, "couldn't establish MSI-X for config\n"); | 940 | aprint_error_dev(self, "couldn't establish MSI-X for config\n"); | |
940 | goto error; | 941 | goto error; | |
941 | } | 942 | } | |
942 | 943 | |||
943 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 944 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
944 | if (sc->sc_child_mq) { | 945 | if (psc->sc_intr_pervq) { | |
945 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | 946 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | |
946 | n = idx + qid; | 947 | n = idx + qid; | |
947 | vq = &sc->sc_vqs[qid]; | 948 | vq = &sc->sc_vqs[qid]; | |
948 | 949 | |||
949 | snprintf(intr_xname, sizeof(intr_xname), "%s vq#%d", | 950 | snprintf(intr_xname, sizeof(intr_xname), "%s vq#%d", | |
950 | device_xname(sc->sc_dev), qid); | 951 | device_xname(sc->sc_dev), qid); | |
951 | 952 | |||
952 | if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE) { | 953 | if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE) { | |
953 | pci_intr_setattr(pc, &psc->sc_ihp[n], | 954 | pci_intr_setattr(pc, &psc->sc_ihp[n], | |
954 | PCI_INTR_MPSAFE, true); | 955 | PCI_INTR_MPSAFE, true); | |
955 | } | 956 | } | |
956 | 957 | |||
957 | psc->sc_ihs[n] = pci_intr_establish_xname(pc, psc->sc_ihp[n], | 958 | psc->sc_ihs[n] = pci_intr_establish_xname(pc, psc->sc_ihp[n], | |
@@ -969,27 +970,27 @@ virtio_pci_establish_msix_interrupts(str | @@ -969,27 +970,27 @@ virtio_pci_establish_msix_interrupts(str | |||
969 | device_xname(sc->sc_dev)); | 970 | device_xname(sc->sc_dev)); | |
970 | psc->sc_ihs[idx] = pci_intr_establish_xname(pc, psc->sc_ihp[idx], | 971 | psc->sc_ihs[idx] = pci_intr_establish_xname(pc, psc->sc_ihp[idx], | |
971 | sc->sc_ipl, virtio_pci_msix_queue_intr, sc, intr_xname); | 972 | sc->sc_ipl, virtio_pci_msix_queue_intr, sc, intr_xname); | |
972 | if (psc->sc_ihs[idx] == NULL) { | 973 | if (psc->sc_ihs[idx] == NULL) { | |
973 | aprint_error_dev(self, "couldn't establish MSI-X for queues\n"); | 974 | aprint_error_dev(self, "couldn't establish MSI-X for queues\n"); | |
974 | goto error; | 975 | goto error; | |
975 | } | 976 | } | |
976 | } | 977 | } | |
977 | 978 | |||
978 | idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | 979 | idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | |
979 | intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); | 980 | intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); | |
980 | aprint_normal_dev(self, "config interrupting at %s\n", intrstr); | 981 | aprint_normal_dev(self, "config interrupting at %s\n", intrstr); | |
981 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 982 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
982 | if (sc->sc_child_mq) { | 983 | if (psc->sc_intr_pervq) { | |
983 | kcpuset_t *affinity; | 984 | kcpuset_t *affinity; | |
984 | int affinity_to, r; | 985 | int affinity_to, r; | |
985 | 986 | |||
986 | kcpuset_create(&affinity, false); | 987 | kcpuset_create(&affinity, false); | |
987 | 988 | |||
988 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | 989 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | |
989 | n = idx + qid; | 990 | n = idx + qid; | |
990 | affinity_to = (qid / 2) % ncpu; | 991 | affinity_to = (qid / 2) % ncpu; | |
991 | 992 | |||
992 | intrstr = pci_intr_string(pc, psc->sc_ihp[n], | 993 | intrstr = pci_intr_string(pc, psc->sc_ihp[n], | |
993 | intrbuf, sizeof(intrbuf)); | 994 | intrbuf, sizeof(intrbuf)); | |
994 | 995 | |||
995 | kcpuset_zero(affinity); | 996 | kcpuset_zero(affinity); | |
@@ -1009,27 +1010,27 @@ virtio_pci_establish_msix_interrupts(str | @@ -1009,27 +1010,27 @@ virtio_pci_establish_msix_interrupts(str | |||
1009 | kcpuset_destroy(affinity); | 1010 | kcpuset_destroy(affinity); | |
1010 | } else { | 1011 | } else { | |
1011 | intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); | 1012 | intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf)); | |
1012 | aprint_normal_dev(self, "queues interrupting at %s\n", intrstr); | 1013 | aprint_normal_dev(self, "queues interrupting at %s\n", intrstr); | |
1013 | } | 1014 | } | |
1014 | 1015 | |||
1015 | return 0; | 1016 | return 0; | |
1016 | 1017 | |||
1017 | error: | 1018 | error: | |
1018 | idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | 1019 | idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; | |
1019 | if (psc->sc_ihs[idx] != NULL) | 1020 | if (psc->sc_ihs[idx] != NULL) | |
1020 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[idx]); | 1021 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[idx]); | |
1021 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 1022 | idx = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
1022 | if (sc->sc_child_mq) { | 1023 | if (psc->sc_intr_pervq) { | |
1023 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | 1024 | for (qid = 0; qid < sc->sc_nvqs; qid++) { | |
1024 | n = idx + qid; | 1025 | n = idx + qid; | |
1025 | if (psc->sc_ihs[n] == NULL) | 1026 | if (psc->sc_ihs[n] == NULL) | |
1026 | continue; | 1027 | continue; | |
1027 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[n]); | 1028 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[n]); | |
1028 | } | 1029 | } | |
1029 | 1030 | |||
1030 | } else { | 1031 | } else { | |
1031 | if (psc->sc_ihs[idx] != NULL) | 1032 | if (psc->sc_ihs[idx] != NULL) | |
1032 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[idx]); | 1033 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[idx]); | |
1033 | } | 1034 | } | |
1034 | 1035 | |||
1035 | return -1; | 1036 | return -1; | |
@@ -1075,90 +1076,91 @@ virtio_pci_alloc_interrupts(struct virti | @@ -1075,90 +1076,91 @@ virtio_pci_alloc_interrupts(struct virti | |||
1075 | pci_intr_type_t max_type; | 1076 | pci_intr_type_t max_type; | |
1076 | pcireg_t ctl; | 1077 | pcireg_t ctl; | |
1077 | 1078 | |||
1078 | nmsix = pci_msix_count(psc->sc_pa.pa_pc, psc->sc_pa.pa_tag); | 1079 | nmsix = pci_msix_count(psc->sc_pa.pa_pc, psc->sc_pa.pa_tag); | |
1079 | aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix); | 1080 | aprint_debug_dev(self, "pci_msix_count=%d\n", nmsix); | |
1080 | 1081 | |||
1081 | /* We need at least two: one for config and the other for queues */ | 1082 | /* We need at least two: one for config and the other for queues */ | |
1082 | if ((sc->sc_flags & VIRTIO_F_INTR_MSIX) == 0 || nmsix < 2) { | 1083 | if ((sc->sc_flags & VIRTIO_F_INTR_MSIX) == 0 || nmsix < 2) { | |
1083 | /* Try INTx only */ | 1084 | /* Try INTx only */ | |
1084 | max_type = PCI_INTR_TYPE_INTX; | 1085 | max_type = PCI_INTR_TYPE_INTX; | |
1085 | counts[PCI_INTR_TYPE_INTX] = 1; | 1086 | counts[PCI_INTR_TYPE_INTX] = 1; | |
1086 | } else { | 1087 | } else { | |
1087 | /* Try MSI-X first and INTx second */ | 1088 | /* Try MSI-X first and INTx second */ | |
1088 | if (sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX <= nmsix) { | 1089 | if (ISSET(sc->sc_flags, VIRTIO_F_INTR_PERVQ) && | |
1090 | sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX <= nmsix) { | |||
1089 | nmsix = sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | 1091 | nmsix = sc->sc_nvqs + VIRTIO_MSIX_QUEUE_VECTOR_INDEX; | |
1090 | } else { | 1092 | } else { | |
1091 | sc->sc_child_mq = false; | |||
1092 | } | |||
1093 | ||||
1094 | if (sc->sc_child_mq == false) { | |||
1095 | nmsix = 2; | 1093 | nmsix = 2; | |
1096 | } | 1094 | } | |
1097 | 1095 | |||
1098 | max_type = PCI_INTR_TYPE_MSIX; | 1096 | max_type = PCI_INTR_TYPE_MSIX; | |
1099 | counts[PCI_INTR_TYPE_MSIX] = nmsix; | 1097 | counts[PCI_INTR_TYPE_MSIX] = nmsix; | |
1100 | counts[PCI_INTR_TYPE_MSI] = 0; | 1098 | counts[PCI_INTR_TYPE_MSI] = 0; | |
1101 | counts[PCI_INTR_TYPE_INTX] = 1; | 1099 | counts[PCI_INTR_TYPE_INTX] = 1; | |
1102 | } | 1100 | } | |
1103 | 1101 | |||
1104 | retry: | 1102 | retry: | |
1105 | error = pci_intr_alloc(&psc->sc_pa, &psc->sc_ihp, counts, max_type); | 1103 | error = pci_intr_alloc(&psc->sc_pa, &psc->sc_ihp, counts, max_type); | |
1106 | if (error != 0) { | 1104 | if (error != 0) { | |
1107 | aprint_error_dev(self, "couldn't map interrupt\n"); | 1105 | aprint_error_dev(self, "couldn't map interrupt\n"); | |
1108 | return -1; | 1106 | return -1; | |
1109 | } | 1107 | } | |
1110 | 1108 | |||
1111 | if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) { | 1109 | if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX) { | |
1110 | psc->sc_intr_pervq = nmsix > 2 ? true : false; | |||
1112 | psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * nmsix, | 1111 | psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * nmsix, | |
1113 | KM_SLEEP); | 1112 | KM_SLEEP); | |
1114 | 1113 | |||
1115 | error = virtio_pci_establish_msix_interrupts(sc, &psc->sc_pa); | 1114 | error = virtio_pci_establish_msix_interrupts(sc, &psc->sc_pa); | |
1116 | if (error != 0) { | 1115 | if (error != 0) { | |
1117 | kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * nmsix); | 1116 | kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * nmsix); | |
1118 | pci_intr_release(pc, psc->sc_ihp, nmsix); | 1117 | pci_intr_release(pc, psc->sc_ihp, nmsix); | |
1119 | 1118 | |||
1120 | /* Retry INTx */ | 1119 | /* Retry INTx */ | |
1121 | max_type = PCI_INTR_TYPE_INTX; | 1120 | max_type = PCI_INTR_TYPE_INTX; | |
1122 | counts[PCI_INTR_TYPE_INTX] = 1; | 1121 | counts[PCI_INTR_TYPE_INTX] = 1; | |
1123 | goto retry; | 1122 | goto retry; | |
1124 | } | 1123 | } | |
1125 | 1124 | |||
1126 | psc->sc_ihs_num = nmsix; | 1125 | psc->sc_ihs_num = nmsix; | |
1127 | psc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI; | 1126 | psc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI; | |
1128 | virtio_pci_adjust_config_region(psc); | 1127 | virtio_pci_adjust_config_region(psc); | |
1129 | } else if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) { | 1128 | } else if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_INTX) { | |
1129 | psc->sc_intr_pervq = false; | |||
1130 | psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * 1, | 1130 | psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * 1, | |
1131 | KM_SLEEP); | 1131 | KM_SLEEP); | |
1132 | 1132 | |||
1133 | error = virtio_pci_establish_intx_interrupt(sc, &psc->sc_pa); | 1133 | error = virtio_pci_establish_intx_interrupt(sc, &psc->sc_pa); | |
1134 | if (error != 0) { | 1134 | if (error != 0) { | |
1135 | kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * 1); | 1135 | kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * 1); | |
1136 | pci_intr_release(pc, psc->sc_ihp, 1); | 1136 | pci_intr_release(pc, psc->sc_ihp, 1); | |
1137 | return -1; | 1137 | return -1; | |
1138 | } | 1138 | } | |
1139 | 1139 | |||
1140 | psc->sc_ihs_num = 1; | 1140 | psc->sc_ihs_num = 1; | |
1141 | psc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; | 1141 | psc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_NOMSI; | |
1142 | virtio_pci_adjust_config_region(psc); | 1142 | virtio_pci_adjust_config_region(psc); | |
1143 | 1143 | |||
1144 | error = pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, NULL); | 1144 | error = pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, NULL); | |
1145 | if (error != 0) { | 1145 | if (error != 0) { | |
1146 | ctl = pci_conf_read(pc, tag, off + PCI_MSIX_CTL); | 1146 | ctl = pci_conf_read(pc, tag, off + PCI_MSIX_CTL); | |
1147 | ctl &= ~PCI_MSIX_CTL_ENABLE; | 1147 | ctl &= ~PCI_MSIX_CTL_ENABLE; | |
1148 | pci_conf_write(pc, tag, off + PCI_MSIX_CTL, ctl); | 1148 | pci_conf_write(pc, tag, off + PCI_MSIX_CTL, ctl); | |
1149 | } | 1149 | } | |
1150 | } | 1150 | } | |
1151 | 1151 | |||
1152 | if (!psc->sc_intr_pervq) | |||
1153 | CLR(sc->sc_flags, VIRTIO_F_INTR_PERVQ); | |||
1152 | return 0; | 1154 | return 0; | |
1153 | } | 1155 | } | |
1154 | 1156 | |||
1155 | static void | 1157 | static void | |
1156 | virtio_pci_free_interrupts(struct virtio_softc *sc) | 1158 | virtio_pci_free_interrupts(struct virtio_softc *sc) | |
1157 | { | 1159 | { | |
1158 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | 1160 | struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; | |
1159 | 1161 | |||
1160 | for (int i = 0; i < psc->sc_ihs_num; i++) { | 1162 | for (int i = 0; i < psc->sc_ihs_num; i++) { | |
1161 | if (psc->sc_ihs[i] == NULL) | 1163 | if (psc->sc_ihs[i] == NULL) | |
1162 | continue; | 1164 | continue; | |
1163 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[i]); | 1165 | pci_intr_disestablish(psc->sc_pa.pa_pc, psc->sc_ihs[i]); | |
1164 | psc->sc_ihs[i] = NULL; | 1166 | psc->sc_ihs[i] = NULL; |
--- src/sys/dev/pci/virtiovar.h 2022/03/24 08:08:05 1.24
+++ src/sys/dev/pci/virtiovar.h 2023/03/23 03:27:48 1.25
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: virtiovar.h,v 1.24 2022/03/24 08:08:05 andvar Exp $ */ | 1 | /* $NetBSD: virtiovar.h,v 1.25 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2010 Minoura Makoto. | 4 | * Copyright (c) 2010 Minoura Makoto. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -161,39 +161,39 @@ struct virtio_softc { | @@ -161,39 +161,39 @@ struct virtio_softc { | |||
161 | 161 | |||
162 | int sc_flags; /* set by child */ | 162 | int sc_flags; /* set by child */ | |
163 | 163 | |||
164 | uint64_t sc_active_features; | 164 | uint64_t sc_active_features; | |
165 | bool sc_indirect; | 165 | bool sc_indirect; | |
166 | bool sc_version_1; | 166 | bool sc_version_1; | |
167 | bool sc_finished_called; | 167 | bool sc_finished_called; | |
168 | 168 | |||
169 | int sc_nvqs; /* set by child */ | 169 | int sc_nvqs; /* set by child */ | |
170 | struct virtqueue *sc_vqs; /* set by child */ | 170 | struct virtqueue *sc_vqs; /* set by child */ | |
171 | 171 | |||
172 | int sc_childdevid; | 172 | int sc_childdevid; | |
173 | device_t sc_child; /* set by child */ | 173 | device_t sc_child; /* set by child */ | |
174 | bool sc_child_mq; | |||
175 | virtio_callback sc_config_change; /* set by child */ | 174 | virtio_callback sc_config_change; /* set by child */ | |
176 | virtio_callback sc_intrhand; /* set by child */ | 175 | virtio_callback sc_intrhand; /* set by child */ | |
177 | }; | 176 | }; | |
178 | #else | 177 | #else | |
179 | struct virtio_softc; | 178 | struct virtio_softc; | |
180 | #endif | 179 | #endif | |
181 | 180 | |||
182 | 181 | |||
183 | /* interrupt types, stored in virtio_softc->sc_flags */ | 182 | /* interrupt types, stored in virtio_softc->sc_flags */ | |
184 | #define VIRTIO_F_INTR_MPSAFE (1 << 0) | 183 | #define VIRTIO_F_INTR_MPSAFE (1 << 0) | |
185 | #define VIRTIO_F_INTR_SOFTINT (1 << 1) | 184 | #define VIRTIO_F_INTR_SOFTINT (1 << 1) | |
186 | #define VIRTIO_F_INTR_MSIX (1 << 2) | 185 | #define VIRTIO_F_INTR_MSIX (1 << 2) | |
186 | #define VIRTIO_F_INTR_PERVQ (1 << 3) | |||
187 | 187 | |||
188 | 188 | |||
189 | #define VIRTIO_CHILD_FAILED ((void *)1) | 189 | #define VIRTIO_CHILD_FAILED ((void *)1) | |
190 | 190 | |||
191 | /* public interface */ | 191 | /* public interface */ | |
192 | void virtio_negotiate_features(struct virtio_softc*, uint64_t); | 192 | void virtio_negotiate_features(struct virtio_softc*, uint64_t); | |
193 | 193 | |||
194 | uint8_t virtio_read_device_config_1(struct virtio_softc *, int); | 194 | uint8_t virtio_read_device_config_1(struct virtio_softc *, int); | |
195 | uint16_t virtio_read_device_config_2(struct virtio_softc *, int); | 195 | uint16_t virtio_read_device_config_2(struct virtio_softc *, int); | |
196 | uint32_t virtio_read_device_config_4(struct virtio_softc *, int); | 196 | uint32_t virtio_read_device_config_4(struct virtio_softc *, int); | |
197 | uint64_t virtio_read_device_config_8(struct virtio_softc *, int); | 197 | uint64_t virtio_read_device_config_8(struct virtio_softc *, int); | |
198 | uint16_t virtio_read_device_config_le_2(struct virtio_softc *, int); | 198 | uint16_t virtio_read_device_config_le_2(struct virtio_softc *, int); | |
199 | uint32_t virtio_read_device_config_le_4(struct virtio_softc *, int); | 199 | uint32_t virtio_read_device_config_le_4(struct virtio_softc *, int); | |
@@ -201,32 +201,30 @@ void virtio_write_device_config_1(struct | @@ -201,32 +201,30 @@ void virtio_write_device_config_1(struct | |||
201 | void virtio_write_device_config_2(struct virtio_softc *, int, uint16_t); | 201 | void virtio_write_device_config_2(struct virtio_softc *, int, uint16_t); | |
202 | void virtio_write_device_config_4(struct virtio_softc *, int, uint32_t); | 202 | void virtio_write_device_config_4(struct virtio_softc *, int, uint32_t); | |
203 | void virtio_write_device_config_8(struct virtio_softc *, int, uint64_t); | 203 | void virtio_write_device_config_8(struct virtio_softc *, int, uint64_t); | |
204 | void virtio_write_device_config_le_2(struct virtio_softc *, int, uint16_t); | 204 | void virtio_write_device_config_le_2(struct virtio_softc *, int, uint16_t); | |
205 | void virtio_write_device_config_le_4(struct virtio_softc *, int, uint32_t); | 205 | void virtio_write_device_config_le_4(struct virtio_softc *, int, uint32_t); | |
206 | 206 | |||
207 | int virtio_alloc_vq(struct virtio_softc*, struct virtqueue*, int, int, int, | 207 | int virtio_alloc_vq(struct virtio_softc*, struct virtqueue*, int, int, int, | |
208 | const char*); | 208 | const char*); | |
209 | int virtio_free_vq(struct virtio_softc*, struct virtqueue*); | 209 | int virtio_free_vq(struct virtio_softc*, struct virtqueue*); | |
210 | void virtio_reset(struct virtio_softc *); | 210 | void virtio_reset(struct virtio_softc *); | |
211 | int virtio_reinit_start(struct virtio_softc *); | 211 | int virtio_reinit_start(struct virtio_softc *); | |
212 | void virtio_reinit_end(struct virtio_softc *); | 212 | void virtio_reinit_end(struct virtio_softc *); | |
213 | void virtio_child_attach_start(struct virtio_softc *, device_t, int, | 213 | void virtio_child_attach_start(struct virtio_softc *, device_t, int, | |
214 | struct virtqueue *, | 214 | uint64_t, const char *); | |
215 | virtio_callback, virtio_callback, int, | 215 | int virtio_child_attach_finish(struct virtio_softc *, | |
216 | int, const char *); | 216 | struct virtqueue *, size_t, | |
217 | void virtio_child_attach_set_vqs(struct virtio_softc *, | 217 | virtio_callback, virtio_callback, int); | |
218 | struct virtqueue *, int); | |||
219 | int virtio_child_attach_finish(struct virtio_softc *); | |||
220 | void virtio_child_attach_failed(struct virtio_softc *); | 218 | void virtio_child_attach_failed(struct virtio_softc *); | |
221 | void virtio_child_detach(struct virtio_softc *); | 219 | void virtio_child_detach(struct virtio_softc *); | |
222 | 220 | |||
223 | int virtio_enqueue_prep(struct virtio_softc*, struct virtqueue*, int*); | 221 | int virtio_enqueue_prep(struct virtio_softc*, struct virtqueue*, int*); | |
224 | int virtio_enqueue_reserve(struct virtio_softc*, struct virtqueue*, int, int); | 222 | int virtio_enqueue_reserve(struct virtio_softc*, struct virtqueue*, int, int); | |
225 | int virtio_enqueue(struct virtio_softc*, struct virtqueue*, int, | 223 | int virtio_enqueue(struct virtio_softc*, struct virtqueue*, int, | |
226 | bus_dmamap_t, bool); | 224 | bus_dmamap_t, bool); | |
227 | int virtio_enqueue_p(struct virtio_softc*, struct virtqueue*, int, | 225 | int virtio_enqueue_p(struct virtio_softc*, struct virtqueue*, int, | |
228 | bus_dmamap_t, bus_addr_t, bus_size_t, bool); | 226 | bus_dmamap_t, bus_addr_t, bus_size_t, bool); | |
229 | int virtio_enqueue_commit(struct virtio_softc*, struct virtqueue*, int, bool); | 227 | int virtio_enqueue_commit(struct virtio_softc*, struct virtqueue*, int, bool); | |
230 | int virtio_enqueue_abort(struct virtio_softc*, struct virtqueue*, int); | 228 | int virtio_enqueue_abort(struct virtio_softc*, struct virtqueue*, int); | |
231 | 229 | |||
232 | int virtio_dequeue(struct virtio_softc*, struct virtqueue*, int *, int *); | 230 | int virtio_dequeue(struct virtio_softc*, struct virtqueue*, int *, int *); |
--- src/sys/dev/virtio/viocon.c 2022/08/13 17:31:32 1.5
+++ src/sys/dev/virtio/viocon.c 2023/03/23 03:27:48 1.6
@@ -1,34 +1,34 @@ | @@ -1,34 +1,34 @@ | |||
1 | /* $NetBSD: viocon.c,v 1.5 2022/08/13 17:31:32 riastradh Exp $ */ | 1 | /* $NetBSD: viocon.c,v 1.6 2023/03/23 03:27:48 yamaguchi Exp $ */ | |
2 | /* $OpenBSD: viocon.c,v 1.8 2021/11/05 11:38:29 mpi Exp $ */ | 2 | /* $OpenBSD: viocon.c,v 1.8 2021/11/05 11:38:29 mpi Exp $ */ | |
3 | 3 | |||
4 | /* | 4 | /* | |
5 | * Copyright (c) 2013-2015 Stefan Fritsch <sf@sfritsch.de> | 5 | * Copyright (c) 2013-2015 Stefan Fritsch <sf@sfritsch.de> | |
6 | * | 6 | * | |
7 | * Permission to use, copy, modify, and distribute this software for any | 7 | * Permission to use, copy, modify, and distribute this software for any | |
8 | * purpose with or without fee is hereby granted, provided that the above | 8 | * purpose with or without fee is hereby granted, provided that the above | |
9 | * copyright notice and this permission notice appear in all copies. | 9 | * copyright notice and this permission notice appear in all copies. | |
10 | * | 10 | * | |
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | |
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | |
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
18 | */ | 18 | */ | |
19 | 19 | |||
20 | #include <sys/cdefs.h> | 20 | #include <sys/cdefs.h> | |
21 | __KERNEL_RCSID(0, "$NetBSD: viocon.c,v 1.5 2022/08/13 17:31:32 riastradh Exp $"); | 21 | __KERNEL_RCSID(0, "$NetBSD: viocon.c,v 1.6 2023/03/23 03:27:48 yamaguchi Exp $"); | |
22 | 22 | |||
23 | #include <sys/param.h> | 23 | #include <sys/param.h> | |
24 | #include <sys/types.h> | 24 | #include <sys/types.h> | |
25 | 25 | |||
26 | #include <sys/bus.h> | 26 | #include <sys/bus.h> | |
27 | #include <sys/conf.h> | 27 | #include <sys/conf.h> | |
28 | #include <sys/device.h> | 28 | #include <sys/device.h> | |
29 | #include <sys/kauth.h> | 29 | #include <sys/kauth.h> | |
30 | #include <sys/kernel.h> | 30 | #include <sys/kernel.h> | |
31 | #include <sys/kmem.h> | 31 | #include <sys/kmem.h> | |
32 | #include <sys/lwp.h> | 32 | #include <sys/lwp.h> | |
33 | #include <sys/systm.h> | 33 | #include <sys/systm.h> | |
34 | #include <sys/tty.h> | 34 | #include <sys/tty.h> | |
@@ -199,39 +199,38 @@ viocon_attach(struct device *parent, str | @@ -199,39 +199,38 @@ viocon_attach(struct device *parent, str | |||
199 | if (virtio_child(vsc) != NULL) { | 199 | if (virtio_child(vsc) != NULL) { | |
200 | aprint_error(": parent %s already has a child\n", | 200 | aprint_error(": parent %s already has a child\n", | |
201 | device_xname(parent)); | 201 | device_xname(parent)); | |
202 | return; | 202 | return; | |
203 | } | 203 | } | |
204 | sc->sc_virtio = vsc; | 204 | sc->sc_virtio = vsc; | |
205 | sc->sc_max_ports = maxports; | 205 | sc->sc_max_ports = maxports; | |
206 | 206 | |||
207 | sc->sc_vqs = kmem_zalloc(2 * (maxports + 1) * sizeof(sc->sc_vqs[0]), | 207 | sc->sc_vqs = kmem_zalloc(2 * (maxports + 1) * sizeof(sc->sc_vqs[0]), | |
208 | KM_SLEEP); | 208 | KM_SLEEP); | |
209 | sc->sc_ports = kmem_zalloc(maxports * sizeof(sc->sc_ports[0]), | 209 | sc->sc_ports = kmem_zalloc(maxports * sizeof(sc->sc_ports[0]), | |
210 | KM_SLEEP); | 210 | KM_SLEEP); | |
211 | 211 | |||
212 | virtio_child_attach_start(vsc, self, IPL_TTY, sc->sc_vqs, | 212 | virtio_child_attach_start(vsc, self, IPL_TTY, | |
213 | /*config_change*/NULL, virtio_vq_intr, | 213 | /*req_features*/VIRTIO_CONSOLE_F_SIZE, VIRTIO_CONSOLE_FLAG_BITS); | |
214 | /*req_flags*/0, /*req_features*/VIRTIO_CONSOLE_F_SIZE, | |||
215 | VIRTIO_CONSOLE_FLAG_BITS); | |||
216 | 214 | |||
217 | DPRINTF("%s: softc: %p\n", __func__, sc); | 215 | DPRINTF("%s: softc: %p\n", __func__, sc); | |
218 | if (viocon_port_create(sc, 0) != 0) { | 216 | if (viocon_port_create(sc, 0) != 0) { | |
219 | printf("\n%s: viocon_port_create failed\n", __func__); | 217 | printf("\n%s: viocon_port_create failed\n", __func__); | |
220 | goto err; | 218 | goto err; | |
221 | } | 219 | } | |
222 | viocon_rx_fill(sc->sc_ports[0]); | 220 | viocon_rx_fill(sc->sc_ports[0]); | |
223 | 221 | |||
224 | if (virtio_child_attach_finish(vsc) != 0) | 222 | if (virtio_child_attach_finish(vsc, sc->sc_vqs, sc->sc_max_ports * 2, | |
223 | /*config_change*/NULL, virtio_vq_intr, /*req_flags*/0) != 0) | |||
225 | goto err; | 224 | goto err; | |
226 | 225 | |||
227 | return; | 226 | return; | |
228 | err: | 227 | err: | |
229 | kmem_free(sc->sc_vqs, 2 * (maxports + 1) * sizeof(sc->sc_vqs[0])); | 228 | kmem_free(sc->sc_vqs, 2 * (maxports + 1) * sizeof(sc->sc_vqs[0])); | |
230 | kmem_free(sc->sc_ports, maxports * sizeof(sc->sc_ports[0])); | 229 | kmem_free(sc->sc_ports, maxports * sizeof(sc->sc_ports[0])); | |
231 | virtio_child_attach_failed(vsc); | 230 | virtio_child_attach_failed(vsc); | |
232 | } | 231 | } | |
233 | 232 | |||
234 | int | 233 | int | |
235 | viocon_port_create(struct viocon_softc *sc, int portidx) | 234 | viocon_port_create(struct viocon_softc *sc, int portidx) | |
236 | { | 235 | { | |
237 | struct virtio_softc *vsc = sc->sc_virtio; | 236 | struct virtio_softc *vsc = sc->sc_virtio; |