Esempio n. 1
0
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);
}
Esempio n. 2
0
static int
vtpci_setup_interrupts(struct vtpci_softc *sc, enum intr_type type)
{
	int error;

	type |= INTR_MPSAFE;
	KASSERT(sc->vtpci_flags & VTPCI_FLAG_ITYPE_MASK,
	    ("%s: no interrupt type selected %#x", __func__, sc->vtpci_flags));

	error = vtpci_alloc_intr_resources(sc);
	if (error)
		return (error);

	if (sc->vtpci_flags & VTPCI_FLAG_LEGACY)
		error = vtpci_setup_legacy_interrupt(sc, type);
	else if (sc->vtpci_flags & VTPCI_FLAG_MSI)
		error = vtpci_setup_msi_interrupt(sc, type);
	else
		error = vtpci_setup_msix_interrupts(sc, type);

	return (error);
}