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.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 /*-
    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  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
   20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   22  * DEALINGS IN THE SOFTWARE.
   23  *
   24  * $FreeBSD$
   25  */
   26 
   27 #ifdef __FreeBSD__
   28 
   29 #include <sys/sysctl.h>
   30 
   31 static int         DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
   32 static int         DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
   33 static int         DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS;
   34 #if __HAVE_DMA
   35 static int         DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS;
   36 #endif
   37 
   38 struct DRM(sysctl_list) {
   39         const char *name;
   40         int        (*f) DRM_SYSCTL_HANDLER_ARGS;
   41 } DRM(sysctl_list)[] = {
   42         { "name",    DRM(name_info)    },
   43 #ifdef DEBUG_MEMORY
   44         { "mem",     DRM(mem_info)     },
   45 #endif
   46         { "vm",      DRM(vm_info)      },
   47         { "clients", DRM(clients_info) },
   48 #if __HAVE_DMA
   49         { "bufs",    DRM(bufs_info)    },
   50 #endif
   51 };
   52 #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
   53 
   54 struct drm_sysctl_info {
   55         struct sysctl_ctx_list ctx;
   56         char                   name[2];
   57 };
   58 
   59 int DRM(sysctl_init)(drm_device_t *dev)
   60 {
   61         struct drm_sysctl_info *info;
   62         struct sysctl_oid *oid;
   63         struct sysctl_oid *top, *drioid;
   64         int               i;
   65 
   66         info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
   67         if ( !info )
   68                 return 1;
   69         bzero(info, sizeof *info);
   70         dev->sysctl = info;
   71 
   72         /* Add the sysctl node for DRI if it doesn't already exist */
   73         drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
   74         if (!drioid)
   75                 return 1;
   76 
   77         /* Find the next free slot under hw.dri */
   78         i = 0;
   79         SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
   80                 if (i <= oid->oid_arg2)
   81                         i = oid->oid_arg2 + 1;
   82         }
   83         if (i>9)
   84                 return 1;
   85         
   86         /* Add the hw.dri.x for our device */
   87         info->name[0] = '' + i;
   88         info->name[1] = 0;
   89         top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
   90         if (!top)
   91                 return 1;
   92         
   93         for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
   94                 oid = SYSCTL_ADD_OID( &info->ctx, 
   95                         SYSCTL_CHILDREN(top), 
   96                         OID_AUTO, 
   97                         DRM(sysctl_list)[i].name, 
   98                         CTLTYPE_INT | CTLFLAG_RD, 
   99                         dev, 
  100                         0, 
  101                         DRM(sysctl_list)[i].f, 
  102                         "A", 
  103                         NULL);
  104                 if (!oid)
  105                         return 1;
  106         }
  107         return 0;
  108 }
  109 
  110 int DRM(sysctl_cleanup)(drm_device_t *dev)
  111 {
  112         int error;
  113         error = sysctl_ctx_free( &dev->sysctl->ctx );
  114 
  115         DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
  116         dev->sysctl = NULL;
  117 
  118         return error;
  119 }
  120 
  121 #define DRM_SYSCTL_PRINT(fmt, arg...)                           \
  122 do {                                                            \
  123         snprintf(buf, sizeof(buf), fmt, ##arg);                 \
  124         retcode = SYSCTL_OUT(req, buf, strlen(buf));            \
  125         if (retcode)                                            \
  126                 goto done;                                      \
  127 } while (0)
  128 
  129 static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
  130 {
  131         drm_device_t *dev = arg1;
  132         char buf[128];
  133         int retcode;
  134         int hasunique = 0;
  135 
  136         DRM_SYSCTL_PRINT("%s 0x%x", dev->name, dev2udev(dev->devnode));
  137         
  138         DRM_LOCK();
  139         if (dev->unique) {
  140                 snprintf(buf, sizeof(buf), " %s", dev->unique);
  141                 hasunique = 1;
  142         }
  143         DRM_UNLOCK();
  144         
  145         if (hasunique)
  146                 SYSCTL_OUT(req, buf, strlen(buf));
  147 
  148         SYSCTL_OUT(req, "", 1);
  149 
  150 done:
  151         return retcode;
  152 }
  153 
  154 static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
  155 {
  156         drm_device_t *dev = arg1;
  157         drm_local_map_t *map, *tempmaps;
  158         drm_map_list_entry_t    *listentry;
  159         const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
  160         const char *type, *yesno;
  161         int i, mapcount;
  162         char buf[128];
  163         int retcode;
  164 
  165         /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
  166          * temporary copy of all the map entries and then SYSCTL_OUT that.
  167          */
  168         DRM_LOCK();
  169 
  170         mapcount = 0;
  171         TAILQ_FOREACH(listentry, dev->maplist, link)
  172                 mapcount++;
  173 
  174         tempmaps = DRM(alloc)(sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
  175         if (tempmaps == NULL) {
  176                 DRM_UNLOCK();
  177                 return ENOMEM;
  178         }
  179 
  180         i = 0;
  181         TAILQ_FOREACH(listentry, dev->maplist, link)
  182                 tempmaps[i++] = *listentry->map;
  183 
  184         DRM_UNLOCK();
  185 
  186         DRM_SYSCTL_PRINT("\nslot         offset       size type flags    "
  187                          "address mtrr\n");
  188 
  189         for (i = 0; i < mapcount; i++) {
  190                 map = &tempmaps[i];
  191 
  192                 if (map->type < 0 || map->type > 4)
  193                         type = "??";
  194                 else
  195                         type = types[map->type];
  196 
  197                 if (!map->mtrr)
  198                         yesno = "no";
  199                 else
  200                         yesno = "yes";
  201 
  202                 DRM_SYSCTL_PRINT(
  203                     "%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx %s\n", i,
  204                     map->offset, map->size, type, map->flags,
  205                     (unsigned long)map->handle, yesno);
  206         }
  207         SYSCTL_OUT(req, "", 1);
  208 
  209 done:
  210         DRM(free)(tempmaps, sizeof(drm_local_map_t) * mapcount, DRM_MEM_MAPS);
  211         return retcode;
  212 }
  213 
  214 #if __HAVE_DMA
  215 static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
  216 {
  217         drm_device_t     *dev = arg1;
  218         drm_device_dma_t *dma = dev->dma;
  219         drm_device_dma_t tempdma;
  220         int *templists;
  221         int i;
  222         char buf[128];
  223         int retcode;
  224 
  225         /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
  226          * copy of the whole structure and the relevant data from buflist.
  227          */
  228         DRM_LOCK();
  229         if (dma == NULL) {
  230                 DRM_UNLOCK();
  231                 return 0;
  232         }
  233         DRM_SPINLOCK(&dev->dma_lock);
  234         tempdma = *dma;
  235         templists = DRM(alloc)(sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
  236         for (i = 0; i < dma->buf_count; i++)
  237                 templists[i] = dma->buflist[i]->list;
  238         dma = &tempdma;
  239         DRM_SPINUNLOCK(&dev->dma_lock);
  240         DRM_UNLOCK();
  241 
  242         DRM_SYSCTL_PRINT("\n o     size count  free      segs pages    kB\n");
  243         for (i = 0; i <= DRM_MAX_ORDER; i++) {
  244                 if (dma->bufs[i].buf_count)
  245                         DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
  246                                        i,
  247                                        dma->bufs[i].buf_size,
  248                                        dma->bufs[i].buf_count,
  249                                        atomic_read(&dma->bufs[i]
  250                                                    .freelist.count),
  251                                        dma->bufs[i].seg_count,
  252                                        dma->bufs[i].seg_count
  253                                        *(1 << dma->bufs[i].page_order),
  254                                        (dma->bufs[i].seg_count
  255                                         * (1 << dma->bufs[i].page_order))
  256                                        * PAGE_SIZE / 1024);
  257         }
  258         DRM_SYSCTL_PRINT("\n");
  259         for (i = 0; i < dma->buf_count; i++) {
  260                 if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
  261                 DRM_SYSCTL_PRINT(" %d", templists[i]);
  262         }
  263         DRM_SYSCTL_PRINT("\n");
  264 
  265         SYSCTL_OUT(req, "", 1);
  266 done:
  267         DRM(free)(templists, sizeof(int) * dma->buf_count, DRM_MEM_BUFS);
  268         return retcode;
  269 }
  270 #endif
  271 
  272 static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
  273 {
  274         drm_device_t *dev = arg1;
  275         drm_file_t *priv, *tempprivs;
  276         char buf[128];
  277         int retcode;
  278         int privcount, i;
  279 
  280         DRM_LOCK();
  281 
  282         privcount = 0;
  283         TAILQ_FOREACH(priv, &dev->files, link)
  284                 privcount++;
  285 
  286         tempprivs = DRM(alloc)(sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
  287         if (tempprivs == NULL) {
  288                 DRM_UNLOCK();
  289                 return ENOMEM;
  290         }
  291         i = 0;
  292         TAILQ_FOREACH(priv, &dev->files, link)
  293                 tempprivs[i++] = *priv;
  294 
  295         DRM_UNLOCK();
  296 
  297         DRM_SYSCTL_PRINT("\na dev       pid    uid      magic     ioctls\n");
  298         for (i = 0; i < privcount; i++) {
  299                 priv = &tempprivs[i];
  300                 DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
  301                                priv->authenticated ? 'y' : 'n',
  302                                priv->minor,
  303                                priv->pid,
  304                                priv->uid,
  305                                priv->magic,
  306                                priv->ioctl_count);
  307         }
  308 
  309         SYSCTL_OUT(req, "", 1);
  310 done:
  311         DRM(free)(tempprivs, sizeof(drm_file_t) * privcount, DRM_MEM_FILES);
  312         return retcode;
  313 }
  314 
  315 #elif defined(__NetBSD__)
  316 /* stub it out for now, sysctl is only for debugging */
  317 int DRM(sysctl_init)(drm_device_t *dev)
  318 {
  319         return 0;
  320 }
  321 
  322 int DRM(sysctl_cleanup)(drm_device_t *dev)
  323 {
  324         return 0;
  325 }
  326 #endif

Cache object: 4c9caea1f9391a5a7034d6be02bb54be


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