summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/bufs.c5
-rw-r--r--linux/drm.h7
-rw-r--r--linux/drmP.h91
-rw-r--r--linux/fops.c11
-rw-r--r--linux/lists.c35
-rw-r--r--linux/lock.c34
-rw-r--r--linux/memory.c21
-rw-r--r--linux/proc.c7
-rw-r--r--linux/vm.c65
9 files changed, 187 insertions, 89 deletions
diff --git a/linux/bufs.c b/linux/bufs.c
index e9879099..780c4fb6 100644
--- a/linux/bufs.c
+++ b/linux/bufs.c
@@ -1,6 +1,6 @@
/* bufs.c -- IOCTLs to manage buffers -*- linux-c -*-
* Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 22:48:10 1999 by faith@precisioninsight.com
+ * Revised: Fri Dec 3 12:11:11 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -89,10 +89,11 @@ int drm_addmap(struct inode *inode, struct file *filp, unsigned int cmd,
case _DRM_SHM:
- DRM_DEBUG("%ld %d\n", map->size, drm_order(map->size));
map->handle = (void *)drm_alloc_pages(drm_order(map->size)
- PAGE_SHIFT,
DRM_MEM_SAREA);
+ DRM_DEBUG("%ld %d %p\n", map->size, drm_order(map->size),
+ map->handle);
if (!map->handle) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -ENOMEM;
diff --git a/linux/drm.h b/linux/drm.h
index 324e2002..320db51e 100644
--- a/linux/drm.h
+++ b/linux/drm.h
@@ -1,6 +1,6 @@
/* drm.h -- Header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 13:08:18 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 17:11:19 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All rights reserved.
@@ -26,7 +26,10 @@
*
* $PI: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.46 1999/08/20 20:00:53 faith Exp $
* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h,v 1.1 1999/09/25 14:37:58 dawes Exp $
- *
+ *
+ * Acknowledgements:
+ * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic cmpxchg.
+ *
*/
#ifndef _DRM_H_
diff --git a/linux/drmP.h b/linux/drmP.h
index 37b9d053..966e6e05 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -1,6 +1,6 @@
/* drmP.h -- Private header for Direct Rendering Manager -*- linux-c -*-
* Created: Mon Jan 4 10:05:05 1999 by faith@precisioninsight.com
- * Revised: Tue Oct 12 08:51:07 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 16:06:49 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All rights reserved.
@@ -83,33 +83,77 @@
#define DRM_MEM_BUFLISTS 14
/* Backward compatibility section */
+ /* _PAGE_WT changed to _PAGE_PWT in 2.2.6 */
#ifndef _PAGE_PWT
- /* The name of _PAGE_WT was changed to
- _PAGE_PWT in Linux 2.2.6 */
#define _PAGE_PWT _PAGE_WT
#endif
- /* Wait queue declarations changes in 2.3.1 */
+ /* Wait queue declarations changed in 2.3.1 */
#ifndef DECLARE_WAITQUEUE
#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = { c, NULL }
typedef struct wait_queue *wait_queue_head_t;
#define init_waitqueue_head(q) *q = NULL;
#endif
-#define __drm_dummy_lock(lock) (*(__volatile__ unsigned int *)lock)
-#define _DRM_CAS(lock,old,new,__ret) \
- do { \
- int __dummy; /* Can't mark eax as clobbered */ \
- __asm__ __volatile__( \
- "lock ; cmpxchg %4,%1\n\t" \
- "setnz %0" \
- : "=d" (__ret), \
- "=m" (__drm_dummy_lock(lock)), \
- "=a" (__dummy) \
- : "2" (old), \
- "r" (new)); \
- } while (0)
+ /* _PAGE_4M changed to _PAGE_PSE in 2.3.23 */
+#ifndef _PAGE_PSE
+#define _PAGE_PSE _PAGE_4M
+#endif
+
+ /* vm_offset changed to vm_pgoff in 2.3.25 */
+#if LINUX_VERSION_CODE < 0x020319
+#define VM_OFFSET(vma) ((vma)->vm_offset)
+#else
+#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
+#endif
+ /* *_nopage return values defined in 2.3.26 */
+#ifndef NOPAGE_SIGBUS
+#define NOPAGE_SIGBUS 0
+#endif
+#ifndef NOPAGE_OOM
+#define NOPAGE_OOM 0
+#endif
+ /* Generic cmpxchg added in 2.3.x */
+#if CPU != 386
+#ifndef __HAVE_ARCH_CMPXCHG
+ /* Include this here so that driver can be
+ used with older kernels. */
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+ switch (size) {
+ case 1:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 2:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ case 4:
+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2"
+ : "=a"(prev)
+ : "q"(new), "m"(*__xg(ptr)), "0"(old)
+ : "memory");
+ return prev;
+ }
+ return old;
+}
+
+#define cmpxchg(ptr,o,n) \
+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
+ (unsigned long)(n),sizeof(*(ptr))))
+#endif
+#else
+ /* Compiling for a 386 proper... */
+#error DRI not supported on Intel 80386
+#endif
/* Macros to make printk easier */
#define DRM_ERROR(fmt, arg...) \
@@ -436,6 +480,7 @@ extern ssize_t drm_read(struct file *filp, char *buf, size_t count,
extern int drm_write_string(drm_device_t *dev, const char *s);
/* Mapping support (vm.c) */
+#if LINUX_VERSION_CODE < 0x020317
extern unsigned long drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
@@ -445,6 +490,18 @@ extern unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
extern unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access);
+#else
+ /* Return type changed in 2.3.23 */
+extern struct page *drm_vm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern struct page *drm_vm_shm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+extern struct page *drm_vm_dma_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access);
+#endif
extern void drm_vm_open(struct vm_area_struct *vma);
extern void drm_vm_close(struct vm_area_struct *vma);
extern int drm_mmap_dma(struct file *filp,
diff --git a/linux/fops.c b/linux/fops.c
index 403a19bb..47eacb83 100644
--- a/linux/fops.c
+++ b/linux/fops.c
@@ -1,6 +1,6 @@
/* fops.c -- File operations for DRM -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
- * Revised: Tue Oct 12 08:48:59 1999 by faith@precisioninsight.com
+ * Revised: Fri Dec 3 10:26:26 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -75,8 +75,8 @@ int drm_flush(struct file *filp)
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
- DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d, f_count = %d\n",
- current->pid, dev->device, dev->open_count, filp->f_count);
+ DRM_DEBUG("pid = %d, device = 0x%x, open_count = %d\n",
+ current->pid, dev->device, dev->open_count);
return 0;
}
@@ -211,7 +211,12 @@ int drm_write_string(drm_device_t *dev, const char *s)
send -= count;
}
+#if LINUX_VERSION_CODE < 0x020315
if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO);
+#else
+ /* Parameter added in 2.3.21 */
+ if (dev->buf_async) kill_fasync(dev->buf_async, SIGIO, POLL_IN);
+#endif
DRM_DEBUG("waking\n");
wake_up_interruptible(&dev->buf_readers);
return 0;
diff --git a/linux/lists.c b/linux/lists.c
index 3d1263d0..b84561f2 100644
--- a/linux/lists.c
+++ b/linux/lists.c
@@ -1,6 +1,6 @@
/* lists.c -- Buffer list handling routines -*- linux-c -*-
* Created: Mon Apr 19 20:54:22 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 09:27:01 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -130,11 +130,9 @@ int drm_freelist_destroy(drm_freelist_t *bl)
int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
{
- unsigned int old;
- unsigned int new;
- char failed;
+ drm_buf_t *old, *prev;
int count = 0;
- drm_device_dma_t *dma = dev->dma;
+ drm_device_dma_t *dma = dev->dma;
if (!dma) {
DRM_ERROR("No DMA support\n");
@@ -155,15 +153,14 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
#endif
buf->list = DRM_LIST_FREE;
do {
- old = (unsigned long)bl->next;
- buf->next = (void *)old;
- new = (unsigned long)buf;
- _DRM_CAS(&bl->next, old, new, failed);
+ old = bl->next;
+ bl->next = old;
+ prev = cmpxchg(&bl->next, old, buf);
if (++count > DRM_LOOPING_LIMIT) {
DRM_ERROR("Looping\n");
return 1;
}
- } while (failed);
+ } while (prev != old);
atomic_inc(&bl->count);
if (atomic_read(&bl->count) > dma->buf_count) {
DRM_ERROR("%d of %d buffers free after addition of %d\n",
@@ -180,9 +177,7 @@ int drm_freelist_put(drm_device_t *dev, drm_freelist_t *bl, drm_buf_t *buf)
static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
{
- unsigned int old;
- unsigned int new;
- char failed;
+ drm_buf_t *old, *new, *prev;
drm_buf_t *buf;
int count = 0;
@@ -190,20 +185,18 @@ static drm_buf_t *drm_freelist_try(drm_freelist_t *bl)
/* Get buffer */
do {
- old = (unsigned int)bl->next;
- if (!old) {
- return NULL;
- }
- new = (unsigned long)bl->next->next;
- _DRM_CAS(&bl->next, old, new, failed);
+ old = bl->next;
+ if (!old) return NULL;
+ new = bl->next->next;
+ prev = cmpxchg(&bl->next, old, new);
if (++count > DRM_LOOPING_LIMIT) {
DRM_ERROR("Looping\n");
return NULL;
}
- } while (failed);
+ } while (prev != old);
atomic_dec(&bl->count);
- buf = (drm_buf_t *)old;
+ buf = old;
buf->next = NULL;
buf->list = DRM_LIST_NONE;
DRM_DEBUG("%d, count = %d, wfh = %d, w%d, p%d\n",
diff --git a/linux/lock.c b/linux/lock.c
index ab1c0742..e8c1eff1 100644
--- a/linux/lock.c
+++ b/linux/lock.c
@@ -1,6 +1,6 @@
/* lock.c -- IOCTLs for locking -*- linux-c -*-
* Created: Tue Feb 2 08:37:54 1999 by faith@precisioninsight.com
- * Revised: Tue Oct 12 08:51:06 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 16:04:44 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -48,17 +48,15 @@ int drm_unblock(struct inode *inode, struct file *filp, unsigned int cmd,
int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
{
- unsigned int old;
- unsigned int new;
- char failed;
+ unsigned int old, new, prev;
DRM_DEBUG("%d attempts\n", context);
do {
old = *lock;
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
else new = context | _DRM_LOCK_HELD;
- _DRM_CAS(lock, old, new, failed);
- } while (failed);
+ prev = cmpxchg(lock, old, new);
+ } while (prev != old);
if (_DRM_LOCKING_CONTEXT(old) == context) {
if (old & _DRM_LOCK_HELD) {
if (context != DRM_KERNEL_CONTEXT) {
@@ -83,16 +81,14 @@ int drm_lock_take(__volatile__ unsigned int *lock, unsigned int context)
int drm_lock_transfer(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
- unsigned int old;
- unsigned int new;
- char failed;
+ unsigned int old, new, prev;
dev->lock.pid = 0;
do {
- old = *lock;
- new = context | _DRM_LOCK_HELD;
- _DRM_CAS(lock, old, new, failed);
- } while (failed);
+ old = *lock;
+ new = context | _DRM_LOCK_HELD;
+ prev = cmpxchg(lock, old, new);
+ } while (prev != old);
DRM_DEBUG("%d => %d\n", _DRM_LOCKING_CONTEXT(old), context);
return 1;
}
@@ -100,18 +96,16 @@ int drm_lock_transfer(drm_device_t *dev,
int drm_lock_free(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
- unsigned int old;
- unsigned int new;
- char failed;
+ unsigned int old, new, prev;
pid_t pid = dev->lock.pid;
DRM_DEBUG("%d\n", context);
dev->lock.pid = 0;
do {
- old = *lock;
- new = 0;
- _DRM_CAS(lock, old, new, failed);
- } while (failed);
+ old = *lock;
+ new = 0;
+ prev = cmpxchg(lock, old, new);
+ } while (prev != old);
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
DRM_ERROR("%d freed heavyweight lock held by %d (pid %d)\n",
context,
diff --git a/linux/memory.c b/linux/memory.c
index b3fc4fca..af8d510b 100644
--- a/linux/memory.c
+++ b/linux/memory.c
@@ -1,6 +1,6 @@
/* memory.c -- Memory management wrappers for DRM -*- linux-c -*-
* Created: Thu Feb 4 14:00:34 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 13:04:33 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 10:28:18 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -42,7 +42,7 @@ typedef struct drm_mem_stats {
} drm_mem_stats_t;
static spinlock_t drm_mem_lock = SPIN_LOCK_UNLOCKED;
-static unsigned long drm_ram_available = 0;
+static unsigned long drm_ram_available = 0; /* In pages */
static unsigned long drm_ram_used = 0;
static drm_mem_stats_t drm_mem_stats[] = {
[DRM_MEM_DMA] = { "dmabufs" },
@@ -77,7 +77,12 @@ void drm_mem_init(void)
}
si_meminfo(&si);
+#if LINUX_VERSION_CODE < 0x020317
+ /* Changed to page count in 2.3.23 */
+ drm_ram_available = si.totalram >> PAGE_SHIFT;
+#else
drm_ram_available = si.totalram;
+#endif
drm_ram_used = 0;
}
@@ -95,10 +100,11 @@ static int _drm_mem_info(char *buf, char **start, off_t offset, int len,
" | outstanding \n");
DRM_PROC_PRINT("type alloc freed fail bytes freed"
" | allocs bytes\n\n");
- DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
- "system", 0, 0, 0, drm_ram_available);
- DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu |\n",
- "locked", 0, 0, 0, drm_ram_used);
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
+ "system", 0, 0, 0,
+ drm_ram_available << (PAGE_SHIFT - 10));
+ DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
+ "locked", 0, 0, 0, drm_ram_used >> 10);
DRM_PROC_PRINT("\n");
for (pt = drm_mem_stats; pt->name; pt++) {
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
@@ -207,7 +213,8 @@ unsigned long drm_alloc_pages(int order, int area)
unsigned int sz;
spin_lock(&drm_mem_lock);
- if (drm_ram_used > +(DRM_RAM_PERCENT * drm_ram_available) / 100) {
+ if ((drm_ram_used >> PAGE_SHIFT)
+ > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
spin_unlock(&drm_mem_lock);
return 0;
}
diff --git a/linux/proc.c b/linux/proc.c
index 0883d718..33a5b20e 100644
--- a/linux/proc.c
+++ b/linux/proc.c
@@ -1,6 +1,6 @@
/* proc.c -- /proc support for DRM -*- linux-c -*-
* Created: Mon Jan 11 09:48:47 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 11:31:48 1999 by faith@precisioninsight.com
+ * Revised: Fri Dec 3 09:44:16 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -382,7 +382,8 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
vma->vm_flags & VM_LOCKED ? 'l' : '-',
vma->vm_flags & VM_IO ? 'i' : '-',
- vma->vm_offset );
+ VM_OFFSET(vma));
+
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
@@ -393,7 +394,7 @@ static int _drm_vma_info(char *buf, char **start, off_t offset, int len,
pgprot & _PAGE_PCD ? 'u' : 'c',
pgprot & _PAGE_ACCESSED ? 'a' : '-',
pgprot & _PAGE_DIRTY ? 'd' : '-',
- pgprot & _PAGE_4M ? 'm' : 'k',
+ pgprot & _PAGE_PSE ? 'm' : 'k',
pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
#endif
DRM_PROC_PRINT("\n");
diff --git a/linux/vm.c b/linux/vm.c
index 89803784..d649a6e7 100644
--- a/linux/vm.c
+++ b/linux/vm.c
@@ -1,6 +1,6 @@
/* vm.c -- Memory mapping for DRM -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by faith@precisioninsight.com
- * Revised: Fri Aug 20 22:48:11 1999 by faith@precisioninsight.com
+ * Revised: Mon Dec 6 16:54:35 1999 by faith@precisioninsight.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* All Rights Reserved.
@@ -50,18 +50,32 @@ struct vm_operations_struct drm_vm_dma_ops = {
close: drm_vm_close,
};
+#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
+#else
+ /* Return type changed in 2.3.23 */
+struct page *drm_vm_nopage(struct vm_area_struct *vma,
+ unsigned long address,
+ int write_access)
+#endif
{
DRM_DEBUG("0x%08lx, %d\n", address, write_access);
- return 0; /* Disallow mremap */
+ return NOPAGE_SIGBUS; /* Disallow mremap */
}
+#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_shm_nopage(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(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;
@@ -69,8 +83,8 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
unsigned long offset;
unsigned long page;
- if (address > vma->vm_end) return 0; /* Disallow mremap */
- if (!dev->lock.hw_lock) return 0; /* Nothing allocated */
+ if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!dev->lock.hw_lock) return NOPAGE_OOM; /* Nothing allocated */
offset = address - vma->vm_start;
page = offset >> PAGE_SHIFT;
@@ -78,12 +92,23 @@ unsigned long drm_vm_shm_nopage(struct vm_area_struct *vma,
atomic_inc(&mem_map[MAP_NR(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);
+#endif
}
+#if LINUX_VERSION_CODE < 0x020317
unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long address,
int write_access)
+#else
+ /* Return type changed in 2.3.23 */
+struct page *drm_vm_dma_nopage(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;
@@ -92,17 +117,21 @@ unsigned long drm_vm_dma_nopage(struct vm_area_struct *vma,
unsigned long offset;
unsigned long page;
- if (!dma) return 0; /* Error */
- if (address > vma->vm_end) return 0; /* Disallow mremap */
- if (!dma->pagelist) return 0; /* Nothing allocated */
+ if (!dma) return NOPAGE_SIGBUS; /* Error */
+ if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
+ if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
- offset = address - vma->vm_start; /* vm_offset should be 0 */
+ 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 */
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);
+#endif
}
void drm_vm_open(struct vm_area_struct *vma)
@@ -169,7 +198,7 @@ int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
unsigned long length = vma->vm_end - vma->vm_start;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, vma->vm_offset);
+ vma->vm_start, vma->vm_end, VM_OFFSET(vma));
/* Length must match exact page count */
if ((length >> PAGE_SHIFT) != dma->page_count) return -EINVAL;
@@ -195,9 +224,9 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
int i;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
- vma->vm_start, vma->vm_end, vma->vm_offset);
+ vma->vm_start, vma->vm_end, VM_OFFSET(vma));
- if (!vma->vm_offset) return drm_mmap_dma(filp, vma);
+ if (!VM_OFFSET(vma)) return drm_mmap_dma(filp, vma);
/* A sequential search of a linked list is
fine here because: 1) there will only be
@@ -208,7 +237,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
bit longer. */
for (i = 0; i < dev->map_count; i++) {
map = dev->maplist[i];
- if (map->offset == vma->vm_offset) break;
+ if (map->offset == VM_OFFSET(vma)) break;
}
if (i >= dev->map_count) return -EINVAL;
@@ -222,7 +251,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
switch (map->type) {
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
- if (vma->vm_offset >= __pa(high_memory)) {
+ if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__)
if (boot_cpu_data.x86 > 3) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
@@ -232,7 +261,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_IO; /* not in core dump */
}
if (remap_page_range(vma->vm_start,
- vma->vm_offset,
+ VM_OFFSET(vma),
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
return -EAGAIN;
@@ -249,7 +278,15 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
}
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
if (map->flags & _DRM_READ_ONLY) {
+#if defined(__i386__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
+#else
+ /* Ye gads this is ugly. With more thought
+ we could move this up higher and use
+ `protection_map' instead. */
+ vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
+ __pte(pgprot_val(vma->vm_page_prot)))));
+#endif
}