diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-08-05 08:11:22 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-08-05 08:11:22 -0400 |
commit | d1f2b55ad2c11f46e30547a9f7754e99b478348e (patch) | |
tree | cabf9060c4f6cb419c7ed7fdcbcc6b6a91a83ac1 | |
parent | c73681e77b40697d16ada777adf2c6dc4db05917 (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>
-rw-r--r-- | drivers/char/drm/drmP.h | 14 | ||||
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 81 | ||||
-rw-r--r-- | drivers/char/drm/drm_context.c | 15 | ||||
-rw-r--r-- | drivers/char/drm/drm_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/char/drm/drm_proc.c | 4 | ||||
-rw-r--r-- | drivers/char/drm/drm_scatter.c | 11 | ||||
-rw-r--r-- | drivers/char/drm/drm_vm.c | 20 | ||||
-rw-r--r-- | drivers/char/drm/ffb_drv.c | 5 | ||||
-rw-r--r-- | drivers/char/drm/i810_dma.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/i830_dma.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/mga_dma.c | 1 | ||||
-rw-r--r-- | drivers/char/drm/mga_drm.h | 2 | ||||
-rw-r--r-- | drivers/char/drm/mga_ioc32.c | 67 | ||||
-rw-r--r-- | drivers/char/drm/r128_cce.c | 6 | ||||
-rw-r--r-- | drivers/char/drm/radeon_cp.c | 1 |
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 { | |||
539 | typedef struct drm_map_list { | 539 | typedef 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 | ||
544 | typedef drm_map_t drm_local_map_t; | 545 | typedef 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 | ||
1051 | static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset) | 1053 | static __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 | */ |
73 | static unsigned int map32_handle = 0x10000000; | 70 | #define START_RANGE 0x10000000 |
71 | #define END_RANGE 0x40000000 | ||
72 | |||
73 | #ifdef _LP64 | ||
74 | static __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( ¤t->mm->mmap_sem ); | 1512 | up( ¤t->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 | } |
268 | bad: | 279 | bad: |
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 | |||
64 | int drm_sg_alloc( struct inode *inode, struct file *filp, | 70 | int 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 | ||
132 | typedef 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 | |||
142 | static 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 | |||
132 | drm_ioctl_compat_t *mga_compat_ioctls[] = { | 198 | drm_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"); |