aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
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");