summaryrefslogtreecommitdiff
path: root/linux-core/drm_bufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core/drm_bufs.c')
-rw-r--r--linux-core/drm_bufs.c47
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)