summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authoryamaguchi <yamaguchi@NetBSD.org>2021-10-21 05:32:27 +0000
committeryamaguchi <yamaguchi@NetBSD.org>2021-10-21 05:32:27 +0000
commit075aeb24d6c30e2461ecbd3ac70af6da1d37b590 (patch)
tree31b935dec1df8522aabd65c4357920bc743da4e8 /sys/dev
parent0d2b10f2fe81faa6407c5a94fb9426aaa337c323 (diff)
divide setup routine of virtio interrupts
into establishment and device configuration
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/virtio.c11
-rw-r--r--sys/dev/pci/virtio_pci.c63
-rw-r--r--sys/dev/pci/virtiovar.h5
3 files changed, 47 insertions, 32 deletions
diff --git a/sys/dev/pci/virtio.c b/sys/dev/pci/virtio.c
index 81c210db1f5..b8a5dac2608 100644
--- a/sys/dev/pci/virtio.c
+++ b/sys/dev/pci/virtio.c
@@ -1,4 +1,4 @@
-/* $NetBSD: virtio.c,v 1.49 2021/02/07 09:29:53 skrll Exp $ */
+/* $NetBSD: virtio.c,v 1.50 2021/10/21 05:32:27 yamaguchi Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.49 2021/02/07 09:29:53 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio.c,v 1.50 2021/10/21 05:32:27 yamaguchi Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -1199,10 +1199,15 @@ virtio_child_attach_finish(struct virtio_softc *sc)
int r;
sc->sc_finished_called = true;
+ r = sc->sc_ops->alloc_interrupts(sc);
+ if (r != 0) {
+ aprint_error_dev(sc->sc_dev, "failed to allocate interrupts\n");
+ goto fail;
+ }
+
r = sc->sc_ops->setup_interrupts(sc);
if (r != 0) {
aprint_error_dev(sc->sc_dev, "failed to setup interrupts\n");
- goto fail;
}
KASSERT(sc->sc_soft_ih == NULL);
diff --git a/sys/dev/pci/virtio_pci.c b/sys/dev/pci/virtio_pci.c
index 58f0bd90fd8..f355cf9006c 100644
--- a/sys/dev/pci/virtio_pci.c
+++ b/sys/dev/pci/virtio_pci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: virtio_pci.c,v 1.30 2021/08/07 16:19:14 thorpej Exp $ */
+/* $NetBSD: virtio_pci.c,v 1.31 2021/10/21 05:32:27 yamaguchi Exp $ */
/*
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.30 2021/08/07 16:19:14 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: virtio_pci.c,v 1.31 2021/10/21 05:32:27 yamaguchi Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -106,18 +106,19 @@ static void virtio_pci_set_status_10(struct virtio_softc *, int);
static void virtio_pci_negotiate_features_10(struct virtio_softc *, uint64_t);
static int virtio_pci_find_cap(struct virtio_pci_softc *psc, int cfg_type, void *buf, int buflen);
-static int virtio_pci_setup_interrupts(struct virtio_softc *);
+static int virtio_pci_alloc_interrupts(struct virtio_softc *);
static void virtio_pci_free_interrupts(struct virtio_softc *);
static int virtio_pci_adjust_config_region(struct virtio_pci_softc *psc);
static int virtio_pci_intr(void *arg);
static int virtio_pci_msix_queue_intr(void *);
static int virtio_pci_msix_config_intr(void *);
-static int virtio_pci_setup_msix_vectors_09(struct virtio_softc *);
-static int virtio_pci_setup_msix_vectors_10(struct virtio_softc *);
-static int virtio_pci_setup_msix_interrupts(struct virtio_softc *,
+static int virtio_pci_setup_interrupts_09(struct virtio_softc *);
+static int virtio_pci_setup_interrupts_10(struct virtio_softc *);
+static int virtio_pci_establish_msix_interrupts(struct virtio_softc *,
struct pci_attach_args *);
-static int virtio_pci_setup_intx_interrupt(struct virtio_softc *,
+static int virtio_pci_establish_intx_interrupt(struct virtio_softc *,
struct pci_attach_args *);
+static bool virtio_pci_msix_enabled(struct virtio_pci_softc *);
#define VIRTIO_MSIX_CONFIG_VECTOR_INDEX 0
#define VIRTIO_MSIX_QUEUE_VECTOR_INDEX 1
@@ -158,8 +159,9 @@ static const struct virtio_ops virtio_pci_ops_09 = {
.setup_queue = virtio_pci_setup_queue_09,
.set_status = virtio_pci_set_status_09,
.neg_features = virtio_pci_negotiate_features_09,
- .setup_interrupts = virtio_pci_setup_interrupts,
+ .alloc_interrupts = virtio_pci_alloc_interrupts,
.free_interrupts = virtio_pci_free_interrupts,
+ .setup_interrupts = virtio_pci_setup_interrupts_09,
};
static const struct virtio_ops virtio_pci_ops_10 = {
@@ -168,8 +170,9 @@ static const struct virtio_ops virtio_pci_ops_10 = {
.setup_queue = virtio_pci_setup_queue_10,
.set_status = virtio_pci_set_status_10,
.neg_features = virtio_pci_negotiate_features_10,
- .setup_interrupts = virtio_pci_setup_interrupts,
+ .alloc_interrupts = virtio_pci_alloc_interrupts,
.free_interrupts = virtio_pci_free_interrupts,
+ .setup_interrupts = virtio_pci_setup_interrupts_10,
};
static int
@@ -802,7 +805,7 @@ virtio_pci_negotiate_features_10(struct virtio_softc *sc, uint64_t guest_feature
* -------------------------------------*/
static int
-virtio_pci_setup_msix_vectors_10(struct virtio_softc *sc)
+virtio_pci_setup_interrupts_10(struct virtio_softc *sc)
{
struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
device_t self = sc->sc_dev;
@@ -810,6 +813,9 @@ virtio_pci_setup_msix_vectors_10(struct virtio_softc *sc)
bus_space_handle_t ioh = psc->sc_ioh;
int vector, ret, qid;
+ if (!virtio_pci_msix_enabled(psc))
+ return 0;
+
vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
bus_space_write_2(iot, ioh,
VIRTIO_CONFIG1_CONFIG_MSIX_VECTOR, vector);
@@ -840,12 +846,15 @@ virtio_pci_setup_msix_vectors_10(struct virtio_softc *sc)
}
static int
-virtio_pci_setup_msix_vectors_09(struct virtio_softc *sc)
+virtio_pci_setup_interrupts_09(struct virtio_softc *sc)
{
struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
device_t self = sc->sc_dev;
int offset, vector, ret, qid;
+ if (!virtio_pci_msix_enabled(psc))
+ return 0;
+
offset = VIRTIO_CONFIG_MSI_CONFIG_VECTOR;
vector = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
@@ -883,7 +892,7 @@ virtio_pci_setup_msix_vectors_09(struct virtio_softc *sc)
}
static int
-virtio_pci_setup_msix_interrupts(struct virtio_softc *sc,
+virtio_pci_establish_msix_interrupts(struct virtio_softc *sc,
struct pci_attach_args *pa)
{
struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
@@ -894,7 +903,6 @@ virtio_pci_setup_msix_interrupts(struct virtio_softc *sc,
char intr_xname[INTRDEVNAMEBUF];
char const *intrstr;
int idx, qid, n;
- int ret;
idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
if (sc->sc_flags & VIRTIO_F_INTR_MPSAFE)
@@ -945,16 +953,6 @@ virtio_pci_setup_msix_interrupts(struct virtio_softc *sc,
}
}
- if (sc->sc_version_1) {
- ret = virtio_pci_setup_msix_vectors_10(sc);
- } else {
- ret = virtio_pci_setup_msix_vectors_09(sc);
- }
- if (ret) {
- aprint_error_dev(self, "couldn't setup MSI-X vectors\n");
- goto error;
- }
-
idx = VIRTIO_MSIX_CONFIG_VECTOR_INDEX;
intrstr = pci_intr_string(pc, psc->sc_ihp[idx], intrbuf, sizeof(intrbuf));
aprint_normal_dev(self, "config interrupting at %s\n", intrstr);
@@ -1016,7 +1014,7 @@ error:
}
static int
-virtio_pci_setup_intx_interrupt(struct virtio_softc *sc,
+virtio_pci_establish_intx_interrupt(struct virtio_softc *sc,
struct pci_attach_args *pa)
{
struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
@@ -1042,7 +1040,7 @@ virtio_pci_setup_intx_interrupt(struct virtio_softc *sc,
}
static int
-virtio_pci_setup_interrupts(struct virtio_softc *sc)
+virtio_pci_alloc_interrupts(struct virtio_softc *sc)
{
struct virtio_pci_softc * const psc = (struct virtio_pci_softc *)sc;
device_t self = sc->sc_dev;
@@ -1092,7 +1090,7 @@ retry:
psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * nmsix,
KM_SLEEP);
- error = virtio_pci_setup_msix_interrupts(sc, &psc->sc_pa);
+ error = virtio_pci_establish_msix_interrupts(sc, &psc->sc_pa);
if (error != 0) {
kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * nmsix);
pci_intr_release(pc, psc->sc_ihp, nmsix);
@@ -1110,7 +1108,7 @@ retry:
psc->sc_ihs = kmem_zalloc(sizeof(*psc->sc_ihs) * 1,
KM_SLEEP);
- error = virtio_pci_setup_intx_interrupt(sc, &psc->sc_pa);
+ error = virtio_pci_establish_intx_interrupt(sc, &psc->sc_pa);
if (error != 0) {
kmem_free(psc->sc_ihs, sizeof(*psc->sc_ihs) * 1);
pci_intr_release(pc, psc->sc_ihp, 1);
@@ -1154,6 +1152,17 @@ virtio_pci_free_interrupts(struct virtio_softc *sc)
psc->sc_ihs_num = 0;
}
+static bool
+virtio_pci_msix_enabled(struct virtio_pci_softc *psc)
+{
+ pci_chipset_tag_t pc = psc->sc_pa.pa_pc;
+
+ if (pci_intr_type(pc, psc->sc_ihp[0]) == PCI_INTR_TYPE_MSIX)
+ return true;
+
+ return false;
+}
+
/*
* Interrupt handler.
*/
diff --git a/sys/dev/pci/virtiovar.h b/sys/dev/pci/virtiovar.h
index 9b0ce1a709a..301f7d49382 100644
--- a/sys/dev/pci/virtiovar.h
+++ b/sys/dev/pci/virtiovar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: virtiovar.h,v 1.20 2021/02/05 19:18:23 reinoud Exp $ */
+/* $NetBSD: virtiovar.h,v 1.21 2021/10/21 05:32:27 yamaguchi Exp $ */
/*
* Copyright (c) 2010 Minoura Makoto.
@@ -139,8 +139,9 @@ struct virtio_ops {
void (*setup_queue)(struct virtio_softc *, uint16_t, uint64_t);
void (*set_status)(struct virtio_softc *, int);
void (*neg_features)(struct virtio_softc *, uint64_t);
- int (*setup_interrupts)(struct virtio_softc *);
+ int (*alloc_interrupts)(struct virtio_softc *);
void (*free_interrupts)(struct virtio_softc *);
+ int (*setup_interrupts)(struct virtio_softc *);
};
struct virtio_softc {