summaryrefslogtreecommitdiff
path: root/linux-core/drm_bufs.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2005-08-16 12:51:57 +0000
committerDave Airlie <airlied@linux.ie>2005-08-16 12:51:57 +0000
commit7af0186f4ccef285c2158770781ebfc3a26ddd66 (patch)
treee38ae798b605e3c433ba5d1a6c153baf0e9c15ce /linux-core/drm_bufs.c
parent8c21b783c3e38aa2c2d16e11ec01cf695f8e7f8a (diff)
add Egberts 32/64 bit patch (its in kernel already...)
Diffstat (limited to 'linux-core/drm_bufs.c')
-rw-r--r--linux-core/drm_bufs.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c
index 416d7d8c..bad02f2d 100644
--- a/linux-core/drm_bufs.c
+++ b/linux-core/drm_bufs.c
@@ -56,8 +56,7 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
list_for_each(list, &dev->maplist->head) {
drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
if (entry->map && map->type == entry->map->type &&
- ((entry->map->offset == map->offset) ||
- (map->type == _DRM_SHM))) {
+ entry->map->offset == map->offset) {
return entry->map;
}
}
@@ -65,13 +64,42 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
return NULL;
}
-#ifdef CONFIG_COMPAT
+
/*
- * Used to allocate 32-bit handles for _DRM_SHM regions
- * The 0x10000000 value is chosen to be out of the way of
- * FB/register and GART physical addresses.
+ * Used to allocate 32-bit handles for mappings.
*/
-static unsigned int map32_handle = 0x10000000;
+#define START_RANGE 0x10000000
+#define END_RANGE 0x40000000
+
+#ifdef _LP64
+static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev)
+{
+ static unsigned int map32_handle = START_RANGE;
+ unsigned int hash;
+
+ if (lhandle & 0xffffffff00000000) {
+ hash = map32_handle;
+ map32_handle += PAGE_SIZE;
+ if (map32_handle > END_RANGE)
+ map32_handle = START_RANGE;
+ } else
+ hash = lhandle;
+
+ while (1) {
+ drm_map_list_t *_entry;
+ list_for_each_entry(_entry, &dev->maplist->head,head) {
+ if (_entry->user_token == hash)
+ break;
+ }
+ if (&_entry->head == &dev->maplist->head)
+ return hash;
+
+ hash += PAGE_SIZE;
+ map32_handle += PAGE_SIZE;
+ }
+}
+#else
+# define HandleID(x,dev) (unsigned int)(x)
#endif
/**
@@ -228,7 +256,7 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
- map->offset += dev->sg->handle;
+ map->offset += (unsigned long)dev->sg->virtual;
break;
case _DRM_CONSISTENT: {
/* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G.
@@ -260,13 +288,11 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
down(&dev->struct_sem);
list_add(&list->head, &dev->maplist->head);
-#ifdef CONFIG_COMPAT
- /* Assign a 32-bit handle for _DRM_SHM mappings */
+ /* Assign a 32-bit handle */
/* We do it here so that dev->struct_sem protects the increment */
- if (map->type == _DRM_SHM)
- map->offset = map32_handle += PAGE_SIZE;
-#endif
-
+ list->user_token = HandleID(map->type==_DRM_SHM
+ ? (unsigned long)map->handle
+ : map->offset, dev);
up(&dev->struct_sem);
*map_ptr = map;
@@ -283,6 +309,7 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
drm_map_t *map_ptr;
drm_map_t __user *argp = (void __user *)arg;
int err;
+ unsigned long handle = 0;
if (!(filp->f_mode & 3))
return -EACCES; /* Require read/write */
@@ -301,13 +328,20 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
return err;
}
- if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
- return -EFAULT;
- if (map_ptr->type != _DRM_SHM) {
- if (copy_to_user(&argp->handle,
- &map_ptr->offset, sizeof(map_ptr->offset)))
+ {
+ drm_map_list_t *_entry;
+ list_for_each_entry(_entry, &dev->maplist->head, head) {
+ if (_entry->map == map_ptr)
+ handle = _entry->user_token;
+ }
+ if (!handle)
return -EFAULT;
}
+
+ if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
+ return -EFAULT;
+ if (put_user(handle, &argp->handle))
+ return -EFAULT;
return 0;
}
@@ -422,7 +456,7 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
drm_map_list_t *r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map &&
- r_list->map->handle == request.handle &&
+ r_list->user_token == (unsigned long) request.handle &&
r_list->map->flags & _DRM_REMOVABLE) {
map = r_list->map;
break;
@@ -991,7 +1025,8 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request)
buf->offset = (dma->byte_count + offset);
buf->bus_address = agp_offset + offset;
- buf->address = (void *)(agp_offset + offset + dev->sg->handle);
+ buf->address = (void *)(agp_offset + offset
+ + (unsigned long)dev->sg->virtual);
buf->next = NULL;
buf->waiting = 0;
buf->pending = 0;
@@ -1517,6 +1552,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
drm_map_t *map = dev->agp_buffer_map;
+ unsigned long token = dev->agp_buffer_token;
if (!map) {
retcode = -EINVAL;
@@ -1530,7 +1566,7 @@ int drm_mapbufs(struct inode *inode, struct file *filp,
virtual = do_mmap(filp, 0, map->size,
PROT_READ | PROT_WRITE,
MAP_SHARED,
- (unsigned long)map->offset);
+ token);
#if LINUX_VERSION_CODE <= 0x020402
up(&current->mm->mmap_sem);
#else