diff --git a/linux-core/drm_bufs.c b/linux-core/drm_bufs.c index 65818c6..2da8337 100644 --- a/linux-core/drm_bufs.c +++ b/linux-core/drm_bufs.c @@ -54,7 +54,8 @@ struct drm_map_list *drm_find_matching_map(struct drm_device *dev, drm_local_map list_for_each_entry(entry, &dev->maplist, head) { if (entry->map && map->type == entry->map->type && ((entry->map->offset == map->offset) || - (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { + ((map->type == _DRM_SHM) && + (map->flags==_DRM_CONTAINS_LOCK)))) { return entry; } } @@ -407,7 +408,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map) break; case _DRM_SHM: vfree(map->handle); - break; + dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ break; case _DRM_AGP: case _DRM_SCATTER_GATHER: break; diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index bba8414..d268fc3 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -246,8 +246,10 @@ int drm_lastclose(struct drm_device * dev) } list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { - drm_rmmap_locked(dev, r_list->map); - r_list = NULL; + if (!(r_list->map->flags & _DRM_DRIVER)) { + drm_rmmap_locked(dev, r_list->map); + r_list = NULL; + } } if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) { @@ -270,8 +272,7 @@ int drm_lastclose(struct drm_device * dev) if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) drm_dma_takedown(dev); - if (dev->lock.hw_lock) { - dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */ + if (dev->lock.file_priv) { dev->lock.file_priv = NULL; wake_up_interruptible(&dev->lock.lock_queue); } @@ -390,11 +391,6 @@ static void drm_cleanup(struct drm_device * dev) } drm_lastclose(dev); - drm_fence_manager_takedown(dev); - - drm_ht_remove(&dev->map_hash); - drm_mm_takedown(&dev->offset_manager); - drm_ht_remove(&dev->object_hash); if (!drm_fb_loaded) pci_disable_device(dev->pdev); @@ -417,6 +413,11 @@ static void drm_cleanup(struct drm_device * dev) if (dev->driver->unload) dev->driver->unload(dev); + drm_fence_manager_takedown(dev); + drm_ht_remove(&dev->map_hash); + drm_mm_takedown(&dev->offset_manager); + drm_ht_remove(&dev->object_hash); + drm_put_head(&dev->primary); if (drm_put_dev(dev)) DRM_ERROR("Cannot unload module\n"); diff --git a/shared-core/drm.h b/shared-core/drm.h index 3941490..42ff909 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -249,7 +249,8 @@ enum drm_map_flags { _DRM_KERNEL = 0x08, /**< kernel requires access */ _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */ _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */ - _DRM_REMOVABLE = 0x40 /**< Removable mapping */ + _DRM_REMOVABLE = 0x40, /**< Removable mapping */ + _DRM_DRIVER = 0x80, /**< Driver will take care of it */ }; struct drm_ctx_priv_map {