aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_bufs.c
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2006-12-12 18:13:32 -0500
committerDave Jones <davej@redhat.com>2006-12-12 18:13:32 -0500
commitf0eef25339f92f7cd4aeea23d9ae97987a5a1e82 (patch)
tree2472e94d39f43a9580a6d2d5d92de0b749023263 /drivers/char/drm/drm_bufs.c
parent0cfea5dd98205f2fa318836da664a7d7df1afbc1 (diff)
parente1036502e5263851259d147771226161e5ccc85a (diff)
Merge ../linus
Diffstat (limited to 'drivers/char/drm/drm_bufs.c')
-rw-r--r--drivers/char/drm/drm_bufs.c88
1 files changed, 48 insertions, 40 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
index 006b06d29727..9f65f5697ba8 100644
--- a/drivers/char/drm/drm_bufs.c
+++ b/drivers/char/drm/drm_bufs.c
@@ -65,43 +65,29 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
65 return NULL; 65 return NULL;
66} 66}
67 67
68/* 68static int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
69 * Used to allocate 32-bit handles for mappings. 69 unsigned long user_token, int hashed_handle)
70 */
71#define START_RANGE 0x10000000
72#define END_RANGE 0x40000000
73
74#ifdef _LP64
75static __inline__ unsigned int HandleID(unsigned long lhandle,
76 drm_device_t *dev)
77{ 70{
78 static unsigned int map32_handle = START_RANGE; 71 int use_hashed_handle;
79 unsigned int hash; 72#if (BITS_PER_LONG == 64)
80 73 use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
81 if (lhandle & 0xffffffff00000000) { 74#elif (BITS_PER_LONG == 32)
82 hash = map32_handle; 75 use_hashed_handle = hashed_handle;
83 map32_handle += PAGE_SIZE; 76#else
84 if (map32_handle > END_RANGE) 77#error Unsupported long size. Neither 64 nor 32 bits.
85 map32_handle = START_RANGE; 78#endif
86 } else
87 hash = lhandle;
88
89 while (1) {
90 drm_map_list_t *_entry;
91 list_for_each_entry(_entry, &dev->maplist->head, head) {
92 if (_entry->user_token == hash)
93 break;
94 }
95 if (&_entry->head == &dev->maplist->head)
96 return hash;
97 79
98 hash += PAGE_SIZE; 80 if (!use_hashed_handle) {
99 map32_handle += PAGE_SIZE; 81 int ret;
82 hash->key = user_token;
83 ret = drm_ht_insert_item(&dev->map_hash, hash);
84 if (ret != -EINVAL)
85 return ret;
100 } 86 }
87 return drm_ht_just_insert_please(&dev->map_hash, hash,
88 user_token, 32 - PAGE_SHIFT - 3,
89 PAGE_SHIFT, DRM_MAP_HASH_OFFSET);
101} 90}
102#else
103# define HandleID(x,dev) (unsigned int)(x)
104#endif
105 91
106/** 92/**
107 * Ioctl to specify a range of memory that is available for mapping by a non-root process. 93 * Ioctl to specify a range of memory that is available for mapping by a non-root process.
@@ -123,6 +109,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
123 drm_map_t *map; 109 drm_map_t *map;
124 drm_map_list_t *list; 110 drm_map_list_t *list;
125 drm_dma_handle_t *dmah; 111 drm_dma_handle_t *dmah;
112 unsigned long user_token;
113 int ret;
126 114
127 map = drm_alloc(sizeof(*map), DRM_MEM_MAPS); 115 map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
128 if (!map) 116 if (!map)
@@ -249,6 +237,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
249 237
250 list = drm_alloc(sizeof(*list), DRM_MEM_MAPS); 238 list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
251 if (!list) { 239 if (!list) {
240 if (map->type == _DRM_REGISTERS)
241 drm_ioremapfree(map->handle, map->size, dev);
252 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 242 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
253 return -EINVAL; 243 return -EINVAL;
254 } 244 }
@@ -257,11 +247,22 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
257 247
258 mutex_lock(&dev->struct_mutex); 248 mutex_lock(&dev->struct_mutex);
259 list_add(&list->head, &dev->maplist->head); 249 list_add(&list->head, &dev->maplist->head);
250
260 /* Assign a 32-bit handle */ 251 /* Assign a 32-bit handle */
261 /* We do it here so that dev->struct_mutex protects the increment */ 252 /* We do it here so that dev->struct_mutex protects the increment */
262 list->user_token = HandleID(map->type == _DRM_SHM 253 user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
263 ? (unsigned long)map->handle 254 map->offset;
264 : map->offset, dev); 255 ret = drm_map_handle(dev, &list->hash, user_token, 0);
256 if (ret) {
257 if (map->type == _DRM_REGISTERS)
258 drm_ioremapfree(map->handle, map->size, dev);
259 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
260 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
261 mutex_unlock(&dev->struct_mutex);
262 return ret;
263 }
264
265 list->user_token = list->hash.key;
265 mutex_unlock(&dev->struct_mutex); 266 mutex_unlock(&dev->struct_mutex);
266 267
267 *maplist = list; 268 *maplist = list;
@@ -346,6 +347,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
346 347
347 if (r_list->map == map) { 348 if (r_list->map == map) {
348 list_del(list); 349 list_del(list);
350 drm_ht_remove_key(&dev->map_hash, r_list->user_token);
349 drm_free(list, sizeof(*list), DRM_MEM_MAPS); 351 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
350 break; 352 break;
351 } 353 }
@@ -441,8 +443,10 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp,
441 return -EINVAL; 443 return -EINVAL;
442 } 444 }
443 445
444 if (!map) 446 if (!map) {
447 mutex_unlock(&dev->struct_mutex);
445 return -EINVAL; 448 return -EINVAL;
449 }
446 450
447 /* Register and framebuffer maps are permanent */ 451 /* Register and framebuffer maps are permanent */
448 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { 452 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
@@ -883,6 +887,9 @@ int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request)
883 request->count = entry->buf_count; 887 request->count = entry->buf_count;
884 request->size = size; 888 request->size = size;
885 889
890 if (request->flags & _DRM_PCI_BUFFER_RO)
891 dma->flags = _DRM_DMA_USE_PCI_RO;
892
886 atomic_dec(&dev->buf_alloc); 893 atomic_dec(&dev->buf_alloc);
887 return 0; 894 return 0;
888 895
@@ -1467,9 +1474,10 @@ int drm_freebufs(struct inode *inode, struct file *filp,
1467 * \param arg pointer to a drm_buf_map structure. 1474 * \param arg pointer to a drm_buf_map structure.
1468 * \return zero on success or a negative number on failure. 1475 * \return zero on success or a negative number on failure.
1469 * 1476 *
1470 * Maps the AGP or SG buffer region with do_mmap(), and copies information 1477 * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
1471 * about each buffer into user space. The PCI buffers are already mapped on the 1478 * about each buffer into user space. For PCI buffers, it calls do_mmap() with
1472 * addbufs_pci() call. 1479 * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
1480 * drm_mmap_dma().
1473 */ 1481 */
1474int drm_mapbufs(struct inode *inode, struct file *filp, 1482int drm_mapbufs(struct inode *inode, struct file *filp,
1475 unsigned int cmd, unsigned long arg) 1483 unsigned int cmd, unsigned long arg)