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

Reply via email to