aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_bufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_bufs.c')
-rw-r--r--drivers/gpu/drm/drm_bufs.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index bde64b84166e..72c667f9bee1 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -54,9 +54,9 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
54{ 54{
55 struct drm_map_list *entry; 55 struct drm_map_list *entry;
56 list_for_each_entry(entry, &dev->maplist, head) { 56 list_for_each_entry(entry, &dev->maplist, head) {
57 if (entry->map && map->type == entry->map->type && 57 if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) &&
58 ((entry->map->offset == map->offset) || 58 ((entry->map->offset == map->offset) ||
59 (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { 59 ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) {
60 return entry; 60 return entry;
61 } 61 }
62 } 62 }
@@ -210,12 +210,12 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
210 map->offset = (unsigned long)map->handle; 210 map->offset = (unsigned long)map->handle;
211 if (map->flags & _DRM_CONTAINS_LOCK) { 211 if (map->flags & _DRM_CONTAINS_LOCK) {
212 /* Prevent a 2nd X Server from creating a 2nd lock */ 212 /* Prevent a 2nd X Server from creating a 2nd lock */
213 if (dev->lock.hw_lock != NULL) { 213 if (dev->primary->master->lock.hw_lock != NULL) {
214 vfree(map->handle); 214 vfree(map->handle);
215 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 215 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
216 return -EBUSY; 216 return -EBUSY;
217 } 217 }
218 dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ 218 dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */
219 } 219 }
220 break; 220 break;
221 case _DRM_AGP: { 221 case _DRM_AGP: {
@@ -262,6 +262,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
262 DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size); 262 DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
263 263
264 break; 264 break;
265 case _DRM_GEM:
266 DRM_ERROR("tried to rmmap GEM object\n");
267 break;
265 } 268 }
266 case _DRM_SCATTER_GATHER: 269 case _DRM_SCATTER_GATHER:
267 if (!dev->sg) { 270 if (!dev->sg) {
@@ -319,6 +322,7 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
319 list->user_token = list->hash.key << PAGE_SHIFT; 322 list->user_token = list->hash.key << PAGE_SHIFT;
320 mutex_unlock(&dev->struct_mutex); 323 mutex_unlock(&dev->struct_mutex);
321 324
325 list->master = dev->primary->master;
322 *maplist = list; 326 *maplist = list;
323 return 0; 327 return 0;
324 } 328 }
@@ -345,7 +349,7 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data,
345 struct drm_map_list *maplist; 349 struct drm_map_list *maplist;
346 int err; 350 int err;
347 351
348 if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP)) 352 if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM))
349 return -EPERM; 353 return -EPERM;
350 354
351 err = drm_addmap_core(dev, map->offset, map->size, map->type, 355 err = drm_addmap_core(dev, map->offset, map->size, map->type,
@@ -380,10 +384,12 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
380 struct drm_map_list *r_list = NULL, *list_t; 384 struct drm_map_list *r_list = NULL, *list_t;
381 drm_dma_handle_t dmah; 385 drm_dma_handle_t dmah;
382 int found = 0; 386 int found = 0;
387 struct drm_master *master;
383 388
384 /* Find the list entry for the map and remove it */ 389 /* Find the list entry for the map and remove it */
385 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { 390 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
386 if (r_list->map == map) { 391 if (r_list->map == map) {
392 master = r_list->master;
387 list_del(&r_list->head); 393 list_del(&r_list->head);
388 drm_ht_remove_key(&dev->map_hash, 394 drm_ht_remove_key(&dev->map_hash,
389 r_list->user_token >> PAGE_SHIFT); 395 r_list->user_token >> PAGE_SHIFT);
@@ -409,6 +415,13 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
409 break; 415 break;
410 case _DRM_SHM: 416 case _DRM_SHM:
411 vfree(map->handle); 417 vfree(map->handle);
418 if (master) {
419 if (dev->sigdata.lock == master->lock.hw_lock)
420 dev->sigdata.lock = NULL;
421 master->lock.hw_lock = NULL; /* SHM removed */
422 master->lock.file_priv = NULL;
423 wake_up_interruptible(&master->lock.lock_queue);
424 }
412 break; 425 break;
413 case _DRM_AGP: 426 case _DRM_AGP:
414 case _DRM_SCATTER_GATHER: 427 case _DRM_SCATTER_GATHER:
@@ -419,11 +432,15 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
419 dmah.size = map->size; 432 dmah.size = map->size;
420 __drm_pci_free(dev, &dmah); 433 __drm_pci_free(dev, &dmah);
421 break; 434 break;
435 case _DRM_GEM:
436 DRM_ERROR("tried to rmmap GEM object\n");
437 break;
422 } 438 }
423 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 439 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
424 440
425 return 0; 441 return 0;
426} 442}
443EXPORT_SYMBOL(drm_rmmap_locked);
427 444
428int drm_rmmap(struct drm_device *dev, drm_local_map_t *map) 445int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
429{ 446{