Thomas Hellström wrote:
Johannes,
If the patch works, it looks correct to me.
However, you need to make sure (using defines) that the code will
compile also on kernels that don't have the .fault method.
/Thomas
Hi Thomas,
thanks for reviewing and suggesting. :)
I created a new variable DRM_HAS_FAULT which is defined for kernels from
2.6.23 and decides about using .fault or .nopfn.
I attach a corrected version.
Cheers, Johannes
>From afa7bf20a62ce37b00c06a1ac53527656e4c1c43 Mon Sep 17 00:00:00 2001
From: Johannes Engel <[EMAIL PROTECTED]>
Date: Tue, 29 Jul 2008 21:54:20 +0100
Subject: [PATCH 1/1] Replace nopfn by fault
This is necessary since kernel 2.6.27 will ship without nopfn.
The .fault method is supposed to be supported for kernels >= 2.6.23.
Signed-off-by: Johannes Engel <[EMAIL PROTECTED]>
---
linux-core/drm_compat.h | 3 ++
linux-core/drm_vm.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h
index 6e5d252..4b56863 100644
--- a/linux-core/drm_compat.h
+++ b/linux-core/drm_compat.h
@@ -176,6 +176,9 @@ static __inline__ void *kcalloc(size_t nmemb, size_t size, int flags)
#define DRM_FULL_MM_COMPAT
#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
+#define DRM_HAS_FAULT
+#endif
/*
* Flush relevant caches and clear a VMA structure so that page references
diff --git a/linux-core/drm_vm.c b/linux-core/drm_vm.c
index 6618c0a..61ea915 100644
--- a/linux-core/drm_vm.c
+++ b/linux-core/drm_vm.c
@@ -699,8 +699,13 @@ EXPORT_SYMBOL(drm_mmap);
*/
#ifdef DRM_FULL_MM_COMPAT
+#ifdef DRM_HAS_FAULT
+static int drm_bo_vm_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
+#else
static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
unsigned long address)
+#endif
{
struct drm_buffer_object *bo = (struct drm_buffer_object *) vma->vm_private_data;
unsigned long page_offset;
@@ -708,29 +713,52 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
struct drm_ttm *ttm;
struct drm_device *dev;
unsigned long pfn;
+#ifdef DRM_HAS_FAULT
+ unsigned long address = (unsigned long)vmf->virtual_address;
+#endif
int err;
unsigned long bus_base;
unsigned long bus_offset;
unsigned long bus_size;
+#ifdef DRM_HAS_FAULT
+ int ret = VM_FAULT_NOPAGE;
+#else
unsigned long ret = NOPFN_REFAULT;
+#endif
if (address > vma->vm_end)
+#ifdef DRM_HAS_FAULT
+ return VM_FAULT_SIGBUS;
+#else
return NOPFN_SIGBUS;
+#endif
dev = bo->dev;
err = drm_bo_read_lock(&dev->bm.bm_lock, 1);
if (err)
+#ifdef DRM_HAS_FAULT
+ return VM_FAULT_NOPAGE;
+#else
return NOPFN_REFAULT;
+#endif
err = mutex_lock_interruptible(&bo->mutex);
if (err) {
drm_bo_read_unlock(&dev->bm.bm_lock);
+#ifdef DRM_HAS_FAULT
+ return VM_FAULT_NOPAGE;
+#else
return NOPFN_REFAULT;
+#endif
}
err = drm_bo_wait(bo, 0, 1, 0, 1);
if (err) {
+#ifdef DRM_HAS_FAULT
+ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
+#else
ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT;
+#endif
bo->priv_flags &= ~_DRM_BO_FLAG_UNLOCKED;
goto out_unlock;
}
@@ -748,7 +776,11 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
DRM_BO_FLAG_FORCE_MAPPABLE;
err = drm_bo_move_buffer(bo, new_flags, 0, 0);
if (err) {
+#ifdef DRM_HAS_FAULT
+ ret = (err != -EAGAIN) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE;
+#else
ret = (err != -EAGAIN) ? NOPFN_SIGBUS : NOPFN_REFAULT;
+#endif
goto out_unlock;
}
}
@@ -757,11 +789,19 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
&bus_size);
if (err) {
+#ifdef DRM_HAS_FAULT
+ ret = VM_FAULT_SIGBUS;
+#else
ret = NOPFN_SIGBUS;
+#endif
goto out_unlock;
}
+#ifdef DRM_HAS_FAULT
+ page_offset = 0 >> PAGE_SHIFT;
+#else
page_offset = (address - vma->vm_start) >> PAGE_SHIFT;
+#endif
if (bus_size) {
struct drm_mem_type_manager *man = &dev->bm.man[bo->mem.mem_type];
@@ -774,7 +814,11 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
drm_ttm_fixup_caching(ttm);
page = drm_ttm_get_page(ttm, page_offset);
if (!page) {
+#ifdef DRM_HAS_FAULT
+ ret = VM_FAULT_OOM;
+#else
ret = NOPFN_OOM;
+#endif
goto out_unlock;
}
pfn = page_to_pfn(page);
@@ -785,7 +829,11 @@ static unsigned long drm_bo_vm_nopfn(struct vm_area_struct *vma,
err = vm_insert_pfn(vma, address, pfn);
if (err) {
+#ifdef DRM_HAS_FAULT
+ ret = (err != -EAGAIN) ? VM_FAULT_OOM : VM_FAULT_NOPAGE;
+#else
ret = (err != -EAGAIN) ? NOPFN_OOM : NOPFN_REFAULT;
+#endif
goto out_unlock;
}
out_unlock:
@@ -848,6 +896,9 @@ static void drm_bo_vm_close(struct vm_area_struct *vma)
}
static struct vm_operations_struct drm_bo_vm_ops = {
+#ifdef DRM_HAS_FAULT
+ .fault = drm_bo_vm_fault,
+#else
#ifdef DRM_FULL_MM_COMPAT
.nopfn = drm_bo_vm_nopfn,
#else
@@ -857,6 +908,7 @@ static struct vm_operations_struct drm_bo_vm_ops = {
.nopage = drm_bo_vm_nopage,
#endif
#endif
+#endif
.open = drm_bo_vm_open,
.close = drm_bo_vm_close,
};
--
1.5.4.5
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel