xref: /dflybsd-src/sys/dev/drm/drm_sysctl.c (revision 5718399f454457d2fede1f011bbf41c5c7070ecf)
17f3c3d6fSHasso Tepper /*-
27f3c3d6fSHasso Tepper  * Copyright 2003 Eric Anholt
37f3c3d6fSHasso Tepper  * All Rights Reserved.
47f3c3d6fSHasso Tepper  *
57f3c3d6fSHasso Tepper  * Permission is hereby granted, free of charge, to any person obtaining a
67f3c3d6fSHasso Tepper  * copy of this software and associated documentation files (the "Software"),
77f3c3d6fSHasso Tepper  * to deal in the Software without restriction, including without limitation
87f3c3d6fSHasso Tepper  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
97f3c3d6fSHasso Tepper  * and/or sell copies of the Software, and to permit persons to whom the
107f3c3d6fSHasso Tepper  * Software is furnished to do so, subject to the following conditions:
117f3c3d6fSHasso Tepper  *
127f3c3d6fSHasso Tepper  * The above copyright notice and this permission notice (including the next
137f3c3d6fSHasso Tepper  * paragraph) shall be included in all copies or substantial portions of the
147f3c3d6fSHasso Tepper  * Software.
157f3c3d6fSHasso Tepper  *
167f3c3d6fSHasso Tepper  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
177f3c3d6fSHasso Tepper  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
187f3c3d6fSHasso Tepper  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
197f3c3d6fSHasso Tepper  * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
207f3c3d6fSHasso Tepper  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
217f3c3d6fSHasso Tepper  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*5718399fSFrançois Tigeot  *
23*5718399fSFrançois Tigeot  * $FreeBSD: src/sys/dev/drm2/drm_sysctl.c,v 1.1 2012/05/22 11:07:44 kib Exp $
247f3c3d6fSHasso Tepper  */
257f3c3d6fSHasso Tepper 
267f3c3d6fSHasso Tepper /** @file drm_sysctl.c
277f3c3d6fSHasso Tepper  * Implementation of various sysctls for controlling DRM behavior and reporting
287f3c3d6fSHasso Tepper  * debug information.
297f3c3d6fSHasso Tepper  */
307f3c3d6fSHasso Tepper 
31*5718399fSFrançois Tigeot #include <sys/conf.h>
32*5718399fSFrançois Tigeot #include <sys/sysctl.h>
33*5718399fSFrançois Tigeot #include <sys/types.h>
34*5718399fSFrançois Tigeot 
35b3705d71SHasso Tepper #include "dev/drm/drmP.h"
36b3705d71SHasso Tepper #include "dev/drm/drm.h"
377f3c3d6fSHasso Tepper 
387f3c3d6fSHasso Tepper static int	   drm_name_info DRM_SYSCTL_HANDLER_ARGS;
397f3c3d6fSHasso Tepper static int	   drm_vm_info DRM_SYSCTL_HANDLER_ARGS;
407f3c3d6fSHasso Tepper static int	   drm_clients_info DRM_SYSCTL_HANDLER_ARGS;
417f3c3d6fSHasso Tepper static int	   drm_bufs_info DRM_SYSCTL_HANDLER_ARGS;
427ae23ad1SHasso Tepper static int	   drm_vblank_info DRM_SYSCTL_HANDLER_ARGS;
437f3c3d6fSHasso Tepper 
447f3c3d6fSHasso Tepper struct drm_sysctl_list {
457f3c3d6fSHasso Tepper 	const char *name;
467f3c3d6fSHasso Tepper 	int	   (*f) DRM_SYSCTL_HANDLER_ARGS;
477f3c3d6fSHasso Tepper } drm_sysctl_list[] = {
487f3c3d6fSHasso Tepper 	{"name",    drm_name_info},
497f3c3d6fSHasso Tepper 	{"vm",	    drm_vm_info},
507f3c3d6fSHasso Tepper 	{"clients", drm_clients_info},
517f3c3d6fSHasso Tepper 	{"bufs",    drm_bufs_info},
527ae23ad1SHasso Tepper 	{"vblank",    drm_vblank_info},
537f3c3d6fSHasso Tepper };
54c157ff7aSSascha Wildner #define DRM_SYSCTL_ENTRIES NELEM(drm_sysctl_list)
557f3c3d6fSHasso Tepper 
567f3c3d6fSHasso Tepper struct drm_sysctl_info {
577f3c3d6fSHasso Tepper 	struct sysctl_ctx_list ctx;
587f3c3d6fSHasso Tepper 	char		       name[2];
597f3c3d6fSHasso Tepper };
607f3c3d6fSHasso Tepper 
61b3705d71SHasso Tepper int drm_sysctl_init(struct drm_device *dev)
627f3c3d6fSHasso Tepper {
637f3c3d6fSHasso Tepper 	struct drm_sysctl_info *info;
647f3c3d6fSHasso Tepper 	struct sysctl_oid *oid;
657f3c3d6fSHasso Tepper 	struct sysctl_oid *top, *drioid;
667f3c3d6fSHasso Tepper 	int		  i;
677f3c3d6fSHasso Tepper 
68*5718399fSFrançois Tigeot 	info = kmalloc(sizeof *info, DRM_MEM_DRIVER, M_WAITOK | M_ZERO);
697f3c3d6fSHasso Tepper 	if ( !info )
707f3c3d6fSHasso Tepper 		return 1;
717f3c3d6fSHasso Tepper 	dev->sysctl = info;
727f3c3d6fSHasso Tepper 
737f3c3d6fSHasso Tepper 	/* Add the sysctl node for DRI if it doesn't already exist */
74*5718399fSFrançois Tigeot 	drioid = SYSCTL_ADD_NODE(&info->ctx, &sysctl__hw_children, OID_AUTO,
75*5718399fSFrançois Tigeot 	    "dri", CTLFLAG_RW, NULL, "DRI Graphics");
767f3c3d6fSHasso Tepper 	if (!drioid)
777f3c3d6fSHasso Tepper 		return 1;
787f3c3d6fSHasso Tepper 
797f3c3d6fSHasso Tepper 	/* Find the next free slot under hw.dri */
807f3c3d6fSHasso Tepper 	i = 0;
817f3c3d6fSHasso Tepper 	SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
827f3c3d6fSHasso Tepper 		if (i <= oid->oid_arg2)
837f3c3d6fSHasso Tepper 			i = oid->oid_arg2 + 1;
847f3c3d6fSHasso Tepper 	}
857f3c3d6fSHasso Tepper 	if (i>9)
867f3c3d6fSHasso Tepper 		return 1;
877f3c3d6fSHasso Tepper 
88*5718399fSFrançois Tigeot 	dev->sysctl_node_idx = i;
897f3c3d6fSHasso Tepper 	/* Add the hw.dri.x for our device */
907f3c3d6fSHasso Tepper 	info->name[0] = '0' + i;
917f3c3d6fSHasso Tepper 	info->name[1] = 0;
92*5718399fSFrançois Tigeot 	top = SYSCTL_ADD_NODE(&info->ctx, SYSCTL_CHILDREN(drioid),
93*5718399fSFrançois Tigeot 	    OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
947f3c3d6fSHasso Tepper 	if (!top)
957f3c3d6fSHasso Tepper 		return 1;
967f3c3d6fSHasso Tepper 
977f3c3d6fSHasso Tepper 	for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
987f3c3d6fSHasso Tepper 		oid = SYSCTL_ADD_OID(&info->ctx,
997f3c3d6fSHasso Tepper 			SYSCTL_CHILDREN(top),
1007f3c3d6fSHasso Tepper 			OID_AUTO,
1017f3c3d6fSHasso Tepper 			drm_sysctl_list[i].name,
10299f70504SFrançois Tigeot 			CTLTYPE_STRING | CTLFLAG_RD,
1037f3c3d6fSHasso Tepper 			dev,
1047f3c3d6fSHasso Tepper 			0,
1057f3c3d6fSHasso Tepper 			drm_sysctl_list[i].f,
1067f3c3d6fSHasso Tepper 			"A",
1077f3c3d6fSHasso Tepper 			NULL);
1087f3c3d6fSHasso Tepper 		if (!oid)
1097f3c3d6fSHasso Tepper 			return 1;
1107f3c3d6fSHasso Tepper 	}
111*5718399fSFrançois Tigeot 	SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "debug",
1127f3c3d6fSHasso Tepper 	    CTLFLAG_RW, &drm_debug_flag, sizeof(drm_debug_flag),
1137f3c3d6fSHasso Tepper 	    "Enable debugging output");
114*5718399fSFrançois Tigeot 	SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, "notyet",
115*5718399fSFrançois Tigeot 	    CTLFLAG_RW, &drm_notyet_flag, sizeof(drm_debug_flag),
116*5718399fSFrançois Tigeot 	    "Enable notyet reminders");
1177f3c3d6fSHasso Tepper 
118*5718399fSFrançois Tigeot 	if (dev->driver->sysctl_init != NULL)
119*5718399fSFrançois Tigeot 		dev->driver->sysctl_init(dev, &info->ctx, top);
120*5718399fSFrançois Tigeot 
121*5718399fSFrançois Tigeot 	SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO,
122*5718399fSFrançois Tigeot 	    "vblank_offdelay", CTLFLAG_RW, &drm_vblank_offdelay,
123*5718399fSFrançois Tigeot 	    sizeof(drm_vblank_offdelay),
124*5718399fSFrançois Tigeot 	    "");
125*5718399fSFrançois Tigeot 	SYSCTL_ADD_INT(&info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO,
126*5718399fSFrançois Tigeot 	    "timestamp_precision", CTLFLAG_RW, &drm_timestamp_precision,
127*5718399fSFrançois Tigeot 	    sizeof(drm_timestamp_precision),
128*5718399fSFrançois Tigeot 	    "");
129*5718399fSFrançois Tigeot 
130*5718399fSFrançois Tigeot 	return (0);
1317f3c3d6fSHasso Tepper }
1327f3c3d6fSHasso Tepper 
133b3705d71SHasso Tepper int drm_sysctl_cleanup(struct drm_device *dev)
1347f3c3d6fSHasso Tepper {
1357f3c3d6fSHasso Tepper 	int error;
136*5718399fSFrançois Tigeot 
1377f3c3d6fSHasso Tepper 	error = sysctl_ctx_free(&dev->sysctl->ctx);
138*5718399fSFrançois Tigeot 	drm_free(dev->sysctl, DRM_MEM_DRIVER);
1397f3c3d6fSHasso Tepper 	dev->sysctl = NULL;
140*5718399fSFrançois Tigeot 	if (dev->driver->sysctl_cleanup != NULL)
141*5718399fSFrançois Tigeot 		dev->driver->sysctl_cleanup(dev);
1427f3c3d6fSHasso Tepper 
143*5718399fSFrançois Tigeot 	return (error);
1447f3c3d6fSHasso Tepper }
1457f3c3d6fSHasso Tepper 
1467f3c3d6fSHasso Tepper #define DRM_SYSCTL_PRINT(fmt, arg...)				\
1477f3c3d6fSHasso Tepper do {								\
148*5718399fSFrançois Tigeot 	ksnprintf(buf, sizeof(buf), fmt, ##arg);			\
1497f3c3d6fSHasso Tepper 	retcode = SYSCTL_OUT(req, buf, strlen(buf));		\
1507f3c3d6fSHasso Tepper 	if (retcode)						\
1517f3c3d6fSHasso Tepper 		goto done;					\
1527f3c3d6fSHasso Tepper } while (0)
1537f3c3d6fSHasso Tepper 
1547f3c3d6fSHasso Tepper static int drm_name_info DRM_SYSCTL_HANDLER_ARGS
1557f3c3d6fSHasso Tepper {
156b3705d71SHasso Tepper 	struct drm_device *dev = arg1;
1577f3c3d6fSHasso Tepper 	char buf[128];
1587f3c3d6fSHasso Tepper 	int retcode;
1597f3c3d6fSHasso Tepper 	int hasunique = 0;
1607f3c3d6fSHasso Tepper 
161b3705d71SHasso Tepper 	DRM_SYSCTL_PRINT("%s 0x%x", dev->driver->name, dev2udev(dev->devnode));
1627f3c3d6fSHasso Tepper 
163*5718399fSFrançois Tigeot 	DRM_LOCK(dev);
1647f3c3d6fSHasso Tepper 	if (dev->unique) {
165*5718399fSFrançois Tigeot 		ksnprintf(buf, sizeof(buf), " %s", dev->unique);
1667f3c3d6fSHasso Tepper 		hasunique = 1;
1677f3c3d6fSHasso Tepper 	}
168*5718399fSFrançois Tigeot 	DRM_UNLOCK(dev);
1697f3c3d6fSHasso Tepper 
1707f3c3d6fSHasso Tepper 	if (hasunique)
1717f3c3d6fSHasso Tepper 		SYSCTL_OUT(req, buf, strlen(buf));
1727f3c3d6fSHasso Tepper 
1737f3c3d6fSHasso Tepper 	SYSCTL_OUT(req, "", 1);
1747f3c3d6fSHasso Tepper 
1757f3c3d6fSHasso Tepper done:
1767f3c3d6fSHasso Tepper 	return retcode;
1777f3c3d6fSHasso Tepper }
1787f3c3d6fSHasso Tepper 
1797f3c3d6fSHasso Tepper static int drm_vm_info DRM_SYSCTL_HANDLER_ARGS
1807f3c3d6fSHasso Tepper {
181b3705d71SHasso Tepper 	struct drm_device *dev = arg1;
1827f3c3d6fSHasso Tepper 	drm_local_map_t *map, *tempmaps;
1837f3c3d6fSHasso Tepper 	const char   *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
1847f3c3d6fSHasso Tepper 	const char *type, *yesno;
1857f3c3d6fSHasso Tepper 	int i, mapcount;
1867f3c3d6fSHasso Tepper 	char buf[128];
1877f3c3d6fSHasso Tepper 	int retcode;
1887f3c3d6fSHasso Tepper 
1897f3c3d6fSHasso Tepper 	/* We can't hold the lock while doing SYSCTL_OUTs, so allocate a
1907f3c3d6fSHasso Tepper 	 * temporary copy of all the map entries and then SYSCTL_OUT that.
1917f3c3d6fSHasso Tepper 	 */
192*5718399fSFrançois Tigeot 	DRM_LOCK(dev);
1937f3c3d6fSHasso Tepper 
1947f3c3d6fSHasso Tepper 	mapcount = 0;
1957f3c3d6fSHasso Tepper 	TAILQ_FOREACH(map, &dev->maplist, link)
1967f3c3d6fSHasso Tepper 		mapcount++;
1977f3c3d6fSHasso Tepper 
198*5718399fSFrançois Tigeot 	tempmaps = kmalloc(sizeof(drm_local_map_t) * mapcount, DRM_MEM_DRIVER,
199b3705d71SHasso Tepper 	    M_NOWAIT);
2007f3c3d6fSHasso Tepper 	if (tempmaps == NULL) {
201*5718399fSFrançois Tigeot 		DRM_UNLOCK(dev);
2027f3c3d6fSHasso Tepper 		return ENOMEM;
2037f3c3d6fSHasso Tepper 	}
2047f3c3d6fSHasso Tepper 
2057f3c3d6fSHasso Tepper 	i = 0;
2067f3c3d6fSHasso Tepper 	TAILQ_FOREACH(map, &dev->maplist, link)
2077f3c3d6fSHasso Tepper 		tempmaps[i++] = *map;
2087f3c3d6fSHasso Tepper 
209*5718399fSFrançois Tigeot 	DRM_UNLOCK(dev);
2107f3c3d6fSHasso Tepper 
211b3705d71SHasso Tepper 	DRM_SYSCTL_PRINT("\nslot offset	        size       "
21299f70504SFrançois Tigeot 	    "type flags address            handle mtrr\n");
2137f3c3d6fSHasso Tepper 
2147f3c3d6fSHasso Tepper 	for (i = 0; i < mapcount; i++) {
2157f3c3d6fSHasso Tepper 		map = &tempmaps[i];
2167f3c3d6fSHasso Tepper 
2177f3c3d6fSHasso Tepper 		if (map->type < 0 || map->type > 4)
2187f3c3d6fSHasso Tepper 			type = "??";
2197f3c3d6fSHasso Tepper 		else
2207f3c3d6fSHasso Tepper 			type = types[map->type];
2217f3c3d6fSHasso Tepper 
2227f3c3d6fSHasso Tepper 		if (!map->mtrr)
2237f3c3d6fSHasso Tepper 			yesno = "no";
2247f3c3d6fSHasso Tepper 		else
2257f3c3d6fSHasso Tepper 			yesno = "yes";
2267f3c3d6fSHasso Tepper 
2277f3c3d6fSHasso Tepper 		DRM_SYSCTL_PRINT(
22899f70504SFrançois Tigeot 		    "%4d 0x%016lx 0x%08lx %4.4s  0x%02x 0x%016lx %6d %s\n",
22999f70504SFrançois Tigeot 		    i, map->offset, map->size, type, map->flags,
23099f70504SFrançois Tigeot 		    (unsigned long)map->virtual,
23199f70504SFrançois Tigeot 		    (unsigned int)((unsigned long)map->handle >>
23299f70504SFrançois Tigeot 		    DRM_MAP_HANDLE_SHIFT), yesno);
2337f3c3d6fSHasso Tepper 	}
2347f3c3d6fSHasso Tepper 	SYSCTL_OUT(req, "", 1);
2357f3c3d6fSHasso Tepper 
2367f3c3d6fSHasso Tepper done:
237*5718399fSFrançois Tigeot 	drm_free(tempmaps, DRM_MEM_DRIVER);
2387f3c3d6fSHasso Tepper 	return retcode;
2397f3c3d6fSHasso Tepper }
2407f3c3d6fSHasso Tepper 
2417f3c3d6fSHasso Tepper static int drm_bufs_info DRM_SYSCTL_HANDLER_ARGS
2427f3c3d6fSHasso Tepper {
243b3705d71SHasso Tepper 	struct drm_device	 *dev = arg1;
2447f3c3d6fSHasso Tepper 	drm_device_dma_t *dma = dev->dma;
2457f3c3d6fSHasso Tepper 	drm_device_dma_t tempdma;
2467f3c3d6fSHasso Tepper 	int *templists;
2477f3c3d6fSHasso Tepper 	int i;
2487f3c3d6fSHasso Tepper 	char buf[128];
2497f3c3d6fSHasso Tepper 	int retcode;
2507f3c3d6fSHasso Tepper 
2517f3c3d6fSHasso Tepper 	/* We can't hold the locks around DRM_SYSCTL_PRINT, so make a temporary
2527f3c3d6fSHasso Tepper 	 * copy of the whole structure and the relevant data from buflist.
2537f3c3d6fSHasso Tepper 	 */
254*5718399fSFrançois Tigeot 	DRM_LOCK(dev);
2557f3c3d6fSHasso Tepper 	if (dma == NULL) {
256*5718399fSFrançois Tigeot 		DRM_UNLOCK(dev);
2577f3c3d6fSHasso Tepper 		return 0;
2587f3c3d6fSHasso Tepper 	}
259*5718399fSFrançois Tigeot 	spin_lock(&dev->dma_lock);
2607f3c3d6fSHasso Tepper 	tempdma = *dma;
261*5718399fSFrançois Tigeot 	templists = kmalloc(sizeof(int) * dma->buf_count, DRM_MEM_DRIVER,
262b3705d71SHasso Tepper 	    M_NOWAIT);
2637f3c3d6fSHasso Tepper 	for (i = 0; i < dma->buf_count; i++)
2647f3c3d6fSHasso Tepper 		templists[i] = dma->buflist[i]->list;
2657f3c3d6fSHasso Tepper 	dma = &tempdma;
266*5718399fSFrançois Tigeot 	spin_unlock(&dev->dma_lock);
267*5718399fSFrançois Tigeot 	DRM_UNLOCK(dev);
2687f3c3d6fSHasso Tepper 
2697f3c3d6fSHasso Tepper 	DRM_SYSCTL_PRINT("\n o     size count  free	 segs pages    kB\n");
2707f3c3d6fSHasso Tepper 	for (i = 0; i <= DRM_MAX_ORDER; i++) {
2717f3c3d6fSHasso Tepper 		if (dma->bufs[i].buf_count)
2727f3c3d6fSHasso Tepper 			DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
2737f3c3d6fSHasso Tepper 				       i,
2747f3c3d6fSHasso Tepper 				       dma->bufs[i].buf_size,
2757f3c3d6fSHasso Tepper 				       dma->bufs[i].buf_count,
2767f3c3d6fSHasso Tepper 				       atomic_read(&dma->bufs[i]
2777f3c3d6fSHasso Tepper 						   .freelist.count),
2787f3c3d6fSHasso Tepper 				       dma->bufs[i].seg_count,
2797f3c3d6fSHasso Tepper 				       dma->bufs[i].seg_count
2807f3c3d6fSHasso Tepper 				       *(1 << dma->bufs[i].page_order),
2817f3c3d6fSHasso Tepper 				       (dma->bufs[i].seg_count
2827f3c3d6fSHasso Tepper 					* (1 << dma->bufs[i].page_order))
283*5718399fSFrançois Tigeot 				       * (int)PAGE_SIZE / 1024);
2847f3c3d6fSHasso Tepper 	}
2857f3c3d6fSHasso Tepper 	DRM_SYSCTL_PRINT("\n");
2867f3c3d6fSHasso Tepper 	for (i = 0; i < dma->buf_count; i++) {
2877f3c3d6fSHasso Tepper 		if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
2887f3c3d6fSHasso Tepper 		DRM_SYSCTL_PRINT(" %d", templists[i]);
2897f3c3d6fSHasso Tepper 	}
2907f3c3d6fSHasso Tepper 	DRM_SYSCTL_PRINT("\n");
2917f3c3d6fSHasso Tepper 
2927f3c3d6fSHasso Tepper 	SYSCTL_OUT(req, "", 1);
2937f3c3d6fSHasso Tepper done:
294*5718399fSFrançois Tigeot 	drm_free(templists, DRM_MEM_DRIVER);
2957f3c3d6fSHasso Tepper 	return retcode;
2967f3c3d6fSHasso Tepper }
2977f3c3d6fSHasso Tepper 
2987f3c3d6fSHasso Tepper static int drm_clients_info DRM_SYSCTL_HANDLER_ARGS
2997f3c3d6fSHasso Tepper {
300b3705d71SHasso Tepper 	struct drm_device *dev = arg1;
301b3705d71SHasso Tepper 	struct drm_file *priv, *tempprivs;
3027f3c3d6fSHasso Tepper 	char buf[128];
3037f3c3d6fSHasso Tepper 	int retcode;
3047f3c3d6fSHasso Tepper 	int privcount, i;
3057f3c3d6fSHasso Tepper 
306*5718399fSFrançois Tigeot 	DRM_LOCK(dev);
3077f3c3d6fSHasso Tepper 
3087f3c3d6fSHasso Tepper 	privcount = 0;
3097f3c3d6fSHasso Tepper 	TAILQ_FOREACH(priv, &dev->files, link)
3107f3c3d6fSHasso Tepper 		privcount++;
3117f3c3d6fSHasso Tepper 
312*5718399fSFrançois Tigeot 	tempprivs = kmalloc(sizeof(struct drm_file) * privcount, DRM_MEM_DRIVER,
313b3705d71SHasso Tepper 	    M_NOWAIT);
3147f3c3d6fSHasso Tepper 	if (tempprivs == NULL) {
315*5718399fSFrançois Tigeot 		DRM_UNLOCK(dev);
3167f3c3d6fSHasso Tepper 		return ENOMEM;
3177f3c3d6fSHasso Tepper 	}
3187f3c3d6fSHasso Tepper 	i = 0;
3197f3c3d6fSHasso Tepper 	TAILQ_FOREACH(priv, &dev->files, link)
3207f3c3d6fSHasso Tepper 		tempprivs[i++] = *priv;
3217f3c3d6fSHasso Tepper 
322*5718399fSFrançois Tigeot 	DRM_UNLOCK(dev);
3237f3c3d6fSHasso Tepper 
324*5718399fSFrançois Tigeot 	DRM_SYSCTL_PRINT(
325*5718399fSFrançois Tigeot 	    "\na dev            pid   uid      magic     ioctls\n");
3267f3c3d6fSHasso Tepper 	for (i = 0; i < privcount; i++) {
3277f3c3d6fSHasso Tepper 		priv = &tempprivs[i];
328*5718399fSFrançois Tigeot 		DRM_SYSCTL_PRINT("%c %-12s %5d %5d %10u %10lu\n",
3297f3c3d6fSHasso Tepper 			       priv->authenticated ? 'y' : 'n',
330*5718399fSFrançois Tigeot 			       devtoname(priv->dev->devnode),
3317f3c3d6fSHasso Tepper 			       priv->pid,
3327f3c3d6fSHasso Tepper 			       priv->uid,
3337f3c3d6fSHasso Tepper 			       priv->magic,
3347f3c3d6fSHasso Tepper 			       priv->ioctl_count);
3357f3c3d6fSHasso Tepper 	}
3367f3c3d6fSHasso Tepper 
3377f3c3d6fSHasso Tepper 	SYSCTL_OUT(req, "", 1);
3387f3c3d6fSHasso Tepper done:
339*5718399fSFrançois Tigeot 	drm_free(tempprivs, DRM_MEM_DRIVER);
3407f3c3d6fSHasso Tepper 	return retcode;
3417f3c3d6fSHasso Tepper }
3427ae23ad1SHasso Tepper 
3437ae23ad1SHasso Tepper static int drm_vblank_info DRM_SYSCTL_HANDLER_ARGS
3447ae23ad1SHasso Tepper {
3457ae23ad1SHasso Tepper 	struct drm_device *dev = arg1;
3467ae23ad1SHasso Tepper 	char buf[128];
3477ae23ad1SHasso Tepper 	int retcode;
3487ae23ad1SHasso Tepper 	int i;
3497ae23ad1SHasso Tepper 
3507ae23ad1SHasso Tepper 	DRM_SYSCTL_PRINT("\ncrtc ref count    last     enabled inmodeset\n");
351*5718399fSFrançois Tigeot 	DRM_LOCK(dev);
352*5718399fSFrançois Tigeot 	if (dev->_vblank_count == NULL)
353*5718399fSFrançois Tigeot 		goto done;
3547ae23ad1SHasso Tepper 	for (i = 0 ; i < dev->num_crtcs ; i++) {
3557ae23ad1SHasso Tepper 		DRM_SYSCTL_PRINT("  %02d  %02d %08d %08d %02d      %02d\n",
356*5718399fSFrançois Tigeot 		    i, dev->vblank_refcount[i],
357*5718399fSFrançois Tigeot 		    dev->_vblank_count[i],
358*5718399fSFrançois Tigeot 		    dev->last_vblank[i],
359*5718399fSFrançois Tigeot 		    dev->vblank_enabled[i],
360*5718399fSFrançois Tigeot 		    dev->vblank_inmodeset[i]);
3617ae23ad1SHasso Tepper 	}
362*5718399fSFrançois Tigeot done:
363*5718399fSFrançois Tigeot 	DRM_UNLOCK(dev);
3647ae23ad1SHasso Tepper 
3657ae23ad1SHasso Tepper 	SYSCTL_OUT(req, "", -1);
3667ae23ad1SHasso Tepper 	return retcode;
3677ae23ad1SHasso Tepper }
368