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()
177 return -ENOMEM; in xen_setup_msi_irqs()
190 "pcifront-msi-x" : in xen_setup_msi_irqs()
191 "pcifront-msi", in xen_setup_msi_irqs()
203 if (ret == -ENOSYS) in xen_setup_msi_irqs()
204 dev_err(&dev->dev, "Xen PCI frontend has not registered MSI/MSI-X support!\n"); in xen_setup_msi_irqs()
206 dev_err(&dev->dev, "Xen PCI frontend error: %d!\n", ret); in xen_setup_msi_irqs()
221 msg->address_hi = X86_MSI_BASE_ADDRESS_HIGH; in xen_msi_compose_msg()
222 msg->arch_addr_hi.destid_8_31 = pirq >> 8; in xen_msi_compose_msg()
223 msg->arch_addr_lo.destid_0_7 = pirq & 0xFF; in xen_msi_compose_msg()
224 msg->arch_addr_lo.base_address = X86_MSI_BASE_ADDRESS_LOW; in xen_msi_compose_msg()
225 msg->arch_data.delivery_mode = APIC_DELIVERY_MODE_EXTINT; in xen_msi_compose_msg()
240 irq = -ENODEV; in xen_hvm_setup_msi_irqs()
245 dev_dbg(&dev->dev, "xen: msi bound to pirq=%d\n", pirq); in xen_hvm_setup_msi_irqs()
249 "msi-x" : "msi", in xen_hvm_setup_msi_irqs()
253 dev_dbg(&dev->dev, in xen_hvm_setup_msi_irqs()
254 "xen: msi --> pirq=%d --> irq=%d\n", pirq, irq); in xen_hvm_setup_msi_irqs()
259 dev_err(&dev->dev, "Failed to create MSI%s! ret=%d!\n", in xen_hvm_setup_msi_irqs()
260 type == PCI_CAP_ID_MSI ? "" : "-X", irq); in xen_hvm_setup_msi_irqs()
277 /* N.B. Casting int's -ENODEV to uint16_t results in 0xFFED, in xen_initdom_setup_msi_irqs()
285 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
286 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
287 map_irq.bus = dev->bus->number | in xen_initdom_setup_msi_irqs()
288 (pci_domain_nr(dev->bus) << 16); in xen_initdom_setup_msi_irqs()
289 map_irq.devfn = dev->devfn; in xen_initdom_setup_msi_irqs()
299 pos = dev->msix_cap; in xen_initdom_setup_msi_irqs()
305 return -EINVAL; in xen_initdom_setup_msi_irqs()
308 map_irq.entry_nr = msidesc->msi_attrib.entry_nr; in xen_initdom_setup_msi_irqs()
311 ret = -EINVAL; in xen_initdom_setup_msi_irqs()
325 if (ret == -EINVAL && !pci_domain_nr(dev->bus)) { in xen_initdom_setup_msi_irqs()
327 map_irq.index = -1; in xen_initdom_setup_msi_irqs()
328 map_irq.pirq = -1; in xen_initdom_setup_msi_irqs()
329 map_irq.bus = dev->bus->number; in xen_initdom_setup_msi_irqs()
332 if (ret != -EINVAL) in xen_initdom_setup_msi_irqs()
336 dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n", in xen_initdom_setup_msi_irqs()
343 (type == PCI_CAP_ID_MSIX) ? "msi-x" : "msi", in xen_initdom_setup_msi_irqs()
360 restore_ext.seg = pci_domain_nr(dev->bus); in xen_initdom_restore_msi_irqs()
361 restore_ext.bus = dev->bus->number; in xen_initdom_restore_msi_irqs()
362 restore_ext.devfn = dev->devfn; in xen_initdom_restore_msi_irqs()
365 if (ret == -ENOSYS) in xen_initdom_restore_msi_irqs()
367 WARN(ret && ret != -ENOSYS, "restore_msi_ext -> %d\n", ret); in xen_initdom_restore_msi_irqs()
372 restore.bus = dev->bus->number; in xen_initdom_restore_msi_irqs()
373 restore.devfn = dev->devfn; in xen_initdom_restore_msi_irqs()
375 WARN(ret && ret != -ENOSYS, "restore_msi -> %d\n", ret); in xen_initdom_restore_msi_irqs()
389 if (msidesc->irq) { in xen_teardown_msi_irqs()
390 for (i = 0; i < msidesc->nvec_used; i++) in xen_teardown_msi_irqs()
391 xen_destroy_irq(msidesc->irq + i); in xen_teardown_msi_irqs()
400 if (msidesc->msi_attrib.is_msix) in xen_pv_teardown_msi_irqs()
408 static int xen_msi_domain_alloc_irqs(struct irq_domain *domain, in xen_msi_domain_alloc_irqs() argument
414 return -EINVAL; in xen_msi_domain_alloc_irqs()
416 if (first_msi_entry(dev)->msi_attrib.is_msix) in xen_msi_domain_alloc_irqs()
424 static void xen_msi_domain_free_irqs(struct irq_domain *domain, in xen_msi_domain_free_irqs() argument
443 * This irq domain is a blatant violation of the irq domain design, but
447 * domain pointer in struct device. This irq domain wrappery allows to do
455 fn = irq_domain_alloc_named_fwnode("XEN-MSI"); in xen_create_pci_msi_domain()
485 * Override the PCI/MSI irq domain init function. No point in xen_setup_pci_msi()
486 * in allocating the native domain and never use it. in xen_setup_pci_msi()
498 return -ENODEV; in pci_xen_init()
500 printk(KERN_INFO "PCI: setting up Xen PCI frontend stub\n"); in pci_xen_init()
567 * Pre-allocate the legacy IRQs. Use NR_LEGACY_IRQS here in pci_xen_initial_domain()
573 if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) in pci_xen_initial_domain()
582 xen_bind_pirq_gsi_to_irq(irq, irq, 0, "xt-pic"); in pci_xen_initial_domain()
591 domid_t domain; member
604 if (owner->dev == dev) in find_device()
613 int domain = -ENODEV; in xen_find_device_domain_owner() local
618 domain = owner->domain; in xen_find_device_domain_owner()
620 return domain; in xen_find_device_domain_owner()
624 int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain) in xen_register_device_domain_owner() argument
630 return -ENODEV; in xen_register_device_domain_owner()
636 return -EEXIST; in xen_register_device_domain_owner()
638 owner->domain = domain; in xen_register_device_domain_owner()
639 owner->dev = dev; in xen_register_device_domain_owner()
640 list_add_tail(&owner->list, &dev_domain_list); in xen_register_device_domain_owner()
654 return -ENODEV; in xen_unregister_device_domain_owner()
656 list_del(&owner->list); in xen_unregister_device_domain_owner()