patch-2.4.0-test6 linux/drivers/char/drm/vm.c

Next file: linux/drivers/char/ftape/lowlevel/ftape-buffer.c
Previous file: linux/drivers/char/drm/tdfx_drv.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test5/linux/drivers/char/drm/vm.c linux/drivers/char/drm/vm.c
@@ -31,8 +31,6 @@
 
 #define __NO_VERSION__
 #include "drmP.h"
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
 
 struct vm_operations_struct   drm_vm_ops = {
 	nopage:	 drm_vm_nopage,
@@ -46,6 +44,12 @@
 	close:	 drm_vm_close,
 };
 
+struct vm_operations_struct   drm_vm_shm_lock_ops = {
+	nopage:	 drm_vm_shm_nopage_lock,
+	open:	 drm_vm_open,
+	close:	 drm_vm_close,
+};
+
 struct vm_operations_struct   drm_vm_dma_ops = {
 	nopage:	 drm_vm_dma_nopage,
 	open:	 drm_vm_open,
@@ -79,6 +83,40 @@
 			       int write_access)
 #endif
 {
+#if LINUX_VERSION_CODE >= 0x020300
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_private_data;
+#else
+	drm_map_t	 *map	 = (drm_map_t *)vma->vm_pte;
+#endif
+	unsigned long	 physical;
+	unsigned long	 offset;
+
+	if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+	if (!map)    		   return NOPAGE_OOM;  /* Nothing allocated */
+
+	offset	 = address - vma->vm_start;
+	physical = (unsigned long)map->handle + offset;
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
+
+	DRM_DEBUG("0x%08lx => 0x%08lx\n", address, physical);
+#if LINUX_VERSION_CODE < 0x020317
+	return physical;
+#else
+	return virt_to_page(physical);
+#endif
+}
+
+#if LINUX_VERSION_CODE < 0x020317
+unsigned long drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+				     unsigned long address,
+				     int write_access)
+#else
+				/* Return type changed in 2.3.23 */
+struct page *drm_vm_shm_nopage_lock(struct vm_area_struct *vma,
+				    unsigned long address,
+				    int write_access)
+#endif
+{
 	drm_file_t	 *priv	 = vma->vm_file->private_data;
 	drm_device_t	 *dev	 = priv->dev;
 	unsigned long	 physical;
@@ -91,13 +129,13 @@
 	offset	 = address - vma->vm_start;
 	page	 = offset >> PAGE_SHIFT;
 	physical = (unsigned long)dev->lock.hw_lock + offset;
-	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
 
 	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
 #if LINUX_VERSION_CODE < 0x020317
 	return physical;
 #else
-	return mem_map + MAP_NR(physical);
+	return virt_to_page(physical);
 #endif
 }
 
@@ -126,13 +164,13 @@
 	offset	 = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
 	page	 = offset >> PAGE_SHIFT;
 	physical = dma->pagelist[page] + (offset & (~PAGE_MASK));
-	atomic_inc(&mem_map[MAP_NR(physical)].count); /* Dec. by kernel */
+	atomic_inc(&virt_to_page(physical)->count); /* Dec. by kernel */
 
 	DRM_DEBUG("0x%08lx (page %lu) => 0x%08lx\n", address, page, physical);
 #if LINUX_VERSION_CODE < 0x020317
 	return physical;
 #else
-	return mem_map + MAP_NR(physical);
+	return virt_to_page(physical);
 #endif
 }
 
@@ -147,6 +185,11 @@
 	DRM_DEBUG("0x%08lx,0x%08lx\n",
 		  vma->vm_start, vma->vm_end - vma->vm_start);
 	atomic_inc(&dev->vma_count);
+#if LINUX_VERSION_CODE < 0x020333
+				/* The map can exist after the fd is closed. */
+	MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
+
 
 #if DRM_DEBUG_CODE
 	vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
@@ -171,6 +214,9 @@
 
 	DRM_DEBUG("0x%08lx,0x%08lx\n",
 		  vma->vm_start, vma->vm_end - vma->vm_start);
+#if LINUX_VERSION_CODE < 0x020333
+	MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */
+#endif
 	atomic_dec(&dev->vma_count);
 
 #if DRM_DEBUG_CODE
@@ -292,7 +338,17 @@
 		vma->vm_ops = &drm_vm_ops;
 		break;
 	case _DRM_SHM:
-		vma->vm_ops = &drm_vm_shm_ops;
+		if (map->flags & _DRM_CONTAINS_LOCK)
+			vma->vm_ops = &drm_vm_shm_lock_ops;
+		else {
+			vma->vm_ops = &drm_vm_shm_ops;
+#if LINUX_VERSION_CODE >= 0x020300
+			vma->vm_private_data = (void *)map;
+#else
+			vma->vm_pte = (unsigned long)map;
+#endif
+		}
+
 				/* Don't let this area swap.  Change when
 				   DRM_KERNEL advisory is supported. */
 		vma->vm_flags |= VM_LOCKED;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)