Lines Matching +full:virtio +full:- +full:pci
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
43 #include <dev/pci/pcivar.h>
44 #include <dev/pci/pcireg.h>
46 #include <dev/virtio/virtio.h>
47 #include <dev/virtio/virtqueue.h>
48 #include <dev/virtio/pci/virtio_pci.h>
49 #include <dev/virtio/pci/virtio_pci_var.h>
93 * - virtio_pci_legacy for pre-V1 support
94 * - virtio_pci_modern for V1 support
97 MODULE_DEPEND(virtio_pci, pci, 1, 1, 1);
98 MODULE_DEPEND(virtio_pci, virtio, 1, 1, 1);
101 TUNABLE_INT("hw.virtio.pci.disable_msix", &vtpci_disable_msix);
106 return (VIRTIO_PCI_READ_ISR(cn->vtpci_dev));
112 return (VIRTIO_PCI_GET_VQ_SIZE(cn->vtpci_dev, idx));
118 return (VIRTIO_PCI_GET_VQ_NOTIFY_OFF(cn->vtpci_dev, idx));
124 VIRTIO_PCI_SET_VQ(cn->vtpci_dev, vq);
130 VIRTIO_PCI_DISABLE_VQ(cn->vtpci_dev, idx);
136 return (VIRTIO_PCI_REGISTER_CFG_MSIX(cn->vtpci_dev, intr));
143 return (VIRTIO_PCI_REGISTER_VQ_MSIX(cn->vtpci_dev, idx, intr));
150 cn->vtpci_dev = dev;
155 cn->vtpci_flags |= VTPCI_FLAG_MODERN;
157 cn->vtpci_flags |= VTPCI_FLAG_NO_MSI;
159 cn->vtpci_flags |= VTPCI_FLAG_NO_MSIX;
169 dev = cn->vtpci_dev;
177 cn->vtpci_child_dev = child;
188 dev = cn->vtpci_dev;
203 cn->vtpci_child_feat_desc = NULL;
204 cn->vtpci_host_features = 0;
205 cn->vtpci_features = 0;
213 for (idx = 0; idx < cn->vtpci_nvqs; idx++) {
234 dev = cn->vtpci_dev;
235 child = cn->vtpci_child_dev;
240 virtio_describe(dev, msg, features, cn->vtpci_child_feat_desc);
249 cn->vtpci_host_features = host_features;
259 cn->vtpci_features = features;
268 return ((cn->vtpci_features & feature) != 0);
277 dev = cn->vtpci_dev;
312 cn->vtpci_child_feat_desc = (void *) value;
328 dev = cn->vtpci_dev;
331 * This is VIRTIO_PCI_VRING_ALIGN from legacy VirtIO. In modern VirtIO,
337 if (cn->vtpci_nvqs != 0)
342 cn->vtpci_vqs = malloc(nvqs * sizeof(struct vtpci_virtqueue),
344 if (cn->vtpci_vqs == NULL)
354 vqx = &cn->vtpci_vqs[idx];
370 vqx->vtv_vq = *info->vqai_vq = vq;
371 vqx->vtv_no_intr = info->vqai_intr == NULL;
373 cn->vtpci_nvqs++;
388 dev = cn->vtpci_dev;
399 cn->vtpci_nmsix_resources = required;
414 dev = cn->vtpci_dev;
435 if (vtpci_disable_msix != 0 || cn->vtpci_flags & VTPCI_FLAG_NO_MSIX)
438 for (nvectors = 0, i = 0; i < cn->vtpci_nvqs; i++) {
439 if (cn->vtpci_vqs[i].vtv_no_intr == 0)
447 cn->vtpci_flags |= VTPCI_FLAG_MSIX;
457 if (vtpci_disable_msix != 0 || cn->vtpci_flags & VTPCI_FLAG_NO_MSIX)
464 cn->vtpci_flags |= VTPCI_FLAG_MSIX | VTPCI_FLAG_SHARED_MSIX;
475 if (cn->vtpci_flags & VTPCI_FLAG_NO_MSI)
482 cn->vtpci_flags |= VTPCI_FLAG_MSI;
491 cn->vtpci_flags |= VTPCI_FLAG_INTX;
502 irq = bus_alloc_resource_any(cn->vtpci_dev, SYS_RES_IRQ, &rid, flags);
506 intr->vti_irq = irq;
507 intr->vti_rid = rid;
517 dev = cn->vtpci_dev;
519 if (intr->vti_handler != NULL) {
520 bus_teardown_intr(dev, intr->vti_irq, intr->vti_handler);
521 intr->vti_handler = NULL;
524 if (intr->vti_irq != NULL) {
525 bus_release_resource(dev, SYS_RES_IRQ, intr->vti_rid,
526 intr->vti_irq);
527 intr->vti_irq = NULL;
528 intr->vti_rid = -1;
538 vtpci_free_interrupt(cn, &cn->vtpci_device_interrupt);
540 if (cn->vtpci_nmsix_resources != 0) {
541 nvq_intrs = cn->vtpci_nmsix_resources - 1;
542 cn->vtpci_nmsix_resources = 0;
544 if ((intr = cn->vtpci_msix_vq_interrupts) != NULL) {
548 free(cn->vtpci_msix_vq_interrupts, M_DEVBUF);
549 cn->vtpci_msix_vq_interrupts = NULL;
553 if (cn->vtpci_flags & (VTPCI_FLAG_MSI | VTPCI_FLAG_MSIX))
554 pci_release_msi(cn->vtpci_dev);
556 cn->vtpci_flags &= ~VTPCI_FLAG_ITYPE_MASK;
565 for (idx = 0; idx < cn->vtpci_nvqs; idx++) {
568 vqx = &cn->vtpci_vqs[idx];
569 virtqueue_free(vqx->vtv_vq);
570 vqx->vtv_vq = NULL;
573 free(cn->vtpci_vqs, M_DEVBUF);
574 cn->vtpci_vqs = NULL;
575 cn->vtpci_nvqs = 0;
591 if (cn->vtpci_flags & VTPCI_FLAG_MSIX) {
594 for (idx = 0; idx < cn->vtpci_nvqs; idx++)
609 if (cn->vtpci_flags & VTPCI_FLAG_INTX) {
620 intr = &cn->vtpci_device_interrupt;
623 if (error || cn->vtpci_flags & (VTPCI_FLAG_INTX | VTPCI_FLAG_MSI))
631 nvq_intrs = cn->vtpci_nmsix_resources - 1;
633 cn->vtpci_msix_vq_interrupts = malloc(nvq_intrs *
635 if (cn->vtpci_msix_vq_interrupts == NULL)
638 intr = cn->vtpci_msix_vq_interrupts;
655 intr = &cn->vtpci_device_interrupt;
657 error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, NULL,
658 vtpci_intx_intr, cn, &intr->vti_handler);
670 intr = cn->vtpci_msix_vq_interrupts;
672 for (i = 0; i < cn->vtpci_nvqs; i++) {
673 vqx = &cn->vtpci_vqs[i];
675 if (vqx->vtv_no_intr)
678 error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type,
679 vtpci_vq_intr_filter, vtpci_vq_intr, vqx->vtv_vq,
680 &intr->vti_handler);
696 intr = &cn->vtpci_device_interrupt;
701 intr = cn->vtpci_msix_vq_interrupts;
702 for (idx = 0; idx < cn->vtpci_nvqs; idx++) {
703 if (cn->vtpci_vqs[idx].vtv_no_intr)
716 if (!cn->vtpci_vqs[idx].vtv_no_intr &&
717 (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) == 0)
730 intr = &cn->vtpci_device_interrupt;
732 error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type, NULL,
733 vtpci_config_intr, cn, &intr->vti_handler);
737 if (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX) {
738 intr = &cn->vtpci_msix_vq_interrupts[0];
740 error = bus_setup_intr(cn->vtpci_dev, intr->vti_irq, type,
742 &intr->vti_handler);
755 KASSERT(cn->vtpci_flags & VTPCI_FLAG_ITYPE_MASK,
756 ("%s: no interrupt type selected %#x", __func__, cn->vtpci_flags));
762 if (cn->vtpci_flags & VTPCI_FLAG_INTX)
764 else if (cn->vtpci_flags & VTPCI_FLAG_MSI)
778 dev = cn->vtpci_dev;
811 if (cn->vtpci_flags & VTPCI_FLAG_INTX)
813 else if (cn->vtpci_flags & VTPCI_FLAG_MSI)
815 else if (cn->vtpci_flags & VTPCI_FLAG_SHARED_MSIX)
831 vqx = &cn->vtpci_vqs[idx];
832 vq = vqx->vtv_vq;
858 vqx = &cn->vtpci_vqs[0];
859 for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) {
860 if (vqx->vtv_no_intr == 0)
861 virtqueue_intr(vqx->vtv_vq);
874 vqx = &cn->vtpci_vqs[0];
877 for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) {
878 if (vqx->vtv_no_intr == 0)
879 rc |= virtqueue_intr_filter(vqx->vtv_vq);
893 vqx = &cn->vtpci_vqs[0];
895 for (i = 0; i < cn->vtpci_nvqs; i++, vqx++) {
896 if (vqx->vtv_no_intr == 0)
897 virtqueue_intr(vqx->vtv_vq);
929 child = cn->vtpci_child_dev;
946 error = virtio_describe_sbuf(sb, features, cn->vtpci_child_feat_desc);
959 return (vtpci_feature_sysctl(req, cn, cn->vtpci_host_features));
969 return (vtpci_feature_sysctl(req, cn, cn->vtpci_features));
980 dev = cn->vtpci_dev;
986 CTLFLAG_RD, &cn->vtpci_nvqs, 0, "Number of virtqueues");