diff options
Diffstat (limited to 'linux-core/drm_drv.c')
-rw-r--r-- | linux-core/drm_drv.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index d0dceaab..3eec29a0 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -329,6 +329,12 @@ static int DRM(setup)( drm_device_t *dev ) memset(dev->maplist, 0, sizeof(*dev->maplist)); INIT_LIST_HEAD(&dev->maplist->head); + dev->ctxlist = DRM(alloc)(sizeof(*dev->ctxlist), + DRM_MEM_CTXLIST); + if(dev->ctxlist == NULL) return -ENOMEM; + memset(dev->ctxlist, 0, sizeof(*dev->ctxlist)); + INIT_LIST_HEAD(&dev->ctxlist->head); + dev->vmalist = NULL; dev->sigdata.lock = dev->lock.hw_lock = NULL; init_waitqueue_head( &dev->lock.lock_queue ); @@ -567,6 +573,7 @@ static int DRM(probe)(struct pci_dev *pdev) dev->count_lock = SPIN_LOCK_UNLOCKED; init_timer( &dev->timer ); sema_init( &dev->struct_sem, 1 ); + sema_init( &dev->ctxlist_sem, 1 ); if ((dev->minor = DRM(stub_register)(DRIVER_NAME, &DRM(fops),dev)) < 0) return -EPERM; @@ -896,6 +903,25 @@ int DRM(release)( struct inode *inode, struct file *filp ) DRM(fasync)( -1, filp, 0 ); + down( &dev->ctxlist_sem ); + if ( !list_empty( &dev->ctxlist->head ) ) { + drm_ctx_list_t *pos, *n; + + list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) { + if ( pos->tag == priv && + pos->handle != DRM_KERNEL_CONTEXT ) { +#ifdef DRIVER_CTX_DTOR + DRIVER_CTX_DTOR(pos->handle); +#endif + DRM(ctxbitmap_free)( dev, pos->handle ); + + list_del( &pos->head ); + DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST ); + } + } + } + up( &dev->ctxlist_sem ); + down( &dev->struct_sem ); if ( priv->remove_auth_on_close == 1 ) { drm_file_t *temp = dev->file_first; |