From dc275227176c1aad7ca774d4d07f055bf683ffb0 Mon Sep 17 00:00:00 2001 From: sf Date: Mon, 26 Aug 2024 19:37:54 +0000 Subject: [PATCH] virtio: Introduce dedicated attach args 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 | 9 ++++---- sys/dev/pci/virtio_pci.c | 46 +++++++++++++++++++++++++-------------- sys/dev/pv/if_vio.c | 6 ++--- sys/dev/pv/vioblk.c | 6 ++--- sys/dev/pv/viocon.c | 6 ++--- sys/dev/pv/viogpu.c | 6 ++--- sys/dev/pv/viomb.c | 6 ++--- sys/dev/pv/viornd.c | 6 ++--- sys/dev/pv/vioscsi.c | 6 ++--- sys/dev/pv/virtiovar.h | 8 +++++-- sys/dev/pv/vmmci.c | 6 ++--- 11 files changed, 65 insertions(+), 46 deletions(-) diff --git a/sys/dev/fdt/virtio_mmio.c b/sys/dev/fdt/virtio_mmio.c index c88d58e3efb..2ec1db919d7 100644 --- a/sys/dev/fdt/virtio_mmio.c +++ b/sys/dev/fdt/virtio_mmio.c @@ -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); diff --git a/sys/dev/pci/virtio_pci.c b/sys/dev/pci/virtio_pci.c index f069df6887e..9b8842b03c4 100644 --- a/sys/dev/pci/virtio_pci.c +++ b/sys/dev/pci/virtio_pci.c @@ -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; } diff --git a/sys/dev/pv/if_vio.c b/sys/dev/pv/if_vio.c index 55de44893ab..ae805c6c78a 100644 --- a/sys/dev/pv/if_vio.c +++ b/sys/dev/pv/if_vio.c @@ -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; diff --git a/sys/dev/pv/vioblk.c b/sys/dev/pv/vioblk.c index 108309f4afb..297d0b9aeea 100644 --- a/sys/dev/pv/vioblk.c +++ b/sys/dev/pv/vioblk.c @@ -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; } diff --git a/sys/dev/pv/viocon.c b/sys/dev/pv/viocon.c index 40992228573..68e4155e678 100644 --- a/sys/dev/pv/viocon.c +++ b/sys/dev/pv/viocon.c @@ -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 @@ -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; } diff --git a/sys/dev/pv/viogpu.c b/sys/dev/pv/viogpu.c index aa9f1596e70..20e6afbac60 100644 --- a/sys/dev/pv/viogpu.c +++ b/sys/dev/pv/viogpu.c @@ -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 @@ -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; diff --git a/sys/dev/pv/viomb.c b/sys/dev/pv/viomb.c index a8906ecaab9..995968887d4 100644 --- a/sys/dev/pv/viomb.c +++ b/sys/dev/pv/viomb.c @@ -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); } diff --git a/sys/dev/pv/viornd.c b/sys/dev/pv/viornd.c index cc652ba5ed7..67f6f380701 100644 --- a/sys/dev/pv/viornd.c +++ b/sys/dev/pv/viornd.c @@ -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 @@ -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; } diff --git a/sys/dev/pv/vioscsi.c b/sys/dev/pv/vioscsi.c index a9246eb2317..6eba242a420 100644 --- a/sys/dev/pv/vioscsi.c +++ b/sys/dev/pv/vioscsi.c @@ -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); } diff --git a/sys/dev/pv/virtiovar.h b/sys/dev/pv/virtiovar.h index 887bc23633f..5dfe2ef4a91 100644 --- a/sys/dev/pv/virtiovar.h +++ b/sys/dev/pv/virtiovar.h @@ -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 $ */ /* @@ -85,6 +85,11 @@ #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 */ diff --git a/sys/dev/pv/vmmci.c b/sys/dev/pv/vmmci.c index f8385dfe1b4..580228bdb4c 100644 --- a/sys/dev/pv/vmmci.c +++ b/sys/dev/pv/vmmci.c @@ -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 @@ -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); } -- 2.20.1