Lines Matching +full:pci +full:- +full:domain
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Xen PCI - handle PCI (INTx) and MSI infrastructure calls for PV, HVM and
4 * initial domain support. We also handle the DSDT _PRT callbacks for GSI's
5 * used in HVM and initial domain mode (PV does not parse ACPI, so it has no
7 * 0xcf8 PCI configuration read/write.
15 #include <linux/pci.h>
26 #include <asm/xen/pci.h>
41 dev_warn(&dev->dev, "Xen PCI: failed to read interrupt line: %d\n", in xen_pcifront_enable_irq()
45 /* In PV DomU the Xen PCI backend puts the PIRQ in the interrupt line.*/ in xen_pcifront_enable_irq()
53 dev_warn(&dev->dev, "Xen PCI: failed to bind GSI%d (PIRQ%d) to IRQ: %d\n", in xen_pcifront_enable_irq()
58 dev->irq = rc; in xen_pcifront_enable_irq()
59 dev_info(&dev->dev, "Xen PCI mapped GSI%d to IRQ%d\n", gsi, dev->irq); in xen_pcifront_enable_irq()
66 int rc, pirq = -1, irq; in xen_register_pirq()
86 return -1; in xen_register_pirq()
91 name = "ioapic-edge"; in xen_register_pirq()
94 name = "ioapic-level"; in xen_register_pirq()
101 printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", map_irq.pirq, irq, gsi); in xen_register_pirq()
110 return -1; in acpi_register_gsi_xen_hvm()
123 return -1; in xen_register_gsi()
135 if (rc == -EEXIST) in xen_register_gsi()
178 return -ENOMEM; in xen_setup_msi_irqs()
191 "pcifront-msi-x" : in xen_setup_msi_irqs()
192 "pcifront-msi", in xen_setup_msi_irqs()
204 if (ret == -ENOSYS) in xen_setup_msi_irqs()
205 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); in xen_setup_msi_irqs()
207 dev_err(&dev->dev, "Xen PCI frontend error: %d!\n", ret); in xen_setup_msi_irqs()
222 msg->address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(pirq); in xen_msi_compose_msg()
223 msg->address_lo = in xen_msi_compose_msg()
229 msg->data = XEN_PIRQ_MSI_DATA; in xen_msi_compose_msg()
244 irq = -ENODEV; in xen_hvm_setup_msi_irqs()
249 dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); in xen_hvm_setup_msi_irqs()
253 "msi-x" : "msi", in xen_hvm_setup_msi_irqs()
257 dev_dbg(&dev->dev, in xen_hvm_setup_msi_irqs()
258 "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq); in xen_hvm_setup_msi_irqs()
263 dev_err(&dev->dev, "Failed to create MSI%s! ret=%d!\n", in xen_hvm_setup_msi_irqs()
264 type == PCI_CAP_ID_MSI ? "" : "-X", irq); in xen_hvm_setup_msi_irqs()
281 /* N.B. Casting int's -ENODEV to uint16_t results in 0xFFED, in xen_initdom_setup_msi_irqs()
289 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
290 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
291 map_irq.bus = dev->bus->number | in xen_initdom_setup_msi_irqs()
292 (pci_domain_nr(dev->bus) << 16); in xen_initdom_setup_msi_irqs()
293 map_irq.devfn = dev->devfn; in xen_initdom_setup_msi_irqs()
303 pos = dev->msix_cap; in xen_initdom_setup_msi_irqs()
309 return -EINVAL; in xen_initdom_setup_msi_irqs()
312 map_irq.entry_nr = msidesc->msi_attrib.entry_nr; in xen_initdom_setup_msi_irqs()
315 ret = -EINVAL; in xen_initdom_setup_msi_irqs()
329 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { in xen_initdom_setup_msi_irqs()
331 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
332 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
333 map_irq.bus = dev->bus->number; in xen_initdom_setup_msi_irqs()
336 if (ret != -EINVAL) in xen_initdom_setup_msi_irqs()
340 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n", in xen_initdom_setup_msi_irqs()
347 (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", in xen_initdom_setup_msi_irqs()
364 restore_ext.seg = pci_domain_nr(dev->bus); in xen_initdom_restore_msi_irqs()
365 restore_ext.bus = dev->bus->number; in xen_initdom_restore_msi_irqs()
366 restore_ext.devfn = dev->devfn; in xen_initdom_restore_msi_irqs()
369 if (ret == -ENOSYS) in xen_initdom_restore_msi_irqs()
371 WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret); in xen_initdom_restore_msi_irqs()
376 restore.bus = dev->bus->number; in xen_initdom_restore_msi_irqs()
377 restore.devfn = dev->devfn; in xen_initdom_restore_msi_irqs()
379 WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret); in xen_initdom_restore_msi_irqs()
393 if (msidesc->irq) { in xen_teardown_msi_irqs()
394 for (i = 0; i < msidesc->nvec_used; i++) in xen_teardown_msi_irqs()
395 xen_destroy_irq(msidesc->irq + i); in xen_teardown_msi_irqs()
404 if (msidesc->msi_attrib.is_msix) in xen_pv_teardown_msi_irqs()
412 static int xen_msi_domain_alloc_irqs(struct irq_domain *domain, in xen_msi_domain_alloc_irqs() argument
418 return -EINVAL; in xen_msi_domain_alloc_irqs()
420 if (first_msi_entry(dev)->msi_attrib.is_msix) in xen_msi_domain_alloc_irqs()
428 static void xen_msi_domain_free_irqs(struct irq_domain *domain, in xen_msi_domain_free_irqs() argument
447 * This irq domain is a blatant violation of the irq domain design, but
451 * domain pointer in struct device. This irq domain wrappery allows to do
459 fn = irq_domain_alloc_named_fwnode("XEN-MSI"); in xen_create_pci_msi_domain()
488 * Override the PCI/MSI irq domain init function. No point in xen_setup_pci_msi()
489 * in allocating the native domain and never use it. in xen_setup_pci_msi()
493 * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely in xen_setup_pci_msi()
506 return -ENODEV; in pci_xen_init()
508 printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n"); in pci_xen_init()
575 * Pre-allocate the legacy IRQs. Use NR_LEGACY_IRQS here in pci_xen_initial_domain()
581 if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) in pci_xen_initial_domain()
590 xen_bind_pirq_gsi_to_irq(irq, irq, 0, "xt-pic"); in pci_xen_initial_domain()
596 domid_t domain; member
609 if (owner->dev == dev) in find_device()
618 int domain = -ENODEV; in xen_find_device_domain_owner() local
623 domain = owner->domain; in xen_find_device_domain_owner()
625 return domain; in xen_find_device_domain_owner()
629 int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain) in xen_register_device_domain_owner() argument
635 return -ENODEV; in xen_register_device_domain_owner()
641 return -EEXIST; in xen_register_device_domain_owner()
643 owner->domain = domain; in xen_register_device_domain_owner()
644 owner->dev = dev; in xen_register_device_domain_owner()
645 list_add_tail(&owner->list, &dev_domain_list); in xen_register_device_domain_owner()
659 return -ENODEV; in xen_unregister_device_domain_owner()
661 list_del(&owner->list); in xen_unregister_device_domain_owner()