OSDN Git Service

[FreeBSD] Declare vblank_disable_fn callout MPSAFE.
[android-x86/external-libdrm.git] / bsd-core / drm_sysctl.c
index 02e4b28..a6adf0f 100644 (file)
-SYSCTL_NODE(_hw, OID_AUTO, dri, CTLFLAG_RW, 0, "DRI Graphics");
-
-static int        DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
-static int        DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
-static int        DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS;
-static int        DRM(queues_info)DRM_SYSCTL_HANDLER_ARGS;
-static int        DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS;
-#if DRM_DEBUG_CODExx
-static int        DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS;
-#endif
-#if DRM_DMA_HISTOGRAM
-static int        DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS;
-#endif
-
-struct DRM(sysctl_list) {
+/*-
+ * Copyright 2003 Eric Anholt
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/** @file drm_sysctl.c
+ * Implementation of various sysctls for controlling DRM behavior and reporting
+ * debug information.
+ */
+
+#include "drmP.h"
+#include "drm.h"
+
+#include <sys/sysctl.h>
+
+static int        drm_name_info DRM_SYSCTL_HANDLER_ARGS;
+static int        drm_vm_info DRM_SYSCTL_HANDLER_ARGS;
+static int        drm_clients_info DRM_SYSCTL_HANDLER_ARGS;
+static int        drm_bufs_info DRM_SYSCTL_HANDLER_ARGS;
+
+struct drm_sysctl_list {
        const char *name;
        int        (*f) DRM_SYSCTL_HANDLER_ARGS;
-} DRM(sysctl_list)[] = {
-       { "name",    DRM(name_info)    },
-       { "mem",     DRM(mem_info)     },
-       { "vm",      DRM(vm_info)      },
-       { "clients", DRM(clients_info) },
-       { "queues",  DRM(queues_info)  },
-       { "bufs",    DRM(bufs_info)    },
-#if DRM_DEBUG_CODExx
-       { "vma",     DRM(vma_info)     },
-#endif
-#if DRM_DMA_HISTOGRAM
-       { "histo",   drm_histo_info)   },
-#endif
+} drm_sysctl_list[] = {
+       {"name",    drm_name_info},
+       {"vm",      drm_vm_info},
+       {"clients", drm_clients_info},
+       {"bufs",    drm_bufs_info},
 };
-#define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
+#define DRM_SYSCTL_ENTRIES (sizeof(drm_sysctl_list)/sizeof(drm_sysctl_list[0]))
 
 struct drm_sysctl_info {
-       struct sysctl_oid      oids[DRM_SYSCTL_ENTRIES + 1];
-       struct sysctl_oid_list list;
+       struct sysctl_ctx_list ctx;
        char                   name[2];
 };
 
-int DRM(sysctl_init)(drm_device_t *dev)
+int drm_sysctl_init(struct drm_device *dev)
 {
        struct drm_sysctl_info *info;
        struct sysctl_oid *oid;
-       struct sysctl_oid *top;
+       struct sysctl_oid *top, *drioid;
        int               i;
 
-       /* Find the next free slot under hw.graphics */
+       info = malloc(sizeof *info, M_DRM, M_WAITOK | M_ZERO);
+       if ( !info )
+               return 1;
+       dev->sysctl = info;
+
+       /* Add the sysctl node for DRI if it doesn't already exist */
+       drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
+       if (!drioid)
+               return 1;
+
+       /* Find the next free slot under hw.dri */
        i = 0;
-       SLIST_FOREACH(oid, &sysctl__hw_dri_children, oid_link) {
+       SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
                if (i <= oid->oid_arg2)
                        i = oid->oid_arg2 + 1;
        }
+       if (i>9)
+               return 1;
        
-       info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
-       dev->sysctl = info;
-
-       /* Construct the node under hw.graphics */
+       /* Add the hw.dri.x for our device */
        info->name[0] = '0' + i;
        info->name[1] = 0;
-       oid = &info->oids[DRM_SYSCTL_ENTRIES];
-       bzero(oid, sizeof(*oid));
-       oid->oid_parent = &sysctl__hw_dri_children;
-       oid->oid_number = OID_AUTO;
-       oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW;
-       oid->oid_arg1 = &info->list;
-       oid->oid_arg2 = i;
-       oid->oid_name = info->name;
-       oid->oid_handler = 0;
-       oid->oid_fmt = "N";
-       SLIST_INIT(&info->list);
-       sysctl_register_oid(oid);
-       top = oid;
-
+       top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
+       if (!top)
+               return 1;
+       
        for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
-               oid = &info->oids[i];
-               bzero(oid, sizeof(*oid));
-               oid->oid_parent = top->oid_arg1;
-               oid->oid_number = OID_AUTO;
-               oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD;
-               oid->oid_arg1 = dev;
-               oid->oid_arg2 = 0;
-               oid->oid_name = DRM(sysctl_list)[i].name;
-               oid->oid_handler = DRM(sysctl_list[)i].f;
-               oid->oid_fmt = "A";
-               sysctl_register_oid(oid);
+               oid = SYSCTL_ADD_OID(&info->ctx, 
+                       SYSCTL_CHILDREN(top), 
+                       OID_AUTO, 
+                       drm_sysctl_list[i].name, 
+                       CTLTYPE_INT | CTLFLAG_RD, 
+                       dev, 
+                       0, 
+                       drm_sysctl_list[i].f, 
+                       "A", 
+                       NULL);
+               if (!oid)
+                       return 1;
        }
+       SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(top), OID_AUTO, "debug",
+           CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag),
+           "Enable debugging output");
 
        return 0;
 }
 
-int DRM(sysctl_cleanup)(drm_device_t *dev)
+int drm_sysctl_cleanup(struct drm_device *dev)
 {
-       int i;
-
-       DRM_DEBUG("dev->sysctl=%p\n", dev->sysctl);
-       for (i = 0; i < DRM_SYSCTL_ENTRIES + 1; i++)
-               sysctl_unregister_oid(&dev->sysctl->oids[i]);
+       int error;
+       error = sysctl_ctx_free( &dev->sysctl->ctx );
 
-       DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
+       free(dev->sysctl, M_DRM);
        dev->sysctl = NULL;
 
-       return 0;
+       return error;
 }
 
-static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
+#define DRM_SYSCTL_PRINT(fmt, arg...)                          \
+do {                                                           \
+       snprintf(buf, sizeof(buf), fmt, ##arg);                 \
+       retcode = SYSCTL_OUT(req, buf, strlen(buf));            \
+       if (retcode)                                            \
+               goto done;                                      \
+} while (0)
+
+static int drm_name_info DRM_SYSCTL_HANDLER_ARGS
 {
-       drm_device_t *dev = arg1;
+       struct drm_device *dev = arg1;
        char buf[128];
-       int error;
+       int retcode;
+       int hasunique = 0;
 
+       DRM_SYSCTL_PRINT("%s 0x%x", dev->driver.name, dev2udev(dev->devnode));
+       
+       DRM_LOCK();
        if (dev->unique) {
-               DRM_SYSCTL_PRINT("%s 0x%x %s\n",
-                              dev->name, dev2udev(dev->devnode), dev->unique);
-       } else {
-               DRM_SYSCTL_PRINT("%s 0x%x\n", dev->name, dev2udev(dev->devnode));
+               snprintf(buf, sizeof(buf), " %s", dev->unique);
+               hasunique = 1;
        }
+       DRM_UNLOCK();
+       
+       if (hasunique)
+               SYSCTL_OUT(req, buf, strlen(buf));
 
        SYSCTL_OUT(req, "", 1);
 
-       return 0;
+done:
+       return retcode;
 }
 
-static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
+static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
 {
-       drm_device_t *dev = arg1;
-       drm_map_t    *map;
-       drm_map_list_entry_t    *listentry;
-       const char   *types[] = { "FB", "REG", "SHM" };
-       const char   *type;
-       int          i=0;
-       char         buf[128];
-       int          error;
-
-       DRM_SYSCTL_PRINT("slot   offset       size type flags    "
-                        "address mtrr\n\n");
-       error = SYSCTL_OUT(req, buf, strlen(buf));
-       if (error) return error;
-
-       if (dev->maplist != NULL) {
-               TAILQ_FOREACH(listentry, dev->maplist, link) {
-                       map = listentry->map;
-                       if (map->type < 0 || map->type > 2) type = "??";
-                       else                                type = types[map->type];
-                       DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
-                                        i,
-                                        map->offset,
-                                        map->size,
-                                        type,
-                                        map->flags,
-                                        (unsigned long)map->handle);
-                       if (map->mtrr < 0) {
-                               DRM_SYSCTL_PRINT("none\n");
-                       } else {
-                               DRM_SYSCTL_PRINT("%4d\n", map->mtrr);
-                       }
-                       i++;
-               }
+       struct drm_device *dev = arg1;
+       drm_local_map_t *map, *tempmaps;
+       const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
+       const char *type, *yesno;
+       int i, mapcount;
+       char buf[128];
+       int retcode;
+
+       /* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
+        * temporary copy of all the map entries and then SYSCTL_OUT that.
+        */
+       DRM_LOCK();
+
+       mapcount = 0;
+       TAILQ_FOREACH(map, &dev->maplist, link)
+               mapcount++;
+
+       tempmaps = malloc(sizeof(drm_local_map_t) * mapcount, M_DRM, M_NOWAIT);
+       if (tempmaps == NULL) {
+               DRM_UNLOCK();
+               return ENOMEM;
        }
-       SYSCTL_OUT(req, "", 1);
 
-       return 0;
-}
+       i = 0;
+       TAILQ_FOREACH(map, &dev->maplist, link)
+               tempmaps[i++] = *map;
 
-static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          ret;
+       DRM_UNLOCK();
 
-       DRM_OS_LOCK;
-       ret = DRM(_vm_info)(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
+       DRM_SYSCTL_PRINT("\nslot         offset       size type flags    "
+                        "address mtrr\n");
 
-       return ret;
-}
+       for (i = 0; i < mapcount; i++) {
+               map = &tempmaps[i];
 
+               if (map->type < 0 || map->type > 4)
+                       type = "??";
+               else
+                       type = types[map->type];
 
-static int DRM(_queues_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          i;
-       drm_queue_t  *q;
-       char         buf[128];
-       int          error;
-
-       DRM_SYSCTL_PRINT("  ctx/flags   use   fin"
-                        "   blk/rw/rwf  wait    flushed           queued"
-                        "      locks\n\n");
-       for (i = 0; i < dev->queue_count; i++) {
-               q = dev->queuelist[i];
-               atomic_inc(&q->use_count);
-               DRM_SYSCTL_PRINT_RET(atomic_dec(&q->use_count),
-                                    "%5d/0x%03x %5ld %5ld"
-                                    " %5ld/%c%c/%c%c%c %5d %10ld %10ld %10ld\n",
-                                    i,
-                                    q->flags,
-                                    atomic_read(&q->use_count),
-                                    atomic_read(&q->finalization),
-                                    atomic_read(&q->block_count),
-                                    atomic_read(&q->block_read) ? 'r' : '-',
-                                    atomic_read(&q->block_write) ? 'w' : '-',
-                                    q->read_queue ? 'r':'-',
-                                    q->write_queue ? 'w':'-',
-                                    q->flush_queue ? 'f':'-',
-                                    DRM_BUFCOUNT(&q->waitlist),
-                                    atomic_read(&q->total_flushed),
-                                    atomic_read(&q->total_queued),
-                                    atomic_read(&q->total_locks));
-               atomic_dec(&q->use_count);
-       }
+               if (!map->mtrr)
+                       yesno = "no";
+               else
+                       yesno = "yes";
 
+               DRM_SYSCTL_PRINT(
+                   "%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx %s\n", i,
+                   map->offset, map->size, type, map->flags,
+                   (unsigned long)map->handle, yesno);
+       }
        SYSCTL_OUT(req, "", 1);
-       return 0;
-}
-
-static int DRM(queues_info) DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          ret;
 
-       DRM_OS_LOCK;
-       ret = DRM(_queues_info)(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
-       return ret;
+done:
+       free(tempmaps, M_DRM);
+       return retcode;
 }
 
-/* drm_bufs_info is called whenever a process reads
-   hw.dri.0.bufs. */
-
-static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
+static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
 {
-       drm_device_t     *dev = arg1;
+       struct drm_device        *dev = arg1;
        drm_device_dma_t *dma = dev->dma;
-       int              i;
-       char             buf[128];
-       int              error;
-
-       if (!dma)       return 0;
-       DRM_SYSCTL_PRINT(" o     size count  free        segs pages    kB\n\n");
+       drm_device_dma_t tempdma;
+       int *templists;
+       int i;
+       char buf[128];
+       int retcode;
+
+       /* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
+        * copy of the whole structure and the relevant data from buflist.
+        */
+       DRM_LOCK();
+       if (dma == NULL) {
+               DRM_UNLOCK();
+               return 0;
+       }
+       DRM_SPINLOCK(&dev->dma_lock);
+       tempdma = *dma;
+       templists = malloc(sizeof(int) * dma->buf_count, M_DRM, M_NOWAIT);
+       for (i = 0; i < dma->buf_count; i++)
+               templists[i] = dma->buflist[i]->list;
+       dma = &tempdma;
+       DRM_SPINUNLOCK(&dev->dma_lock);
+       DRM_UNLOCK();
+
+       DRM_SYSCTL_PRINT("\n o     size count  free      segs pages    kB\n");
        for (i = 0; i <= DRM_MAX_ORDER; i++) {
                if (dma->bufs[i].buf_count)
-                       DRM_SYSCTL_PRINT("%2d %8d %5d %5ld %5d %5d %5d\n",
+                       DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
                                       i,
                                       dma->bufs[i].buf_size,
                                       dma->bufs[i].buf_count,
@@ -254,35 +255,44 @@ static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
        DRM_SYSCTL_PRINT("\n");
        for (i = 0; i < dma->buf_count; i++) {
                if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
-               DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
+               DRM_SYSCTL_PRINT(" %d", templists[i]);
        }
        DRM_SYSCTL_PRINT("\n");
 
        SYSCTL_OUT(req, "", 1);
-       return 0;
+done:
+       free(templists, M_DRM);
+       return retcode;
 }
 
-static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
+static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
 {
-       drm_device_t *dev = arg1;
-       int          ret;
+       struct drm_device *dev = arg1;
+       drm_file_t *priv, *tempprivs;
+       char buf[128];
+       int retcode;
+       int privcount, i;
 
-       DRM_OS_LOCK;
-       ret = DRM(_bufs_info)(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
-       return ret;
-}
+       DRM_LOCK();
 
+       privcount = 0;
+       TAILQ_FOREACH(priv, &dev->files, link)
+               privcount++;
 
-static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       drm_file_t   *priv;
-       char         buf[128];
-       int          error;
+       tempprivs = malloc(sizeof(drm_file_t) * privcount, M_DRM, M_NOWAIT);
+       if (tempprivs == NULL) {
+               DRM_UNLOCK();
+               return ENOMEM;
+       }
+       i = 0;
+       TAILQ_FOREACH(priv, &dev->files, link)
+               tempprivs[i++] = *priv;
+
+       DRM_UNLOCK();
 
-       DRM_SYSCTL_PRINT("a dev pid    uid      magic     ioctls\n\n");
-       TAILQ_FOREACH(priv, &dev->files, link) {
+       DRM_SYSCTL_PRINT("\na dev       pid    uid      magic     ioctls\n");
+       for (i = 0; i < privcount; i++) {
+               priv = &tempprivs[i];
                DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
                               priv->authenticated ? 'y' : 'n',
                               priv->minor,
@@ -293,231 +303,7 @@ static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
        }
 
        SYSCTL_OUT(req, "", 1);
-       return 0;
-}
-
-static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          ret;
-
-       DRM_OS_LOCK;
-       ret = DRM(_clients_info)(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
-       return ret;
-}
-
-#if DRM_DEBUG_CODExx
-
-static int DRM(_vma_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t          *dev = arg1;
-       drm_vma_entry_t       *pt;
-       pgd_t                 *pgd;
-       pmd_t                 *pmd;
-       pte_t                 *pte;
-       unsigned long         i;
-       struct vm_area_struct *vma;
-       unsigned long         address;
-#if defined(__i386__)
-       unsigned int          pgprot;
-#endif
-       char                  buf[128];
-       int                   error;
-
-       DRM_SYSCTL_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
-                      atomic_read(&dev->vma_count),
-                      high_memory, virt_to_phys(high_memory));
-       for (pt = dev->vmalist; pt; pt = pt->next) {
-               if (!(vma = pt->vma)) continue;
-               DRM_SYSCTL_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
-                              pt->pid,
-                              vma->vm_start,
-                              vma->vm_end,
-                              vma->vm_flags & VM_READ     ? 'r' : '-',
-                              vma->vm_flags & VM_WRITE    ? 'w' : '-',
-                              vma->vm_flags & VM_EXEC     ? 'x' : '-',
-                              vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
-                              vma->vm_flags & VM_LOCKED   ? 'l' : '-',
-                              vma->vm_flags & VM_IO       ? 'i' : '-',
-                              vma->vm_offset );
-#if defined(__i386__)
-               pgprot = pgprot_val(vma->vm_page_prot);
-               DRM_SYSCTL_PRINT(" %c%c%c%c%c%c%c%c%c",
-                              pgprot & _PAGE_PRESENT  ? 'p' : '-',
-                              pgprot & _PAGE_RW       ? 'w' : 'r',
-                              pgprot & _PAGE_USER     ? 'u' : 's',
-                              pgprot & _PAGE_PWT      ? 't' : 'b',
-                              pgprot & _PAGE_PCD      ? 'u' : 'c',
-                              pgprot & _PAGE_ACCESSED ? 'a' : '-',
-                              pgprot & _PAGE_DIRTY    ? 'd' : '-',
-                              pgprot & _PAGE_4M       ? 'm' : 'k',
-                              pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
-#endif         
-               DRM_SYSCTL_PRINT("\n");
-               for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
-                       pgd = pgd_offset(vma->vm_mm, i);
-                       pmd = pmd_offset(pgd, i);
-                       pte = pte_offset(pmd, i);
-                       if (pte_present(*pte)) {
-                               address = __pa(pte_page(*pte))
-                                       + (i & (PAGE_SIZE-1));
-                               DRM_SYSCTL_PRINT("      0x%08lx -> 0x%08lx"
-                                              " %c%c%c%c%c\n",
-                                              i,
-                                              address,
-                                              pte_read(*pte)  ? 'r' : '-',
-                                              pte_write(*pte) ? 'w' : '-',
-                                              pte_exec(*pte)  ? 'x' : '-',
-                                              pte_dirty(*pte) ? 'd' : '-',
-                                              pte_young(*pte) ? 'a' : '-' );
-                       } else {
-                               DRM_SYSCTL_PRINT("      0x%08lx\n", i);
-                       }
-               }
-       }
-       
-       SYSCTL_OUT(req, "", 1);
-       return 0;
-}
-
-static int DRM(vma_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          ret;
-
-       DRM_OS_LOCK;
-       ret = DRM(_vma_info)(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
-       return ret;
-}
-#endif
-
-
-#if DRM_DMA_HISTOGRAM
-static int DRM(_histo_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t     *dev = arg1;
-       drm_device_dma_t *dma = dev->dma;
-       int              i;
-       unsigned long    slot_value = DRM_DMA_HISTOGRAM_INITIAL;
-       unsigned long    prev_value = 0;
-       drm_buf_t        *buffer;
-       char             buf[128];
-       int              error;
-
-       DRM_SYSCTL_PRINT("general statistics:\n");
-       DRM_SYSCTL_PRINT("total  %10u\n", atomic_read(&dev->histo.total));
-       DRM_SYSCTL_PRINT("open   %10u\n", atomic_read(&dev->total_open));
-       DRM_SYSCTL_PRINT("close  %10u\n", atomic_read(&dev->total_close));
-       DRM_SYSCTL_PRINT("ioctl  %10u\n", atomic_read(&dev->total_ioctl));
-       DRM_SYSCTL_PRINT("irq    %10u\n", atomic_read(&dev->total_irq));
-       DRM_SYSCTL_PRINT("ctx    %10u\n", atomic_read(&dev->total_ctx));
-       
-       DRM_SYSCTL_PRINT("\nlock statistics:\n");
-       DRM_SYSCTL_PRINT("locks  %10u\n", atomic_read(&dev->total_locks));
-       DRM_SYSCTL_PRINT("unlocks        %10u\n", atomic_read(&dev->total_unlocks));
-       DRM_SYSCTL_PRINT("contends %10u\n", atomic_read(&dev->total_contends));
-       DRM_SYSCTL_PRINT("sleeps         %10u\n", atomic_read(&dev->total_sleeps));
-
-
-       if (dma) {
-               DRM_SYSCTL_PRINT("\ndma statistics:\n");
-               DRM_SYSCTL_PRINT("prio   %10u\n",
-                              atomic_read(&dma->total_prio));
-               DRM_SYSCTL_PRINT("bytes  %10u\n",
-                              atomic_read(&dma->total_bytes));
-               DRM_SYSCTL_PRINT("dmas   %10u\n",
-                              atomic_read(&dma->total_dmas));
-               DRM_SYSCTL_PRINT("missed:\n");
-               DRM_SYSCTL_PRINT("  dma  %10u\n",
-                              atomic_read(&dma->total_missed_dma));
-               DRM_SYSCTL_PRINT("  lock         %10u\n",
-                              atomic_read(&dma->total_missed_lock));
-               DRM_SYSCTL_PRINT("  free         %10u\n",
-                              atomic_read(&dma->total_missed_free));
-               DRM_SYSCTL_PRINT("  sched        %10u\n",
-                              atomic_read(&dma->total_missed_sched));
-               DRM_SYSCTL_PRINT("tried  %10u\n",
-                              atomic_read(&dma->total_tried));
-               DRM_SYSCTL_PRINT("hit    %10u\n",
-                              atomic_read(&dma->total_hit));
-               DRM_SYSCTL_PRINT("lost   %10u\n",
-                              atomic_read(&dma->total_lost));
-               
-               buffer = dma->next_buffer;
-               if (buffer) {
-                       DRM_SYSCTL_PRINT("next_buffer %7d\n", buffer->idx);
-               } else {
-                       DRM_SYSCTL_PRINT("next_buffer    none\n");
-               }
-               buffer = dma->this_buffer;
-               if (buffer) {
-                       DRM_SYSCTL_PRINT("this_buffer %7d\n", buffer->idx);
-               } else {
-                       DRM_SYSCTL_PRINT("this_buffer    none\n");
-               }
-       }
-       
-
-       DRM_SYSCTL_PRINT("\nvalues:\n");
-       if (dev->lock.hw_lock) {
-               DRM_SYSCTL_PRINT("lock         0x%08x\n",
-                              dev->lock.hw_lock->lock);
-       } else {
-               DRM_SYSCTL_PRINT("lock               none\n");
-       }
-       DRM_SYSCTL_PRINT("context_flag   0x%08x\n", dev->context_flag);
-       DRM_SYSCTL_PRINT("interrupt_flag 0x%08x\n", dev->interrupt_flag);
-       DRM_SYSCTL_PRINT("dma_flag       0x%08x\n", dev->dma_flag);
-
-       DRM_SYSCTL_PRINT("queue_count    %10d\n",        dev->queue_count);
-       DRM_SYSCTL_PRINT("last_context   %10d\n",        dev->last_context);
-       DRM_SYSCTL_PRINT("last_switch    %10u\n",        dev->last_switch);
-       DRM_SYSCTL_PRINT("last_checked   %10d\n",        dev->last_checked);
-               
-       
-       DRM_SYSCTL_PRINT("\n                   q2d        d2c        c2f"
-                      "        q2c        q2f        dma        sch"
-                      "        ctx       lacq       lhld\n\n");
-       for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
-               DRM_SYSCTL_PRINT("%s %10lu %10u %10u %10u %10u %10u"
-                              " %10u %10u %10u %10u %10u\n",
-                              i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
-                              i == DRM_DMA_HISTOGRAM_SLOTS - 1
-                              ? prev_value : slot_value ,
-                              
-                              atomic_read(&dev->histo
-                                          .queued_to_dispatched[i]),
-                              atomic_read(&dev->histo
-                                          .dispatched_to_completed[i]),
-                              atomic_read(&dev->histo
-                                          .completed_to_freed[i]),
-                              
-                              atomic_read(&dev->histo
-                                          .queued_to_completed[i]),
-                              atomic_read(&dev->histo
-                                          .queued_to_freed[i]),
-                              atomic_read(&dev->histo.dma[i]),
-                              atomic_read(&dev->histo.schedule[i]),
-                              atomic_read(&dev->histo.ctx[i]),
-                              atomic_read(&dev->histo.lacq[i]),
-                              atomic_read(&dev->histo.lhld[i]));
-               prev_value = slot_value;
-               slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
-       }
-       SYSCTL_OUT(req, "", 1);
-       return 0;
-}
-
-static int DRM(histo_info)DRM_SYSCTL_HANDLER_ARGS
-{
-       drm_device_t *dev = arg1;
-       int          ret;
-
-       DRM_OS_LOCK;
-       ret = _drm_histo_info(oidp, arg1, arg2, req);
-       DRM_OS_UNLOCK;
-       return ret;
+done:
+       free(tempprivs, M_DRM);
+       return retcode;
 }
-#endif