1f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \file xf86drm.c
3f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * User-level interface to DRM device
4f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
5f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \author Rickard E. (Rik) Faith <faith@valinux.com>
6f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \author Kevin E. Martin <martin@valinux.com>
7f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
8f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
9f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/*
10f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * All Rights Reserved.
13f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
14f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Permission is hereby granted, free of charge, to any person obtaining a
15f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * copy of this software and associated documentation files (the "Software"),
16f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * to deal in the Software without restriction, including without limitation
17f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * and/or sell copies of the Software, and to permit persons to whom the
19f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Software is furnished to do so, subject to the following conditions:
20f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
21f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * The above copyright notice and this permission notice (including the next
22f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * paragraph) shall be included in all copies or substantial portions of the
23f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Software.
24f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
25f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
28f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * DEALINGS IN THE SOFTWARE.
32f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
33f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
34f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifdef HAVE_CONFIG_H
35f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu# include <config.h>
36f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
37f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <stdio.h>
38f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <stdlib.h>
39f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <unistd.h>
40f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <string.h>
41f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <strings.h>
42f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <ctype.h>
43f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <fcntl.h>
44f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <errno.h>
45f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <signal.h>
46f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <time.h>
47f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <sys/types.h>
48f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <sys/stat.h>
49f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define stat_t struct stat
50f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <sys/ioctl.h>
51f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <sys/mman.h>
52f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <sys/time.h>
53f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include <stdarg.h>
54f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
55f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/* Not all systems have MAP_FAILED defined */
56f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifndef MAP_FAILED
57f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define MAP_FAILED ((void *)-1)
58f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
59f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
60f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#include "xf86drm.h"
61f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
62f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
63f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MAJOR 145
64f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
65f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
66f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifdef __NetBSD__
67f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MAJOR 34
68f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
69f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
70f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu# ifdef __OpenBSD__
71f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#  define DRM_MAJOR 81
72f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu# endif
73f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
74f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifndef DRM_MAJOR
75f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MAJOR 226		/* Linux */
76f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
77f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
78f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifndef DRM_MAX_MINOR
79f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MAX_MINOR 16
80f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
81f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
82f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/*
83f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This definition needs to be changed on some systems if dev_t is a structure.
84f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * If there is a header file we can get it from, there would be best.
85f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
86f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifndef makedev
87f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define makedev(x,y)    ((dev_t)(((x) << 8) | (y)))
88f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
89f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
90f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MSG_VERBOSITY 3
91f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
92f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_NODE_CONTROL 0
93f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_NODE_RENDER 1
94f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
95f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic drmServerInfoPtr drm_server_info;
96f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
97f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmSetServerInfo(drmServerInfoPtr info)
98f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
99f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_server_info = info;
100f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
101f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
102f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
103f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Output a message to stderr.
104f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
105f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param format printf() like format string.
106f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
107f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
108f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around vfprintf().
109f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
110f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
111f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmDebugPrint(const char *format, va_list ap)
112f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
113f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return vfprintf(stderr, format, ap);
114f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
115f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
116f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
117f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
118f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid
119f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmMsg(const char *format, ...)
120f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
121f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    va_list	ap;
122f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    const char *env;
123f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info)
124f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    {
125f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	va_start(ap, format);
126f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (drm_server_info) {
127f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	  drm_server_info->debug_print(format,ap);
128f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	} else {
129f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	  drm_debug_print(format, ap);
130f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
131f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	va_end(ap);
132f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
133f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
134f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
135f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid
136f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
137f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
138f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_debug_print = debug_msg_ptr;
139f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
140f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
141f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic void *drmHashTable = NULL; /* Context switch callbacks */
142f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
143f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid *drmGetHashTable(void)
144f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
145f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return drmHashTable;
146f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
147f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
148f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid *drmMalloc(int size)
149f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
150f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    void *pt;
151f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if ((pt = malloc(size)))
152f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	memset(pt, 0, size);
153f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return pt;
154f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
155f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
156f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmFree(void *pt)
157f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
158f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (pt)
159f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	free(pt);
160f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
161f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
162f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
163f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic char *drmStrdup(const char *s)
164f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
165f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    char *retval;
166f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
167f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!s)
168f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu        return NULL;
169f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
170f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    retval = malloc(strlen(s)+1);
171f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!retval)
172f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu        return NULL;
173f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
174f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    strcpy(retval, s);
175f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
176f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return retval;
177f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
178f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
179f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
180f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Call ioctl, restarting if it is interupted
181f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
182f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint
183f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmIoctl(int fd, unsigned long request, void *arg)
184f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
185f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int	ret;
186f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
187f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    do {
188f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = ioctl(fd, request, arg);
189f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
190f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return ret;
191f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
192f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
193f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic unsigned long drmGetKeyFromFd(int fd)
194f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
195f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stat_t     st;
196f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
197f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    st.st_rdev = 0;
198f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    fstat(fd, &st);
199f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return st.st_rdev;
200f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
201f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
202f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmHashEntry *drmGetEntry(int fd)
203f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
204f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long key = drmGetKeyFromFd(fd);
205f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    void          *value;
206f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashEntry  *entry;
207f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
208f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!drmHashTable)
209f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmHashTable = drmHashCreate();
210f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
211f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmHashLookup(drmHashTable, key, &value)) {
212f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	entry           = drmMalloc(sizeof(*entry));
213f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	entry->fd       = fd;
214f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	entry->f        = NULL;
215f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	entry->tagTable = drmHashCreate();
216f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmHashInsert(drmHashTable, key, entry);
217f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    } else {
218f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	entry = value;
219f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
220f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return entry;
221f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
222f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
223f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
224f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Compare two busid strings
225f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
226f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param first
227f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param second
228f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
229f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return 1 if matched.
230f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
231f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
232f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function compares two bus ID strings.  It understands the older
233f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
234f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * domain, b is bus, d is device, f is function.
235f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
236f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmMatchBusID(const char *id1, const char *id2)
237f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
238f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* First, check if the IDs are exactly the same */
239f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (strcasecmp(id1, id2) == 0)
240f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 1;
241f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
242f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* Try to match old/new-style PCI bus IDs. */
243f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (strncasecmp(id1, "pci", 3) == 0) {
244f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	unsigned int o1, b1, d1, f1;
245f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	unsigned int o2, b2, d2, f2;
246f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int ret;
247f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
248f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
249f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (ret != 4) {
250f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    o1 = 0;
251f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
252f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (ret != 3)
253f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return 0;
254f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
255f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
256f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
257f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (ret != 4) {
258f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    o2 = 0;
259f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
260f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (ret != 3)
261f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return 0;
262f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
263f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
264f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
265f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return 0;
266f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	else
267f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return 1;
268f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
269f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
270f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
271f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
272f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
273f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Handles error checking for chown call.
274f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
275f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param path to file.
276f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param id of the new owner.
277f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param id of the new group.
278f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
279f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero if success or -1 if failure.
280f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
281f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
282f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Checks for failure. If failure was caused by signal call chown again.
283f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * If any other failure happened then it will output error mesage using
284f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * drmMsg() call.
285f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
286f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int chown_check_return(const char *path, uid_t owner, gid_t group)
287f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
288f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int rv;
289f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
290f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	do {
291f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		rv = chown(path, owner, group);
292f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	} while (rv != 0 && errno == EINTR);
293f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
294f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (rv == 0)
295f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return 0;
296f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
297f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmMsg("Failed to change owner or group for file %s! %d: %s\n",
298f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			path, errno, strerror(errno));
299f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -1;
300f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
301f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
302f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
303f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Open the DRM device, creating it if necessary.
304f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
305f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param dev major and minor numbers of the device.
306f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param minor minor number of the device.
307f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
308f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a file descriptor on success, or a negative value on error.
309f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
310f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
311f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Assembles the device name from \p minor and opens it, creating the device
312f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * special file node with the major and minor numbers specified by \p dev and
313f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * parent directory if necessary and was called by root.
314f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
315f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmOpenDevice(long dev, int minor, int type)
316f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
317f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stat_t          st;
318f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    char            buf[64];
319f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int             fd;
320f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    mode_t          devmode = DRM_DEV_MODE, serv_mode;
321f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int             isroot  = !geteuid();
322f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    uid_t           user    = DRM_DEV_UID;
323f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    gid_t           group   = DRM_DEV_GID, serv_group;
324f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
32507399050725e781899bc541c1a503b56aa55b8e9Elaine Wang    snprintf(buf, sizeof(buf), type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
326f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmMsg("drmOpenDevice: node name is %s\n", buf);
327f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
328f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drm_server_info) {
329f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drm_server_info->get_perms(&serv_group, &serv_mode);
330f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
331f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
332f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
333f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
334f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
335f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#if !defined(UDEV)
336f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (stat(DRM_DIR_NAME, &st)) {
337f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!isroot)
338f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return DRM_ERR_NOT_ROOT;
339f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
340f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
341f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
342f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
343f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
344f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* Check if the device node exists and create it if necessary. */
345f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (stat(buf, &st)) {
346f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!isroot)
347f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return DRM_ERR_NOT_ROOT;
348f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	remove(buf);
349f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	mknod(buf, S_IFCHR | devmode, dev);
350f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
351f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
352f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drm_server_info) {
353f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	chown_check_return(buf, user, group);
354f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	chmod(buf, devmode);
355f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
356f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#else
357f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* if we modprobed then wait for udev */
358f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    {
359f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int udev_count = 0;
360f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuwait_for_udev:
361f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu        if (stat(DRM_DIR_NAME, &st)) {
362f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		usleep(20);
363f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		udev_count++;
364f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
365f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		if (udev_count == 50)
366f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			return -1;
367f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		goto wait_for_udev;
368f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
369f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
370f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    	if (stat(buf, &st)) {
371f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		usleep(20);
372f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		udev_count++;
373f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
374f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		if (udev_count == 50)
375f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			return -1;
376f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		goto wait_for_udev;
377f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    	}
378f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
379f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
380f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
381f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    fd = open(buf, O_RDWR, 0);
382f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
383f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		fd, fd < 0 ? strerror(errno) : "OK");
384f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (fd >= 0)
385f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return fd;
386f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
387f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* Check if the device node is not what we expect it to be, and recreate it
388f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * and try again if so.
389f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     */
390f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (st.st_rdev != dev) {
391f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!isroot)
392f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return DRM_ERR_NOT_ROOT;
393f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	remove(buf);
394f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	mknod(buf, S_IFCHR | devmode, dev);
395f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (drm_server_info) {
396f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    chown_check_return(buf, user, group);
397f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    chmod(buf, devmode);
398f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
399f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
400f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    fd = open(buf, O_RDWR, 0);
401f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
402f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		fd, fd < 0 ? strerror(errno) : "OK");
403f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (fd >= 0)
404f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return fd;
405f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
406f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmMsg("drmOpenDevice: Open failed\n");
407f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    remove(buf);
408f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return -errno;
409f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
410f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
411f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
412f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
413f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Open the DRM device
414f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
415f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param minor device minor number.
416f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param create allow to create the device if set.
417f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
418f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a file descriptor on success, or a negative value on error.
419f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
420f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
421f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
422f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * name from \p minor and opens it.
423f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
424f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmOpenMinor(int minor, int create, int type)
425f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
426f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int  fd;
427f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    char buf[64];
428f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
429f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (create)
430f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
43107399050725e781899bc541c1a503b56aa55b8e9Elaine Wang
43207399050725e781899bc541c1a503b56aa55b8e9Elaine Wang    snprintf(buf, sizeof(buf), type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
433f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if ((fd = open(buf, O_RDWR, 0)) >= 0)
434f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return fd;
435f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return -errno;
436f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
437f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
438f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
439f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
440f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Determine whether the DRM kernel driver has been loaded.
441f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
442f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return 1 if the DRM driver is loaded, 0 otherwise.
443f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
444f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
445f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Determine the presence of the kernel driver by attempting to open the 0
446f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * minor and get version information.  For backward compatibility with older
447f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Linux implementations, /proc/dri is also checked.
448f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
449f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAvailable(void)
450f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
451f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmVersionPtr version;
452f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           retval = 0;
453f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           fd;
454f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
455f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
456f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifdef __linux__
457f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	/* Try proc for backward Linux compatibility */
458f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!access("/proc/dri/0", R_OK))
459f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return 1;
460f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
461f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
462f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
463f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
464f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if ((version = drmGetVersion(fd))) {
465f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval = 1;
466f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFreeVersion(version);
467f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
468f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    close(fd);
469f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
470f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return retval;
471f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
472f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
473f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
474f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
475f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Open the device by bus ID.
476f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
477f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param busid bus ID.
478f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
479f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a file descriptor on success, or a negative value on error.
480f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
481f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
482f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
483f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * comparing the device bus ID with the one supplied.
484f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
485f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \sa drmOpenMinor() and drmGetBusid().
486f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
487f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmOpenByBusid(const char *busid)
488f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
489f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int        i;
490f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int        fd;
491f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    const char *buf;
492f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmSetVersion sv;
493f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
494f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
495f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < DRM_MAX_MINOR; i++) {
496f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
497f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
498f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (fd >= 0) {
499f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    sv.drm_di_major = 1;
500f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    sv.drm_di_minor = 1;
501f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    sv.drm_dd_major = -1;	/* Don't care */
502f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    sv.drm_dd_minor = -1;	/* Don't care */
503f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmSetInterfaceVersion(fd, &sv);
504f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    buf = drmGetBusid(fd);
505f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
506f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (buf && drmMatchBusID(buf, busid)) {
507f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		drmFreeBusid(buf);
508f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return fd;
509f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    }
510f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (buf)
511f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		drmFreeBusid(buf);
512f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    close(fd);
513f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
514f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
515f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return -1;
516f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
517f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
518f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
519f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
520f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Open the device by name.
521f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
522f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param name driver name.
523f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
524f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a file descriptor on success, or a negative value on error.
525f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
526f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
527f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function opens the first minor number that matches the driver name and
528f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * isn't already in use.  If it's in use it then it will already have a bus ID
529f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * assigned.
530f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
531f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
532f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
533f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int drmOpenByName(const char *name)
534f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
535f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           i;
536f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           fd;
537f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmVersionPtr version;
538f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    char *        id;
539f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
540f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!drmAvailable()) {
541f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!drm_server_info) {
542f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return -1;
543f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
544f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	else {
545f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    /* try to load the kernel module now */
546f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (!drm_server_info->load_module(name)) {
547f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
548f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return -1;
549f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    }
550f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
551f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
552f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
553f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /*
554f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * Open the first minor number that matches the driver name and isn't
555f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * already in use.  If it's in use it will have a busid assigned already.
556f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     */
557f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < DRM_MAX_MINOR; i++) {
558f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
559f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if ((version = drmGetVersion(fd))) {
560f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		if (!strcmp(version->name, name)) {
561f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    drmFreeVersion(version);
562f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    id = drmGetBusid(fd);
563f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
564f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    if (!id || !*id) {
565f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			if (id)
566f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			    drmFreeBusid(id);
567f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			return fd;
568f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    } else {
569f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			drmFreeBusid(id);
570f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    }
571f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		} else {
572f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    drmFreeVersion(version);
573f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		}
574f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    }
575f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    close(fd);
576f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
577f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
578f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
579f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#ifdef __linux__
580f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* Backward-compatibility /proc support */
581f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < 8; i++) {
582f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	char proc_name[64], buf[512];
583f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	char *driver, *pt, *devstring;
584f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int  retcode;
585f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
58607399050725e781899bc541c1a503b56aa55b8e9Elaine Wang	snprintf(proc_name, sizeof(proc_name), "/proc/dri/%d/name", i);
587f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if ((fd = open(proc_name, 0, 0)) >= 0) {
588f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retcode = read(fd, buf, sizeof(buf)-1);
589f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    close(fd);
59007399050725e781899bc541c1a503b56aa55b8e9Elaine Wang	    if (retcode > 0) {
591f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		buf[retcode-1] = '\0';
592f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		for (driver = pt = buf; *pt && *pt != ' '; ++pt)
593f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    ;
594f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		if (*pt) { /* Device is next */
595f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    *pt = '\0';
596f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    if (!strcmp(driver, name)) { /* Match */
597f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
598f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			    ;
599f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			if (*pt) { /* Found busid */
600f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			    return drmOpenByBusid(++pt);
601f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			} else { /* No busid */
602f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			    return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
603f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			}
604f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    }
605f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		}
606f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    }
607f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
608f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
609f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#endif
610f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
611f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return -1;
612f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
613f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
614f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
615f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
616f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Open the DRM device.
617f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
618f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Looks up the specified name and bus ID, and opens the device found.  The
619f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * entry in /dev/dri is created if necessary and if called by root.
620f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
621f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param name driver name. Not referenced if bus ID is supplied.
622f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param busid bus ID. Zero if not known.
623f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
624f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a file descriptor on success, or a negative value on error.
625f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
626f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
627f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
628f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * otherwise.
629f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
630f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmOpen(const char *name, const char *busid)
631f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
632f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!drmAvailable() && name != NULL && drm_server_info) {
633f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	/* try to load the kernel */
634f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!drm_server_info->load_module(name)) {
635f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
636f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return -1;
637f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
638f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
639f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
640f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (busid) {
641f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int fd = drmOpenByBusid(busid);
642f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (fd >= 0)
643f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return fd;
644f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
645f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
646f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (name)
647f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return drmOpenByName(name);
648f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
649f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return -1;
650f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
651f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
652f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmOpenControl(int minor)
653f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
654f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
655f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
656f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
657f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
658f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free the version information returned by drmGetVersion().
659f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
660f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param v pointer to the version information.
661f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
662f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
663f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It frees the memory pointed by \p %v as well as all the non-null strings
664f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * pointers in it.
665f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
666f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmFreeVersion(drmVersionPtr v)
667f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
668f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!v)
669f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return;
670f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->name);
671f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->date);
672f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->desc);
673f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v);
674f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
675f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
676f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
677f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
678f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free the non-public version information returned by the kernel.
679f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
680f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param v pointer to the version information.
681f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
682f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
683f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
684f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the non-null strings pointers in it.
685f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
686f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic void drmFreeKernelVersion(drm_version_t *v)
687f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
688f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!v)
689f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return;
690f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->name);
691f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->date);
692f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v->desc);
693f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(v);
694f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
695f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
696f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
697f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
698f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Copy version information.
699f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
700f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param d destination pointer.
701f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param s source pointer.
702f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
703f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
704f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Used by drmGetVersion() to translate the information returned by the ioctl
705f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * interface in a private structure into the public structure counterpart.
706f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
707f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
708f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
709f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->version_major      = s->version_major;
710f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->version_minor      = s->version_minor;
711f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->version_patchlevel = s->version_patchlevel;
712f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->name_len           = s->name_len;
713f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->name               = drmStrdup(s->name);
714f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->date_len           = s->date_len;
715f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->date               = drmStrdup(s->date);
716f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->desc_len           = s->desc_len;
717f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    d->desc               = drmStrdup(s->desc);
718f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
719f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
720f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
721f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
722f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Query the driver version information.
723f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
724f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
725f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
726f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return pointer to a drmVersion structure which should be freed with
727f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * drmFreeVersion().
728f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
729f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note Similar information is available via /proc/dri.
730f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
731f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
732f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
733f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * first with zeros to get the string lengths, and then the actually strings.
734f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It also null-terminates them since they might not be already.
735f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
736f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmVersionPtr drmGetVersion(int fd)
737f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
738f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmVersionPtr retval;
739f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_version_t *version = drmMalloc(sizeof(*version));
740f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
741f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->name_len    = 0;
742f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->name        = NULL;
743f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->date_len    = 0;
744f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->date        = NULL;
745f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->desc_len    = 0;
746f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->desc        = NULL;
747f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
748f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
749f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFreeKernelVersion(version);
750f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
751f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
752f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
753f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->name_len)
754f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	version->name    = drmMalloc(version->name_len + 1);
755f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->date_len)
756f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	version->date    = drmMalloc(version->date_len + 1);
757f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->desc_len)
758f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	version->desc    = drmMalloc(version->desc_len + 1);
759f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
760f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
761f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
762f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFreeKernelVersion(version);
763f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
764f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
765f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
766f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* The results might not be null-terminated strings, so terminate them. */
767f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->name_len) version->name[version->name_len] = '\0';
768f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->date_len) version->date[version->date_len] = '\0';
769f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (version->desc_len) version->desc[version->desc_len] = '\0';
770f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
771f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    retval = drmMalloc(sizeof(*retval));
772f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmCopyVersion(retval, version);
773f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFreeKernelVersion(version);
774f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return retval;
775f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
776f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
777f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
778f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
779f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get version information for the DRM user space library.
780f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
781f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This version number is driver independent.
782f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
783f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
784f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
785f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return version information.
786f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
787f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
788f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function allocates and fills a drm_version structure with a hard coded
789f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * version number.
790f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
791f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmVersionPtr drmGetLibVersion(int fd)
792f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
793f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_version_t *version = drmMalloc(sizeof(*version));
794f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
795f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /* Version history:
796f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *   NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
797f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *   revision 1.0.x = original DRM interface with no drmGetLibVersion
798f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *                    entry point and many drm<Device> extensions
799f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *   revision 1.1.x = added drmCommand entry points for device extensions
800f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *                    added drmGetLibVersion to identify libdrm.a version
801f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *   revision 1.2.x = added drmSetInterfaceVersion
802f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *                    modified drmOpen to handle both busid and name
803f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     *   revision 1.3.x = added server + memory manager
804f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     */
805f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->version_major      = 1;
806f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->version_minor      = 3;
807f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->version_patchlevel = 0;
808f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
809f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return (drmVersionPtr)version;
810f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
811f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
812f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
813f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
814f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free the bus ID information.
815f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
816f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param busid bus ID information string as given by drmGetBusid().
817f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
818f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
819f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is just frees the memory pointed by \p busid.
820f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
821f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmFreeBusid(const char *busid)
822f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
823f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree((void *)busid);
824f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
825f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
826f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
827f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
828f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get the bus ID of the device.
829f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
830f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
831f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
832f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return bus ID string.
833f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
834f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
835f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
836f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * get the string length and data, passing the arguments in a drm_unique
837f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * structure.
838f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
839f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuchar *drmGetBusid(int fd)
840f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
841f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_unique_t u;
842f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
843f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique_len = 0;
844f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique     = NULL;
845f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
846f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
847f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
848f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique = drmMalloc(u.unique_len + 1);
849f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
850f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
851f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique[u.unique_len] = '\0';
852f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
853f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return u.unique;
854f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
855f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
856f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
857f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
858f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Set the bus ID of the device.
859f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
860f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
861f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param busid bus ID string.
862f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
863f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, negative on failure.
864f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
865f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
866f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
867f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the arguments in a drm_unique structure.
868f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
869f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmSetBusid(int fd, const char *busid)
870f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
871f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_unique_t u;
872f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
873f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique     = (char *)busid;
874f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    u.unique_len = strlen(busid);
875f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
876f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
877f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
878f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
879f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
880f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
881f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
882f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetMagic(int fd, drm_magic_t * magic)
883f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
884f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_auth_t auth;
885f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
886f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *magic = 0;
887f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
888f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
889f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *magic = auth.magic;
890f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
891f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
892f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
893f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAuthMagic(int fd, drm_magic_t magic)
894f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
895f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_auth_t auth;
896f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
897f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    auth.magic = magic;
898f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
899f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
900f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
901f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
902f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
903f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
904f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Specifies a range of memory that is available for mapping by a
905f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * non-root process.
906f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
907f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
908f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param offset usually the physical address. The actual meaning depends of
909f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the \p type parameter. See below.
910f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size of the memory in bytes.
911f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param type type of the memory to be mapped.
912f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param flags combination of several flags to modify the function actions.
913f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle will be set to a value that may be used as the offset
914f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * parameter for mmap().
915f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
916f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success or a negative value on error.
917f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
918f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par Mapping the frame buffer
919f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * For the frame buffer
920f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p offset will be the physical address of the start of the frame buffer,
921f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p size will be the size of the frame buffer in bytes, and
922f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p type will be DRM_FRAME_BUFFER.
923f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
924f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par
925f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * The area mapped will be uncached. If MTRR support is available in the
926f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * kernel, the frame buffer area will be set to write combining.
927f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
928f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par Mapping the MMIO register area
929f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * For the MMIO register area,
930f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p offset will be the physical address of the start of the register area,
931f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p size will be the size of the register area bytes, and
932f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p type will be DRM_REGISTERS.
933f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par
934f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * The area mapped will be uncached.
935f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
936f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par Mapping the SAREA
937f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * For the SAREA,
938f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p offset will be ignored and should be set to zero,
939f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p size will be the desired size of the SAREA in bytes,
940f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * - \p type will be DRM_SHM.
941f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
942f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \par
943f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * A shared memory area of the requested size will be created and locked in
944f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * kernel memory. This area may be mapped into client-space by using the handle
945f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * returned.
946f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
947f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note May only be called by root.
948f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
949f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
950f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
951f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the arguments in a drm_map structure.
952f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
953f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
954f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	      drmMapFlags flags, drm_handle_t *handle)
955f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
956f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_map_t map;
957f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
958f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.offset  = offset;
959f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.size    = size;
960f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.handle  = 0;
961f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.type    = type;
962f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.flags   = flags;
963f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
964f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
965f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (handle)
966f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	*handle = (drm_handle_t)map.handle;
967f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
968f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
969f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
970f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmRmMap(int fd, drm_handle_t handle)
971f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
972f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_map_t map;
973f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
974f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.handle = (void *)handle;
975f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
976f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
977f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
978f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
979f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
980f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
981f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
982f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Make buffers available for DMA transfers.
983f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
984f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
985f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param count number of buffers.
986f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size of each buffer.
987f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param flags buffer allocation flags.
988f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param agp_offset offset in the AGP aperture
989f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
990f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return number of buffers allocated, negative on error.
991f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
992f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
993f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
994f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
995f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \sa drm_buf_desc.
996f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
997f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
998f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	       int agp_offset)
999f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1000f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_buf_desc_t request;
1001f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1002f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.count     = count;
1003f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.size      = size;
1004f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.low_mark  = 0;
1005f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.high_mark = 0;
1006f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.flags     = flags;
1007f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.agp_start = agp_offset;
1008f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1009f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1010f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1011f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return request.count;
1012f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1013f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1014f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmMarkBufs(int fd, double low, double high)
1015f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1016f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_buf_info_t info;
1017f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int            i;
1018f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1019f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    info.count = 0;
1020f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    info.list  = NULL;
1021f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1022f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1023f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -EINVAL;
1024f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1025f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!info.count)
1026f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -EINVAL;
1027f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1028f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1029f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -ENOMEM;
1030f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1031f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1032f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int retval = -errno;
1033f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFree(info.list);
1034f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return retval;
1035f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1036f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1037f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < info.count; i++) {
1038f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	info.list[i].low_mark  = low  * info.list[i].count;
1039f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	info.list[i].high_mark = high * info.list[i].count;
1040f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1041f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    int retval = -errno;
1042f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmFree(info.list);
1043f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return retval;
1044f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
1045f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1046f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(info.list);
1047f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1048f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1049f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1050f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1051f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1052f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free buffers.
1053f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1054f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1055f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param count number of buffers to free.
1056f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param list list of buffers to be freed.
1057f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1058f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1059f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1060f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note This function is primarily used for debugging.
1061f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1062f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1063f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1064f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the arguments in a drm_buf_free structure.
1065f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1066f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmFreeBufs(int fd, int count, int *list)
1067f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1068f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_buf_free_t request;
1069f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1070f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.count = count;
1071f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request.list  = list;
1072f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1073f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1074f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1075f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1076f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1077f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1078f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1079f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Close the device.
1080f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1081f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1082f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1083f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1084f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function closes the file descriptor.
1085f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1086f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmClose(int fd)
1087f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1088f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long key    = drmGetKeyFromFd(fd);
1089f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashEntry  *entry = drmGetEntry(fd);
1090f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1091f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashDestroy(entry->tagTable);
1092f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    entry->fd       = 0;
1093f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    entry->f        = NULL;
1094f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    entry->tagTable = NULL;
1095f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1096f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashDelete(drmHashTable, key);
1097f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(entry);
1098f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1099f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return close(fd);
1100f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1101f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1102f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1103f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1104f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Map a region of memory.
1105f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1106f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1107f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle handle returned by drmAddMap().
1108f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size in bytes. Must match the size used by drmAddMap().
1109f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param address will contain the user-space virtual address where the mapping
1110f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * begins.
1111f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1112f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1113f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1114f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1115f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper for mmap().
1116f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1117f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1118f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1119f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    static unsigned long pagesize_mask = 0;
1120f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1121f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (fd < 0)
1122f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -EINVAL;
1123f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1124f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!pagesize_mask)
1125f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	pagesize_mask = getpagesize() - 1;
1126f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1127f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    size = (size + pagesize_mask) & ~pagesize_mask;
1128f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1129f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1130f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (*address == MAP_FAILED)
1131f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1132f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1133f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1134f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1135f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1136f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1137f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Unmap mappings obtained with drmMap().
1138f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1139f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param address address as given by drmMap().
1140f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size in bytes. Must match the size used by drmMap().
1141f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1142f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1143f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1144f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1145f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper for munmap().
1146f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1147f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmUnmap(drmAddress address, drmSize size)
1148f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1149f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return munmap(address, size);
1150f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1151f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1152f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmBufInfoPtr drmGetBufInfo(int fd)
1153f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1154f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_buf_info_t info;
1155f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmBufInfoPtr  retval;
1156f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int            i;
1157f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1158f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    info.count = 0;
1159f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    info.list  = NULL;
1160f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1161f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1162f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1163f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1164f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (info.count) {
1165f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1166f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return NULL;
1167f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1168f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1169f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmFree(info.list);
1170f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return NULL;
1171f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
1172f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1173f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval = drmMalloc(sizeof(*retval));
1174f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval->count = info.count;
1175f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
1176f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	for (i = 0; i < info.count; i++) {
1177f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].count     = info.list[i].count;
1178f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].size      = info.list[i].size;
1179f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].low_mark  = info.list[i].low_mark;
1180f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].high_mark = info.list[i].high_mark;
1181f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
1182f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFree(info.list);
1183f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return retval;
1184f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1185f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return NULL;
1186f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1187f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1188f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1189f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Map all DMA buffers into client-virtual space.
1190f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1191f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1192f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1193f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return a pointer to a ::drmBufMap structure.
1194f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1195f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note The client may not use these buffers until obtaining buffer indices
1196f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * with drmDMA().
1197f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1198f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1199f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1200f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * information about the buffers in a drm_buf_map structure into the
1201f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * client-visible data structures.
1202f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1203f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun RyudrmBufMapPtr drmMapBufs(int fd)
1204f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1205f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_buf_map_t bufs;
1206f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmBufMapPtr  retval;
1207f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           i;
1208f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1209f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    bufs.count = 0;
1210f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    bufs.list  = NULL;
1211f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    bufs.virtual = NULL;
1212f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1213f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1214f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1215f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!bufs.count)
1216f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1217f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1218f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1219f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return NULL;
1220f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1221f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1222f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    drmFree(bufs.list);
1223f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return NULL;
1224f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
1225f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1226f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval = drmMalloc(sizeof(*retval));
1227f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval->count = bufs.count;
1228f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
1229f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	for (i = 0; i < bufs.count; i++) {
1230f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].idx     = bufs.list[i].idx;
1231f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].total   = bufs.list[i].total;
1232f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].used    = 0;
1233f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    retval->list[i].address = bufs.list[i].address;
1234f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
1235f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1236f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFree(bufs.list);
1237f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1238f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return retval;
1239f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1240f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1241f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1242f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1243f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Unmap buffers allocated with drmMapBufs().
1244f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1245f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or negative value on failure.
1246f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1247f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1248f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Calls munmap() for every buffer stored in \p bufs and frees the
1249f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * memory allocated by drmMapBufs().
1250f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1251f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmUnmapBufs(drmBufMapPtr bufs)
1252f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1253f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int i;
1254f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1255f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < bufs->count; i++) {
1256f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	munmap(bufs->list[i].address, bufs->list[i].total);
1257f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1258f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1259f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(bufs->list);
1260f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(bufs);
1261f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1262f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1263f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1264f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1265f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1266f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_DMA_RETRY		16
1267f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1268f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1269f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Reserve DMA buffers.
1270f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1271f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1272f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param request
1273f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1274f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1275f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1276f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1277f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Assemble the arguments into a drm_dma structure and keeps issuing the
1278f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1279f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1280f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmDMA(int fd, drmDMAReqPtr request)
1281f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1282f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_dma_t dma;
1283f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int ret, i = 0;
1284f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1285f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.context         = request->context;
1286f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.send_count      = request->send_count;
1287f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.send_indices    = request->send_list;
1288f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.send_sizes      = request->send_sizes;
1289f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.flags           = request->flags;
1290f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.request_count   = request->request_count;
1291f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.request_size    = request->request_size;
1292f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.request_indices = request->request_list;
1293f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.request_sizes   = request->request_sizes;
1294f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    dma.granted_count   = 0;
1295f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1296f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    do {
1297f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1298f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1299f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1300f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if ( ret == 0 ) {
1301f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	request->granted_count = dma.granted_count;
1302f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1303f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    } else {
1304f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1305f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1306f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1307f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1308f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1309f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1310f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Obtain heavyweight hardware lock.
1311f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1312f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1313f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param context context.
1314f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param flags flags that determine the sate of the hardware when the function
1315f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * returns.
1316f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1317f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return always zero.
1318f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1319f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1320f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function translates the arguments into a drm_lock structure and issue
1321f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1322f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1323f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1324f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1325f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_lock_t lock;
1326f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1327f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.context = context;
1328f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.flags   = 0;
1329f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
1330f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
1331f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
1332f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
1333f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1334f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1335f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1336f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1337f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	;
1338f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1339f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1340f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1341f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1342f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Release the hardware lock.
1343f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1344f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1345f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param context context.
1346f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1347f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1348f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1349f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1350f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1351f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_lock structure.
1352f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1353f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmUnlock(int fd, drm_context_t context)
1354f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1355f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_lock_t lock;
1356f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1357f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.context = context;
1358f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.flags   = 0;
1359f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1360f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1361f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1362f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryudrm_context_t *drmGetReservedContextList(int fd, int *count)
1363f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1364f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_res_t res;
1365f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t     *list;
1366f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_context_t * retval;
1367f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int           i;
1368f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1369f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    res.count    = 0;
1370f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    res.contexts = NULL;
1371f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1372f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1373f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1374f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!res.count)
1375f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1376f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1377f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!(list   = drmMalloc(res.count * sizeof(*list))))
1378f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1379f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1380f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmFree(list);
1381f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1382f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1383f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1384f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    res.contexts = list;
1385f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1386f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
1387f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1388f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < res.count; i++)
1389f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retval[i] = list[i].handle;
1390f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(list);
1391f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1392f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *count = res.count;
1393f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return retval;
1394f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1395f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1396f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmFreeReservedContextList(drm_context_t *pt)
1397f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1398f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmFree(pt);
1399f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1400f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1401f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1402f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Create context.
1403f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1404f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Used by the X server during GLXContext initialization. This causes
1405f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * per-context kernel-level resources to be allocated.
1406f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1407f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1408f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle is set on success. To be used by the client when requesting DMA
1409f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * dispatch with drmDMA().
1410f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1411f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1412f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1413f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note May only be called by root.
1414f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1415f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1416f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1417f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_ctx structure.
1418f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1419f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCreateContext(int fd, drm_context_t *handle)
1420f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1421f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t ctx;
1422f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1423f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.flags = 0;	/* Modified with functions below */
1424f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1425f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1426f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = ctx.handle;
1427f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1428f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1429f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1430f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmSwitchToContext(int fd, drm_context_t context)
1431f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1432f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t ctx;
1433f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1434f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.handle = context;
1435f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1436f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1437f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1438f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1439f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1440f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1441f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1442f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t ctx;
1443f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1444f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    /*
1445f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * Context preserving means that no context switches are done between DMA
1446f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * buffers from one context and the next.  This is suitable for use in the
1447f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * X server (which promises to maintain hardware context), or in the
1448f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     * client-side library when buffers are swapped on behalf of two threads.
1449f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu     */
1450f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.handle = context;
1451f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.flags  = 0;
1452f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_CONTEXT_PRESERVED)
1453f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ctx.flags |= _DRM_CONTEXT_PRESERVED;
1454f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_CONTEXT_2DONLY)
1455f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ctx.flags |= _DRM_CONTEXT_2DONLY;
1456f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
1457f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1458f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1459f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1460f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1461f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetContextFlags(int fd, drm_context_t context,
1462f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                       drm_context_tFlagsPtr flags)
1463f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1464f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t ctx;
1465f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1466f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.handle = context;
1467f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1468f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1469f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *flags = 0;
1470f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1471f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	*flags |= DRM_CONTEXT_PRESERVED;
1472f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (ctx.flags & _DRM_CONTEXT_2DONLY)
1473f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	*flags |= DRM_CONTEXT_2DONLY;
1474f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1475f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1476f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1477f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1478f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Destroy context.
1479f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1480f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free any kernel-level resources allocated with drmCreateContext() associated
1481f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * with the context.
1482f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1483f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1484f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle handle given by drmCreateContext().
1485f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1486f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1487f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1488f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \note May only be called by root.
1489f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1490f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1491f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1492f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_ctx structure.
1493f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1494f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmDestroyContext(int fd, drm_context_t handle)
1495f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1496f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_t ctx;
1497f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctx.handle = handle;
1498f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1499f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1500f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1501f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1502f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1503f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCreateDrawable(int fd, drm_drawable_t *handle)
1504f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1505f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_draw_t draw;
1506f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1507f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1508f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = draw.handle;
1509f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1510f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1511f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1512f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmDestroyDrawable(int fd, drm_drawable_t handle)
1513f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1514f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_draw_t draw;
1515f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    draw.handle = handle;
1516f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1517f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1518f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1519f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1520f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1521f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1522f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			   drm_drawable_info_type_t type, unsigned int num,
1523f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu			   void *data)
1524f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1525f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_update_draw_t update;
1526f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1527f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    update.handle = handle;
1528f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    update.type = type;
1529f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    update.num = num;
1530f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    update.data = (unsigned long long)(unsigned long)data;
1531f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1532f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1533f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1534f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1535f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1536f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1537f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1538f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1539f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Acquire the AGP device.
1540f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1541f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Must be called before any of the other AGP related calls.
1542f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1543f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1544f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1545f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1546f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1547f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1548f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1549f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1550f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpAcquire(int fd)
1551f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1552f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1553f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1554f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1555f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1556f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1557f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1558f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1559f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Release the AGP device.
1560f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1561f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1562f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1563f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1564f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1565f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1566f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1567f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1568f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpRelease(int fd)
1569f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1570f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1571f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1572f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1573f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1574f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1575f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1576f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1577f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Set the AGP mode.
1578f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1579f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1580f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param mode AGP mode.
1581f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1582f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1583f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1584f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1585f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1586f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_agp_mode structure.
1587f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1588f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpEnable(int fd, unsigned long mode)
1589f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1590f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_mode_t m;
1591f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1592f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    m.mode = mode;
1593f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1594f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1595f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1596f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1597f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1598f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1599f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1600f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Allocate a chunk of AGP memory.
1601f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1602f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1603f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size requested memory size in bytes. Will be rounded to page boundary.
1604f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param type type of memory to allocate.
1605f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param address if not zero, will be set to the physical address of the
1606f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * allocated memory.
1607f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle on success will be set to a handle of the allocated memory.
1608f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1609f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1610f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1611f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1612f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1613f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * arguments in a drm_agp_buffer structure.
1614f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1615f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1616f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		unsigned long *address, drm_handle_t *handle)
1617f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1618f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_buffer_t b;
1619f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1620f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = DRM_AGP_NO_HANDLE;
1621f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.size   = size;
1622f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.handle = 0;
1623f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.type   = type;
1624f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1625f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1626f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (address != 0UL)
1627f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	*address = b.physical;
1628f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = b.handle;
1629f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1630f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1631f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1632f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1633f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1634f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Free a chunk of AGP memory.
1635f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1636f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1637f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1638f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1639f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1640f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1641f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1642f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1643f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_agp_buffer structure.
1644f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1645f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpFree(int fd, drm_handle_t handle)
1646f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1647f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_buffer_t b;
1648f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1649f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.size   = 0;
1650f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.handle = handle;
1651f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1652f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1653f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1654f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1655f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1656f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1657f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1658f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Bind a chunk of AGP memory.
1659f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1660f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1661f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1662f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param offset offset in bytes. It will round to page boundary.
1663f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1664f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1665f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1666f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1667f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1668f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_agp_binding structure.
1669f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1670f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1671f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1672f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_binding_t b;
1673f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1674f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.handle = handle;
1675f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.offset = offset;
1676f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1677f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1678f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1679f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1680f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1681f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1682f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1683f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Unbind a chunk of AGP memory.
1684f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1685f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1686f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1687f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1688f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1689f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1690f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1691f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1692f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * the argument in a drm_agp_binding structure.
1693f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1694f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpUnbind(int fd, drm_handle_t handle)
1695f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1696f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_binding_t b;
1697f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1698f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.handle = handle;
1699f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    b.offset = 0;
1700f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1701f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1702f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1703f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1704f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1705f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1706f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1707f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get AGP driver major version number.
1708f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1709f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1710f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1711f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return major version number on success, or a negative value on failure..
1712f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1713f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1714f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1715f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1716f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1717f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpVersionMajor(int fd)
1718f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1719f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1720f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1721f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1722f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1723f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.agp_version_major;
1724f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1725f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1726f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1727f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1728f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get AGP driver minor version number.
1729f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1730f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1731f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1732f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return minor version number on success, or a negative value on failure.
1733f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1734f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1735f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1736f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1737f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1738f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAgpVersionMinor(int fd)
1739f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1740f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1741f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1742f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1743f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1744f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.agp_version_minor;
1745f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1746f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1747f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1748f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1749f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get AGP mode.
1750f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1751f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1752f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1753f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return mode on success, or zero on failure.
1754f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1755f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1756f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1757f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1758f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1759f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned long drmAgpGetMode(int fd)
1760f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1761f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1762f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1763f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1764f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1765f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.mode;
1766f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1767f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1768f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1769f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1770f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get AGP aperture base.
1771f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1772f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1773f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1774f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return aperture base on success, zero on failure.
1775f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1776f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1777f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1778f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1779f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1780f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned long drmAgpBase(int fd)
1781f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1782f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1783f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1784f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1785f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1786f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.aperture_base;
1787f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1788f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1789f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1790f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1791f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get AGP aperture size.
1792f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1793f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1794f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1795f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return aperture size on success, zero on failure.
1796f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1797f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1798f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1799f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1800f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1801f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned long drmAgpSize(int fd)
1802f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1803f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1804f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1805f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1806f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1807f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.aperture_size;
1808f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1809f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1810f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1811f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1812f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get used AGP memory.
1813f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1814f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1815f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1816f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return memory used on success, or zero on failure.
1817f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1818f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1819f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1820f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1821f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1822f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned long drmAgpMemoryUsed(int fd)
1823f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1824f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1825f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1826f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1827f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1828f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.memory_used;
1829f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1830f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1831f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1832f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1833f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get available AGP memory.
1834f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1835f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1836f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1837f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return memory available on success, or zero on failure.
1838f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1839f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1840f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1841f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1842f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1843f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned long drmAgpMemoryAvail(int fd)
1844f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1845f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1846f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1847f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1848f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1849f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.memory_allowed;
1850f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1851f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1852f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1853f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1854f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get hardware vendor ID.
1855f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1856f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1857f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1858f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return vendor ID on success, or zero on failure.
1859f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1860f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1861f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1862f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1863f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1864f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned int drmAgpVendorId(int fd)
1865f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1866f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1867f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1868f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1869f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1870f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.id_vendor;
1871f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1872f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1873f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1874f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1875f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get hardware device ID.
1876f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1877f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1878f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1879f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or zero on failure.
1880f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1881f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1882f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1883f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * necessary information in a drm_agp_info structure.
1884f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1885f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuunsigned int drmAgpDeviceId(int fd)
1886f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1887f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_agp_info_t i;
1888f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1889f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1890f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return 0;
1891f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return i.id_device;
1892f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1893f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1894f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
1895f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1896f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_scatter_gather_t sg;
1897f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1898f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = 0;
1899f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sg.size   = size;
1900f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sg.handle = 0;
1901f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
1902f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1903f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = sg.handle;
1904f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1905f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1906f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1907f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmScatterGatherFree(int fd, drm_handle_t handle)
1908f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1909f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_scatter_gather_t sg;
1910f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1911f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sg.size   = 0;
1912f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sg.handle = handle;
1913f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
1914f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
1915f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
1916f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1917f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1918f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1919f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Wait for VBLANK.
1920f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1921f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1922f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param vbl pointer to a drmVBlank structure.
1923f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1924f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1925f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1926f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1927f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
1928f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1929f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmWaitVBlank(int fd, drmVBlankPtr vbl)
1930f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1931f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    struct timespec timeout, cur;
1932f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int ret;
1933f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1934f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
1935f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (ret < 0) {
1936f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "clock_gettime failed: %s\n", strerror(ret));
1937f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	goto out;
1938f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1939f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    timeout.tv_sec++;
1940f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1941f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    do {
1942f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu       ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
1943f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
1944f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu       if (ret && errno == EINTR) {
1945f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	       clock_gettime(CLOCK_MONOTONIC, &cur);
1946f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	       /* Timeout after 1s */
1947f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	       if (cur.tv_sec > timeout.tv_sec + 1 ||
1948f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		   (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
1949f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    timeout.tv_nsec)) {
1950f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		       errno = EBUSY;
1951f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		       ret = -1;
1952f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		       break;
1953f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	       }
1954f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu       }
1955f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    } while (ret && errno == EINTR);
1956f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1957f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuout:
1958f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return ret;
1959f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1960f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1961f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmError(int err, const char *label)
1962f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
1963f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    switch (err) {
1964f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    case DRM_ERR_NO_DEVICE:
1965f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "%s: no device\n", label);
1966f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	break;
1967f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    case DRM_ERR_NO_ACCESS:
1968f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "%s: no access\n", label);
1969f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	break;
1970f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    case DRM_ERR_NOT_ROOT:
1971f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "%s: not root\n", label);
1972f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	break;
1973f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    case DRM_ERR_INVALID:
1974f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "%s: invalid args\n", label);
1975f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	break;
1976f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    default:
1977f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (err < 0)
1978f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    err = -err;
1979f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
1980f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	break;
1981f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
1982f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1983f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 1;
1984f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
1985f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
1986f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
1987f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Install IRQ handler.
1988f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1989f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
1990f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param irq IRQ number.
1991f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1992f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
1993f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
1994f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
1995f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1996f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_control structure.
1997f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
1998f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCtlInstHandler(int fd, int irq)
1999f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2000f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_control_t ctl;
2001f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2002f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctl.func  = DRM_INST_HANDLER;
2003f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctl.irq   = irq;
2004f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2005f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2006f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2007f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2008f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2009f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2010f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2011f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Uninstall IRQ handler.
2012f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2013f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2014f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2015f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2016f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2017f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2018f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2019f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * argument in a drm_control structure.
2020f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2021f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCtlUninstHandler(int fd)
2022f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2023f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_control_t ctl;
2024f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2025f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctl.func  = DRM_UNINST_HANDLER;
2026f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    ctl.irq   = 0;
2027f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2028f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2029f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2030f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2031f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2032f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmFinish(int fd, int context, drmLockFlags flags)
2033f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2034f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_lock_t lock;
2035f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2036f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.context = context;
2037f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    lock.flags   = 0;
2038f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
2039f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
2040f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
2041f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
2042f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2043f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
2044f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2045f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2046f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2047f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2048f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2049f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2050f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Get IRQ from bus ID.
2051f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2052f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2053f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param busnum bus number.
2054f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param devnum device number.
2055f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param funcnum function number.
2056f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2057f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return IRQ number on success, or a negative value on failure.
2058f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2059f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2060f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2061f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * arguments in a drm_irq_busid structure.
2062f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2063f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2064f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2065f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_irq_busid_t p;
2066f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2067f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    p.busnum  = busnum;
2068f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    p.devnum  = devnum;
2069f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    p.funcnum = funcnum;
2070f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2071f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2072f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return p.irq;
2073f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2074f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2075f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAddContextTag(int fd, drm_context_t context, void *tag)
2076f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2077f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashEntry  *entry = drmGetEntry(fd);
2078f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2079f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmHashInsert(entry->tagTable, context, tag)) {
2080f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmHashDelete(entry->tagTable, context);
2081f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	drmHashInsert(entry->tagTable, context, tag);
2082f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2083f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2084f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2085f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2086f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmDelContextTag(int fd, drm_context_t context)
2087f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2088f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashEntry  *entry = drmGetEntry(fd);
2089f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2090f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return drmHashDelete(entry->tagTable, context);
2091f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2092f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2093f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid *drmGetContextTag(int fd, drm_context_t context)
2094f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2095f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drmHashEntry  *entry = drmGetEntry(fd);
2096f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    void          *value;
2097f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2098f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmHashLookup(entry->tagTable, context, &value))
2099f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return NULL;
2100f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2101f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return value;
2102f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2103f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2104f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
2105f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                                drm_handle_t handle)
2106f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2107f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_priv_map_t map;
2108f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2109f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.ctx_id = ctx_id;
2110f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.handle = (void *)handle;
2111f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2112f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2113f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2114f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2115f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2116f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2117f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
2118f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                                drm_handle_t *handle)
2119f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2120f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_ctx_priv_map_t map;
2121f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2122f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.ctx_id = ctx_id;
2123f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2124f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2125f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2126f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (handle)
2127f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	*handle = (drm_handle_t)map.handle;
2128f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2129f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2130f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2131f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2132f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2133f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	      drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
2134f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	      int *mtrr)
2135f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2136f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_map_t map;
2137f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2138f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    map.offset = idx;
2139f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2140f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2141f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *offset = map.offset;
2142f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *size   = map.size;
2143f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *type   = map.type;
2144f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *flags  = map.flags;
2145f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *handle = (unsigned long)map.handle;
2146f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *mtrr   = map.mtrr;
2147f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2148f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2149f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2150f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2151f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		 unsigned long *magic, unsigned long *iocs)
2152f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2153f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_client_t client;
2154f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2155f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    client.idx = idx;
2156f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2157f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2158f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *auth      = client.auth;
2159f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *pid       = client.pid;
2160f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *uid       = client.uid;
2161f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *magic     = client.magic;
2162f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *iocs      = client.iocs;
2163f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2164f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2165f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2166f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmGetStats(int fd, drmStatsT *stats)
2167f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2168f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_stats_t s;
2169f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int         i;
2170f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2171f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2172f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2173f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2174f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->count = 0;
2175f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    memset(stats, 0, sizeof(*stats));
2176f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
2177f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -1;
2178f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2179f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define SET_VALUE                              \
2180f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].long_format = "%-20.20s";   \
2181f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].rate_format = "%8.8s";      \
2182f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].isvalue     = 1;            \
2183f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].verbose     = 0
2184f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2185f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define SET_COUNT                              \
2186f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].long_format = "%-20.20s";   \
2187f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].rate_format = "%5.5s";      \
2188f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].isvalue     = 0;            \
2189f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].mult_names  = "kgm";        \
2190f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].mult        = 1000;         \
2191f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].verbose     = 0
2192f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2193f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define SET_BYTE                               \
2194f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].long_format = "%-20.20s";   \
2195f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].rate_format = "%5.5s";      \
2196f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].isvalue     = 0;            \
2197f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].mult_names  = "KGM";        \
2198f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].mult        = 1024;         \
2199f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->data[i].verbose     = 0
2200f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2201f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2202f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    stats->count = s.count;
2203f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < s.count; i++) {
2204f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	stats->data[i].value = s.data[i].value;
2205f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	switch (s.data[i].type) {
2206f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_LOCK:
2207f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Lock";
2208f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Lock";
2209f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_VALUE;
2210f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2211f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_OPENS:
2212f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Opens";
2213f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "O";
2214f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2215f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].verbose   = 1;
2216f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2217f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_CLOSES:
2218f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Closes";
2219f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Lock";
2220f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2221f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].verbose   = 1;
2222f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2223f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_IOCTLS:
2224f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Ioctls";
2225f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Ioc/s";
2226f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2227f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2228f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_LOCKS:
2229f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Locks";
2230f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Lck/s";
2231f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2232f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2233f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_UNLOCKS:
2234f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Unlocks";
2235f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Unl/s";
2236f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2237f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2238f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_IRQ:
2239f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "IRQs";
2240f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "IRQ/s";
2241f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2242f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2243f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_PRIMARY:
2244f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Primary Bytes";
2245f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "PB/s";
2246f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_BYTE;
2247f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2248f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_SECONDARY:
2249f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Secondary Bytes";
2250f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "SB/s";
2251f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_BYTE;
2252f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2253f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_DMA:
2254f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "DMA";
2255f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "DMA/s";
2256f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2257f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2258f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_SPECIAL:
2259f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Special DMA";
2260f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "dma/s";
2261f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2262f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2263f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_MISSED:
2264f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Miss";
2265f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Ms/s";
2266f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2267f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2268f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_VALUE:
2269f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Value";
2270f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Value";
2271f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_VALUE;
2272f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2273f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_BYTE:
2274f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Bytes";
2275f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "B/s";
2276f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_BYTE;
2277f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2278f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	case _DRM_STAT_COUNT:
2279f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	default:
2280f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].long_name = "Count";
2281f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    stats->data[i].rate_name = "Cnt/s";
2282f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    SET_COUNT;
2283f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    break;
2284f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
2285f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2286f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2287f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2288f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2289f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2290f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Issue a set-version ioctl.
2291f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2292f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2293f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param drmCommandIndex command index
2294f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param data source pointer of the data to be read and written.
2295f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size of the data to be read and written.
2296f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2297f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2298f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2299f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2300f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It issues a read-write ioctl given by
2301f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2302f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2303f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmSetInterfaceVersion(int fd, drmSetVersion *version)
2304f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2305f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int retcode = 0;
2306f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    drm_set_version_t sv;
2307f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2308f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sv.drm_di_major = version->drm_di_major;
2309f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sv.drm_di_minor = version->drm_di_minor;
2310f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sv.drm_dd_major = version->drm_dd_major;
2311f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    sv.drm_dd_minor = version->drm_dd_minor;
2312f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2313f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
2314f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	retcode = -errno;
2315f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2316f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2317f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->drm_di_major = sv.drm_di_major;
2318f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->drm_di_minor = sv.drm_di_minor;
2319f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->drm_dd_major = sv.drm_dd_major;
2320f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    version->drm_dd_minor = sv.drm_dd_minor;
2321f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2322f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return retcode;
2323f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2324f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2325f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2326f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Send a device-specific command.
2327f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2328f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2329f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param drmCommandIndex command index
2330f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2331f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2332f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2333f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2334f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It issues a ioctl given by
2335f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2336f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2337f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCommandNone(int fd, unsigned long drmCommandIndex)
2338f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2339f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    void *data = NULL; /* dummy */
2340f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long request;
2341f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2342f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
2343f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2344f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, request, data)) {
2345f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2346f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2347f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2348f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2349f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2350f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2351f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2352f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Send a device-specific read command.
2353f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2354f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2355f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param drmCommandIndex command index
2356f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param data destination pointer of the data to be read.
2357f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size of the data to be read.
2358f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2359f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2360f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2361f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2362f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It issues a read ioctl given by
2363f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2364f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2365f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
2366f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                   unsigned long size)
2367f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2368f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long request;
2369f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2370f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
2371f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	DRM_COMMAND_BASE + drmCommandIndex, size);
2372f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2373f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, request, data)) {
2374f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2375f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2376f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2377f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2378f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2379f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2380f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2381f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Send a device-specific write command.
2382f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2383f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2384f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param drmCommandIndex command index
2385f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param data source pointer of the data to be written.
2386f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size of the data to be written.
2387f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2388f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2389f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2390f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2391f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It issues a write ioctl given by
2392f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2393f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2394f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
2395f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                    unsigned long size)
2396f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2397f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long request;
2398f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2399f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
2400f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	DRM_COMMAND_BASE + drmCommandIndex, size);
2401f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2402f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, request, data)) {
2403f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2404f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2405f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2406f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2407f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2408f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2409f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu/**
2410f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * Send a device-specific read-write command.
2411f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2412f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param fd file descriptor.
2413f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param drmCommandIndex command index
2414f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param data source pointer of the data to be read and written.
2415f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \param size size of the data to be read and written.
2416f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2417f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \return zero on success, or a negative value on failure.
2418f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu *
2419f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \internal
2420f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * It issues a read-write ioctl given by
2421f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2422f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu */
2423f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
2424f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu                        unsigned long size)
2425f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2426f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    unsigned long request;
2427f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2428f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
2429f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	DRM_COMMAND_BASE + drmCommandIndex, size);
2430f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2431f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (drmIoctl(fd, request, data))
2432f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return -errno;
2433f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return 0;
2434f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2435f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2436f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu#define DRM_MAX_FDS 16
2437f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic struct {
2438f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    char *BusID;
2439f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int fd;
2440f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int refcount;
2441f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu} connection[DRM_MAX_FDS];
2442f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2443f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryustatic int nr_fds = 0;
2444f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2445f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmOpenOnce(void *unused,
2446f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		const char *BusID,
2447f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		int *newlyopened)
2448f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2449f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int i;
2450f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int fd;
2451f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2452f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < nr_fds; i++)
2453f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (strcmp(BusID, connection[i].BusID) == 0) {
2454f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    connection[i].refcount++;
2455f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    *newlyopened = 0;
2456f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    return connection[i].fd;
2457f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
2458f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2459f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    fd = drmOpen(unused, BusID);
2460f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (fd <= 0 || nr_fds == DRM_MAX_FDS)
2461f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return fd;
2462f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2463f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    connection[nr_fds].BusID = strdup(BusID);
2464f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    connection[nr_fds].fd = fd;
2465f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    connection[nr_fds].refcount = 1;
2466f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    *newlyopened = 1;
2467f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2468f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    if (0)
2469f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr, "saved connection %d for %s %d\n",
2470f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		nr_fds, connection[nr_fds].BusID,
2471f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		strcmp(BusID, connection[nr_fds].BusID));
2472f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2473f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    nr_fds++;
2474f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2475f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    return fd;
2476f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2477f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2478f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuvoid drmCloseOnce(int fd)
2479f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2480f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    int i;
2481f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2482f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    for (i = 0; i < nr_fds; i++) {
2483f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	if (fd == connection[i].fd) {
2484f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    if (--connection[i].refcount == 0) {
2485f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		drmClose(connection[i].fd);
2486f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		free(connection[i].BusID);
2487f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2488f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		if (i < --nr_fds)
2489f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		    connection[i] = connection[nr_fds];
2490f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2491f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu		return;
2492f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	    }
2493f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	}
2494f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu    }
2495f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2496f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2497f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmSetMaster(int fd)
2498f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2499f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int ret;
2500f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2501f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr,"Setting master \n");
2502f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
2503f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return ret;
2504f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2505f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu
2506f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryuint drmDropMaster(int fd)
2507f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu{
2508f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	int ret;
2509f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	fprintf(stderr,"Dropping master \n");
2510f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	ret = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2511f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu	return ret;
2512f0352d4fde4ec179ffe04c3f834199d3bad36087Ho-Eun Ryu}
2513