The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/drm/drm_context.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
    2  * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
    3  */
    4 /*-
    5  * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
    6  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
    7  * All Rights Reserved.
    8  *
    9  * Permission is hereby granted, free of charge, to any person obtaining a
   10  * copy of this software and associated documentation files (the "Software"),
   11  * to deal in the Software without restriction, including without limitation
   12  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   13  * and/or sell copies of the Software, and to permit persons to whom the
   14  * Software is furnished to do so, subject to the following conditions:
   15  *
   16  * The above copyright notice and this permission notice (including the next
   17  * paragraph) shall be included in all copies or substantial portions of the
   18  * Software.
   19  *
   20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   23  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   26  * OTHER DEALINGS IN THE SOFTWARE.
   27  *
   28  * Authors:
   29  *    Rickard E. (Rik) Faith <faith@valinux.com>
   30  *    Gareth Hughes <gareth@valinux.com>
   31  *
   32  */
   33 
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: releng/6.4/sys/dev/drm/drm_context.c 153401 2005-12-14 00:52:59Z anholt $");
   36 
   37 #include "dev/drm/drmP.h"
   38 
   39 /* ================================================================
   40  * Context bitmap support
   41  */
   42 
   43 void drm_ctxbitmap_free(drm_device_t *dev, int ctx_handle)
   44 {
   45         if (ctx_handle < 0 || ctx_handle >= DRM_MAX_CTXBITMAP || 
   46             dev->ctx_bitmap == NULL) {
   47                 DRM_ERROR("Attempt to free invalid context handle: %d\n",
   48                    ctx_handle);
   49                 return;
   50         }
   51 
   52         DRM_LOCK();
   53         clear_bit(ctx_handle, dev->ctx_bitmap);
   54         dev->context_sareas[ctx_handle] = NULL;
   55         DRM_UNLOCK();
   56         return;
   57 }
   58 
   59 int drm_ctxbitmap_next(drm_device_t *dev)
   60 {
   61         int bit;
   62 
   63         if (dev->ctx_bitmap == NULL)
   64                 return -1;
   65 
   66         DRM_LOCK();
   67         bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
   68         if (bit >= DRM_MAX_CTXBITMAP) {
   69                 DRM_UNLOCK();
   70                 return -1;
   71         }
   72 
   73         set_bit(bit, dev->ctx_bitmap);
   74         DRM_DEBUG("drm_ctxbitmap_next bit : %d\n", bit);
   75         if ((bit+1) > dev->max_context) {
   76                 dev->max_context = (bit+1);
   77                 if (dev->context_sareas != NULL) {
   78                         drm_local_map_t **ctx_sareas;
   79 
   80                         ctx_sareas = realloc(dev->context_sareas,
   81                             dev->max_context * sizeof(*dev->context_sareas),
   82                             M_DRM, M_NOWAIT);
   83                         if (ctx_sareas == NULL) {
   84                                 clear_bit(bit, dev->ctx_bitmap);
   85                                 DRM_UNLOCK();
   86                                 return -1;
   87                         }
   88                         dev->context_sareas = ctx_sareas;
   89                         dev->context_sareas[bit] = NULL;
   90                 } else {
   91                         /* max_context == 1 at this point */
   92                         dev->context_sareas = malloc(dev->max_context * 
   93                             sizeof(*dev->context_sareas), M_DRM, M_NOWAIT);
   94                         if (dev->context_sareas == NULL) {
   95                                 clear_bit(bit, dev->ctx_bitmap);
   96                                 DRM_UNLOCK();
   97                                 return -1;
   98                         }
   99                         dev->context_sareas[bit] = NULL;
  100                 }
  101         }
  102         DRM_UNLOCK();
  103         return bit;
  104 }
  105 
  106 int drm_ctxbitmap_init(drm_device_t *dev)
  107 {
  108         int i;
  109         int temp;
  110 
  111         DRM_LOCK();
  112         dev->ctx_bitmap = malloc(PAGE_SIZE, M_DRM, M_NOWAIT | M_ZERO);
  113         if ( dev->ctx_bitmap == NULL ) {
  114                 DRM_UNLOCK();
  115                 return DRM_ERR(ENOMEM);
  116         }
  117         dev->context_sareas = NULL;
  118         dev->max_context = -1;
  119         DRM_UNLOCK();
  120 
  121         for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
  122                 temp = drm_ctxbitmap_next(dev);
  123                 DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
  124         }
  125 
  126         return 0;
  127 }
  128 
  129 void drm_ctxbitmap_cleanup(drm_device_t *dev)
  130 {
  131         DRM_LOCK();
  132         if (dev->context_sareas != NULL)
  133                 free(dev->context_sareas, M_DRM);
  134         free(dev->ctx_bitmap, M_DRM);
  135         DRM_UNLOCK();
  136 }
  137 
  138 /* ================================================================
  139  * Per Context SAREA Support
  140  */
  141 
  142 int drm_getsareactx( DRM_IOCTL_ARGS )
  143 {
  144         DRM_DEVICE;
  145         drm_ctx_priv_map_t request;
  146         drm_local_map_t *map;
  147 
  148         DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data, 
  149                            sizeof(request) );
  150 
  151         DRM_LOCK();
  152         if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
  153                 DRM_UNLOCK();
  154                 return DRM_ERR(EINVAL);
  155         }
  156 
  157         map = dev->context_sareas[request.ctx_id];
  158         DRM_UNLOCK();
  159 
  160         request.handle = map->handle;
  161 
  162         DRM_COPY_TO_USER_IOCTL( (drm_ctx_priv_map_t *)data, request, sizeof(request) );
  163 
  164         return 0;
  165 }
  166 
  167 int drm_setsareactx( DRM_IOCTL_ARGS )
  168 {
  169         DRM_DEVICE;
  170         drm_ctx_priv_map_t request;
  171         drm_local_map_t *map = NULL;
  172 
  173         DRM_COPY_FROM_USER_IOCTL( request, (drm_ctx_priv_map_t *)data,
  174                            sizeof(request) );
  175 
  176         DRM_LOCK();
  177         TAILQ_FOREACH(map, &dev->maplist, link) {
  178                 if (map->handle == request.handle) {
  179                         if (dev->max_context < 0)
  180                                 goto bad;
  181                         if (request.ctx_id >= (unsigned) dev->max_context)
  182                                 goto bad;
  183                         dev->context_sareas[request.ctx_id] = map;
  184                         DRM_UNLOCK();
  185                         return 0;
  186                 }
  187         }
  188 
  189 bad:
  190         DRM_UNLOCK();
  191         return DRM_ERR(EINVAL);
  192 }
  193 
  194 /* ================================================================
  195  * The actual DRM context handling routines
  196  */
  197 
  198 int drm_context_switch(drm_device_t *dev, int old, int new)
  199 {
  200         if ( test_and_set_bit( 0, &dev->context_flag ) ) {
  201                 DRM_ERROR( "Reentering -- FIXME\n" );
  202                 return DRM_ERR(EBUSY);
  203         }
  204 
  205         DRM_DEBUG( "Context switch from %d to %d\n", old, new );
  206 
  207         if ( new == dev->last_context ) {
  208                 clear_bit( 0, &dev->context_flag );
  209                 return 0;
  210         }
  211 
  212         return 0;
  213 }
  214 
  215 int drm_context_switch_complete(drm_device_t *dev, int new)
  216 {
  217         dev->last_context = new;  /* PRE/POST: This is the _only_ writer. */
  218 
  219         if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
  220                 DRM_ERROR( "Lock isn't held after context switch\n" );
  221         }
  222 
  223                                 /* If a context switch is ever initiated
  224                                    when the kernel holds the lock, release
  225                                    that lock here. */
  226         clear_bit( 0, &dev->context_flag );
  227 
  228         return 0;
  229 }
  230 
  231 int drm_resctx(DRM_IOCTL_ARGS)
  232 {
  233         drm_ctx_res_t res;
  234         drm_ctx_t ctx;
  235         int i;
  236 
  237         DRM_COPY_FROM_USER_IOCTL( res, (drm_ctx_res_t *)data, sizeof(res) );
  238 
  239         if ( res.count >= DRM_RESERVED_CONTEXTS ) {
  240                 bzero(&ctx, sizeof(ctx));
  241                 for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
  242                         ctx.handle = i;
  243                         if ( DRM_COPY_TO_USER( &res.contexts[i],
  244                                            &ctx, sizeof(ctx) ) )
  245                                 return DRM_ERR(EFAULT);
  246                 }
  247         }
  248         res.count = DRM_RESERVED_CONTEXTS;
  249 
  250         DRM_COPY_TO_USER_IOCTL( (drm_ctx_res_t *)data, res, sizeof(res) );
  251 
  252         return 0;
  253 }
  254 
  255 int drm_addctx(DRM_IOCTL_ARGS)
  256 {
  257         DRM_DEVICE;
  258         drm_ctx_t ctx;
  259 
  260         DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
  261 
  262         ctx.handle = drm_ctxbitmap_next(dev);
  263         if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
  264                                 /* Skip kernel's context and get a new one. */
  265                 ctx.handle = drm_ctxbitmap_next(dev);
  266         }
  267         DRM_DEBUG( "%d\n", ctx.handle );
  268         if ( ctx.handle == -1 ) {
  269                 DRM_DEBUG( "Not enough free contexts.\n" );
  270                                 /* Should this return -EBUSY instead? */
  271                 return DRM_ERR(ENOMEM);
  272         }
  273 
  274         if (dev->driver.context_ctor && ctx.handle != DRM_KERNEL_CONTEXT) {
  275                 DRM_LOCK();
  276                 dev->driver.context_ctor(dev, ctx.handle);
  277                 DRM_UNLOCK();
  278         }
  279 
  280         DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
  281 
  282         return 0;
  283 }
  284 
  285 int drm_modctx(DRM_IOCTL_ARGS)
  286 {
  287         /* This does nothing */
  288         return 0;
  289 }
  290 
  291 int drm_getctx(DRM_IOCTL_ARGS)
  292 {
  293         drm_ctx_t ctx;
  294 
  295         DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
  296 
  297         /* This is 0, because we don't handle any context flags */
  298         ctx.flags = 0;
  299 
  300         DRM_COPY_TO_USER_IOCTL( (drm_ctx_t *)data, ctx, sizeof(ctx) );
  301 
  302         return 0;
  303 }
  304 
  305 int drm_switchctx(DRM_IOCTL_ARGS)
  306 {
  307         DRM_DEVICE;
  308         drm_ctx_t ctx;
  309 
  310         DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
  311 
  312         DRM_DEBUG( "%d\n", ctx.handle );
  313         return drm_context_switch(dev, dev->last_context, ctx.handle);
  314 }
  315 
  316 int drm_newctx(DRM_IOCTL_ARGS)
  317 {
  318         DRM_DEVICE;
  319         drm_ctx_t ctx;
  320 
  321         DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
  322 
  323         DRM_DEBUG( "%d\n", ctx.handle );
  324         drm_context_switch_complete(dev, ctx.handle);
  325 
  326         return 0;
  327 }
  328 
  329 int drm_rmctx(DRM_IOCTL_ARGS)
  330 {
  331         DRM_DEVICE;
  332         drm_ctx_t ctx;
  333 
  334         DRM_COPY_FROM_USER_IOCTL( ctx, (drm_ctx_t *)data, sizeof(ctx) );
  335 
  336         DRM_DEBUG( "%d\n", ctx.handle );
  337         if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
  338                 if (dev->driver.context_dtor) {
  339                         DRM_LOCK();
  340                         dev->driver.context_dtor(dev, ctx.handle);
  341                         DRM_UNLOCK();
  342                 }
  343 
  344                 drm_ctxbitmap_free(dev, ctx.handle);
  345         }
  346 
  347         return 0;
  348 }

Cache object: ec64a583160673ac00137dc40ad4f766


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.