Skip to content

Patch for compiling PCIe example driver on newer Linux kernels #16

@kevpatt

Description

@kevpatt

I made a patch to gowin_demo_drv.c to allow building on newer Linux kernels. Successfully tested on 6.14.0-23-generic (Ubuntu x86_64).

diff --git a/pcie_dma_demo/gowin_pcie_demo/gowin_pcie_demo/driver/gowin_demo_drv.c b/pcie_dma_demo/gowin_pcie_demo/gowin_pcie_demo/driver/gowin_demo_drv.c
index 8c9dc00..f2e5a35 100644
--- a/pcie_dma_demo/gowin_pcie_demo/gowin_pcie_demo/driver/gowin_demo_drv.c
+++ b/pcie_dma_demo/gowin_pcie_demo/gowin_pcie_demo/driver/gowin_demo_drv.c
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/wait.h>
+#include <linux/version.h>
 
 
 #include "../include/gowin_pcie_bar_drv_uapi.h"
@@ -59,6 +60,7 @@ struct dma_context {
 
 struct gowin_bar_data {
     struct pci_dev         *pdev;
+    void __iomem * const   *iomap;
     // void   __iomem          *base;
     // void   __iomem          *bar[PCI_STD_NUM_BARS];
 
@@ -107,7 +109,7 @@ static inline u32 gowin_readl(
         return 0;
     }
     else {
-        return readl(pcim_iomap_table(data->pdev)[bar] + offset);
+        return readl(data->iomap[bar] + offset);
     }
 }
 
@@ -127,7 +129,7 @@ static inline void gowin_writel(
         return;
     }
     else  {
-        writel(value, pcim_iomap_table(data->pdev)[bar] + offset);
+        writel(value, data->iomap[bar] + offset);
     }
 }
 
@@ -146,7 +148,7 @@ static inline u16 gowin_readw(
         return 0;
     }
     else {
-        return readw(pcim_iomap_table(data->pdev)[bar] + offset);
+        return readw(data->iomap[bar] + offset);
     }
 }
 
@@ -166,7 +168,7 @@ static inline void gowin_writew(
         return;
     }
     else  {
-        writew(value, pcim_iomap_table(data->pdev)[bar] + offset);
+        writew(value, data->iomap[bar] + offset);
     }
 }
 
@@ -185,7 +187,7 @@ static inline u8 gowin_readb(
         return 0;
     }
     else {
-        return readb(pcim_iomap_table(data->pdev)[bar] + offset);
+        return readb(data->iomap[bar] + offset);
     }
 }
 
@@ -205,7 +207,7 @@ static inline void gowin_writeb(
         return;
     }
     else  {
-        writeb(value, pcim_iomap_table(data->pdev)[bar] + offset);
+        writeb(value, data->iomap[bar] + offset);
     }
 }
 
@@ -681,7 +683,7 @@ static int ioctl_switch_bar_mem(
             dev_err(dev, "Wrong parameter.");
             return -EINVAL;
         }
-        if (pcim_iomap_table(data->pdev)[index] == NULL) {
+        if (data->iomap[index] == NULL) {
             return -EINVAL;
         }
         data->cur_bar = index;
@@ -1017,7 +1019,12 @@ static int gowin_bar_mmap(struct file *filp, struct vm_area_struct *vma)
      * prevent touching the pages (byte access) for swap-in,
      * and prevent the pages from being swapped out
      */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,3,0)
+    vm_flags_set(vma, VMEM_FLAGS);
+#else
     vma->vm_flags |= VMEM_FLAGS;
+#endif
+   
     if (data->mem_select == 0) {
         /*! make MMIO accessible to user space */
         //! TODO
@@ -1062,7 +1069,7 @@ static const struct file_operations gowin_bar_fops = {
     .owner          = THIS_MODULE,
     .unlocked_ioctl = gowin_bar_ioctl,
     .compat_ioctl   = compat_ptr_ioctl,
-    .llseek         = no_llseek,
+    .llseek         = noop_llseek,
     .open           = gowin_bar_open,
     //.write          = ,
     .mmap           = gowin_bar_mmap,
@@ -1134,18 +1141,28 @@ static int gowin_bar_probe(struct pci_dev *pdev,
     }
 
 #if 1
-    err = pcim_iomap_regions_request_all(pdev, 1, DRIVER_NAME);
+    /* Reserve BAR regions (bitmask: 1 << BAR0 = 1) */
+    err = pcim_iomap_regions(pdev, 1, DRIVER_NAME);
     if (unlikely(err)) {
-        dev_err(dev, "pcim_iomap_regions_request_all() failed. (%d)\n", err);
+        dev_err(dev, "pcim_iomap_regions() failed. (%d)\n", err);
         return err;
     }
+
+    /* Get I/O mapping table */
+    data->iomap = pcim_iomap_table(pdev);
+    if (!data->iomap) {
+        dev_err(dev, "pcim_iomap_table() returned NULL.\n");
+        return -ENOMEM;
+    }
+
     data->cur_bar = -1;
     for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
-        if (!pcim_iomap_table(pdev)[bar])
+        if (!data->iomap[bar])
             continue;
         if (data->cur_bar < 0)
             data->cur_bar = bar;
     }
+
     if (data->cur_bar < 0) {
         dev_err(dev, "No BAR available.\n");
         return -ENOMEM;
@@ -1211,7 +1228,11 @@ static int gowin_bar_probe(struct pci_dev *pdev,
         goto err_unregister_chrdev_region;
     }
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,0)
+    data->gw_class = class_create(CLASS_NAME);
+#else
     data->gw_class = class_create(THIS_MODULE, CLASS_NAME);
+#endif
 
     if (IS_ERR(data->gw_class)) {
         dev_err(dev, "class_create() failed.\n");

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions