Exemplo 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);
}
Exemplo n.º 2
0
static int
vtpci_alloc_intr_msix_shared(struct vtpci_softc *sc)
{
	int error;

	if (vtpci_disable_msix != 0 ||
	    sc->vtpci_flags & VTPCI_FLAG_NO_MSIX)
		return (ENOTSUP);

	error = vtpci_alloc_msix(sc, 1);
	if (error)
		return (error);

	sc->vtpci_flags |= VTPCI_FLAG_MSIX | VTPCI_FLAG_SHARED_MSIX;

	return (0);
}
Exemplo n.º 3
0
static int
vtpci_alloc_intr_msix_pervq(struct vtpci_softc *sc)
{
	int i, nvectors, error;

	if (vtpci_disable_msix != 0 ||
	    sc->vtpci_flags & VTPCI_FLAG_NO_MSIX)
		return (ENOTSUP);

	for (nvectors = 0, i = 0; i < sc->vtpci_nvqs; i++) {
		if (sc->vtpci_vqs[i].vtv_no_intr == 0)
			nvectors++;
	}

	error = vtpci_alloc_msix(sc, nvectors);
	if (error)
		return (error);

	sc->vtpci_flags |= VTPCI_FLAG_MSIX;

	return (0);
}