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.h

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

Cache object: 70f7018901c2cc985236fa4549e2ab9e


[ 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.