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/sis_mm.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 /* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*-
    2  * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw *
    3  */
    4 /*-
    5  * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
    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  * PRECISION INSIGHT 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 OTHER
   25  * DEALINGS IN THE SOFTWARE.
   26  * 
   27  * Authors:
   28  *    Sung-Ching Lin <sclin@sis.com.tw>
   29  * 
   30  * $FreeBSD$
   31  */
   32 
   33 #include "dev/drm/sis.h"
   34 #include "dev/drm/drmP.h"
   35 #include "dev/drm/sis_drm.h"
   36 #include "dev/drm/sis_drv.h"
   37 #include "dev/drm/sis_ds.h"
   38 #if defined(__linux__) && defined(CONFIG_FB_SIS)
   39 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
   40 #include <video/sisfb.h>
   41 #else
   42 #include <linux/sisfb.h>
   43 #endif
   44 #endif
   45 
   46 #define MAX_CONTEXT 100
   47 #define VIDEO_TYPE 0 
   48 #define AGP_TYPE 1
   49 
   50 typedef struct {
   51         int used;
   52         int context;
   53         set_t *sets[2]; /* 0 for video, 1 for AGP */
   54 } sis_context_t;
   55 
   56 static sis_context_t global_ppriv[MAX_CONTEXT];
   57 
   58 
   59 static int add_alloc_set(int context, int type, unsigned int val)
   60 {
   61         int i, retval = 0;
   62         
   63         for (i = 0; i < MAX_CONTEXT; i++) {
   64                 if (global_ppriv[i].used && global_ppriv[i].context == context)
   65                 {
   66                         retval = setAdd(global_ppriv[i].sets[type], val);
   67                         break;
   68                 }
   69         }
   70         return retval;
   71 }
   72 
   73 static int del_alloc_set(int context, int type, unsigned int val)
   74 {  
   75         int i, retval = 0;
   76 
   77         for (i = 0; i < MAX_CONTEXT; i++) {
   78                 if (global_ppriv[i].used && global_ppriv[i].context == context)
   79                 {
   80                         retval = setDel(global_ppriv[i].sets[type], val);
   81                         break;
   82                 }
   83         }
   84         return retval;
   85 }
   86 
   87 /* fb management via fb device */ 
   88 #if defined(__linux__) && defined(CONFIG_FB_SIS)
   89 
   90 int sis_fb_init( DRM_IOCTL_ARGS )
   91 {
   92         return 0;
   93 }
   94 
   95 int sis_fb_alloc( DRM_IOCTL_ARGS )
   96 {
   97         drm_sis_mem_t fb;
   98         struct sis_memreq req;
   99         int retval = 0;
  100 
  101         DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
  102 
  103         req.size = fb.size;
  104         sis_malloc(&req);
  105         if (req.offset) {
  106                 /* TODO */
  107                 fb.offset = req.offset;
  108                 fb.free = req.offset;
  109                 if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
  110                         DRM_DEBUG("adding to allocation set fails\n");
  111                         sis_free(req.offset);
  112                         retval = DRM_ERR(EINVAL);
  113                 }
  114         } else {  
  115                 fb.offset = 0;
  116                 fb.size = 0;
  117                 fb.free = 0;
  118         }
  119 
  120         DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
  121 
  122         DRM_DEBUG("alloc fb, size = %d, offset = %ld\n", fb.size, req.offset);
  123 
  124         return retval;
  125 }
  126 
  127 int sis_fb_free( DRM_IOCTL_ARGS )
  128 {
  129         drm_sis_mem_t fb;
  130         int retval = 0;
  131 
  132         DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
  133 
  134         if (!fb.free)
  135                 return DRM_ERR(EINVAL);
  136 
  137         if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
  138                 retval = DRM_ERR(EINVAL);
  139         sis_free(fb.free);
  140 
  141         DRM_DEBUG("free fb, offset = 0x%lx\n", fb.free);
  142 
  143         return retval;
  144 }
  145 
  146 #else
  147 
  148 /* Called by the X Server to initialize the FB heap.  Allocations will fail
  149  * unless this is called.  Offset is the beginning of the heap from the
  150  * framebuffer offset (MaxXFBMem in XFree86).
  151  *
  152  * Memory layout according to Thomas Winischofer:
  153  * |------------------|DDDDDDDDDDDDDDDDDDDDDDDDDDDDD|HHHH|CCCCCCCCCCC|
  154  *
  155  *    X driver/sisfb                                  HW-   Command-
  156  *  framebuffer memory           DRI heap           Cursor   queue
  157  */
  158 int sis_fb_init( DRM_IOCTL_ARGS )
  159 {
  160         DRM_DEVICE;
  161         drm_sis_private_t *dev_priv = dev->dev_private;
  162         drm_sis_fb_t fb;
  163 
  164         DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_fb_t *)data, sizeof(fb));
  165 
  166         if (dev_priv == NULL) {
  167                 dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
  168                     DRM_MEM_DRIVER);
  169                 dev_priv = dev->dev_private;
  170                 if (dev_priv == NULL)
  171                         return ENOMEM;
  172         }
  173 
  174         if (dev_priv->FBHeap != NULL)
  175                 return DRM_ERR(EINVAL);
  176 
  177         dev_priv->FBHeap = mmInit(fb.offset, fb.size);
  178 
  179         DRM_DEBUG("offset = %u, size = %u", fb.offset, fb.size);
  180 
  181         return 0;
  182 }
  183 
  184 int sis_fb_alloc( DRM_IOCTL_ARGS )
  185 {
  186         DRM_DEVICE;
  187         drm_sis_private_t *dev_priv = dev->dev_private;
  188         drm_sis_mem_t fb;
  189         PMemBlock block;
  190         int retval = 0;
  191 
  192         if (dev_priv == NULL || dev_priv->FBHeap == NULL)
  193                 return DRM_ERR(EINVAL);
  194   
  195         DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
  196   
  197         block = mmAllocMem(dev_priv->FBHeap, fb.size, 0, 0);
  198         if (block) {
  199                 /* TODO */
  200                 fb.offset = block->ofs;
  201                 fb.free = (unsigned long)block;
  202                 if (!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)) {
  203                         DRM_DEBUG("adding to allocation set fails\n");
  204                         mmFreeMem((PMemBlock)fb.free);
  205                         retval = DRM_ERR(EINVAL);
  206                 }
  207         } else {
  208                 fb.offset = 0;
  209                 fb.size = 0;
  210                 fb.free = 0;
  211         }
  212 
  213         DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, fb, sizeof(fb));
  214 
  215         DRM_DEBUG("alloc fb, size = %d, offset = %d\n", fb.size, fb.offset);
  216 
  217         return retval;
  218 }
  219 
  220 int sis_fb_free( DRM_IOCTL_ARGS )
  221 {
  222         DRM_DEVICE;
  223         drm_sis_private_t *dev_priv = dev->dev_private;
  224         drm_sis_mem_t fb;
  225 
  226         if (dev_priv == NULL || dev_priv->FBHeap == NULL)
  227                 return DRM_ERR(EINVAL);
  228 
  229         DRM_COPY_FROM_USER_IOCTL(fb, (drm_sis_mem_t *)data, sizeof(fb));
  230 
  231         if (!mmBlockInHeap(dev_priv->FBHeap, (PMemBlock)fb.free))
  232                 return DRM_ERR(EINVAL);
  233 
  234         if (!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
  235                 return DRM_ERR(EINVAL);
  236         mmFreeMem((PMemBlock)fb.free);
  237 
  238         DRM_DEBUG("free fb, free = 0x%lx\n", fb.free);
  239 
  240         return 0;
  241 }
  242 
  243 #endif
  244 
  245 /* agp memory management */ 
  246 
  247 int sis_ioctl_agp_init( DRM_IOCTL_ARGS )
  248 {
  249         DRM_DEVICE;
  250         drm_sis_private_t *dev_priv = dev->dev_private;
  251         drm_sis_agp_t agp;
  252 
  253         if (dev_priv == NULL) {
  254                 dev->dev_private = DRM(calloc)(1, sizeof(drm_sis_private_t),
  255                     DRM_MEM_DRIVER);
  256                 dev_priv = dev->dev_private;
  257                 if (dev_priv == NULL)
  258                         return ENOMEM;
  259         }
  260 
  261         if (dev_priv->AGPHeap != NULL)
  262                 return DRM_ERR(EINVAL);
  263 
  264         DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_agp_t *)data, sizeof(agp));
  265 
  266         dev_priv->AGPHeap = mmInit(agp.offset, agp.size);
  267 
  268         DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
  269   
  270         return 0;
  271 }
  272 
  273 int sis_ioctl_agp_alloc( DRM_IOCTL_ARGS )
  274 {
  275         DRM_DEVICE;
  276         drm_sis_private_t *dev_priv = dev->dev_private;
  277         drm_sis_mem_t agp;
  278         PMemBlock block;
  279         int retval = 0;
  280    
  281         if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
  282                 return DRM_ERR(EINVAL);
  283   
  284         DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t *)data, sizeof(agp));
  285   
  286         block = mmAllocMem(dev_priv->AGPHeap, agp.size, 0, 0);
  287         if (block) {
  288                 /* TODO */
  289                 agp.offset = block->ofs;
  290                 agp.free = (unsigned long)block;
  291                 if (!add_alloc_set(agp.context, AGP_TYPE, agp.free)) {
  292                         DRM_DEBUG("adding to allocation set fails\n");
  293                         mmFreeMem((PMemBlock)agp.free);
  294                         retval = -1;
  295                 }
  296         } else {  
  297                 agp.offset = 0;
  298                 agp.size = 0;
  299                 agp.free = 0;
  300         }
  301 
  302         DRM_COPY_TO_USER_IOCTL((drm_sis_mem_t *)data, agp, sizeof(agp));
  303 
  304         DRM_DEBUG("alloc agp, size = %d, offset = %d\n", agp.size, agp.offset);
  305 
  306         return retval;
  307 }
  308 
  309 int sis_ioctl_agp_free( DRM_IOCTL_ARGS )
  310 {
  311         DRM_DEVICE;
  312         drm_sis_private_t *dev_priv = dev->dev_private;
  313         drm_sis_mem_t agp;
  314 
  315         if (dev_priv == NULL || dev_priv->AGPHeap == NULL)
  316                 return DRM_ERR(EINVAL);
  317 
  318         DRM_COPY_FROM_USER_IOCTL(agp, (drm_sis_mem_t *)data, sizeof(agp));
  319 
  320         if (!mmBlockInHeap(dev_priv->AGPHeap, (PMemBlock)agp.free))
  321                 return DRM_ERR(EINVAL);
  322 
  323         mmFreeMem((PMemBlock)agp.free);
  324         if (!del_alloc_set(agp.context, AGP_TYPE, agp.free))
  325                 return DRM_ERR(EINVAL);
  326 
  327         DRM_DEBUG("free agp, free = 0x%lx\n", agp.free);
  328 
  329         return 0;
  330 }
  331 
  332 int sis_init_context(int context)
  333 {
  334         int i;
  335 
  336         for (i = 0; i < MAX_CONTEXT ; i++) {
  337                 if (global_ppriv[i].used &&
  338                     (global_ppriv[i].context == context))
  339                         break;
  340         }
  341 
  342         if (i >= MAX_CONTEXT) {
  343                 for (i = 0; i < MAX_CONTEXT ; i++) {
  344                         if (!global_ppriv[i].used) {
  345                                 global_ppriv[i].context = context;
  346                                 global_ppriv[i].used = 1;
  347                                 global_ppriv[i].sets[0] = setInit();
  348                                 global_ppriv[i].sets[1] = setInit();
  349                                 DRM_DEBUG("init allocation set, socket=%d, "
  350                                     "context = %d\n", i, context);
  351                                 break;
  352                         }
  353                 }
  354                 if ((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
  355                     (global_ppriv[i].sets[1] == NULL))
  356                 {
  357                         return 0;
  358                 }
  359         }
  360         
  361         return 1;
  362 }
  363 
  364 int sis_final_context(int context)
  365 {
  366         int i;
  367 
  368         for (i=0; i<MAX_CONTEXT; i++) {
  369                 if (global_ppriv[i].used &&
  370                     (global_ppriv[i].context == context))
  371                         break;
  372         }
  373 
  374         if (i < MAX_CONTEXT) {
  375                 set_t *set;
  376                 ITEM_TYPE item;
  377                 int retval;
  378 
  379                 DRM_DEBUG("find socket %d, context = %d\n", i, context);
  380 
  381                 /* Video Memory */
  382                 set = global_ppriv[i].sets[0];
  383                 retval = setFirst(set, &item);
  384                 while (retval) {
  385                         DRM_DEBUG("free video memory 0x%lx\n", item);
  386 #if defined(__linux__) && defined(CONFIG_FB_SIS)
  387                         sis_free(item);
  388 #else
  389                         mmFreeMem((PMemBlock)item);
  390 #endif
  391                         retval = setNext(set, &item);
  392                 }
  393                 setDestroy(set);
  394 
  395                 /* AGP Memory */
  396                 set = global_ppriv[i].sets[1];
  397                 retval = setFirst(set, &item);
  398                 while (retval) {
  399                         DRM_DEBUG("free agp memory 0x%lx\n", item);
  400                         mmFreeMem((PMemBlock)item);
  401                         retval = setNext(set, &item);
  402                 }
  403                 setDestroy(set);
  404 
  405                 global_ppriv[i].used = 0;         
  406         }
  407         
  408         return 1;
  409 }

Cache object: 440ff381428a4feaa1b16932e6e4e28d


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