X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Fdrm%2Fdrm_context.h;h=79b200e088b0d60cc82e45c8cf9b67d9d122c7ae;hb=78a6196531f0fe10aae05a9bc4c2701df614ac3d;hp=64d32d6c9e41059e3e0aedc4dec264409ce36c8c;hpb=86090fcac5e27b630656fe3d963a6b80e26dac44;p=linux-2.6.git diff --git a/drivers/char/drm/drm_context.h b/drivers/char/drm/drm_context.h index 64d32d6c9..79b200e08 100644 --- a/drivers/char/drm/drm_context.h +++ b/drivers/char/drm/drm_context.h @@ -401,6 +401,7 @@ int DRM(addctx)( struct inode *inode, struct file *filp, { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; + drm_ctx_list_t * ctx_entry; drm_ctx_t ctx; if ( copy_from_user( &ctx, (drm_ctx_t *)arg, sizeof(ctx) ) ) @@ -421,6 +422,20 @@ int DRM(addctx)( struct inode *inode, struct file *filp, if ( ctx.handle != DRM_KERNEL_CONTEXT ) DRIVER_CTX_CTOR(ctx.handle); /* XXX: also pass dev ? */ #endif + ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST ); + if ( !ctx_entry ) { + DRM_DEBUG("out of memory\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD( &ctx_entry->head ); + ctx_entry->handle = ctx.handle; + ctx_entry->tag = priv; + + down( &dev->ctxlist_sem ); + list_add( &ctx_entry->head, &dev->ctxlist->head ); + ++dev->ctx_count; + up( &dev->ctxlist_sem ); if ( copy_to_user( (drm_ctx_t *)arg, &ctx, sizeof(ctx) ) ) return -EFAULT; @@ -543,6 +558,20 @@ int DRM(rmctx)( struct inode *inode, struct file *filp, DRM(ctxbitmap_free)( dev, ctx.handle ); } + 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->handle == ctx.handle ) { + list_del( &pos->head ); + DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST ); + --dev->ctx_count; + } + } + } + up( &dev->ctxlist_sem ); + return 0; }