summaryrefslogtreecommitdiffstats
path: root/driver/rdma.c
diff options
context:
space:
mode:
authorVasilii Chernov <vchernov@inr.ru>2016-03-03 10:34:49 +0100
committerVasilii Chernov <vchernov@inr.ru>2016-03-03 10:34:49 +0100
commitee16e47966afe180d3c32e2b1d93301052894fac (patch)
tree56aecf261aaae57e28c08cef573ae6642ec5394d /driver/rdma.c
parent02d0026e2df2ba5c68c0c1a67aec4437c9e8e8f3 (diff)
parent195c28f3074486165b6e0935362810f8a1fb9531 (diff)
downloadpcitool-ee16e47966afe180d3c32e2b1d93301052894fac.tar.gz
pcitool-ee16e47966afe180d3c32e2b1d93301052894fac.tar.bz2
pcitool-ee16e47966afe180d3c32e2b1d93301052894fac.tar.xz
pcitool-ee16e47966afe180d3c32e2b1d93301052894fac.zip
Merge with http://ufo.kit.edu/ufo/log/csa/pcitool 369 revision
Diffstat (limited to 'driver/rdma.c')
-rw-r--r--driver/rdma.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/driver/rdma.c b/driver/rdma.c
index 22a4a5e..b1d939a 100644
--- a/driver/rdma.c
+++ b/driver/rdma.c
@@ -7,8 +7,9 @@
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/hugetlb.h>
+#include <linux/cdev.h>
-#include "rdma.h"
+#include "base.h"
static unsigned long pcidriver_follow_pte(struct mm_struct *mm, unsigned long address)
{
@@ -17,37 +18,53 @@ static unsigned long pcidriver_follow_pte(struct mm_struct *mm, unsigned long ad
pmd_t *pmd;
pte_t *pte;
- spinlock_t *ptl;
+ spinlock_t *ptl;
unsigned long pfn = 0;
pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
- return 0;
-
+ if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
+ return 0;
+
pud = pud_offset(pgd, address);
- if (pud_none(*pud) || unlikely(pud_bad(*pud)))
- return 0;
+ if (pud_none(*pud) || unlikely(pud_bad(*pud)))
+ return 0;
pmd = pmd_offset(pud, address);
- if (pmd_none(*pmd))
- return 0;
+ if (pmd_none(*pmd))
+ return 0;
pte = pte_offset_map_lock(mm, pmd, address, &ptl);
if (!pte_none(*pte))
- pfn = (pte_pfn(*pte) << PAGE_SHIFT);
- pte_unmap_unlock(pte, ptl);
+ pfn = (pte_pfn(*pte) << PAGE_SHIFT);
+ pte_unmap_unlock(pte, ptl);
return pfn;
}
unsigned long pcidriver_resolve_bar(unsigned long address) {
+ int dev, bar;
unsigned long pfn;
address = (address >> PAGE_SHIFT) << PAGE_SHIFT;
pfn = pcidriver_follow_pte(current->mm, address);
- return pfn;
+ for (dev = 0; dev < MAXDEVICES; dev++)
+ {
+ pcidriver_privdata_t *privdata = pcidriver_get_privdata(dev);
+ if (!privdata) continue;
+
+ for (bar = 0; bar < 6; bar++)
+ {
+ unsigned long start = pci_resource_start(privdata->pdev, bar);
+ unsigned long end = start + pci_resource_len(privdata->pdev, bar);
+ if ((pfn >= start)&&(pfn < end))
+ return pfn;
+ }
+ pcidriver_put_privdata(privdata);
+ }
+
+ return 0;
}
EXPORT_SYMBOL(pcidriver_resolve_bar);