diff options
author | Dave Airlie <airlied@linux.ie> | 2005-08-16 12:51:57 +0000 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-08-16 12:51:57 +0000 |
commit | 7af0186f4ccef285c2158770781ebfc3a26ddd66 (patch) | |
tree | e38ae798b605e3c433ba5d1a6c153baf0e9c15ce /linux-core/drm_bufs.c | |
parent | 8c21b783c3e38aa2c2d16e11ec01cf695f8e7f8a (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.c | 80 |
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(¤t->mm->mmap_sem); #else |