diff options
Diffstat (limited to 'linux-core/drm_bufs.c')
| -rw-r--r-- | linux-core/drm_bufs.c | 47 | 
1 files changed, 28 insertions, 19 deletions
diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 2eeb401d..d6ebc8d1 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -65,8 +65,8 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,  	return NULL;  } -int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,  -		   unsigned long user_token, int hashed_handle) +static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash, +			  unsigned long user_token, int hashed_handle)  {  	int use_hashed_handle; @@ -78,14 +78,16 @@ int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,  #error Unsupported long size. Neither 64 nor 32 bits.  #endif -	if (use_hashed_handle) { -		return drm_ht_just_insert_please(&dev->map_hash, hash,  -						 user_token, 32 - PAGE_SHIFT - 3, -						 PAGE_SHIFT, DRM_MAP_HASH_OFFSET); -	} else { -		hash->key = user_token; -		return drm_ht_insert_item(&dev->map_hash, hash); +	if (!use_hashed_handle) { +		int ret; +		hash->key = user_token >> PAGE_SHIFT; +		ret = drm_ht_insert_item(&dev->map_hash, hash); +		if (ret != -EINVAL)  +			return ret;  	} +	return drm_ht_just_insert_please(&dev->map_hash, hash,  +					 user_token, 32 - PAGE_SHIFT - 3, +					 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);  }  /** @@ -290,16 +292,16 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,  	user_token = (map->type == _DRM_SHM) ? (unsigned long) map->handle :   		map->offset; -        ret = drm_map_handle(dev, &list->hash, user_token, 0);  +	ret = drm_map_handle(dev, &list->hash, user_token, 0);  	if (ret) { -                drm_free(map, sizeof(*map), DRM_MEM_MAPS); -                drm_free(list, sizeof(*list), DRM_MEM_MAPS); -                mutex_unlock(&dev->struct_mutex); -                return ret; +		drm_free(map, sizeof(*map), DRM_MEM_MAPS); +		drm_free(list, sizeof(*list), DRM_MEM_MAPS); +		mutex_unlock(&dev->struct_mutex); +		return ret;  	} -	list->user_token = list->hash.key; +	list->user_token = list->hash.key << PAGE_SHIFT;  	mutex_unlock(&dev->struct_mutex);  	*maplist = list; @@ -384,7 +386,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)  		if (r_list->map == map) {  			list_del(list); -                        drm_ht_remove_key(&dev->map_hash, r_list->user_token); +			drm_ht_remove_key(&dev->map_hash,  +					  r_list->user_token >> PAGE_SHIFT);  			drm_free(list, sizeof(*list), DRM_MEM_MAPS);  			break;  		} @@ -420,6 +423,8 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)  		dmah.size = map->size;  		__drm_pci_free(dev, &dmah);  		break; +	case _DRM_TTM: +		BUG_ON(1);  	}  	drm_free(map, sizeof(*map), DRM_MEM_MAPS); @@ -940,6 +945,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)  	request->count = entry->buf_count;  	request->size = size; +	if (request->flags & _DRM_PCI_BUFFER_RO) +		dma->flags = _DRM_DMA_USE_PCI_RO; +  	atomic_dec(&dev->buf_alloc);  	return 0; @@ -1526,9 +1534,10 @@ int drm_freebufs(struct inode *inode, struct file *filp,   * \param arg pointer to a drm_buf_map structure.   * \return zero on success or a negative number on failure.   * - * Maps the AGP or SG buffer region with do_mmap(), and copies information - * about each buffer into user space. The PCI buffers are already mapped on the - * addbufs_pci() call. + * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information + * about each buffer into user space. For PCI buffers, it calls do_mmap() with + * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls + * drm_mmap_dma().   */  int drm_mapbufs(struct inode *inode, struct file *filp,  		unsigned int cmd, unsigned long arg)  | 
