Thu Oct 21 05:37:43 2021 UTC ()
virtio: reconfigure MSI-X vector on re-initialization

This may fix a problem that some interrupts, for example
link-state change of vioif(4) are not notified.


(yamaguchi)
diff -r1.50 -r1.51 src/sys/dev/pci/virtio.c
diff -r1.31 -r1.32 src/sys/dev/pci/virtio_pci.c
diff -r1.21 -r1.22 src/sys/dev/pci/virtiovar.h

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

--- src/sys/dev/pci/virtio.c 2021/10/21 05:32:27 1.50
+++ src/sys/dev/pci/virtio.c 2021/10/21 05:37:43 1.51
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: virtio.c,v 1.50 2021/10/21 05:32:27 yamaguchi Exp $ */ 1/* $NetBSD: virtio.c,v 1.51 2021/10/21 05:37:43 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.50 2021/10/21 05:32:27 yamaguchi Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.51 2021/10/21 05:37:43 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 */
@@ -83,45 +83,51 @@ virtio_set_status(struct virtio_softc *s @@ -83,45 +83,51 @@ virtio_set_status(struct virtio_softc *s
83 * <some other initialization>; 83 * <some other initialization>;
84 * virtio_reinit_end(sc); // device activated; enqueue allowed 84 * virtio_reinit_end(sc); // device activated; enqueue allowed
85 * Once attached, feature negotiation can only be allowed after virtio_reset. 85 * Once attached, feature negotiation can only be allowed after virtio_reset.
86 */ 86 */
87void 87void
88virtio_reset(struct virtio_softc *sc) 88virtio_reset(struct virtio_softc *sc)
89{ 89{
90 virtio_device_reset(sc); 90 virtio_device_reset(sc);
91} 91}
92 92
93void 93void
94virtio_reinit_start(struct virtio_softc *sc) 94virtio_reinit_start(struct virtio_softc *sc)
95{ 95{
96 int i; 96 int i, r;
97 97
98 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK); 98 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
99 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER); 99 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
100 for (i = 0; i < sc->sc_nvqs; i++) { 100 for (i = 0; i < sc->sc_nvqs; i++) {
101 int n; 101 int n;
102 struct virtqueue *vq = &sc->sc_vqs[i]; 102 struct virtqueue *vq = &sc->sc_vqs[i];
103 n = sc->sc_ops->read_queue_size(sc, vq->vq_index); 103 n = sc->sc_ops->read_queue_size(sc, vq->vq_index);
104 if (n == 0) /* vq disappeared */ 104 if (n == 0) /* vq disappeared */
105 continue; 105 continue;
106 if (n != vq->vq_num) { 106 if (n != vq->vq_num) {
107 panic("%s: virtqueue size changed, vq index %d\n", 107 panic("%s: virtqueue size changed, vq index %d\n",
108 device_xname(sc->sc_dev), 108 device_xname(sc->sc_dev),
109 vq->vq_index); 109 vq->vq_index);
110 } 110 }
111 virtio_init_vq(sc, vq, true); 111 virtio_init_vq(sc, vq, true);
112 sc->sc_ops->setup_queue(sc, vq->vq_index, 112 sc->sc_ops->setup_queue(sc, vq->vq_index,
113 vq->vq_dmamap->dm_segs[0].ds_addr); 113 vq->vq_dmamap->dm_segs[0].ds_addr);
114 } 114 }
 115
 116 r = sc->sc_ops->setup_interrupts(sc, 1);
 117 if (r != 0) {
 118 printf("%s: failed to setup interrupts\n",
 119 device_xname(sc->sc_dev));
 120 }
115} 121}
116 122
117void 123void
118virtio_reinit_end(struct virtio_softc *sc) 124virtio_reinit_end(struct virtio_softc *sc)
119{ 125{
120 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK); 126 virtio_set_status(sc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER_OK);
121} 127}
122 128
123/* 129/*
124 * Feature negotiation. 130 * Feature negotiation.
125 */ 131 */
126void 132void
127virtio_negotiate_features(struct virtio_softc *sc, uint64_t guest_features) 133virtio_negotiate_features(struct virtio_softc *sc, uint64_t guest_features)
@@ -1195,27 +1201,27 @@ virtio_child_attach_set_vqs(struct virti @@ -1195,27 +1201,27 @@ virtio_child_attach_set_vqs(struct virti
1195 1201
1196int 1202int
1197virtio_child_attach_finish(struct virtio_softc *sc) 1203virtio_child_attach_finish(struct virtio_softc *sc)
1198{ 1204{
1199 int r; 1205 int r;
1200 1206
1201 sc->sc_finished_called = true; 1207 sc->sc_finished_called = true;
1202 r = sc->sc_ops->alloc_interrupts(sc); 1208 r = sc->sc_ops->alloc_interrupts(sc);
1203 if (r != 0) { 1209 if (r != 0) {
1204 aprint_error_dev(sc->sc_dev, "failed to allocate interrupts\n"); 1210 aprint_error_dev(sc->sc_dev, "failed to allocate interrupts\n");
1205 goto fail; 1211 goto fail;
1206 } 1212 }
1207 1213
1208 r = sc->sc_ops->setup_interrupts(sc); 1214 r = sc->sc_ops->setup_interrupts(sc, 0);
1209 if (r != 0) { 1215 if (r != 0) {
1210 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n"); 1216 aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n");
1211 } 1217 }
1212 1218
1213 KASSERT(sc->sc_soft_ih == NULL); 1219 KASSERT(sc->sc_soft_ih == NULL);
1214 if (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) { 1220 if (sc->sc_flags & VIRTIO_F_INTR_SOFTINT) {
1215 u_int flags = SOFTINT_NET; 1221 u_int flags = SOFTINT_NET;
1216 if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE) 1222 if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE)
1217 flags |= SOFTINT_MPSAFE; 1223 flags |= SOFTINT_MPSAFE;
1218 1224
1219 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc); 1225 sc->sc_soft_ih = softint_establish(flags, virtio_soft_intr, sc);
1220 if (sc->sc_soft_ih == NULL) { 1226 if (sc->sc_soft_ih == NULL) {
1221 sc->sc_ops->free_interrupts(sc); 1227 sc->sc_ops->free_interrupts(sc);

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

--- src/sys/dev/pci/virtio_pci.c 2021/10/21 05:32:27 1.31
+++ src/sys/dev/pci/virtio_pci.c 2021/10/21 05:37:43 1.32
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: virtio_pci.c,v 1.31 2021/10/21 05:32:27 yamaguchi Exp $ */ 1/* $NetBSD: virtio_pci.c,v 1.32 2021/10/21 05:37:43 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.31 2021/10/21 05:32:27 yamaguchi Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.32 2021/10/21 05:37:43 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 39
40#include <sys/device.h> 40#include <sys/device.h>
41 41
42#include <dev/pci/pcidevs.h> 42#include <dev/pci/pcidevs.h>
43#include <dev/pci/pcireg.h> 43#include <dev/pci/pcireg.h>
44#include <dev/pci/pcivar.h> 44#include <dev/pci/pcivar.h>
@@ -102,28 +102,28 @@ static int virtio_pci_attach_10(device_t @@ -102,28 +102,28 @@ static int virtio_pci_attach_10(device_t
102static void virtio_pci_kick_10(struct virtio_softc *, uint16_t); 102static void virtio_pci_kick_10(struct virtio_softc *, uint16_t);
103static uint16_t virtio_pci_read_queue_size_10(struct virtio_softc *, uint16_t); 103static uint16_t virtio_pci_read_queue_size_10(struct virtio_softc *, uint16_t);
104static void virtio_pci_setup_queue_10(struct virtio_softc *, uint16_t, uint64_t); 104static void virtio_pci_setup_queue_10(struct virtio_softc *, uint16_t, uint64_t);
105static void virtio_pci_set_status_10(struct virtio_softc *, int); 105static void virtio_pci_set_status_10(struct virtio_softc *, int);
106static void virtio_pci_negotiate_features_10(struct virtio_softc *, uint64_t); 106static void virtio_pci_negotiate_features_10(struct virtio_softc *, uint64_t);
107static int virtio_pci_find_cap(struct virtio_pci_softc *psc, int cfg_type, void *buf, int buflen); 107static int virtio_pci_find_cap(struct virtio_pci_softc *psc, int cfg_type, void *buf, int buflen);
108 108
109static int virtio_pci_alloc_interrupts(struct virtio_softc *); 109static int virtio_pci_alloc_interrupts(struct virtio_softc *);
110static void virtio_pci_free_interrupts(struct virtio_softc *); 110static void virtio_pci_free_interrupts(struct virtio_softc *);
111static int virtio_pci_adjust_config_region(struct virtio_pci_softc *psc); 111static int virtio_pci_adjust_config_region(struct virtio_pci_softc *psc);
112static int virtio_pci_intr(void *arg); 112static int virtio_pci_intr(void *arg);
113static int virtio_pci_msix_queue_intr(void *); 113static int virtio_pci_msix_queue_intr(void *);
114static int virtio_pci_msix_config_intr(void *); 114static int virtio_pci_msix_config_intr(void *);
115static int virtio_pci_setup_interrupts_09(struct virtio_softc *); 115static int virtio_pci_setup_interrupts_09(struct virtio_softc *, int);
116static int virtio_pci_setup_interrupts_10(struct virtio_softc *); 116static int virtio_pci_setup_interrupts_10(struct virtio_softc *, int);
117static int virtio_pci_establish_msix_interrupts(struct virtio_softc *, 117static int virtio_pci_establish_msix_interrupts(struct virtio_softc *,
118 struct pci_attach_args *); 118 struct pci_attach_args *);
119static int virtio_pci_establish_intx_interrupt(struct virtio_softc *, 119static int virtio_pci_establish_intx_interrupt(struct virtio_softc *,
120 struct pci_attach_args *); 120 struct pci_attach_args *);
121static bool virtio_pci_msix_enabled(struct virtio_pci_softc *); 121static bool virtio_pci_msix_enabled(struct virtio_pci_softc *);
122 122
123#define VIRTIO_MSIX_CONFIG_VECTOR_INDEX 0 123#define VIRTIO_MSIX_CONFIG_VECTOR_INDEX 0
124#define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1 124#define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1
125 125
126/* 126/*
127 * When using PCI attached virtio on aarch64-eb under Qemu, the IO space 127 * When using PCI attached virtio on aarch64-eb under Qemu, the IO space
128 * suddenly read BIG_ENDIAN where it should stay LITTLE_ENDIAN. The data read 128 * suddenly read BIG_ENDIAN where it should stay LITTLE_ENDIAN. The data read
129 * 1 byte at a time seem OK but reading bigger lengths result in swapped 129 * 1 byte at a time seem OK but reading bigger lengths result in swapped
@@ -795,105 +795,115 @@ virtio_pci_negotiate_features_10(struct  @@ -795,105 +795,115 @@ virtio_pci_negotiate_features_10(struct
795 return; 795 return;
796 } 796 }
797 797
798 sc->sc_active_features = negotiated; 798 sc->sc_active_features = negotiated;
799 return; 799 return;
800} 800}
801 801
802 802
803/* ------------------------------------- 803/* -------------------------------------
804 * Generic PCI interrupt code 804 * Generic PCI interrupt code
805 * -------------------------------------*/ 805 * -------------------------------------*/
806 806
807static int 807static int
808virtio_pci_setup_interrupts_10(struct virtio_softc *sc) 808virtio_pci_setup_interrupts_10(struct virtio_softc *sc, int reinit)
809{ 809{
810 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; 810 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
811 device_t self = sc->sc_dev; 811 device_t self = sc->sc_dev;
812 bus_space_tag_t iot = psc->sc_iot; 812 bus_space_tag_t iot = psc->sc_iot;
813 bus_space_handle_t ioh = psc->sc_ioh; 813 bus_space_handle_t ioh = psc->sc_ioh;
814 int vector, ret, qid; 814 int vector, ret, qid;
815 815
816 if (!virtio_pci_msix_enabled(psc)) 816 if (!virtio_pci_msix_enabled(psc))
817 return 0; 817 return 0;
818 818
819 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 819 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
820 bus_space_write_2(iot, ioh, 820 bus_space_write_2(iot, ioh,
821 VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector); 821 VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector);
822 ret = bus_space_read_2(iot, ioh, VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR); 822 ret = bus_space_read_2(iot, ioh, VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR);
823 if (ret != vector) { 823 if (ret != vector) {
824 aprint_error_dev(self, "can't set config msix vector\n"); 824 if (reinit == 0) {
 825 aprint_error_dev(self,
 826 "can't set config msix vector\n");
 827 }
825 return -1; 828 return -1;
826 } 829 }
827 830
828 for (qid = 0; qid < sc->sc_nvqs; qid++) { 831 for (qid = 0; qid < sc->sc_nvqs; qid++) {
829 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 832 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
830 833
831 if (sc->sc_child_mq) 834 if (sc->sc_child_mq)
832 vector += qid; 835 vector += qid;
833 bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_SELECT, qid); 836 bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_SELECT, qid);
834 bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR, 837 bus_space_write_2(iot, ioh, VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR,
835 vector); 838 vector);
836 ret = bus_space_read_2(iot, ioh, 839 ret = bus_space_read_2(iot, ioh,
837 VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR); 840 VIRTIO_CONFIG1_QUEUE_MSIX_VECTOR);
838 if (ret != vector) { 841 if (ret != vector) {
839 aprint_error_dev(self, "can't set queue %d " 842 if (reinit == 0) {
840 "msix vector\n", qid); 843 aprint_error_dev(self, "can't set queue %d "
 844 "msix vector\n", qid);
 845 }
841 return -1; 846 return -1;
842 } 847 }
843 } 848 }
844 849
845 return 0; 850 return 0;
846} 851}
847 852
848static int 853static int
849virtio_pci_setup_interrupts_09(struct virtio_softc *sc) 854virtio_pci_setup_interrupts_09(struct virtio_softc *sc, int reinit)
850{ 855{
851 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; 856 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
852 device_t self = sc->sc_dev; 857 device_t self = sc->sc_dev;
853 int offset, vector, ret, qid; 858 int offset, vector, ret, qid;
854 859
855 if (!virtio_pci_msix_enabled(psc)) 860 if (!virtio_pci_msix_enabled(psc))
856 return 0; 861 return 0;
857 862
858 offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR; 863 offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR;
859 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX; 864 vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
860 865
861 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector); 866 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector);
862 ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset); 867 ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset);
863 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n", 868 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
864 vector, ret); 869 vector, ret);
865 if (ret != vector) { 870 if (ret != vector) {
866 aprint_error_dev(self, "can't set config msix vector\n"); 871 if (reinit == 0) {
 872 aprint_error_dev(self,
 873 "can't set config msix vector\n");
 874 }
867 return -1; 875 return -1;
868 } 876 }
869 877
870 for (qid = 0; qid < sc->sc_nvqs; qid++) { 878 for (qid = 0; qid < sc->sc_nvqs; qid++) {
871 offset = VIRTIO_CONFIG_QUEUE_SELECT; 879 offset = VIRTIO_CONFIG_QUEUE_SELECT;
872 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, qid); 880 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, qid);
873 881
874 offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR; 882 offset = VIRTIO_CONFIG_MSI_QUEUE_VECTOR;
875 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX; 883 vector = VIRTIO_MSIX_QUEUE_VECTOR_INDEX;
876 884
877 if (sc->sc_child_mq) 885 if (sc->sc_child_mq)
878 vector += qid; 886 vector += qid;
879 887
880 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector); 888 bus_space_write_2(psc->sc_iot, psc->sc_ioh, offset, vector);
881 ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset); 889 ret = bus_space_read_2(psc->sc_iot, psc->sc_ioh, offset);
882 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n", 890 aprint_debug_dev(sc->sc_dev, "expected=%d, actual=%d\n",
883 vector, ret); 891 vector, ret);
884 if (ret != vector) { 892 if (ret != vector) {
885 aprint_error_dev(self, "can't set queue %d " 893 if (reinit == 0) {
886 "msix vector\n", qid); 894 aprint_error_dev(self, "can't set queue %d "
 895 "msix vector\n", qid);
 896 }
887 return -1; 897 return -1;
888 } 898 }
889 } 899 }
890 900
891 return 0; 901 return 0;
892} 902}
893 903
894static int 904static int
895virtio_pci_establish_msix_interrupts(struct virtio_softc *sc, 905virtio_pci_establish_msix_interrupts(struct virtio_softc *sc,
896 struct pci_attach_args *pa) 906 struct pci_attach_args *pa)
897{ 907{
898 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc; 908 struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
899 device_t self = sc->sc_dev; 909 device_t self = sc->sc_dev;

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

--- src/sys/dev/pci/virtiovar.h 2021/10/21 05:32:27 1.21
+++ src/sys/dev/pci/virtiovar.h 2021/10/21 05:37:43 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: virtiovar.h,v 1.21 2021/10/21 05:32:27 yamaguchi Exp $ */ 1/* $NetBSD: virtiovar.h,v 1.22 2021/10/21 05:37:43 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.
@@ -131,27 +131,27 @@ struct virtio_attach_args { @@ -131,27 +131,27 @@ struct virtio_attach_args {
131}; 131};
132 132
133typedef int (*virtio_callback)(struct virtio_softc*); 133typedef int (*virtio_callback)(struct virtio_softc*);
134 134
135#ifdef VIRTIO_PRIVATE 135#ifdef VIRTIO_PRIVATE
136struct virtio_ops { 136struct virtio_ops {
137 void (*kick)(struct virtio_softc *, uint16_t); 137 void (*kick)(struct virtio_softc *, uint16_t);
138 uint16_t (*read_queue_size)(struct virtio_softc *, uint16_t); 138 uint16_t (*read_queue_size)(struct virtio_softc *, uint16_t);
139 void (*setup_queue)(struct virtio_softc *, uint16_t, uint64_t); 139 void (*setup_queue)(struct virtio_softc *, uint16_t, uint64_t);
140 void (*set_status)(struct virtio_softc *, int); 140 void (*set_status)(struct virtio_softc *, int);
141 void (*neg_features)(struct virtio_softc *, uint64_t); 141 void (*neg_features)(struct virtio_softc *, uint64_t);
142 int (*alloc_interrupts)(struct virtio_softc *); 142 int (*alloc_interrupts)(struct virtio_softc *);
143 void (*free_interrupts)(struct virtio_softc *); 143 void (*free_interrupts)(struct virtio_softc *);
144 int (*setup_interrupts)(struct virtio_softc *); 144 int (*setup_interrupts)(struct virtio_softc *, int);
145}; 145};
146 146
147struct virtio_softc { 147struct virtio_softc {
148 device_t sc_dev; 148 device_t sc_dev;
149 const struct virtio_ops *sc_ops; 149 const struct virtio_ops *sc_ops;
150 bus_dma_tag_t sc_dmat; 150 bus_dma_tag_t sc_dmat;
151 151
152 int sc_bus_endian; 152 int sc_bus_endian;
153 int sc_struct_endian; 153 int sc_struct_endian;
154 154
155 bus_space_tag_t sc_devcfg_iot; 155 bus_space_tag_t sc_devcfg_iot;
156 bus_space_handle_t sc_devcfg_ioh; 156 bus_space_handle_t sc_devcfg_ioh;
157 bus_size_t sc_devcfg_iosize; 157 bus_size_t sc_devcfg_iosize;