Author: hselasky
Date: Thu Sep  5 09:28:58 2019
New Revision: 351840
URL: https://svnweb.freebsd.org/changeset/base/351840

Log:
  MFC r351009:
  Implement pci_enable_msi() and pci_disable_msi() in the LinuxKPI.
  This patch makes the DRM graphics driver in ports usable on aarch64.
  
  Submitted by: Greg V <greg@unrelenting.technology>
  Differential Revision:        https://reviews.freebsd.org/D21008
  Sponsored by: Mellanox Technologies

Modified:
  stable/12/sys/compat/linuxkpi/common/include/linux/device.h
  stable/12/sys/compat/linuxkpi/common/include/linux/interrupt.h
  stable/12/sys/compat/linuxkpi/common/include/linux/pci.h
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/device.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/device.h Thu Sep  5 
09:23:05 2019        (r351839)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/device.h Thu Sep  5 
09:28:58 2019        (r351840)
@@ -110,8 +110,8 @@ struct device {
        void            *driver_data;
        unsigned int    irq;
 #define        LINUX_IRQ_INVALID       65535
-       unsigned int    msix;
-       unsigned int    msix_max;
+       unsigned int    irq_start;
+       unsigned int    irq_end;
        const struct attribute_group **groups;
        struct fwnode_handle *fwnode;
 

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/interrupt.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/interrupt.h      Thu Sep 
 5 09:23:05 2019        (r351839)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/interrupt.h      Thu Sep 
 5 09:28:58 2019        (r351840)
@@ -55,9 +55,11 @@ struct irq_ent {
 static inline int
 linux_irq_rid(struct device *dev, unsigned int irq)
 {
-       if (irq == dev->irq)
+       /* check for MSI- or MSIX- interrupt */
+       if (irq >= dev->irq_start && irq < dev->irq_end)
+               return (irq - dev->irq_start + 1);
+       else
                return (0);
-       return irq - dev->msix + 1;
 }
 
 extern void linux_irq_handler(void *);

Modified: stable/12/sys/compat/linuxkpi/common/include/linux/pci.h
==============================================================================
--- stable/12/sys/compat/linuxkpi/common/include/linux/pci.h    Thu Sep  5 
09:23:05 2019        (r351839)
+++ stable/12/sys/compat/linuxkpi/common/include/linux/pci.h    Thu Sep  5 
09:28:58 2019        (r351840)
@@ -216,6 +216,7 @@ struct pci_dev {
        unsigned int            devfn;
        uint32_t                class;
        uint8_t                 revision;
+       bool                    msi_enabled;
 };
 
 static inline struct resource_list_entry *
@@ -250,7 +251,7 @@ linux_pci_find_irq_dev(unsigned int irq)
        spin_lock(&pci_lock);
        list_for_each_entry(pdev, &pci_devices, links) {
                if (irq == pdev->dev.irq ||
-                   (irq >= pdev->dev.msix && irq < pdev->dev.msix_max)) {
+                   (irq >= pdev->dev.irq_start && irq < pdev->dev.irq_end)) {
                        found = &pdev->dev;
                        break;
                }
@@ -432,10 +433,25 @@ pci_disable_msix(struct pci_dev *pdev)
         * linux_pci_find_irq_dev() does no longer see them by
         * resetting their references to zero:
         */
-       pdev->dev.msix = 0;
-       pdev->dev.msix_max = 0;
+       pdev->dev.irq_start = 0;
+       pdev->dev.irq_end = 0;
 }
 
+#define        pci_disable_msi(pdev) \
+  linux_pci_disable_msi(pdev)
+
+static inline void
+linux_pci_disable_msi(struct pci_dev *pdev)
+{
+
+       pci_release_msi(pdev->dev.bsddev);
+
+       pdev->dev.irq_start = 0;
+       pdev->dev.irq_end = 0;
+       pdev->irq = pdev->dev.irq;
+       pdev->msi_enabled = false;
+}
+
 static inline bus_addr_t
 pci_bus_address(struct pci_dev *pdev, int bar)
 {
@@ -567,10 +583,10 @@ pci_enable_msix(struct pci_dev *pdev, struct msix_entr
                return avail;
        }
        rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
-       pdev->dev.msix = rle->start;
-       pdev->dev.msix_max = rle->start + avail;
+       pdev->dev.irq_start = rle->start;
+       pdev->dev.irq_end = rle->start + avail;
        for (i = 0; i < nreq; i++)
-               entries[i].vector = pdev->dev.msix + i;
+               entries[i].vector = pdev->dev.irq_start + i;
        return (0);
 }
 
@@ -598,6 +614,32 @@ pci_enable_msix_range(struct pci_dev *dev, struct msix
                }
        } while (rc);
        return (nvec);
+}
+
+#define        pci_enable_msi(pdev) \
+  linux_pci_enable_msi(pdev)
+
+static inline int
+pci_enable_msi(struct pci_dev *pdev)
+{
+       struct resource_list_entry *rle;
+       int error;
+       int avail;
+
+       avail = pci_msi_count(pdev->dev.bsddev);
+       if (avail < 1)
+               return -EINVAL;
+
+       avail = 1;      /* this function only enable one MSI IRQ */
+       if ((error = -pci_alloc_msi(pdev->dev.bsddev, &avail)) != 0)
+               return error;
+
+       rle = linux_pci_get_rle(pdev, SYS_RES_IRQ, 1);
+       pdev->dev.irq_start = rle->start;
+       pdev->dev.irq_end = rle->start + avail;
+       pdev->irq = rle->start;
+       pdev->msi_enabled = true;
+       return (0);
 }
 
 static inline int
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to