diff options
| author | yamaguchi <yamaguchi@NetBSD.org> | 2021-10-21 05:32:27 +0000 |
|---|---|---|
| committer | yamaguchi <yamaguchi@NetBSD.org> | 2021-10-21 05:32:27 +0000 |
| commit | 075aeb24d6c30e2461ecbd3ac70af6da1d37b590 (patch) | |
| tree | 31b935dec1df8522aabd65c4357920bc743da4e8 /sys/dev | |
| parent | 0d2b10f2fe81faa6407c5a94fb9426aaa337c323 (diff) | |
divide setup routine of virtio interrupts
into establishment and device configuration
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/pci/virtio.c | 11 | ||||
| -rw-r--r-- | sys/dev/pci/virtio_pci.c | 63 | ||||
| -rw-r--r-- | sys/dev/pci/virtiovar.h | 5 |
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 { |
