aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-08-05 08:11:22 -0400
committerDave Airlie <airlied@linux.ie>2005-08-05 08:11:22 -0400
commitd1f2b55ad2c11f46e30547a9f7754e99b478348e (patch)
treecabf9060c4f6cb419c7ed7fdcbcc6b6a91a83ac1 /drivers/char/drm
parentc73681e77b40697d16ada777adf2c6dc4db05917 (diff)
drm: updated DRM map patch for 32/64 bit systems
I basically combined Paul's patches with additions that I had made for PCI scatter gather. I also tried more carefully to avoid problems with the same token assigned multiple times while trying to use the base address in the token if possible to gain as much backward compatibility as possible for broken DRI clients. From: Paul Mackerras <paulus@samba.org> and Egbert Eich <eich@suse.de> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r--drivers/char/drm/drmP.h14
-rw-r--r--drivers/char/drm/drm_bufs.c81
-rw-r--r--drivers/char/drm/drm_context.c15
-rw-r--r--drivers/char/drm/drm_ioctl.c2
-rw-r--r--drivers/char/drm/drm_proc.c4
-rw-r--r--drivers/char/drm/drm_scatter.c11
-rw-r--r--drivers/char/drm/drm_vm.c20
-rw-r--r--drivers/char/drm/ffb_drv.c5
-rw-r--r--drivers/char/drm/i810_dma.c1
-rw-r--r--drivers/char/drm/i830_dma.c1
-rw-r--r--drivers/char/drm/mga_dma.c1
-rw-r--r--drivers/char/drm/mga_drm.h2
-rw-r--r--drivers/char/drm/mga_ioc32.c67
-rw-r--r--drivers/char/drm/r128_cce.c6
-rw-r--r--drivers/char/drm/radeon_cp.c1
15 files changed, 177 insertions, 54 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index fb2af9279148..0a4358996970 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -539,6 +539,7 @@ typedef struct drm_dma_handle {
539typedef struct drm_map_list { 539typedef struct drm_map_list {
540 struct list_head head; /**< list head */ 540 struct list_head head; /**< list head */
541 drm_map_t *map; /**< mapping */ 541 drm_map_t *map; /**< mapping */
542 unsigned int user_token;
542} drm_map_list_t; 543} drm_map_list_t;
543 544
544typedef drm_map_t drm_local_map_t; 545typedef drm_map_t drm_local_map_t;
@@ -759,6 +760,7 @@ typedef struct drm_device {
759 760
760 struct drm_driver *driver; 761 struct drm_driver *driver;
761 drm_local_map_t *agp_buffer_map; 762 drm_local_map_t *agp_buffer_map;
763 unsigned int agp_buffer_token;
762 drm_head_t primary; /**< primary screen head */ 764 drm_head_t primary; /**< primary screen head */
763} drm_device_t; 765} drm_device_t;
764 766
@@ -1048,16 +1050,12 @@ static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_devi
1048 drm_ioremapfree( map->handle, map->size, dev ); 1050 drm_ioremapfree( map->handle, map->size, dev );
1049} 1051}
1050 1052
1051static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset) 1053static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned int token)
1052{ 1054{
1053 struct list_head *_list; 1055 drm_map_list_t *_entry;
1054 list_for_each( _list, &dev->maplist->head ) { 1056 list_for_each_entry(_entry, &dev->maplist->head, head)
1055 drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head ); 1057 if (_entry->user_token == token)
1056 if ( _entry->map &&
1057 _entry->map->offset == offset ) {
1058 return _entry->map; 1058 return _entry->map;
1059 }
1060 }
1061 return NULL; 1059 return NULL;
1062} 1060}
1063 1061
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index fcc8d244f46f..d1e0b106c261 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -64,13 +64,41 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
64 return NULL; 64 return NULL;
65} 65}
66 66
67#ifdef CONFIG_COMPAT
68/* 67/*
69 * Used to allocate 32-bit handles for _DRM_SHM regions 68 * Used to allocate 32-bit handles for mappings.
70 * The 0x10000000 value is chosen to be out of the way of
71 * FB/register and GART physical addresses.
72 */ 69 */
73static unsigned int map32_handle = 0x10000000; 70#define START_RANGE 0x10000000
71#define END_RANGE 0x40000000
72
73#ifdef _LP64
74static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev)
75{
76 static unsigned int map32_handle = START_RANGE;
77 unsigned int hash;
78
79 if (lhandle & 0xffffffff00000000) {
80 hash = map32_handle;
81 map32_handle += PAGE_SIZE;
82 if (map32_handle > END_RANGE)
83 map32_handle = START_RANGE;
84 } else
85 hash = lhandle;
86
87 while (1) {
88 drm_map_list_t *_entry;
89 list_for_each_entry(_entry, &dev->maplist->head,head) {
90 if (_entry->user_token == hash)
91 break;
92 }
93 if (&_entry->head == &dev->maplist->head)
94 return hash;
95
96 hash += PAGE_SIZE;
97 map32_handle += PAGE_SIZE;
98 }
99}
100#else
101# define HandleID(x,dev) (unsigned int)(x)
74#endif 102#endif
75 103
76/** 104/**
@@ -198,7 +226,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
198 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 226 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
199 return -EINVAL; 227 return -EINVAL;
200 } 228 }
201 map->offset += dev->sg->handle; 229 map->offset += (unsigned long)dev->sg->virtual;
202 break; 230 break;
203 case _DRM_CONSISTENT: 231 case _DRM_CONSISTENT:
204 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G, 232 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
@@ -229,12 +257,11 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
229 257
230 down(&dev->struct_sem); 258 down(&dev->struct_sem);
231 list_add(&list->head, &dev->maplist->head); 259 list_add(&list->head, &dev->maplist->head);
232#ifdef CONFIG_COMPAT 260 /* Assign a 32-bit handle */
233 /* Assign a 32-bit handle for _DRM_SHM mappings */
234 /* We do it here so that dev->struct_sem protects the increment */ 261 /* We do it here so that dev->struct_sem protects the increment */
235 if (map->type == _DRM_SHM) 262 list->user_token = HandleID(map->type==_DRM_SHM
236 map->offset = map32_handle += PAGE_SIZE; 263 ? (unsigned long)map->handle
237#endif 264 : map->offset, dev);
238 up(&dev->struct_sem); 265 up(&dev->struct_sem);
239 266
240 *map_ptr = map; 267 *map_ptr = map;
@@ -251,6 +278,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
251 drm_map_t *map_ptr; 278 drm_map_t *map_ptr;
252 drm_map_t __user *argp = (void __user *)arg; 279 drm_map_t __user *argp = (void __user *)arg;
253 int err; 280 int err;
281 unsigned long handle = 0;
254 282
255 if (!(filp->f_mode & 3)) 283 if (!(filp->f_mode & 3))
256 return -EACCES; /* Require read/write */ 284 return -EACCES; /* Require read/write */
@@ -259,22 +287,29 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
259 return -EFAULT; 287 return -EFAULT;
260 } 288 }
261 289
262 err = drm_addmap( dev, map.offset, map.size, map.type, map.flags, 290 err = drm_addmap(dev, map.offset, map.size, map.type, map.flags,
263 &map_ptr ); 291 &map_ptr);
264 292
265 if (err) { 293 if (err) {
266 return err; 294 return err;
267 } 295 }
268 296
269 if (copy_to_user(argp, map_ptr, sizeof(*map_ptr))) 297 {
270 return -EFAULT; 298 drm_map_list_t *_entry;
271 if (map_ptr->type != _DRM_SHM) { 299 list_for_each_entry(_entry, &dev->maplist->head, head) {
272 if (copy_to_user(&argp->handle, &map_ptr->offset, 300 if (_entry->map == map_ptr)
273 sizeof(map_ptr->offset))) 301 handle = _entry->user_token;
302 }
303 if (!handle)
274 return -EFAULT; 304 return -EFAULT;
275 } 305 }
306
307 if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
308 return -EFAULT;
309 if (put_user(handle, &argp->handle))
310 return -EFAULT;
276 return 0; 311 return 0;
277} 312 }
278 313
279 314
280/** 315/**
@@ -388,7 +423,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
388 drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head); 423 drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
389 424
390 if (r_list->map && 425 if (r_list->map &&
391 r_list->map->handle == request.handle && 426 r_list->user_token == (unsigned long) request.handle &&
392 r_list->map->flags & _DRM_REMOVABLE) { 427 r_list->map->flags & _DRM_REMOVABLE) {
393 map = r_list->map; 428 map = r_list->map;
394 break; 429 break;
@@ -939,7 +974,8 @@ static int drm_addbufs_sg(drm_device_t *dev, drm_buf_desc_t *request)
939 974
940 buf->offset = (dma->byte_count + offset); 975 buf->offset = (dma->byte_count + offset);
941 buf->bus_address = agp_offset + offset; 976 buf->bus_address = agp_offset + offset;
942 buf->address = (void *)(agp_offset + offset + dev->sg->handle); 977 buf->address = (void *)(agp_offset + offset
978 + (unsigned long)dev->sg->virtual);
943 buf->next = NULL; 979 buf->next = NULL;
944 buf->waiting = 0; 980 buf->waiting = 0;
945 buf->pending = 0; 981 buf->pending = 0;
@@ -1456,6 +1492,7 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
1456 || (drm_core_check_feature(dev, DRIVER_FB_DMA) 1492 || (drm_core_check_feature(dev, DRIVER_FB_DMA)
1457 && (dma->flags & _DRM_DMA_USE_FB))) { 1493 && (dma->flags & _DRM_DMA_USE_FB))) {
1458 drm_map_t *map = dev->agp_buffer_map; 1494 drm_map_t *map = dev->agp_buffer_map;
1495 unsigned long token = dev->agp_buffer_token;
1459 1496
1460 if ( !map ) { 1497 if ( !map ) {
1461 retcode = -EINVAL; 1498 retcode = -EINVAL;
@@ -1470,7 +1507,7 @@ int drm_mapbufs( struct inode *inode, struct file *filp,
1470 virtual = do_mmap( filp, 0, map->size, 1507 virtual = do_mmap( filp, 0, map->size,
1471 PROT_READ | PROT_WRITE, 1508 PROT_READ | PROT_WRITE,
1472 MAP_SHARED, 1509 MAP_SHARED,
1473 (unsigned long)map->offset ); 1510 token );
1474#if LINUX_VERSION_CODE <= 0x020402 1511#if LINUX_VERSION_CODE <= 0x020402
1475 up( &current->mm->mmap_sem ); 1512 up( &current->mm->mmap_sem );
1476#else 1513#else
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index 5af46c9830ec..f515567e5b6f 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -212,6 +212,7 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
212 drm_ctx_priv_map_t __user *argp = (void __user *)arg; 212 drm_ctx_priv_map_t __user *argp = (void __user *)arg;
213 drm_ctx_priv_map_t request; 213 drm_ctx_priv_map_t request;
214 drm_map_t *map; 214 drm_map_t *map;
215 drm_map_list_t *_entry;
215 216
216 if (copy_from_user(&request, argp, sizeof(request))) 217 if (copy_from_user(&request, argp, sizeof(request)))
217 return -EFAULT; 218 return -EFAULT;
@@ -225,7 +226,17 @@ int drm_getsareactx(struct inode *inode, struct file *filp,
225 map = dev->context_sareas[request.ctx_id]; 226 map = dev->context_sareas[request.ctx_id];
226 up(&dev->struct_sem); 227 up(&dev->struct_sem);
227 228
228 request.handle = (void *) map->offset; 229 request.handle = 0;
230 list_for_each_entry(_entry, &dev->maplist->head,head) {
231 if (_entry->map == map) {
232 request.handle = (void *)(unsigned long)_entry->user_token;
233 break;
234 }
235 }
236 if (request.handle == 0)
237 return -EINVAL;
238
239
229 if (copy_to_user(argp, &request, sizeof(request))) 240 if (copy_to_user(argp, &request, sizeof(request)))
230 return -EFAULT; 241 return -EFAULT;
231 return 0; 242 return 0;
@@ -262,7 +273,7 @@ int drm_setsareactx(struct inode *inode, struct file *filp,
262 list_for_each(list, &dev->maplist->head) { 273 list_for_each(list, &dev->maplist->head) {
263 r_list = list_entry(list, drm_map_list_t, head); 274 r_list = list_entry(list, drm_map_list_t, head);
264 if (r_list->map 275 if (r_list->map
265 && r_list->map->offset == (unsigned long) request.handle) 276 && r_list->user_token == (unsigned long) request.handle)
266 goto found; 277 goto found;
267 } 278 }
268bad: 279bad:
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
index 39afda0ccabe..d2ed3ba5aca9 100644
--- a/drivers/char/drm/drm_ioctl.c
+++ b/drivers/char/drm/drm_ioctl.c
@@ -208,7 +208,7 @@ int drm_getmap( struct inode *inode, struct file *filp,
208 map.size = r_list->map->size; 208 map.size = r_list->map->size;
209 map.type = r_list->map->type; 209 map.type = r_list->map->type;
210 map.flags = r_list->map->flags; 210 map.flags = r_list->map->flags;
211 map.handle = r_list->map->handle; 211 map.handle = (void *)(unsigned long) r_list->user_token;
212 map.mtrr = r_list->map->mtrr; 212 map.mtrr = r_list->map->mtrr;
213 up(&dev->struct_sem); 213 up(&dev->struct_sem);
214 214
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
index f4154cc71abb..32d2bb99462c 100644
--- a/drivers/char/drm/drm_proc.c
+++ b/drivers/char/drm/drm_proc.c
@@ -235,13 +235,13 @@ static int drm__vm_info(char *buf, char **start, off_t offset, int request,
235 type = "??"; 235 type = "??";
236 else 236 else
237 type = types[map->type]; 237 type = types[map->type];
238 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", 238 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08x ",
239 i, 239 i,
240 map->offset, 240 map->offset,
241 map->size, 241 map->size,
242 type, 242 type,
243 map->flags, 243 map->flags,
244 (unsigned long)map->handle); 244 r_list->user_token);
245 if (map->mtrr < 0) { 245 if (map->mtrr < 0) {
246 DRM_PROC_PRINT("none\n"); 246 DRM_PROC_PRINT("none\n");
247 } else { 247 } else {
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
index 54fddb6ea2d1..ed267d49bc6a 100644
--- a/drivers/char/drm/drm_scatter.c
+++ b/drivers/char/drm/drm_scatter.c
@@ -61,6 +61,12 @@ void drm_sg_cleanup( drm_sg_mem_t *entry )
61 DRM_MEM_SGLISTS ); 61 DRM_MEM_SGLISTS );
62} 62}
63 63
64#ifdef _LP64
65# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
66#else
67# define ScatterHandle(x) (unsigned int)(x)
68#endif
69
64int drm_sg_alloc( struct inode *inode, struct file *filp, 70int drm_sg_alloc( struct inode *inode, struct file *filp,
65 unsigned int cmd, unsigned long arg ) 71 unsigned int cmd, unsigned long arg )
66{ 72{
@@ -133,12 +139,13 @@ int drm_sg_alloc( struct inode *inode, struct file *filp,
133 */ 139 */
134 memset( entry->virtual, 0, pages << PAGE_SHIFT ); 140 memset( entry->virtual, 0, pages << PAGE_SHIFT );
135 141
136 entry->handle = (unsigned long)entry->virtual; 142 entry->handle = ScatterHandle((unsigned long)entry->virtual);
137 143
138 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle ); 144 DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
139 DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual ); 145 DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
140 146
141 for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) { 147 for (i = (unsigned long)entry->virtual, j = 0; j < pages;
148 i += PAGE_SIZE, j++) {
142 entry->pagelist[j] = vmalloc_to_page((void *)i); 149 entry->pagelist[j] = vmalloc_to_page((void *)i);
143 if (!entry->pagelist[j]) 150 if (!entry->pagelist[j])
144 goto failed; 151 goto failed;
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
index 675d2397def9..99b5c86f7513 100644
--- a/drivers/char/drm/drm_vm.c
+++ b/drivers/char/drm/drm_vm.c
@@ -73,12 +73,13 @@ static __inline__ struct page *drm_do_vm_nopage(struct vm_area_struct *vma,
73 r_list = list_entry(list, drm_map_list_t, head); 73 r_list = list_entry(list, drm_map_list_t, head);
74 map = r_list->map; 74 map = r_list->map;
75 if (!map) continue; 75 if (!map) continue;
76 if (map->offset == VM_OFFSET(vma)) break; 76 if (r_list->user_token == VM_OFFSET(vma))
77 break;
77 } 78 }
78 79
79 if (map && map->type == _DRM_AGP) { 80 if (map && map->type == _DRM_AGP) {
80 unsigned long offset = address - vma->vm_start; 81 unsigned long offset = address - vma->vm_start;
81 unsigned long baddr = VM_OFFSET(vma) + offset; 82 unsigned long baddr = map->offset + offset;
82 struct drm_agp_mem *agpmem; 83 struct drm_agp_mem *agpmem;
83 struct page *page; 84 struct page *page;
84 85
@@ -304,7 +305,7 @@ static __inline__ struct page *drm_do_vm_sg_nopage(struct vm_area_struct *vma,
304 305
305 306
306 offset = address - vma->vm_start; 307 offset = address - vma->vm_start;
307 map_offset = map->offset - dev->sg->handle; 308 map_offset = map->offset - (unsigned long)dev->sg->virtual;
308 page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT); 309 page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
309 page = entry->pagelist[page_offset]; 310 page = entry->pagelist[page_offset];
310 get_page(page); 311 get_page(page);
@@ -568,13 +569,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
568 for performance, even if the list was a 569 for performance, even if the list was a
569 bit longer. */ 570 bit longer. */
570 list_for_each(list, &dev->maplist->head) { 571 list_for_each(list, &dev->maplist->head) {
571 unsigned long off;
572 572
573 r_list = list_entry(list, drm_map_list_t, head); 573 r_list = list_entry(list, drm_map_list_t, head);
574 map = r_list->map; 574 map = r_list->map;
575 if (!map) continue; 575 if (!map) continue;
576 off = dev->driver->get_map_ofs(map); 576 if (r_list->user_token == VM_OFFSET(vma))
577 if (off == VM_OFFSET(vma)) break; 577 break;
578 } 578 }
579 579
580 if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) 580 if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
@@ -613,7 +613,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
613 /* fall through to _DRM_FRAME_BUFFER... */ 613 /* fall through to _DRM_FRAME_BUFFER... */
614 case _DRM_FRAME_BUFFER: 614 case _DRM_FRAME_BUFFER:
615 case _DRM_REGISTERS: 615 case _DRM_REGISTERS:
616 if (VM_OFFSET(vma) >= __pa(high_memory)) { 616 if (map->offset >= __pa(high_memory)) {
617#if defined(__i386__) || defined(__x86_64__) 617#if defined(__i386__) || defined(__x86_64__)
618 if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) { 618 if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
619 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; 619 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
@@ -636,12 +636,12 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
636 offset = dev->driver->get_reg_ofs(dev); 636 offset = dev->driver->get_reg_ofs(dev);
637#ifdef __sparc__ 637#ifdef __sparc__
638 if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start, 638 if (io_remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
639 (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, 639 (map->offset + offset) >> PAGE_SHIFT,
640 vma->vm_end - vma->vm_start, 640 vma->vm_end - vma->vm_start,
641 vma->vm_page_prot)) 641 vma->vm_page_prot))
642#else 642#else
643 if (io_remap_pfn_range(vma, vma->vm_start, 643 if (io_remap_pfn_range(vma, vma->vm_start,
644 (VM_OFFSET(vma) + offset) >> PAGE_SHIFT, 644 (map->offset + offset) >> PAGE_SHIFT,
645 vma->vm_end - vma->vm_start, 645 vma->vm_end - vma->vm_start,
646 vma->vm_page_prot)) 646 vma->vm_page_prot))
647#endif 647#endif
@@ -649,7 +649,7 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
649 DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx," 649 DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
650 " offset = 0x%lx\n", 650 " offset = 0x%lx\n",
651 map->type, 651 map->type,
652 vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset); 652 vma->vm_start, vma->vm_end, map->offset + offset);
653 vma->vm_ops = &drm_vm_ops; 653 vma->vm_ops = &drm_vm_ops;
654 break; 654 break;
655 case _DRM_SHM: 655 case _DRM_SHM:
diff --git a/drivers/char/drm/ffb_drv.c b/drivers/char/drm/ffb_drv.c
index ec614fff8f04..1bd0d55ee0f0 100644
--- a/drivers/char/drm/ffb_drv.c
+++ b/drivers/char/drm/ffb_drv.c
@@ -152,14 +152,11 @@ static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
152 return NULL; 152 return NULL;
153 153
154 list_for_each(list, &dev->maplist->head) { 154 list_for_each(list, &dev->maplist->head) {
155 unsigned long uoff;
156
157 r_list = (drm_map_list_t *)list; 155 r_list = (drm_map_list_t *)list;
158 map = r_list->map; 156 map = r_list->map;
159 if (!map) 157 if (!map)
160 continue; 158 continue;
161 uoff = (map->offset & 0xffffffff); 159 if (r_list->user_token == off)
162 if (uoff == off)
163 return map; 160 return map;
164 } 161 }
165 162
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
index 0a9ac1f2e215..f9fd5abd774b 100644
--- a/drivers/char/drm/i810_dma.c
+++ b/drivers/char/drm/i810_dma.c
@@ -351,6 +351,7 @@ static int i810_dma_initialize(drm_device_t *dev,
351 DRM_ERROR("can not find mmio map!\n"); 351 DRM_ERROR("can not find mmio map!\n");
352 return -EINVAL; 352 return -EINVAL;
353 } 353 }
354 dev->agp_buffer_token = init->buffers_offset;
354 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 355 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
355 if (!dev->agp_buffer_map) { 356 if (!dev->agp_buffer_map) {
356 dev->dev_private = (void *)dev_priv; 357 dev->dev_private = (void *)dev_priv;
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
index 80d8966397c1..697cefccd007 100644
--- a/drivers/char/drm/i830_dma.c
+++ b/drivers/char/drm/i830_dma.c
@@ -358,6 +358,7 @@ static int i830_dma_initialize(drm_device_t *dev,
358 DRM_ERROR("can not find mmio map!\n"); 358 DRM_ERROR("can not find mmio map!\n");
359 return -EINVAL; 359 return -EINVAL;
360 } 360 }
361 dev->agp_buffer_token = init->buffers_offset;
361 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 362 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
362 if(!dev->agp_buffer_map) { 363 if(!dev->agp_buffer_map) {
363 dev->dev_private = (void *)dev_priv; 364 dev->dev_private = (void *)dev_priv;
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 7899e281d062..567b425b784f 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -825,6 +825,7 @@ static int mga_do_init_dma( drm_device_t *dev, drm_mga_init_t *init )
825 DRM_ERROR("failed to find primary dma region!\n"); 825 DRM_ERROR("failed to find primary dma region!\n");
826 return DRM_ERR(EINVAL); 826 return DRM_ERR(EINVAL);
827 } 827 }
828 dev->agp_buffer_token = init->buffers_offset;
828 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 829 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
829 if (!dev->agp_buffer_map) { 830 if (!dev->agp_buffer_map) {
830 DRM_ERROR("failed to find dma buffer region!\n"); 831 DRM_ERROR("failed to find dma buffer region!\n");
diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h
index 2d8aa790379e..d20aab3bd57b 100644
--- a/drivers/char/drm/mga_drm.h
+++ b/drivers/char/drm/mga_drm.h
@@ -312,7 +312,7 @@ typedef struct drm_mga_dma_bootstrap {
312 * an IOMMU) is being used for "AGP" textures. 312 * an IOMMU) is being used for "AGP" textures.
313 */ 313 */
314 /*@{*/ 314 /*@{*/
315 drm_handle_t texture_handle; /**< Handle used to map AGP textures. */ 315 unsigned long texture_handle; /**< Handle used to map AGP textures. */
316 uint32_t texture_size; /**< Size of the AGP texture region. */ 316 uint32_t texture_size; /**< Size of the AGP texture region. */
317 /*@}*/ 317 /*@}*/
318 318
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
index bc745cfa2095..77d738e75a4d 100644
--- a/drivers/char/drm/mga_ioc32.c
+++ b/drivers/char/drm/mga_ioc32.c
@@ -129,9 +129,76 @@ static int compat_mga_getparam(struct file *file, unsigned int cmd,
129 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam); 129 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
130} 130}
131 131
132typedef struct drm_mga_drm_bootstrap32 {
133 u32 texture_handle;
134 u32 texture_size;
135 u32 primary_size;
136 u32 secondary_bin_count;
137 u32 secondary_bin_size;
138 u32 agp_mode;
139 u8 agp_size;
140} drm_mga_dma_bootstrap32_t;
141
142static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
143 unsigned long arg)
144{
145 drm_mga_dma_bootstrap32_t dma_bootstrap32;
146 drm_mga_dma_bootstrap_t __user *dma_bootstrap;
147 int err;
148
149 if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
150 sizeof(dma_bootstrap32)))
151 return -EFAULT;
152
153 dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap));
154 if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap))
155 || __put_user(dma_bootstrap32.texture_handle,
156 &dma_bootstrap->texture_handle)
157 || __put_user(dma_bootstrap32.texture_size,
158 &dma_bootstrap->texture_size)
159 || __put_user(dma_bootstrap32.primary_size,
160 &dma_bootstrap->primary_size)
161 || __put_user(dma_bootstrap32.secondary_bin_count,
162 &dma_bootstrap->secondary_bin_count)
163 || __put_user(dma_bootstrap32.secondary_bin_size,
164 &dma_bootstrap->secondary_bin_size)
165 || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
166 || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
167 return -EFAULT;
168
169 err = drm_ioctl(file->f_dentry->d_inode, file,
170 DRM_IOCTL_MGA_DMA_BOOTSTRAP,
171 (unsigned long)dma_bootstrap);
172 if (err)
173 return err;
174
175 if (__get_user(dma_bootstrap32.texture_handle,
176 &dma_bootstrap->texture_handle)
177 || __get_user(dma_bootstrap32.texture_size,
178 &dma_bootstrap->texture_size)
179 || __get_user(dma_bootstrap32.primary_size,
180 &dma_bootstrap->primary_size)
181 || __get_user(dma_bootstrap32.secondary_bin_count,
182 &dma_bootstrap->secondary_bin_count)
183 || __get_user(dma_bootstrap32.secondary_bin_size,
184 &dma_bootstrap->secondary_bin_size)
185 || __get_user(dma_bootstrap32.agp_mode,
186 &dma_bootstrap->agp_mode)
187 || __get_user(dma_bootstrap32.agp_size,
188 &dma_bootstrap->agp_size))
189 return -EFAULT;
190
191 if (copy_to_user((void __user *)arg, &dma_bootstrap32,
192 sizeof(dma_bootstrap32)))
193 return -EFAULT;
194
195 return 0;
196}
197
132drm_ioctl_compat_t *mga_compat_ioctls[] = { 198drm_ioctl_compat_t *mga_compat_ioctls[] = {
133 [DRM_MGA_INIT] = compat_mga_init, 199 [DRM_MGA_INIT] = compat_mga_init,
134 [DRM_MGA_GETPARAM] = compat_mga_getparam, 200 [DRM_MGA_GETPARAM] = compat_mga_getparam,
201 [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap,
135}; 202};
136 203
137/** 204/**
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
index 08ed8d01d9d9..895152206b31 100644
--- a/drivers/char/drm/r128_cce.c
+++ b/drivers/char/drm/r128_cce.c
@@ -326,7 +326,8 @@ static void r128_cce_init_ring_buffer( drm_device_t *dev,
326 ring_start = dev_priv->cce_ring->offset - dev->agp->base; 326 ring_start = dev_priv->cce_ring->offset - dev->agp->base;
327 else 327 else
328#endif 328#endif
329 ring_start = dev_priv->cce_ring->offset - dev->sg->handle; 329 ring_start = dev_priv->cce_ring->offset -
330 (unsigned long)dev->sg->virtual;
330 331
331 R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET ); 332 R128_WRITE( R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET );
332 333
@@ -487,6 +488,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
487 r128_do_cleanup_cce( dev ); 488 r128_do_cleanup_cce( dev );
488 return DRM_ERR(EINVAL); 489 return DRM_ERR(EINVAL);
489 } 490 }
491 dev->agp_buffer_token = init->buffers_offset;
490 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 492 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
491 if(!dev->agp_buffer_map) { 493 if(!dev->agp_buffer_map) {
492 DRM_ERROR("could not find dma buffer region!\n"); 494 DRM_ERROR("could not find dma buffer region!\n");
@@ -537,7 +539,7 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
537 dev_priv->cce_buffers_offset = dev->agp->base; 539 dev_priv->cce_buffers_offset = dev->agp->base;
538 else 540 else
539#endif 541#endif
540 dev_priv->cce_buffers_offset = dev->sg->handle; 542 dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
541 543
542 dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle; 544 dev_priv->ring.start = (u32 *)dev_priv->cce_ring->handle;
543 dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle 545 dev_priv->ring.end = ((u32 *)dev_priv->cce_ring->handle
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
index 8255cc6fdc28..f24a27c4dd17 100644
--- a/drivers/char/drm/radeon_cp.c
+++ b/drivers/char/drm/radeon_cp.c
@@ -1407,6 +1407,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
1407 radeon_do_cleanup_cp(dev); 1407 radeon_do_cleanup_cp(dev);
1408 return DRM_ERR(EINVAL); 1408 return DRM_ERR(EINVAL);
1409 } 1409 }
1410 dev->agp_buffer_token = init->buffers_offset;
1410 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset); 1411 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1411 if(!dev->agp_buffer_map) { 1412 if(!dev->agp_buffer_map) {
1412 DRM_ERROR("could not find dma buffer region!\n"); 1413 DRM_ERROR("could not find dma buffer region!\n");