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_sysctl.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 /*-
    2  * Copyright 2003 Eric Anholt
    3  * All Rights Reserved.
    4  *
    5  * Permission is hereby granted, free of charge, to any person obtaining a
    6  * copy of this software and associated documentation files (the "Software"),
    7  * to deal in the Software without restriction, including without limitation
    8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
    9  * and/or sell copies of the Software, and to permit persons to whom the
   10  * Software is furnished to do so, subject to the following conditions:
   11  * 
   12  * The above copyright notice and this permission notice (including the next
   13  * paragraph) shall be included in all copies or substantial portions of the
   14  * Software.
   15  * 
   16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   19  * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
   20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
   21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
   22  */
   23 
   24 #include <sys/cdefs.h>
   25 __FBSDID("$FreeBSD: releng/6.4/sys/dev/drm/drm_sysctl.c 153401 2005-12-14 00:52:59Z anholt $");
   26 
   27 #include "dev/drm/drmP.h"
   28 #include "dev/drm/drm.h"
   29 
   30 #include <sys/sysctl.h>
   31 
   32 static int         drm_name_info DRM_SYSCTL_HANDLER_ARGS;
   33 static int         drm_vm_info DRM_SYSCTL_HANDLER_ARGS;
   34 static int         drm_clients_info DRM_SYSCTL_HANDLER_ARGS;
   35 static int         drm_bufs_info DRM_SYSCTL_HANDLER_ARGS;
   36 
   37 struct drm_sysctl_list {
   38         const char *name;
   39         int        (*f) DRM_SYSCTL_HANDLER_ARGS;
   40 } drm_sysctl_list[] = {
   41         {"name",    drm_name_info},
   42         {"vm",      drm_vm_info},
   43         {"clients", drm_clients_info},
   44         {"bufs",    drm_bufs_info},
   45 };
   46 #define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0]))
   47 
   48 struct drm_sysctl_info {
   49         struct sysctl_ctx_list ctx;
   50         char                   name[2];
   51 };
   52 
   53 int drm_sysctl_init(drm_device_t *dev)
   54 {
   55         struct drm_sysctl_info *info;
   56         struct sysctl_oid *oid;
   57         struct sysctl_oid *top, *drioid;
   58         int               i;
   59 
   60         info = malloc(sizeof *info, M_DRM, M_WAITOK | M_ZERO);
   61         if ( !info )
   62                 return 1;
   63         dev->sysctl = info;
   64 
   65         /* Add the sysctl node for DRI if it doesn't already exist */
   66         drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
   67         if (!drioid)
   68                 return 1;
   69 
   70         /* Find the next free slot under hw.dri */
   71         i = 0;
   72         SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
   73                 if (i <= oid->oid_arg2)
   74                         i = oid->oid_arg2 + 1;
   75         }
   76         if (i>9)
   77                 return 1;
   78         
   79         /* Add the hw.dri.x for our device */
   80         info->name[0] = '' + i;
   81         info->name[1] = 0;
   82         top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
   83         if (!top)
   84                 return 1;
   85         
   86         for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
   87                 oid = SYSCTL_ADD_OID(&info->ctx, 
   88                         SYSCTL_CHILDREN(top), 
   89                         OID_AUTO, 
   90                         drm_sysctl_list[i].name, 
   91                         CTLTYPE_INT | CTLFLAG_RD, 
   92                         dev, 
   93                         0, 
   94                         drm_sysctl_list[i].f, 
   95                         "A", 
   96                         NULL);
   97                 if (!oid)
   98                         return 1;
   99         }
  100         SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(top), OID_AUTO, "debug",
  101             CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag),
  102             "Enable debugging output");
  103 
  104         return 0;
  105 }
  106 
  107 int drm_sysctl_cleanup(drm_device_t *dev)
  108 {
  109         int error;
  110         error = sysctl_ctx_free( &dev->sysctl->ctx );
  111 
  112         free(dev->sysctl, M_DRM);
  113         dev->sysctl = NULL;
  114 
  115         return error;
  116 }
  117 
  118 #define DRM_SYSCTL_PRINT(fmt, arg...)                           \
  119 do {                                                            \
  120         snprintf(buf, sizeof(buf), fmt, ##arg);                 \
  121         retcode = SYSCTL_OUT(req, buf, strlen(buf));            \
  122         if (retcode)                                            \
  123                 goto done;                                      \
  124 } while (0)
  125 
  126 static int drm_name_info DRM_SYSCTL_HANDLER_ARGS
  127 {
  128         drm_device_t *dev = arg1;
  129         char buf[128];
  130         int retcode;
  131         int hasunique = 0;
  132 
  133         DRM_SYSCTL_PRINT("%s 0x%x", dev->driver.name, dev2udev(dev->devnode));
  134         
  135         DRM_LOCK();
  136         if (dev->unique) {
  137                 snprintf(buf, sizeof(buf), " %s", dev->unique);
  138                 hasunique = 1;
  139         }
  140         DRM_UNLOCK();
  141         
  142         if (hasunique)
  143                 SYSCTL_OUT(req, buf, strlen(buf));
  144 
  145         SYSCTL_OUT(req, "", 1);
  146 
  147 done:
  148         return retcode;
  149 }
  150 
  151 static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
  152 {
  153         drm_device_t *dev = arg1;
  154         drm_local_map_t *map, *tempmaps;
  155         const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
  156         const char *type, *yesno;
  157         int i, mapcount;
  158         char buf[128];
  159         int retcode;
  160 
  161         /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
  162          * temporary copy of all the map entries and then SYSCTL_OUT that.
  163          */
  164         DRM_LOCK();
  165 
  166         mapcount = 0;
  167         TAILQ_FOREACH(map, &dev->maplist, link)
  168                 mapcount++;
  169 
  170         tempmaps = malloc(sizeof(drm_local_map_t) * mapcount, M_DRM, M_NOWAIT);
  171         if (tempmaps == NULL) {
  172                 DRM_UNLOCK();
  173                 return ENOMEM;
  174         }
  175 
  176         i = 0;
  177         TAILQ_FOREACH(map, &dev->maplist, link)
  178                 tempmaps[i++] = *map;
  179 
  180         DRM_UNLOCK();
  181 
  182         DRM_SYSCTL_PRINT("\nslot         offset       size type flags    "
  183                          "address mtrr\n");
  184 
  185         for (i = 0; i < mapcount; i++) {
  186                 map = &tempmaps[i];
  187 
  188                 if (map->type < 0 || map->type > 4)
  189                         type = "??";
  190                 else
  191                         type = types[map->type];
  192 
  193                 if (!map->mtrr)
  194                         yesno = "no";
  195                 else
  196                         yesno = "yes";
  197 
  198                 DRM_SYSCTL_PRINT(
  199                     "%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx %s\n", i,
  200                     map->offset, map->size, type, map->flags,
  201                     (unsigned long)map->handle, yesno);
  202         }
  203         SYSCTL_OUT(req, "", 1);
  204 
  205 done:
  206         free(tempmaps, M_DRM);
  207         return retcode;
  208 }
  209 
  210 static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
  211 {
  212         drm_device_t     *dev = arg1;
  213         drm_device_dma_t *dma = dev->dma;
  214         drm_device_dma_t tempdma;
  215         int *templists;
  216         int i;
  217         char buf[128];
  218         int retcode;
  219 
  220         /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
  221          * copy of the whole structure and the relevant data from buflist.
  222          */
  223         DRM_LOCK();
  224         if (dma == NULL) {
  225                 DRM_UNLOCK();
  226                 return 0;
  227         }
  228         DRM_SPINLOCK(&dev->dma_lock);
  229         tempdma = *dma;
  230         templists = malloc(sizeof(int) * dma->buf_count, M_DRM, M_NOWAIT);
  231         for (i = 0; i < dma->buf_count; i++)
  232                 templists[i] = dma->buflist[i]->list;
  233         dma = &tempdma;
  234         DRM_SPINUNLOCK(&dev->dma_lock);
  235         DRM_UNLOCK();
  236 
  237         DRM_SYSCTL_PRINT("\n o     size count  free      segs pages    kB\n");
  238         for (i = 0; i <= DRM_MAX_ORDER; i++) {
  239                 if (dma->bufs[i].buf_count)
  240                         DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
  241                                        i,
  242                                        dma->bufs[i].buf_size,
  243                                        dma->bufs[i].buf_count,
  244                                        atomic_read(&dma->bufs[i]
  245                                                    .freelist.count),
  246                                        dma->bufs[i].seg_count,
  247                                        dma->bufs[i].seg_count
  248                                        *(1 << dma->bufs[i].page_order),
  249                                        (dma->bufs[i].seg_count
  250                                         * (1 << dma->bufs[i].page_order))
  251                                        * PAGE_SIZE / 1024);
  252         }
  253         DRM_SYSCTL_PRINT("\n");
  254         for (i = 0; i < dma->buf_count; i++) {
  255                 if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
  256                 DRM_SYSCTL_PRINT(" %d", templists[i]);
  257         }
  258         DRM_SYSCTL_PRINT("\n");
  259 
  260         SYSCTL_OUT(req, "", 1);
  261 done:
  262         free(templists, M_DRM);
  263         return retcode;
  264 }
  265 
  266 static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
  267 {
  268         drm_device_t *dev = arg1;
  269         drm_file_t *priv, *tempprivs;
  270         char buf[128];
  271         int retcode;
  272         int privcount, i;
  273 
  274         DRM_LOCK();
  275 
  276         privcount = 0;
  277         TAILQ_FOREACH(priv, &dev->files, link)
  278                 privcount++;
  279 
  280         tempprivs = malloc(sizeof(drm_file_t) * privcount, M_DRM, M_NOWAIT);
  281         if (tempprivs == NULL) {
  282                 DRM_UNLOCK();
  283                 return ENOMEM;
  284         }
  285         i = 0;
  286         TAILQ_FOREACH(priv, &dev->files, link)
  287                 tempprivs[i++] = *priv;
  288 
  289         DRM_UNLOCK();
  290 
  291         DRM_SYSCTL_PRINT("\na dev       pid    uid      magic     ioctls\n");
  292         for (i = 0; i < privcount; i++) {
  293                 priv = &tempprivs[i];
  294                 DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
  295                                priv->authenticated ? 'y' : 'n',
  296                                priv->minor,
  297                                priv->pid,
  298                                priv->uid,
  299                                priv->magic,
  300                                priv->ioctl_count);
  301         }
  302 
  303         SYSCTL_OUT(req, "", 1);
  304 done:
  305         free(tempprivs, M_DRM);
  306         return retcode;
  307 }

Cache object: eea0dc1cebd7cd08bc5beabecdc2b346


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