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 | 
