diff options
Diffstat (limited to 'drivers/char/drm/drm_bufs.c')
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 006b06d29727..029baea33b62 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 | /* | 68 | static 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 | ||
75 | static __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) |
@@ -257,11 +245,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset, | |||
257 | 245 | ||
258 | mutex_lock(&dev->struct_mutex); | 246 | mutex_lock(&dev->struct_mutex); |
259 | list_add(&list->head, &dev->maplist->head); | 247 | list_add(&list->head, &dev->maplist->head); |
248 | |||
260 | /* Assign a 32-bit handle */ | 249 | /* Assign a 32-bit handle */ |
261 | /* We do it here so that dev->struct_mutex protects the increment */ | 250 | /* We do it here so that dev->struct_mutex protects the increment */ |
262 | list->user_token = HandleID(map->type == _DRM_SHM | 251 | user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle : |
263 | ? (unsigned long)map->handle | 252 | map->offset; |
264 | : map->offset, dev); | 253 | ret = drm_map_handle(dev, &list->hash, user_token, 0); |
254 | if (ret) { | ||
255 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | ||
256 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | ||
257 | mutex_unlock(&dev->struct_mutex); | ||
258 | return ret; | ||
259 | } | ||
260 | |||
261 | list->user_token = list->hash.key; | ||
265 | mutex_unlock(&dev->struct_mutex); | 262 | mutex_unlock(&dev->struct_mutex); |
266 | 263 | ||
267 | *maplist = list; | 264 | *maplist = list; |
@@ -346,6 +343,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) | |||
346 | 343 | ||
347 | if (r_list->map == map) { | 344 | if (r_list->map == map) { |
348 | list_del(list); | 345 | list_del(list); |
346 | drm_ht_remove_key(&dev->map_hash, r_list->user_token); | ||
349 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); | 347 | drm_free(list, sizeof(*list), DRM_MEM_MAPS); |
350 | break; | 348 | break; |
351 | } | 349 | } |
@@ -441,8 +439,10 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, | |||
441 | return -EINVAL; | 439 | return -EINVAL; |
442 | } | 440 | } |
443 | 441 | ||
444 | if (!map) | 442 | if (!map) { |
443 | mutex_unlock(&dev->struct_mutex); | ||
445 | return -EINVAL; | 444 | return -EINVAL; |
445 | } | ||
446 | 446 | ||
447 | /* Register and framebuffer maps are permanent */ | 447 | /* Register and framebuffer maps are permanent */ |
448 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { | 448 | if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { |