[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patch 08/10] PCI/MSI: Provide pci_msi_domain_supports_expand()



Not all irq domain implementations can support runtime MSI-X vector
expansion as they assume zero based allocations or have other
restrictions.

The legacy PCI allocation functions are not suited for runtime vector
expansion either.

Add a function which allows to query whether runtime MSI-X vector expansion
is supported or not.

Signed-off-by: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
---
 drivers/pci/msi/irqdomain.c |   29 +++++++++++++++++++++++------
 include/linux/msi.h         |    2 ++
 2 files changed, 25 insertions(+), 6 deletions(-)

--- a/drivers/pci/msi/irqdomain.c
+++ b/drivers/pci/msi/irqdomain.c
@@ -8,12 +8,18 @@
 
 #include "msi.h"
 
+static struct irq_domain *pci_get_msi_domain(struct pci_dev *dev)
+{
+       struct irq_domain *domain = dev_get_msi_domain(&dev->dev);
+
+       return domain && irq_domain_is_hierarchy(domain) ? domain : NULL;
+}
+
 int pci_msi_setup_msi_irqs(struct pci_dev *dev, struct msi_range *range, int 
type)
 {
-       struct irq_domain *domain;
+       struct irq_domain *domain = pci_get_msi_domain(dev);
 
-       domain = dev_get_msi_domain(&dev->dev);
-       if (domain && irq_domain_is_hierarchy(domain))
+       if (domain)
                return msi_domain_alloc_irqs_descs_locked(domain, &dev->dev, 
range);
 
        return pci_msi_legacy_setup_msi_irqs(dev, range->ndesc, type);
@@ -21,15 +27,26 @@ int pci_msi_setup_msi_irqs(struct pci_de
 
 void pci_msi_teardown_msi_irqs(struct pci_dev *dev, struct msi_range *range)
 {
-       struct irq_domain *domain;
+       struct irq_domain *domain = pci_get_msi_domain(dev);
 
-       domain = dev_get_msi_domain(&dev->dev);
-       if (domain && irq_domain_is_hierarchy(domain))
+       if (domain)
                msi_domain_free_irqs_descs_locked(domain, &dev->dev, range);
        else
                pci_msi_legacy_teardown_msi_irqs(dev);
 }
 
+bool pci_msi_domain_supports_expand(struct pci_dev *dev)
+{
+       struct irq_domain *domain = pci_get_msi_domain(dev);
+       struct msi_domain_info *info;
+
+       if (!domain)
+               return false;
+
+       info = domain->host_data;
+       return info->flags & MSI_FLAG_CAN_EXPAND;
+}
+
 /**
  * pci_msi_domain_write_msg - Helper to write MSI message to PCI config space
  * @irq_data:  Pointer to interrupt data of the MSI interrupt
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -552,11 +552,13 @@ struct irq_domain *pci_msi_create_irq_do
 u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev 
*pdev);
 struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev);
 bool pci_dev_has_special_msi_domain(struct pci_dev *pdev);
+bool pci_msi_domain_supports_expand(struct pci_dev *dev);
 #else
 static inline struct irq_domain *pci_msi_get_device_domain(struct pci_dev 
*pdev)
 {
        return NULL;
 }
+static inline bool pci_msi_domain_supports_expand(struct pci_dev *dev) { 
return false; }
 #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */
 
 #endif /* LINUX_MSI_H */




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.