xref: /onnv-gate/usr/src/uts/common/io/drm/drm_context.c (revision 5804:7af97c792162)
12820Skz151634 /*
2*5804Scg149915  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
32820Skz151634  * Use is subject to license terms.
42820Skz151634  */
52820Skz151634 
62820Skz151634 /*
72820Skz151634  * drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
82820Skz151634  * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
92820Skz151634  */
102820Skz151634 /*
112820Skz151634  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
122820Skz151634  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
132820Skz151634  * All Rights Reserved.
142820Skz151634  *
152820Skz151634  * Permission is hereby granted, free of charge, to any person obtaining a
162820Skz151634  * copy of this software and associated documentation files (the "Software"),
172820Skz151634  * to deal in the Software without restriction, including without limitation
182820Skz151634  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
192820Skz151634  * and/or sell copies of the Software, and to permit persons to whom the
202820Skz151634  * Software is furnished to do so, subject to the following conditions:
212820Skz151634  *
222820Skz151634  * The above copyright notice and this permission notice (including the next
232820Skz151634  * paragraph) shall be included in all copies or substantial portions of the
242820Skz151634  * Software.
252820Skz151634  *
262820Skz151634  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
272820Skz151634  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
282820Skz151634  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
292820Skz151634  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
302820Skz151634  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
312820Skz151634  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
322820Skz151634  * OTHER DEALINGS IN THE SOFTWARE.
332820Skz151634  *
342820Skz151634  * Authors:
352820Skz151634  *    Rickard E. (Rik) Faith <faith@valinux.com>
362820Skz151634  *    Gareth Hughes <gareth@valinux.com>
372820Skz151634  *
382820Skz151634  */
392820Skz151634 
402820Skz151634 #pragma ident	"%Z%%M%	%I%	%E% SMI"
412820Skz151634 
422820Skz151634 #include "drmP.h"
43*5804Scg149915 #include "drm_io32.h"
442820Skz151634 
455376Scg149915 static inline int
find_first_zero_bit(volatile void * p,int max)465376Scg149915 find_first_zero_bit(volatile void *p, int max)
475376Scg149915 {
485376Scg149915 	int b;
495376Scg149915 	volatile int *ptr = (volatile int *)p;
505376Scg149915 
515376Scg149915 	for (b = 0; b < max; b += 32) {
525376Scg149915 		if (ptr[b >> 5] != ~0) {
535376Scg149915 			for (;;) {
545376Scg149915 				if ((ptr[b >> 5] & (1 << (b & 0x1f))) == 0)
555376Scg149915 					return (b);
565376Scg149915 				b++;
575376Scg149915 			}
585376Scg149915 		}
595376Scg149915 	}
605376Scg149915 	return (max);
615376Scg149915 }
625376Scg149915 
632820Skz151634 /*
642820Skz151634  * Context bitmap support
652820Skz151634  */
662820Skz151634 void
drm_ctxbitmap_free(drm_device_t * dev,int ctx_handle)672820Skz151634 drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle)
682820Skz151634 {
692820Skz151634 	if (ctx_handle < 0 || ctx_handle >= DRM_MAX_CTXBITMAP ||
702820Skz151634 	    dev->ctx_bitmap == NULL) {
712820Skz151634 		DRM_ERROR("drm_ctxbitmap_free: Attempt to free\
722820Skz151634 		    invalid context handle: %d\n",
732820Skz151634 		    ctx_handle);
742820Skz151634 		return;
752820Skz151634 	}
762820Skz151634 
772820Skz151634 	DRM_LOCK();
782820Skz151634 	clear_bit(ctx_handle, dev->ctx_bitmap);
792820Skz151634 	dev->context_sareas[ctx_handle] = NULL;
802820Skz151634 	DRM_UNLOCK();
812820Skz151634 }
822820Skz151634 
832820Skz151634 /* Is supposed to return -1 if  any error by calling functions */
842820Skz151634 int
drm_ctxbitmap_next(drm_device_t * dev)852820Skz151634 drm_ctxbitmap_next(drm_device_t *dev)
862820Skz151634 {
872820Skz151634 	int bit;
882820Skz151634 
892820Skz151634 	if (dev->ctx_bitmap == NULL)
902820Skz151634 		return (-1);
912820Skz151634 
922820Skz151634 	DRM_LOCK();
932820Skz151634 	bit = find_first_zero_bit(dev->ctx_bitmap, DRM_MAX_CTXBITMAP);
942820Skz151634 	if (bit >= DRM_MAX_CTXBITMAP) {
952820Skz151634 		DRM_UNLOCK();
962820Skz151634 		return (-1);
972820Skz151634 	}
982820Skz151634 
992820Skz151634 	set_bit(bit, dev->ctx_bitmap);
1002820Skz151634 	DRM_DEBUG("drm_ctxbitmap_next: bit : %d", bit);
1012820Skz151634 	if ((bit+1) > dev->max_context) {
1022820Skz151634 		dev->max_context = (bit+1);
1032820Skz151634 		if (dev->context_sareas != NULL) {
1042820Skz151634 			drm_local_map_t **ctx_sareas;
1052820Skz151634 			ctx_sareas = drm_realloc(dev->context_sareas,
1065376Scg149915 			    (dev->max_context - 1) *
1075376Scg149915 			    sizeof (*dev->context_sareas),
1085376Scg149915 			    dev->max_context *
1095376Scg149915 			    sizeof (*dev->context_sareas),
1105376Scg149915 			    DRM_MEM_MAPS);
1112820Skz151634 			if (ctx_sareas == NULL) {
1122820Skz151634 				clear_bit(bit, dev->ctx_bitmap);
1132820Skz151634 				DRM_UNLOCK();
1142820Skz151634 				return (-1);
1152820Skz151634 			}
1162820Skz151634 			dev->context_sareas = ctx_sareas;
1172820Skz151634 			dev->context_sareas[bit] = NULL;
1182820Skz151634 		} else {
1192820Skz151634 			/* max_context == 1 at this point */
1202820Skz151634 			dev->context_sareas = drm_alloc(dev->max_context *
1215376Scg149915 			    sizeof (*dev->context_sareas), KM_NOSLEEP);
1222820Skz151634 			if (dev->context_sareas == NULL) {
1232820Skz151634 				clear_bit(bit, dev->ctx_bitmap);
1242820Skz151634 				DRM_UNLOCK();
1252820Skz151634 				return (-1);
1262820Skz151634 			}
1272820Skz151634 			dev->context_sareas[bit] = NULL;
1282820Skz151634 		}
1292820Skz151634 	}
1302820Skz151634 	DRM_UNLOCK();
1312820Skz151634 	DRM_DEBUG("drm_ctxbitmap_next: return %d", bit);
1322820Skz151634 	return (bit);
1332820Skz151634 }
1342820Skz151634 
1352820Skz151634 int
drm_ctxbitmap_init(drm_device_t * dev)1362820Skz151634 drm_ctxbitmap_init(drm_device_t *dev)
1372820Skz151634 {
1382820Skz151634 	int i;
1392820Skz151634 	int temp;
1402820Skz151634 
1412820Skz151634 	DRM_LOCK();
1422820Skz151634 	dev->ctx_bitmap = drm_calloc(1, DRM_PAGE_SIZE, DRM_MEM_CTXBITMAP);
1432820Skz151634 	if (dev->ctx_bitmap == NULL) {
1442820Skz151634 		DRM_UNLOCK();
145*5804Scg149915 		return (ENOMEM);
1462820Skz151634 	}
1472820Skz151634 	dev->context_sareas = NULL;
1482820Skz151634 	dev->max_context = -1;
1492820Skz151634 	DRM_UNLOCK();
1502820Skz151634 
1512820Skz151634 	for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
1522820Skz151634 		temp = drm_ctxbitmap_next(dev);
1532820Skz151634 		DRM_DEBUG("drm_ctxbitmap_init : %d", temp);
1542820Skz151634 	}
1552820Skz151634 	return (0);
1562820Skz151634 }
1572820Skz151634 
1582820Skz151634 void
drm_ctxbitmap_cleanup(drm_device_t * dev)1592820Skz151634 drm_ctxbitmap_cleanup(drm_device_t *dev)
1602820Skz151634 {
1612820Skz151634 	DRM_LOCK();
1622820Skz151634 	if (dev->context_sareas != NULL)
1632820Skz151634 		drm_free(dev->context_sareas,
1645376Scg149915 		    sizeof (*dev->context_sareas) *
1655376Scg149915 		    dev->max_context,
1665376Scg149915 		    DRM_MEM_MAPS);
1672820Skz151634 	drm_free(dev->ctx_bitmap, DRM_PAGE_SIZE, DRM_MEM_CTXBITMAP);
1682820Skz151634 	DRM_UNLOCK();
1692820Skz151634 }
1702820Skz151634 
1712820Skz151634 /*
1722820Skz151634  * Per Context SAREA Support
1732820Skz151634  */
1742820Skz151634 /*ARGSUSED*/
1752820Skz151634 int
drm_getsareactx(DRM_IOCTL_ARGS)1762820Skz151634 drm_getsareactx(DRM_IOCTL_ARGS)
1772820Skz151634 {
1782820Skz151634 	DRM_DEVICE;
1792820Skz151634 	drm_ctx_priv_map_t request;
1802820Skz151634 	drm_local_map_t *map;
1812820Skz151634 
182*5804Scg149915 #ifdef	_MULTI_DATAMODEL
1832820Skz151634 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
184*5804Scg149915 		drm_ctx_priv_map_32_t request32;
185*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&request32, (void *)data,
186*5804Scg149915 		    sizeof (drm_ctx_priv_map_32_t));
1872820Skz151634 		request.ctx_id = request32.ctx_id;
1882820Skz151634 		request.handle = (void *)(uintptr_t)request32.handle;
1892820Skz151634 	} else
190*5804Scg149915 #endif
191*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&request, (void *)data,
1925376Scg149915 		    sizeof (request));
1932820Skz151634 
1942820Skz151634 	DRM_LOCK();
1952820Skz151634 	if (dev->max_context < 0 || request.ctx_id >= (unsigned)
1962820Skz151634 	    dev->max_context) {
1972820Skz151634 		DRM_UNLOCK();
198*5804Scg149915 		return (EINVAL);
1992820Skz151634 	}
2002820Skz151634 
2012820Skz151634 	map = dev->context_sareas[request.ctx_id];
2022820Skz151634 	DRM_UNLOCK();
2032820Skz151634 
204*5804Scg149915 	if (!map)
205*5804Scg149915 		return (EINVAL);
206*5804Scg149915 
2072820Skz151634 	request.handle = map->handle;
2082820Skz151634 
209*5804Scg149915 #ifdef	_MULTI_DATAMODEL
2102820Skz151634 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
211*5804Scg149915 		drm_ctx_priv_map_32_t request32;
2122820Skz151634 		request32.ctx_id = request.ctx_id;
2132820Skz151634 		request32.handle = (caddr32_t)(uintptr_t)request.handle;
214*5804Scg149915 		DRM_COPYTO_WITH_RETURN((void *)data, &request32,
215*5804Scg149915 		    sizeof (drm_ctx_priv_map_32_t));
2162820Skz151634 	} else
217*5804Scg149915 #endif
218*5804Scg149915 		DRM_COPYTO_WITH_RETURN((void *)data,
219*5804Scg149915 		    &request, sizeof (request));
2202820Skz151634 
2212820Skz151634 	return (0);
2222820Skz151634 }
2232820Skz151634 
2242820Skz151634 /*ARGSUSED*/
2252820Skz151634 int
drm_setsareactx(DRM_IOCTL_ARGS)2262820Skz151634 drm_setsareactx(DRM_IOCTL_ARGS)
2272820Skz151634 {
2282820Skz151634 	DRM_DEVICE;
2292820Skz151634 	drm_ctx_priv_map_t request;
2302820Skz151634 	drm_local_map_t *map = NULL;
2312820Skz151634 
232*5804Scg149915 #ifdef	_MULTI_DATAMODEL
2332820Skz151634 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
234*5804Scg149915 		drm_ctx_priv_map_32_t request32;
2352820Skz151634 
236*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&request32, (void *)data,
237*5804Scg149915 		    sizeof (drm_ctx_priv_map_32_t));
2382820Skz151634 		request.ctx_id = request32.ctx_id;
2392820Skz151634 		request.handle = (void *)(uintptr_t)request32.handle;
2402820Skz151634 	} else
241*5804Scg149915 #endif
242*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&request,
243*5804Scg149915 		    (void *)data, sizeof (request));
2442820Skz151634 
2452820Skz151634 	DRM_LOCK();
2462820Skz151634 	TAILQ_FOREACH(map, &dev->maplist, link) {
2472820Skz151634 		if (map->handle == request.handle) {
2482820Skz151634 			if (dev->max_context < 0)
2492820Skz151634 				goto bad;
2502820Skz151634 			if (request.ctx_id >= (unsigned)dev->max_context)
2512820Skz151634 				goto bad;
2522820Skz151634 			dev->context_sareas[request.ctx_id] = map;
2532820Skz151634 			DRM_UNLOCK();
2542820Skz151634 			return (0);
2552820Skz151634 		}
2562820Skz151634 	}
2572820Skz151634 
2582820Skz151634 bad:
2592820Skz151634 	DRM_UNLOCK();
260*5804Scg149915 	return (EINVAL);
2612820Skz151634 }
2622820Skz151634 
2632820Skz151634 /*
2642820Skz151634  * The actual DRM context handling routines
2652820Skz151634  */
2662820Skz151634 int
drm_context_switch(drm_device_t * dev,int old,int new)2672820Skz151634 drm_context_switch(drm_device_t *dev, int old, int new)
2682820Skz151634 {
2692820Skz151634 	if (test_and_set_bit(0, &dev->context_flag)) {
2702820Skz151634 		DRM_ERROR("drm_context_switch: Reentering -- FIXME");
271*5804Scg149915 		return (EBUSY);
2722820Skz151634 	}
2732820Skz151634 
2742820Skz151634 	DRM_DEBUG("drm_context_switch: Context switch from %d to %d",
2752820Skz151634 	    old, new);
2762820Skz151634 
2772820Skz151634 	if (new == dev->last_context) {
2782820Skz151634 		clear_bit(0, &dev->context_flag);
2792820Skz151634 		return (0);
2802820Skz151634 	}
2812820Skz151634 
2822820Skz151634 	return (0);
2832820Skz151634 }
2842820Skz151634 
2852820Skz151634 int
drm_context_switch_complete(drm_device_t * dev,int new)2862820Skz151634 drm_context_switch_complete(drm_device_t *dev, int new)
2872820Skz151634 {
2882820Skz151634 	dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
2892820Skz151634 
2902820Skz151634 	if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
2912820Skz151634 		DRM_ERROR(
2922820Skz151634 		    "drm_context_switch_complete: Lock not held");
2932820Skz151634 	}
2942820Skz151634 	/*
2952820Skz151634 	 * If a context switch is ever initiated
2962820Skz151634 	 * when the kernel holds the lock, release
2972820Skz151634 	 * that lock here.
2982820Skz151634 	 */
2992820Skz151634 	clear_bit(0, &dev->context_flag);
3002820Skz151634 
3012820Skz151634 	return (0);
3022820Skz151634 }
3032820Skz151634 
3042820Skz151634 /*ARGSUSED*/
3052820Skz151634 int
drm_resctx(DRM_IOCTL_ARGS)3062820Skz151634 drm_resctx(DRM_IOCTL_ARGS)
3072820Skz151634 {
3082820Skz151634 	drm_ctx_res_t res;
3092820Skz151634 	drm_ctx_t ctx;
3102820Skz151634 	int i;
3112820Skz151634 
312*5804Scg149915 #ifdef	_MULTI_DATAMODEL
3132820Skz151634 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
314*5804Scg149915 		drm_ctx_res_32_t res32;
315*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&res32, (void *)data, sizeof (res32));
3162820Skz151634 		res.count = res32.count;
317*5804Scg149915 		res.contexts = (drm_ctx_t *)(uintptr_t)res32.contexts;
3182820Skz151634 	} else
319*5804Scg149915 #endif
320*5804Scg149915 		DRM_COPYFROM_WITH_RETURN(&res, (void *)data, sizeof (res));
3212820Skz151634 
3222820Skz151634 	if (res.count >= DRM_RESERVED_CONTEXTS) {
3232820Skz151634 		bzero(&ctx, sizeof (ctx));
3242820Skz151634 		for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
3252820Skz151634 			ctx.handle = i;
326*5804Scg149915 			DRM_COPYTO_WITH_RETURN(&res.contexts[i],
327*5804Scg149915 			    &ctx, sizeof (ctx));
3282820Skz151634 		}
3292820Skz151634 	}
3302820Skz151634 	res.count = DRM_RESERVED_CONTEXTS;
3312820Skz151634 
332*5804Scg149915 #ifdef	_MULTI_DATAMODEL
3332820Skz151634 	if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
334*5804Scg149915 		drm_ctx_res_32_t res32;
3352820Skz151634 		res32.count = res.count;
3362820Skz151634 		res32.contexts = (caddr32_t)(uintptr_t)res.contexts;
3372820Skz151634 
338*5804Scg149915 		DRM_COPYTO_WITH_RETURN((void *)data, &res32,
339*5804Scg149915 		    sizeof (drm_ctx_res_32_t));
3402820Skz151634 	} else
341*5804Scg149915 #endif
342*5804Scg149915 		DRM_COPYTO_WITH_RETURN((void *)data, &res, sizeof (res));
3432820Skz151634 
3442820Skz151634 	return (0);
3452820Skz151634 }
3462820Skz151634 
3472820Skz151634 /*ARGSUSED*/
3482820Skz151634 int
drm_addctx(DRM_IOCTL_ARGS)3492820Skz151634 drm_addctx(DRM_IOCTL_ARGS)
3502820Skz151634 {
3512820Skz151634 	DRM_DEVICE;
3522820Skz151634 	drm_ctx_t ctx;
3532820Skz151634 
354*5804Scg149915 	DRM_COPYFROM_WITH_RETURN(&ctx, (void *)data, sizeof (ctx));
3552820Skz151634 
3562820Skz151634 	ctx.handle = drm_ctxbitmap_next(dev);
3572820Skz151634 	if (ctx.handle == DRM_KERNEL_CONTEXT) {
3582820Skz151634 		/* Skip kernel's context and get a new one. */
3592820Skz151634 		ctx.handle = drm_ctxbitmap_next(dev);
3602820Skz151634 	}
361*5804Scg149915 	if (ctx.handle == (drm_context_t)-1) {
362*5804Scg149915 		return (ENOMEM);
3632820Skz151634 	}
3642820Skz151634 
365*5804Scg149915 	if (dev->driver->context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) {
366*5804Scg149915 		dev->driver->context_ctor(dev, ctx.handle);
3672820Skz151634 	}
3682820Skz151634 
369*5804Scg149915 	DRM_COPYTO_WITH_RETURN((void *)data, &ctx, sizeof (ctx));
3702820Skz151634 
3712820Skz151634 	return (0);
3722820Skz151634 }
3732820Skz151634 
3742820Skz151634 /*ARGSUSED*/
3752820Skz151634 int
drm_modctx(DRM_IOCTL_ARGS)3762820Skz151634 drm_modctx(DRM_IOCTL_ARGS)
3772820Skz151634 {
3782820Skz151634 	/* This does nothing */
3792820Skz151634 	return (0);
3802820Skz151634 }
3812820Skz151634 
3822820Skz151634 /*ARGSUSED*/
3832820Skz151634 int
drm_getctx(DRM_IOCTL_ARGS)3842820Skz151634 drm_getctx(DRM_IOCTL_ARGS)
3852820Skz151634 {
3862820Skz151634 	drm_ctx_t ctx;
3872820Skz151634 
388*5804Scg149915 	DRM_COPYFROM_WITH_RETURN(&ctx, (void *)data, sizeof (ctx));
3892820Skz151634 
3902820Skz151634 	/* This is 0, because we don't handle any context flags */
3912820Skz151634 	ctx.flags = 0;
3922820Skz151634 
393*5804Scg149915 	DRM_COPYTO_WITH_RETURN((void *)data, &ctx, sizeof (ctx));
3942820Skz151634 
3952820Skz151634 	return (0);
3962820Skz151634 }
3972820Skz151634 
3982820Skz151634 /*ARGSUSED*/
3992820Skz151634 int
drm_switchctx(DRM_IOCTL_ARGS)4002820Skz151634 drm_switchctx(DRM_IOCTL_ARGS)
4012820Skz151634 {
4022820Skz151634 	DRM_DEVICE;
4032820Skz151634 	drm_ctx_t ctx;
4042820Skz151634 
405*5804Scg149915 	DRM_COPYFROM_WITH_RETURN(&ctx, (void *)data, sizeof (ctx));
4062820Skz151634 
4072820Skz151634 	DRM_DEBUG("drm_switchctx: %d", ctx.handle);
4082820Skz151634 	return (drm_context_switch(dev, dev->last_context, ctx.handle));
4092820Skz151634 }
4102820Skz151634 
4112820Skz151634 /*ARGSUSED*/
4122820Skz151634 int
drm_newctx(DRM_IOCTL_ARGS)4132820Skz151634 drm_newctx(DRM_IOCTL_ARGS)
4142820Skz151634 {
4152820Skz151634 	DRM_DEVICE;
4162820Skz151634 	drm_ctx_t ctx;
4172820Skz151634 
418*5804Scg149915 	DRM_COPYFROM_WITH_RETURN(&ctx, (void *)data, sizeof (ctx));
4192820Skz151634 
4202820Skz151634 	DRM_DEBUG("drm_newctx: %d", ctx.handle);
4212820Skz151634 	(void) drm_context_switch_complete(dev, ctx.handle);
4222820Skz151634 
4232820Skz151634 	return (0);
4242820Skz151634 }
4252820Skz151634 
4262820Skz151634 /*ARGSUSED*/
4272820Skz151634 int
drm_rmctx(DRM_IOCTL_ARGS)4282820Skz151634 drm_rmctx(DRM_IOCTL_ARGS)
4292820Skz151634 {
4302820Skz151634 	DRM_DEVICE;
4312820Skz151634 	drm_ctx_t ctx;
4322820Skz151634 
433*5804Scg149915 	DRM_COPYFROM_WITH_RETURN(&ctx, (void *)data, sizeof (ctx));
4342820Skz151634 
4352820Skz151634 	DRM_DEBUG("drm_rmctx : %d", ctx.handle);
4362820Skz151634 	if (ctx.handle != DRM_KERNEL_CONTEXT) {
437*5804Scg149915 		if (dev->driver->context_dtor) {
4382820Skz151634 			DRM_LOCK();
439*5804Scg149915 			dev->driver->context_dtor(dev, ctx.handle);
4402820Skz151634 			DRM_UNLOCK();
4412820Skz151634 		}
4422820Skz151634 
4432820Skz151634 		drm_ctxbitmap_free(dev, ctx.handle);
4442820Skz151634 	}
4452820Skz151634 
4462820Skz151634 	return (0);
4472820Skz151634 }
448