Thu Mar 23 03:27:48 2023 UTC ()
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.


(yamaguchi)
diff -r1.102 -r1.103 src/sys/dev/pci/if_vioif.c
diff -r1.30 -r1.31 src/sys/dev/pci/ld_virtio.c
diff -r1.30 -r1.31 src/sys/dev/pci/vioscsi.c
diff -r1.9 -r1.10 src/sys/dev/pci/vio9p.c
diff -r1.13 -r1.14 src/sys/dev/pci/viomb.c
diff -r1.18 -r1.19 src/sys/dev/pci/viornd.c
diff -r1.65 -r1.66 src/sys/dev/pci/virtio.c
diff -r1.38 -r1.39 src/sys/dev/pci/virtio_pci.c
diff -r1.24 -r1.25 src/sys/dev/pci/virtiovar.h
diff -r1.5 -r1.6 src/sys/dev/virtio/viocon.c

cvs diff -r1.102 -r1.103 src/sys/dev/pci/if_vioif.c (expand / switch to unified diff)

--- 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
456static void 456static void
457vioif_attach(device_t parent, device_t self, void *aux) 457vioif_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
658err: 664err:
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);

cvs diff -r1.30 -r1.31 src/sys/dev/pci/ld_virtio.c (expand / switch to unified diff)

--- 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);

cvs diff -r1.30 -r1.31 src/sys/dev/pci/vioscsi.c (expand / switch to unified diff)

--- 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

cvs diff -r1.9 -r1.10 src/sys/dev/pci/vio9p.c (expand / switch to unified diff)

--- 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
568err_mutex: 565err_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);
571err_dmamap: 568err_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);
574err_vq: 571err_vq:
575 virtio_free_vq(vsc, &sc->sc_vq[0]); 572 virtio_free_vq(vsc, &sc->sc_vq[0]);

cvs diff -r1.13 -r1.14 src/sys/dev/pci/viomb.c (expand / switch to unified diff)

--- 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,

cvs diff -r1.18 -r1.19 src/sys/dev/pci/viornd.c (expand / switch to unified diff)

--- 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
204vio_failed: 205vio_failed:
205 bus_dmamap_unload(virtio_dmat(vsc), sc->sc_dmamap); 206 bus_dmamap_unload(virtio_dmat(vsc), sc->sc_dmamap);

cvs diff -r1.65 -r1.66 src/sys/dev/pci/virtio.c (expand / switch to unified diff)

--- 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 */
757int 757int
758virtio_alloc_vq(struct virtio_softc *sc, struct virtqueue *vq, int index, 758virtio_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
871err: 866err:
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 */
924static struct vq_entry * 917static struct vq_entry *
925vq_alloc_entry(struct virtqueue *vq) 918vq_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 */
1271void 1264void
1272virtio_child_attach_start(struct virtio_softc *sc, device_t child, int ipl, 1265virtio_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
1293void 
1294virtio_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 
1306int 1279int
1307virtio_child_attach_finish(struct virtio_softc *sc) 1280virtio_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

cvs diff -r1.38 -r1.39 src/sys/dev/pci/virtio_pci.c (expand / switch to unified diff)

--- 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
66static int virtio_pci_match(device_t, cfdata_t, void *); 66static int virtio_pci_match(device_t, cfdata_t, void *);
67static void virtio_pci_attach(device_t, device_t, void *); 67static void virtio_pci_attach(device_t, device_t, void *);
68static int virtio_pci_rescan(device_t, const char *, const int *); 68static int virtio_pci_rescan(device_t, const char *, const int *);
69static int virtio_pci_detach(device_t, int); 69static 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))
74struct virtio_pci_softc { 74struct 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
620static void 621static void
621virtio_pci_setup_queue_09(struct virtio_softc *sc, uint16_t idx, uint64_t addr) 622virtio_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
639static void 640static void
640virtio_pci_set_status_09(struct virtio_softc *sc, int status) 641virtio_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
761static void 762static void
762virtio_pci_set_status_10(struct virtio_softc *sc, int status) 763virtio_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
1017error: 1018error:
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
1104retry: 1102retry:
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
1155static void 1157static void
1156virtio_pci_free_interrupts(struct virtio_softc *sc) 1158virtio_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;

cvs diff -r1.24 -r1.25 src/sys/dev/pci/virtiovar.h (expand / switch to unified diff)

--- 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
179struct virtio_softc; 178struct 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 */
192void virtio_negotiate_features(struct virtio_softc*, uint64_t); 192void virtio_negotiate_features(struct virtio_softc*, uint64_t);
193 193
194uint8_t virtio_read_device_config_1(struct virtio_softc *, int); 194uint8_t virtio_read_device_config_1(struct virtio_softc *, int);
195uint16_t virtio_read_device_config_2(struct virtio_softc *, int); 195uint16_t virtio_read_device_config_2(struct virtio_softc *, int);
196uint32_t virtio_read_device_config_4(struct virtio_softc *, int); 196uint32_t virtio_read_device_config_4(struct virtio_softc *, int);
197uint64_t virtio_read_device_config_8(struct virtio_softc *, int); 197uint64_t virtio_read_device_config_8(struct virtio_softc *, int);
198uint16_t virtio_read_device_config_le_2(struct virtio_softc *, int); 198uint16_t virtio_read_device_config_le_2(struct virtio_softc *, int);
199uint32_t virtio_read_device_config_le_4(struct virtio_softc *, int); 199uint32_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
201void virtio_write_device_config_2(struct virtio_softc *, int, uint16_t); 201void virtio_write_device_config_2(struct virtio_softc *, int, uint16_t);
202void virtio_write_device_config_4(struct virtio_softc *, int, uint32_t); 202void virtio_write_device_config_4(struct virtio_softc *, int, uint32_t);
203void virtio_write_device_config_8(struct virtio_softc *, int, uint64_t); 203void virtio_write_device_config_8(struct virtio_softc *, int, uint64_t);
204void virtio_write_device_config_le_2(struct virtio_softc *, int, uint16_t); 204void virtio_write_device_config_le_2(struct virtio_softc *, int, uint16_t);
205void virtio_write_device_config_le_4(struct virtio_softc *, int, uint32_t); 205void virtio_write_device_config_le_4(struct virtio_softc *, int, uint32_t);
206 206
207int virtio_alloc_vq(struct virtio_softc*, struct virtqueue*, int, int, int, 207int virtio_alloc_vq(struct virtio_softc*, struct virtqueue*, int, int, int,
208 const char*); 208 const char*);
209int virtio_free_vq(struct virtio_softc*, struct virtqueue*); 209int virtio_free_vq(struct virtio_softc*, struct virtqueue*);
210void virtio_reset(struct virtio_softc *); 210void virtio_reset(struct virtio_softc *);
211int virtio_reinit_start(struct virtio_softc *); 211int virtio_reinit_start(struct virtio_softc *);
212void virtio_reinit_end(struct virtio_softc *); 212void virtio_reinit_end(struct virtio_softc *);
213void virtio_child_attach_start(struct virtio_softc *, device_t, int, 213void virtio_child_attach_start(struct virtio_softc *, device_t, int,
214 struct virtqueue *, 214 uint64_t, const char *);
215 virtio_callback, virtio_callback, int, 215int virtio_child_attach_finish(struct virtio_softc *,
216 int, const char *); 216 struct virtqueue *, size_t,
217void virtio_child_attach_set_vqs(struct virtio_softc *, 217 virtio_callback, virtio_callback, int);
218 struct virtqueue *, int); 
219int virtio_child_attach_finish(struct virtio_softc *); 
220void virtio_child_attach_failed(struct virtio_softc *); 218void virtio_child_attach_failed(struct virtio_softc *);
221void virtio_child_detach(struct virtio_softc *); 219void virtio_child_detach(struct virtio_softc *);
222 220
223int virtio_enqueue_prep(struct virtio_softc*, struct virtqueue*, int*); 221int virtio_enqueue_prep(struct virtio_softc*, struct virtqueue*, int*);
224int virtio_enqueue_reserve(struct virtio_softc*, struct virtqueue*, int, int); 222int virtio_enqueue_reserve(struct virtio_softc*, struct virtqueue*, int, int);
225int virtio_enqueue(struct virtio_softc*, struct virtqueue*, int, 223int virtio_enqueue(struct virtio_softc*, struct virtqueue*, int,
226 bus_dmamap_t, bool); 224 bus_dmamap_t, bool);
227int virtio_enqueue_p(struct virtio_softc*, struct virtqueue*, int, 225int 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);
229int virtio_enqueue_commit(struct virtio_softc*, struct virtqueue*, int, bool); 227int virtio_enqueue_commit(struct virtio_softc*, struct virtqueue*, int, bool);
230int virtio_enqueue_abort(struct virtio_softc*, struct virtqueue*, int); 228int virtio_enqueue_abort(struct virtio_softc*, struct virtqueue*, int);
231 229
232int virtio_dequeue(struct virtio_softc*, struct virtqueue*, int *, int *); 230int virtio_dequeue(struct virtio_softc*, struct virtqueue*, int *, int *);

cvs diff -r1.5 -r1.6 src/sys/dev/virtio/viocon.c (expand / switch to unified diff)

--- 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;
228err: 227err:
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
234int 233int
235viocon_port_create(struct viocon_softc *sc, int portidx) 234viocon_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;