static int vtpci_alloc_interrupts(struct vtpci_softc *sc, int flags, int nvqs, struct vq_alloc_info *vq_info) { int i, nvectors, error; /* * Only allocate a vector for virtqueues that are actually * expecting an interrupt. */ for (nvectors = 0, i = 0; i < nvqs; i++) if (vq_info[i].vqai_intr != NULL) nvectors++; if (vtpci_disable_msix != 0 || sc->vtpci_flags & VIRTIO_PCI_FLAG_NO_MSIX || flags & VIRTIO_ALLOC_VQS_DISABLE_MSIX || vtpci_alloc_msix(sc, nvectors) != 0) { /* * Use MSI interrupts if available. Otherwise, we fallback * to legacy interrupts. */ if ((sc->vtpci_flags & VIRTIO_PCI_FLAG_NO_MSI) == 0 && vtpci_alloc_msi(sc) == 0) sc->vtpci_flags |= VIRTIO_PCI_FLAG_MSI; sc->vtpci_nintr_res = 1; } error = vtpci_alloc_intr_resources(sc, nvqs, vq_info); return (error); }
static int vtpci_alloc_intr_msi(struct vtpci_softc *sc) { int error; /* Only BHyVe supports MSI. */ if (sc->vtpci_flags & VTPCI_FLAG_NO_MSI) return (ENOTSUP); error = vtpci_alloc_msi(sc); if (error) return (error); sc->vtpci_flags |= VTPCI_FLAG_MSI; return (0); }