Lines Matching +full:virtio +full:- +full:pci

1 // SPDX-License-Identifier: GPL-2.0
7 #include <linux/pci.h>
8 #include <linux/virtio.h>
14 #include <linux/virtio-uml.h>
24 /* for MSI-X we have a 32-bit payload */
89 return -EINVAL; in um_pci_send_cmd()
91 switch (cmd->op) { in um_pci_send_cmd()
95 /* in PCI, writes are posted, so don't wait */ in um_pci_send_cmd()
134 /* add to internal virtio queue */ in um_pci_send_cmd()
135 ret = virtqueue_add_sgs(dev->cmd_vq, sgs_list, in um_pci_send_cmd()
147 virtqueue_kick(dev->cmd_vq); in um_pci_send_cmd()
153 set_bit(UM_PCI_STAT_WAITING, &dev->status); in um_pci_send_cmd()
154 virtqueue_kick(dev->cmd_vq); in um_pci_send_cmd()
157 void *completed = virtqueue_get_buf(dev->cmd_vq, &len); in um_pci_send_cmd()
165 if (WARN_ONCE(virtqueue_is_broken(dev->cmd_vq) || in um_pci_send_cmd()
167 "um virt-pci delay: %d", delay_count)) { in um_pci_send_cmd()
168 ret = -EIO; in um_pci_send_cmd()
173 clear_bit(UM_PCI_STAT_WAITING, &dev->status); in um_pci_send_cmd()
184 struct um_pci_device *dev = reg->dev; in um_pci_cfgspace_read()
190 /* buf->data is maximum size - we may only use parts of it */ in um_pci_cfgspace_read()
194 size_t bytes = sizeof(buf->data); in um_pci_cfgspace_read()
200 data = buf->data; in um_pci_cfgspace_read()
249 struct um_pci_device *dev = reg->dev; in um_pci_cfgspace_write()
252 /* maximum size - we may only use parts of it */ in um_pci_cfgspace_write()
297 struct um_pci_device *dev = container_of(resptr - *resptr, in um_pci_bar_copy_from()
315 /* buf->data is maximum size - we may only use parts of it */ in um_pci_bar_read()
321 data = buf->data; in um_pci_bar_read()
366 struct um_pci_device *dev = container_of(resptr - *resptr, in um_pci_bar_copy_to()
382 /* maximum size - we may only use parts of it */ in um_pci_bar_write()
411 struct um_pci_device *dev = container_of(resptr - *resptr, in um_pci_bar_set()
442 unsigned int busn = bus->number; in um_pci_map_bus()
458 return (void __iomem *)((unsigned long)dev->iomem + where); in um_pci_map_bus()
470 pci_rescan_bus(bridge->bus); in um_pci_rescan()
488 struct virtio_device *vdev = vq->vdev; in um_pci_handle_irq_message()
489 struct um_pci_device *dev = vdev->priv; in um_pci_handle_irq_message()
491 if (!dev->irq) in um_pci_handle_irq_message()
496 switch (msg->op) { in um_pci_handle_irq_message()
498 generic_handle_irq(dev->irq); in um_pci_handle_irq_message()
502 if (msg->size == sizeof(u32)) in um_pci_handle_irq_message()
503 generic_handle_irq(le32_to_cpup((void *)msg->data)); in um_pci_handle_irq_message()
505 generic_handle_irq(le16_to_cpup((void *)msg->data)); in um_pci_handle_irq_message()
508 /* nothing to do - we already woke up due to the message */ in um_pci_handle_irq_message()
511 dev_err(&vdev->dev, "unexpected virt-pci message %d\n", msg->op); in um_pci_handle_irq_message()
518 struct virtio_device *vdev = vq->vdev; in um_pci_cmd_vq_cb()
519 struct um_pci_device *dev = vdev->priv; in um_pci_cmd_vq_cb()
523 if (test_bit(UM_PCI_STAT_WAITING, &dev->status)) in um_pci_cmd_vq_cb()
553 for_each_node_by_type(np, "pci") { in pcibios_get_phb_of_node()
557 prop = of_get_property(np, "bus-range", NULL); in pcibios_get_phb_of_node()
561 if (bus->number == bus_min) in pcibios_get_phb_of_node()
575 err = virtio_find_vqs(dev->vdev, 2, vqs, cbs, names, NULL); in um_pci_init_vqs()
579 dev->cmd_vq = vqs[0]; in um_pci_init_vqs()
580 dev->irq_vq = vqs[1]; in um_pci_init_vqs()
582 virtio_device_ready(dev->vdev); in um_pci_init_vqs()
588 um_pci_irq_vq_addbuf(dev->irq_vq, msg, false); in um_pci_init_vqs()
591 virtqueue_kick(dev->irq_vq); in um_pci_init_vqs()
600 vdev->config->del_vqs(vdev); in __um_pci_virtio_platform_remove()
614 dev->platform = true; in um_pci_virtio_platform_probe()
620 ret = -EBUSY; in um_pci_virtio_platform_probe()
634 ret = of_platform_default_populate(vdev->dev.of_node, NULL, &vdev->dev); in um_pci_virtio_platform_probe()
648 int i, free = -1; in um_pci_virtio_probe()
649 int err = -ENOSPC; in um_pci_virtio_probe()
653 return -ENOMEM; in um_pci_virtio_probe()
655 dev->vdev = vdev; in um_pci_virtio_probe()
656 vdev->priv = dev; in um_pci_virtio_probe()
658 if (of_device_is_compatible(vdev->dev.of_node, "simple-bus")) in um_pci_virtio_probe()
676 dev->irq = irq_alloc_desc(numa_node_id()); in um_pci_virtio_probe()
677 if (dev->irq < 0) { in um_pci_virtio_probe()
678 err = dev->irq; in um_pci_virtio_probe()
682 vdev->priv = dev; in um_pci_virtio_probe()
686 device_set_wakeup_enable(&vdev->dev, true); in um_pci_virtio_probe()
689 * In order to do suspend-resume properly, don't allow VQs in um_pci_virtio_probe()
698 vdev->config->del_vqs(vdev); in um_pci_virtio_probe()
707 struct um_pci_device *dev = vdev->priv; in um_pci_virtio_remove()
710 if (dev->platform) { in um_pci_virtio_remove()
711 of_platform_depopulate(&vdev->dev); in um_pci_virtio_remove()
716 device_set_wakeup_enable(&vdev->dev, false); in um_pci_virtio_remove()
724 irq_free_desc(dev->irq); in um_pci_virtio_remove()
733 pci_dev = pci_get_slot(bridge->bus, i); in um_pci_virtio_remove()
740 dev->cmd_vq = NULL; in um_pci_virtio_remove()
741 dev->irq_vq = NULL; in um_pci_virtio_remove()
742 vdev->config->del_vqs(vdev); in um_pci_virtio_remove()
751 MODULE_DEVICE_TABLE(virtio, id_table);
754 .driver.name = "virtio-pci",
762 .name = "PCI config space",
763 .start = 0xf0000000 - MAX_DEVICES * CFG_SPACE_SIZE,
764 .end = 0xf0000000 - 1,
773 return -EINVAL; in um_pci_map_cfgspace()
782 return -ENOENT; in um_pci_map_cfgspace()
790 .name = "PCI iomem",
807 struct um_pci_device_reg *reg = &um_pci_devices[pdev->devfn / 8]; in um_pci_map_iomem_walk()
811 if (!reg->dev) in um_pci_map_iomem_walk()
814 for (i = 0; i < ARRAY_SIZE(dev->resptr); i++) { in um_pci_map_iomem_walk()
815 struct resource *r = &pdev->resource[i]; in um_pci_map_iomem_walk()
817 if ((r->flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM) in um_pci_map_iomem_walk()
824 if (data->offset < r->start || data->offset > r->end) in um_pci_map_iomem_walk()
826 if (data->offset + data->size - 1 > r->end) in um_pci_map_iomem_walk()
829 dev = reg->dev; in um_pci_map_iomem_walk()
830 *data->ops = &um_pci_device_bar_ops; in um_pci_map_iomem_walk()
831 dev->resptr[i] = i; in um_pci_map_iomem_walk()
832 *data->priv = &dev->resptr[i]; in um_pci_map_iomem_walk()
833 data->ret = data->offset - r->start; in um_pci_map_iomem_walk()
852 .ret = -ENOENT, in um_pci_map_iomem()
855 pci_walk_bus(bridge->bus, um_pci_map_iomem_walk, &data); in um_pci_map_iomem()
867 * in UML, so we can simply map MSI(-X) vectors to there, it cannot be in um_pci_compose_msi_msg()
873 msg->address_hi = 0; in um_pci_compose_msi_msg()
874 msg->address_lo = 0xa0000; in um_pci_compose_msi_msg()
875 msg->data = data->irq; in um_pci_compose_msi_msg()
879 .name = "UM virtio MSI",
895 return -ENOSPC; in um_pci_inner_domain_alloc()
902 domain->host_data, handle_simple_irq, in um_pci_inner_domain_alloc()
915 if (!test_bit(d->hwirq, um_pci_msi_used)) in um_pci_inner_domain_free()
916 pr_err("trying to free unused MSI#%lu\n", d->hwirq); in um_pci_inner_domain_free()
918 __clear_bit(d->hwirq, um_pci_msi_used); in um_pci_inner_domain_free()
929 .name = "UM virtio PCIe MSI",
942 .name = "PCI busn",
950 struct um_pci_device_reg *reg = &um_pci_devices[pdev->devfn / 8]; in um_pci_map_irq()
952 if (WARN_ON(!reg->dev)) in um_pci_map_irq()
953 return -EINVAL; in um_pci_map_irq()
956 return reg->dev->irq; in um_pci_map_irq()
969 return -ENOENT; in um_pci_map_platform()
972 *priv = &um_pci_platform_device->resptr[0]; in um_pci_map_platform()
1000 "No virtio device ID configured for PCI - no PCI support\n")) in um_pci_init()
1005 return -ENOMEM; in um_pci_init()
1009 err = -ENOMEM; in um_pci_init()
1013 um_pci_fwnode = irq_domain_alloc_named_fwnode("um-pci"); in um_pci_init()
1015 err = -ENOMEM; in um_pci_init()
1023 err = -ENOMEM; in um_pci_init()
1031 err = -ENOMEM; in um_pci_init()
1035 pci_add_resource(&bridge->windows, &virt_iomem_resource); in um_pci_init()
1036 pci_add_resource(&bridge->windows, &busn_resource); in um_pci_init()
1037 bridge->ops = &um_pci_ops; in um_pci_init()
1038 bridge->map_irq = um_pci_map_irq; in um_pci_init()
1046 err = -ENOMEM; in um_pci_init()
1065 pci_free_resource_list(&bridge->windows); in um_pci_init()
1078 pci_free_resource_list(&bridge->windows); in um_pci_exit()