virtio: Introduce dedicated attach args
authorsf <sf@openbsd.org>
Mon, 26 Aug 2024 19:37:54 +0000 (19:37 +0000)
committersf <sf@openbsd.org>
Mon, 26 Aug 2024 19:37:54 +0000 (19:37 +0000)
Instead of abusing virtio_softc as attach args, create a separate
struct. Use it to pass the number of available interrupts. This will be
useful for vio(4) multi-queue support.

ok jan@

sys/dev/fdt/virtio_mmio.c
sys/dev/pci/virtio_pci.c
sys/dev/pv/if_vio.c
sys/dev/pv/vioblk.c
sys/dev/pv/viocon.c
sys/dev/pv/viogpu.c
sys/dev/pv/viomb.c
sys/dev/pv/viornd.c
sys/dev/pv/vioscsi.c
sys/dev/pv/virtiovar.h
sys/dev/pv/vmmci.c

index c88d58e..2ec1db9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtio_mmio.c,v 1.14 2024/08/20 07:04:29 sf Exp $     */
+/*     $OpenBSD: virtio_mmio.c,v 1.15 2024/08/26 19:37:54 sf Exp $     */
 /*     $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
 
 /*
@@ -241,6 +241,7 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
        struct virtio_mmio_softc *sc = (struct virtio_mmio_softc *)self;
        struct virtio_softc *vsc = &sc->sc_sc;
        uint32_t id, magic;
+       struct virtio_attach_args va = { 0 };
 
        if (faa->fa_nreg < 1) {
                printf(": no register data\n");
@@ -289,10 +290,10 @@ virtio_mmio_attach(struct device *parent, struct device *self, void *aux)
        virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_ACK);
        virtio_mmio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
 
-       /* XXX: use softc as aux... */
-       vsc->sc_childdevid = id;
+       va.va_devid = id;
+       va.va_nintr = 1;
        vsc->sc_child = NULL;
-       config_found(self, sc, NULL);
+       config_found(self, &va, NULL);
        if (vsc->sc_child == NULL) {
                printf("%s: no matching child driver; not configured\n",
                    vsc->sc_dev.dv_xname);
index f069df6..9b8842b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtio_pci.c,v 1.38 2024/06/26 01:40:49 jsg Exp $     */
+/*     $OpenBSD: virtio_pci.c,v 1.39 2024/08/26 19:37:54 sf Exp $      */
 /*     $NetBSD: virtio.c,v 1.3 2011/11/02 23:05:52 njoly Exp $ */
 
 /*
@@ -53,6 +53,7 @@
 #define MAX_MSIX_VECS  8
 
 struct virtio_pci_softc;
+struct virtio_pci_attach_args;
 
 int            virtio_pci_match(struct device *, void *, void *);
 void           virtio_pci_attach(struct device *, struct device *, void *);
@@ -78,8 +79,8 @@ int           virtio_pci_negotiate_features(struct virtio_softc *, const struct virtio_fe
 int            virtio_pci_negotiate_features_10(struct virtio_softc *, const struct virtio_feature_name *);
 void           virtio_pci_set_msix_queue_vector(struct virtio_pci_softc *, uint32_t, uint16_t);
 void           virtio_pci_set_msix_config_vector(struct virtio_pci_softc *, uint16_t);
-int            virtio_pci_msix_establish(struct virtio_pci_softc *, struct pci_attach_args *, int, int (*)(void *), void *);
-int            virtio_pci_setup_msix(struct virtio_pci_softc *, struct pci_attach_args *, int);
+int            virtio_pci_msix_establish(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int, int (*)(void *), void *);
+int            virtio_pci_setup_msix(struct virtio_pci_softc *, struct virtio_pci_attach_args *, int);
 void           virtio_pci_free_irqs(struct virtio_pci_softc *);
 int            virtio_pci_poll_intr(void *);
 int            virtio_pci_legacy_intr(void *);
@@ -136,6 +137,12 @@ struct virtio_pci_softc {
        enum irq_type           sc_irq_type;
 };
 
+struct virtio_pci_attach_args {
+       struct virtio_attach_args        vpa_va;
+       struct pci_attach_args          *vpa_pa;
+};
+
+
 const struct cfattach virtio_pci_ca = {
        sizeof(struct virtio_pci_softc),
        virtio_pci_match,
@@ -577,6 +584,8 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
        pcireg_t id;
        char const *intrstr;
        pci_intr_handle_t ih;
+       struct virtio_pci_attach_args vpa = { { 0 }, pa };
+       int n;
 
        revision = PCI_REVISION(pa->pa_class);
        switch (revision) {
@@ -608,6 +617,10 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
        virtio_pci_dump_caps(sc);
 #endif
 
+       n = MIN(MAX_MSIX_VECS, pci_intr_msix_count(pa));
+       n = MAX(n, 1);
+       vpa.vpa_va.va_nintr = n;
+
        vsc->sc_ops = &virtio_pci_ops;
        if ((vsc->sc_dev.dv_cfdata->cf_flags & VIRTIO_CF_NO_VERSION_1) == 0 &&
            (revision == 1 ||
@@ -633,9 +646,9 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
        virtio_set_status(vsc, VIRTIO_CONFIG_DEVICE_STATUS_DRIVER);
 
        printf("\n");
-       vsc->sc_childdevid = id;
+       vpa.vpa_va.va_devid = id;
        vsc->sc_child = NULL;
-       config_found(self, sc, NULL);
+       config_found(self, &vpa, NULL);
        if (vsc->sc_child == NULL) {
                printf("%s: no matching child driver; not configured\n",
                    vsc->sc_dev.dv_xname);
@@ -647,10 +660,10 @@ virtio_pci_attach(struct device *parent, struct device *self, void *aux)
                goto fail_1;
        }
 
-       if (virtio_pci_setup_msix(sc, pa, 0) == 0) {
+       if (virtio_pci_setup_msix(sc, &vpa, 0) == 0) {
                sc->sc_irq_type = IRQ_MSIX_PER_VQ;
                intrstr = "msix per-VQ";
-       } else if (virtio_pci_setup_msix(sc, pa, 1) == 0) {
+       } else if (virtio_pci_setup_msix(sc, &vpa, 1) == 0) {
                sc->sc_irq_type = IRQ_MSIX_SHARED;
                intrstr = "msix shared";
        } else {
@@ -910,12 +923,13 @@ virtio_pci_write_device_config_8(struct virtio_softc *vsc,
 
 int
 virtio_pci_msix_establish(struct virtio_pci_softc *sc,
-    struct pci_attach_args *pa, int idx, int (*handler)(void *), void *ih_arg)
+    struct virtio_pci_attach_args *vpa, int idx,
+    int (*handler)(void *), void *ih_arg)
 {
        struct virtio_softc *vsc = &sc->sc_sc;
        pci_intr_handle_t ih;
 
-       if (pci_intr_map_msix(pa, idx, &ih) != 0) {
+       if (pci_intr_map_msix(vpa->vpa_pa, idx, &ih) != 0) {
 #if VIRTIO_DEBUG
                printf("%s[%d]: pci_intr_map_msix failed\n",
                    vsc->sc_dev.dv_xname, idx);
@@ -983,27 +997,27 @@ virtio_pci_free_irqs(struct virtio_pci_softc *sc)
 }
 
 int
-virtio_pci_setup_msix(struct virtio_pci_softc *sc, struct pci_attach_args *pa,
-    int shared)
+virtio_pci_setup_msix(struct virtio_pci_softc *sc,
+    struct virtio_pci_attach_args *vpa, int shared)
 {
        struct virtio_softc *vsc = &sc->sc_sc;
        int i;
 
        /* Shared needs config + queue */
-       if (shared && pci_intr_msix_count(pa) < 1 + 1)
+       if (shared && vpa->vpa_va.va_nintr < 1 + 1)
                return 1;
        /* Per VQ needs config + N * queue */
-       if (!shared && pci_intr_msix_count(pa) < 1 + vsc->sc_nvqs)
+       if (!shared && vpa->vpa_va.va_nintr < 1 + vsc->sc_nvqs)
                return 1;
 
-       if (virtio_pci_msix_establish(sc, pa, 0, virtio_pci_config_intr, vsc))
+       if (virtio_pci_msix_establish(sc, vpa, 0, virtio_pci_config_intr, vsc))
                return 1;
        sc->sc_devcfg_offset = VIRTIO_CONFIG_DEVICE_CONFIG_MSI;
        virtio_pci_adjust_config_region(sc);
        virtio_pci_set_msix_config_vector(sc, 0);
 
        if (shared) {
-               if (virtio_pci_msix_establish(sc, pa, 1,
+               if (virtio_pci_msix_establish(sc, vpa, 1,
                    virtio_pci_shared_queue_intr, vsc)) {
                        goto fail;
                }
@@ -1012,7 +1026,7 @@ virtio_pci_setup_msix(struct virtio_pci_softc *sc, struct pci_attach_args *pa,
                        virtio_pci_set_msix_queue_vector(sc, i, 1);
        } else {
                for (i = 0; i < vsc->sc_nvqs; i++) {
-                       if (virtio_pci_msix_establish(sc, pa, i + 1,
+                       if (virtio_pci_msix_establish(sc, vpa, i + 1,
                            virtio_pci_queue_intr, &vsc->sc_vqs[i])) {
                                goto fail;
                        }
index 55de448..ae805c6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: if_vio.c,v 1.47 2024/08/26 19:24:02 sf Exp $  */
+/*     $OpenBSD: if_vio.c,v 1.48 2024/08/26 19:37:54 sf Exp $  */
 
 /*
  * Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
@@ -330,9 +330,9 @@ void        vio_dump(struct vio_softc *);
 int
 vio_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
+       struct virtio_attach_args *va = aux;
 
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_NETWORK)
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_NETWORK)
                return 1;
 
        return 0;
index 108309f..297d0b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vioblk.c,v 1.41 2024/08/01 11:13:19 sf Exp $  */
+/*     $OpenBSD: vioblk.c,v 1.42 2024/08/26 19:37:54 sf Exp $  */
 
 /*
  * Copyright (c) 2012 Stefan Fritsch.
@@ -156,8 +156,8 @@ const struct scsi_adapter vioblk_switch = {
 int
 vioblk_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_BLOCK)
+       struct virtio_attach_args *va = aux;
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_BLOCK)
                return 1;
        return 0;
 }
index 4099222..68e4155 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: viocon.c,v 1.13 2024/08/01 11:13:19 sf Exp $  */
+/*     $OpenBSD: viocon.c,v 1.14 2024/08/26 19:37:54 sf Exp $  */
 
 /*
  * Copyright (c) 2013-2015 Stefan Fritsch <sf@sfritsch.de>
@@ -162,8 +162,8 @@ dev2port(dev_t dev)
 int
 viocon_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_CONSOLE)
+       struct virtio_attach_args *va = aux;
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_CONSOLE)
                return 1;
        return 0;
 }
index aa9f159..20e6afb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: viogpu.c,v 1.7 2024/08/01 11:13:19 sf Exp $ */
+/*     $OpenBSD: viogpu.c,v 1.8 2024/08/26 19:37:54 sf Exp $ */
 
 /*
  * Copyright (c) 2021-2023 joshua stein <jcs@openbsd.org>
@@ -137,9 +137,9 @@ struct cfdriver viogpu_cd = {
 int
 viogpu_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
+       struct virtio_attach_args *va = aux;
 
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_GPU)
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_GPU)
                return 1;
 
        return 0;
index a8906ec..9959688 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: viomb.c,v 1.10 2024/05/24 10:05:55 jsg Exp $       */
+/* $OpenBSD: viomb.c,v 1.11 2024/08/26 19:37:54 sf Exp $        */
 /* $NetBSD: viomb.c,v 1.1 2011/10/30 12:12:21 hannken Exp $     */
 
 /*
@@ -124,8 +124,8 @@ struct cfdriver viomb_cd = {
 int
 viomb_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_BALLOON)
+       struct virtio_attach_args *va = aux;
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_BALLOON)
                return (1);
        return (0);
 }
index cc652ba..67f6f38 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: viornd.c,v 1.9 2024/06/26 01:40:49 jsg Exp $  */
+/*     $OpenBSD: viornd.c,v 1.10 2024/08/26 19:37:54 sf Exp $  */
 
 /*
  * Copyright (c) 2014 Stefan Fritsch <sf@sfritsch.de>
@@ -72,8 +72,8 @@ struct cfdriver viornd_cd = {
 int
 viornd_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_ENTROPY)
+       struct virtio_attach_args *va = aux;
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_ENTROPY)
                return 1;
        return 0;
 }
index a9246eb..6eba242 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vioscsi.c,v 1.32 2023/05/29 08:13:35 sf Exp $ */
+/*     $OpenBSD: vioscsi.c,v 1.33 2024/08/26 19:37:54 sf Exp $ */
 /*
  * Copyright (c) 2013 Google Inc.
  *
@@ -93,9 +93,9 @@ const char *const vioscsi_vq_names[] = {
 int
 vioscsi_match(struct device *parent, void *self, void *aux)
 {
-       struct virtio_softc *va = (struct virtio_softc *)aux;
+       struct virtio_attach_args *va = aux;
 
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_SCSI)
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_SCSI)
                return (1);
        return (0);
 }
index 887bc23..5dfe2ef 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: virtiovar.h,v 1.18 2024/05/17 16:37:10 sf Exp $       */
+/*     $OpenBSD: virtiovar.h,v 1.19 2024/08/26 19:37:54 sf Exp $       */
 /*     $NetBSD: virtiovar.h,v 1.1 2011/10/30 12:12:21 hannken Exp $    */
 
 /*
 #define VIRTIO_CF_PREFER_VERSION_1     4
 #define VIRTIO_CF_NO_VERSION_1         8
 
+struct virtio_attach_args {
+       int                      va_devid;      /* virtio device id */
+       unsigned int             va_nintr;      /* number of intr vectors */
+};
+
 struct vq_entry {
        SLIST_ENTRY(vq_entry)    qe_list;       /* free list */
        uint16_t                 qe_index;      /* index in vq_desc array */
@@ -177,7 +182,6 @@ struct virtio_softc {
        int                      sc_nvqs;       /* set by child */
        struct virtqueue        *sc_vqs;        /* set by child */
 
-       int                      sc_childdevid; /* set by transport */
        struct device           *sc_child;      /* set by child,
                                                 * VIRTIO_CHILD_ERROR on error
                                                 */
index f8385df..580228b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vmmci.c,v 1.11 2024/05/24 10:05:55 jsg Exp $  */
+/*     $OpenBSD: vmmci.c,v 1.12 2024/08/26 19:37:54 sf Exp $   */
 
 /*
  * Copyright (c) 2017 Reyk Floeter <reyk@openbsd.org>
@@ -78,8 +78,8 @@ struct cfdriver vmmci_cd = {
 int
 vmmci_match(struct device *parent, void *match, void *aux)
 {
-       struct virtio_softc *va = aux;
-       if (va->sc_childdevid == PCI_PRODUCT_VIRTIO_VMMCI)
+       struct virtio_attach_args *va = aux;
+       if (va->va_devid == PCI_PRODUCT_VIRTIO_VMMCI)
                return (1);
        return (0);
 }