xf86drm.c revision 569da5a42ebf10c86d6c6ba81866a888e1c708dc
1b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* xf86drm.c -- User-level interface to DRM device
2b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Created: Tue Jan  5 08:16:21 1999 by faith@precisioninsight.com
3b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
4569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * All Rights Reserved.
7b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
8b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Permission is hereby granted, free of charge, to any person obtaining a
9b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * copy of this software and associated documentation files (the "Software"),
10b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * to deal in the Software without restriction, including without limitation
11b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * and/or sell copies of the Software, and to permit persons to whom the
13b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Software is furnished to do so, subject to the following conditions:
14b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
15b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * The above copyright notice and this permission notice (including the next
16b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * paragraph) shall be included in all copies or substantial portions of the
17b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Software.
18b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
19b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * DEALINGS IN THE SOFTWARE.
26b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
27569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
28569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul *	    Kevin E. Martin <martin@valinux.com>
29569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul *
305bd8014f276d447178a1193d9dea1b976647d6ceJeff Hartmann * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.10 2000/02/23 04:47:23 martin Exp $
31b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
32b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss */
33b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
34b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifdef XFree86Server
35b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include "xf86.h"
36b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include "xf86_OSproc.h"
37b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include "xf86_ansic.h"
38b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include "xf86Priv.h"
39b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# define _DRM_MALLOC xalloc
40b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# define _DRM_FREE   xfree
41b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# ifndef XFree86LOADER
42b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  include <sys/stat.h>
43b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  include <sys/mman.h>
44b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# endif
45b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#else
46b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <stdio.h>
47b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <stdlib.h>
48b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <unistd.h>
49b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <string.h>
50b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <ctype.h>
51b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <fcntl.h>
52b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <errno.h>
53b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <signal.h>
54b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <sys/types.h>
55b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <sys/stat.h>
56b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <sys/ioctl.h>
57b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <sys/mman.h>
58b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# include <sys/time.h>
59b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# ifdef DRM_USE_MALLOC
60b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  define _DRM_MALLOC malloc
61b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  define _DRM_FREE   free
62e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Straussextern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
63b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussextern int xf86RemoveSIGIOHandler(int fd);
64b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# else
65b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  include <Xlibint.h>
66b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  define _DRM_MALLOC Xmalloc
67b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#  define _DRM_FREE   Xfree
68b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss# endif
69b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
70b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
71b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* Not all systems have MAP_FAILED defined */
72b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifndef MAP_FAILED
73b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#define MAP_FAILED ((void *)-1)
74b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
75b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
76b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "xf86drm.h"
77b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "drm.h"
78b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
79569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#define DRM_FIXED_DEVICE_MAJOR 145
80569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
81569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#ifdef __linux__
82569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#include <sys/sysmacros.h>	/* for makedev() */
83569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#endif
84569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
85569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#ifndef makedev
86569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul				/* This definition needs to be changed on
87569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   some systems if dev_t is a structure.
88569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   If there is a header file we can get it
89569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   from, there would be best. */
90569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#define makedev(x,y)    ((dev_t)(((x) << 8) | (y)))
91569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#endif
92569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
93b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void *drmHashTable = NULL; /* Context switch callbacks */
94b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
95b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strausstypedef struct drmHashEntry {
96b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int      fd;
97b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void     (*f)(int, void *, void *);
98b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void     *tagTable;
99b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} drmHashEntry;
100b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
101b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmMalloc(int size)
102b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
103b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void *pt;
104b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if ((pt = _DRM_MALLOC(size))) memset(pt, 0, size);
105b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return pt;
106b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFree(void *pt)
109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
110b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (pt) _DRM_FREE(pt);
111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
113569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul/* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic char *drmStrdup(const char *s)
115b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
116569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    char *retval = NULL;
117569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
118569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    if (s) {
119569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	retval = _DRM_MALLOC(strlen(s)+1);
120569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	strcpy(retval, s);
121569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
122569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    return retval;
123b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
124b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
125b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
126b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic unsigned long drmGetKeyFromFd(int fd)
127b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
128b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifdef XFree86LOADER
129b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    struct xf86stat st;
130b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#else
131b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    struct stat     st;
132b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
133b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
134b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    st.st_rdev = 0;
135b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    fstat(fd, &st);
136b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return st.st_rdev;
137b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
139b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic drmHashEntry *drmGetEntry(int fd)
140b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
141b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key = drmGetKeyFromFd(fd);
142b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
143b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry;
144b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
145b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!drmHashTable) drmHashTable = drmHashCreate();
146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
147b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashLookup(drmHashTable, key, &value)) {
148b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry           = drmMalloc(sizeof(*entry));
149b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->fd       = fd;
150b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->f        = NULL;
151b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->tagTable = drmHashCreate();
152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(drmHashTable, key, entry);
153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    } else {
154b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry = value;
155b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return entry;
157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
159569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul/* drm_open is used to open the /dev/dri device */
160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic int drm_open(const char *file)
162b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
163b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int fd = open(file, O_RDWR, 0);
164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (fd >= 0) return fd;
166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return -errno;
167b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
168b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
169b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussstatic int drmOpenDevice(const char *path, long dev,
170b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			 mode_t mode, uid_t user, gid_t group)
171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifdef XFree86LOADER
173b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    struct xf86stat st;
174b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#else
175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    struct stat     st;
176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
178569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul				/* Fiddle mode to remove execute bits */
179569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    mode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
180569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
181569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    if (!stat(path, &st) && st.st_rdev == dev) {
182569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	if (!geteuid()) {
183569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    chown(path, user, group);
184569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    chmod(path, mode);
185569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
186569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	return drm_open(path);
187569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (geteuid()) return DRM_ERR_NOT_ROOT;
190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    remove(path);
191b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (mknod(path, S_IFCHR, dev)) {
192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	remove(path);
193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return DRM_ERR_NOT_ROOT;
194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
195b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    chown(path, user, group);
196b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    chmod(path, mode);
197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return drm_open(path);
198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
200569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul/* drmAvailable looks for /proc/dri, and returns 1 if it is present.  On
201569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul   OSs that do not have a Linux-like /proc, this information will not be
202569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul   available, and we'll have to create a device and check if the driver is
203569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul   loaded that way. */
204569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
205569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulint drmAvailable(void)
206569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul{
207569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    char          dev_name[64];
208569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    drmVersionPtr version;
209569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           retval = 0;
210569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           fd;
211569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
212569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    if (!access("/proc/dri/0", R_OK)) return 1;
213569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
214569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    sprintf(dev_name, "/dev/dri-temp-%d", getpid());
215569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
216569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    remove(dev_name);
217569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    if ((fd = drmOpenDevice(dev_name, makedev(DRM_FIXED_DEVICE_MAJOR, 0),
218569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul			    S_IRUSR, geteuid(), getegid())) >= 0) {
219569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul				/* Read version to make sure this is
220569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   actually a DRI device. */
221569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	if ((version = drmGetVersion(fd))) {
222569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    retval = 1;
223569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    drmFreeVersion(version);
224569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
225569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	close(fd);
226569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
227569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    remove(dev_name);
228569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
229569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    return retval;
230569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul}
231569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
232e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Straussstatic int drmOpenByBusid(const char *busid)
233e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss{
234e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    int    i;
235e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    char   dev_name[64];
236e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    char   *buf;
237e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    int    fd;
238e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss
239e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    for (i = 0; i < 8; i++) {
2400371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(dev_name, "/dev/dri/card%d", i);
241e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	if ((fd = drm_open(dev_name)) >= 0) {
242e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    buf = drmGetBusid(fd);
243e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    if (buf && !strcmp(buf, busid)) {
244e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	      drmFreeBusid(buf);
245e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	      return fd;
246e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    }
247e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    if (buf) drmFreeBusid(buf);
248e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    close(fd);
249e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	}
250e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    }
251e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    return -1;
252e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss}
253e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss
254b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussstatic int drmOpenByName(const char *name)
255b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss{
256b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    int    i;
257b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   proc_name[64];
258b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   dev_name[64];
259b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   buf[512];
260b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    mode_t mode   = DRM_DEV_MODE;
261b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    mode_t dirmode;
262b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    gid_t  group  = DRM_DEV_GID;
263b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    uid_t  user   = DRM_DEV_UID;
264b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    int    fd;
265b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   *pt;
266b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   *driver = NULL;
267b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    char   *devstring;
268b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    long   dev     = 0;
269b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    int    retcode;
270b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
271b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss#if defined(XFree86Server)
272b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    mode  = xf86ConfigDRI.mode ? xf86ConfigDRI.mode : DRM_DEV_MODE;
273b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    group = xf86ConfigDRI.group ? xf86ConfigDRI.group : DRM_DEV_GID;
274b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss#endif
275b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
27601836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul#if defined(XFree86Server)
27701836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul    if (!drmAvailable()) {
27801836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul        /* try to load the kernel module now */
27901836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul        if (!xf86LoadKernelModule(name)) {
28001836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul            ErrorF("[drm] failed to load kernel module \"%s\"\n",
28101836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul		   name);
28201836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul            return -1;
28301836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul        }
28401836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul    }
28501836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul#else
28601836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul    if (!drmAvailable())
28701836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul       return -1;
28801836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul#endif
28901836824d5b3dd4833573ebf3f98ed4cfb9cd5b3Brian Paul
290b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (!geteuid()) {
291b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	dirmode = mode;
292b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if (dirmode & S_IRUSR) dirmode |= S_IXUSR;
293b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if (dirmode & S_IRGRP) dirmode |= S_IXGRP;
294b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if (dirmode & S_IROTH) dirmode |= S_IXOTH;
295b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	dirmode &= ~(S_IWGRP | S_IWOTH);
2960371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	mkdir("/dev/dri", 0);
2970371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	chown("/dev/dri", user, group);
2980371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	chmod("/dev/dri", dirmode);
299b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
300b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
301b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    for (i = 0; i < 8; i++) {
3020371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(proc_name, "/proc/dri/%d/name", i);
3030371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(dev_name, "/dev/dri/card%d", i);
304b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if ((fd = open(proc_name, 0, 0)) >= 0) {
305b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    retcode = read(fd, buf, sizeof(buf)-1);
306b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    close(fd);
307b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    if (retcode) {
308b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		buf[retcode-1] = '\0';
309b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		for (driver = pt = buf; *pt && *pt != ' '; ++pt)
310b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    ;
311b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		if (*pt) {	/* Device is next */
312b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    *pt = '\0';
313b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    if (!strcmp(driver, name)) { /* Match */
314b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
315b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			    ;
316b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			if (*pt) { /* Found busid */
317b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			  return drmOpenByBusid(++pt);
318b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			} else {	/* No busid */
319b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			  dev = strtol(devstring, NULL, 0);
320b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			  return drmOpenDevice(dev_name, dev,
321b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss					       mode, user, group);
322b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			}
323b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    }
324b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		}
325b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    }
326569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	} else {
327569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    drmVersionPtr version;
328569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul				/* /proc/dri not available, possibly
329569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   because we aren't on a Linux system.
330569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   So, try to create the next device and
331569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul                                   see if it's active. */
332569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    dev = makedev(DRM_FIXED_DEVICE_MAJOR, i);
333569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    if ((fd = drmOpenDevice(dev_name, dev, mode, user, group))) {
334569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul		if ((version = drmGetVersion(fd))) {
335569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul		    if (!strcmp(version->name, name)) {
336569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul			drmFreeVersion(version);
337569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul			return fd;
338569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul		    }
339569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul		    drmFreeVersion(version);
340569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul		}
341569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    }
342569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	    remove(dev_name);
343569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
344b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
345b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return -1;
346b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss}
347b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
348b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss/* drmOpen looks up the specified name and busid, and opens the device
3490371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss   found.  The entry in /dev/dri is created if necessary (and if root).
350b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss   A file descriptor is returned.  On error, the return value is
351b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss   negative. */
352b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
353b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmOpen(const char *name, const char *busid)
354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
355b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
356b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (busid) return drmOpenByBusid(busid);
357b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return drmOpenByName(name);
358b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
359b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
360b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeVersion(drmVersionPtr v)
361b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
362b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!v) return;
363b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->name) drmFree(v->name);
364b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->date) drmFree(v->date);
365b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->desc) drmFree(v->desc);
366b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
367b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
368b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
369b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void drmFreeKernelVersion(drm_version_t *v)
370b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
371b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!v) return;
372b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->name) drmFree(v->name);
373b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->date) drmFree(v->date);
374b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (v->desc) drmFree(v->desc);
375b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
376b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
377b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
378569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulstatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
379b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
380b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_major      = s->version_major;
381b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_minor      = s->version_minor;
382b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_patchlevel = s->version_patchlevel;
383b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->name_len           = s->name_len;
384b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->name               = drmStrdup(s->name);
385b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->date_len           = s->date_len;
386b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->date               = drmStrdup(s->date);
387b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->desc_len           = s->desc_len;
388b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->desc               = drmStrdup(s->desc);
389b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
390b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
391b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* drmVersion obtains the version information via an ioctl.  Similar
392569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * information is available via /proc/dri. */
393b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
394b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmVersionPtr drmGetVersion(int fd)
395b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
396b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmVersionPtr retval;
397b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_version_t *version = drmMalloc(sizeof(*version));
398b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
399b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* First, get the lengths */
400b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->name_len    = 0;
401b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->name        = NULL;
402b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->date_len    = 0;
403b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->date        = NULL;
404b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->desc_len    = 0;
405b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->desc        = NULL;
406b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
407b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
408b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
409b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
410b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
411b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
412b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Now, allocate space and get the data */
413b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len)
414b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->name    = drmMalloc(version->name_len + 1);
415b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len)
416b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->date    = drmMalloc(version->date_len + 1);
417b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len)
418b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->desc    = drmMalloc(version->desc_len + 1);
419b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
420b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_VERSION, version)) {
421b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
422b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
423b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
424b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
425b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* The results might not be null-terminated
426b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   strings, so terminate them. */
427b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
428b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len) version->name[version->name_len] = '\0';
429b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len) version->date[version->date_len] = '\0';
430b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len) version->desc[version->desc_len] = '\0';
431b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
432b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Now, copy it all back into the
433b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   client-visible data structure... */
434b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    retval = drmMalloc(sizeof(*retval));
435b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmCopyVersion(retval, version);
436b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFreeKernelVersion(version);
437b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
438b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
439b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
440b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussvoid drmFreeBusid(const char *busid)
441b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
442b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drmFree((void *)busid);
443b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
444b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
445b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strausschar *drmGetBusid(int fd)
446b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
447b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
448b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
449b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = 0;
450b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = NULL;
451b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
452b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
453b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique = drmMalloc(u.unique_len + 1);
454b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (ioctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) return NULL;
455b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique[u.unique_len] = '\0';
456b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return u.unique;
457b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
458b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
459b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmSetBusid(int fd, const char *busid)
460b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
461b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
462b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
463b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = (char *)busid;
464b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = strlen(busid);
465b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
466b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    if (ioctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) return -errno;
467b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
468b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
469b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
470b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetMagic(int fd, drmMagicPtr magic)
471b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
472b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
473b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
474b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = 0;
475b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) return -errno;
476b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = auth.magic;
477b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
478b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
479b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
480b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmAuthMagic(int fd, drmMagic magic)
481b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
482b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
483b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
484b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    auth.magic = magic;
485b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) return -errno;
486b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
487b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
488b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
489b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmAddMap(int fd,
490b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	      drmHandle offset,
491b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	      drmSize size,
492b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	      drmMapType type,
493b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	      drmMapFlags flags,
494b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	      drmHandlePtr handle)
495b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
496b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_map_t map;
497b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
498b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.offset  = offset;
499b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.size    = size;
500b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.handle  = 0;
501b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.type    = type;
502b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.flags   = flags;
503b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_ADD_MAP, &map)) return -errno;
504b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (handle) *handle = (drmHandle)map.handle;
505b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
506b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
507b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
508ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
509ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann	       int agp_offset)
510b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
511b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_desc_t request;
512b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
513b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count     = count;
514b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.size      = size;
515b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.low_mark  = 0;
516b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.high_mark = 0;
517b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.flags     = flags;
518ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    request.agp_start = agp_offset;
519ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
520b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_ADD_BUFS, &request)) return -errno;
521b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return request.count;
522b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
523b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
524b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMarkBufs(int fd, double low, double high)
525b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
526b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
527b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
528b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
529b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.count = 0;
530b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.list  = NULL;
531b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
532b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return -EINVAL;
533b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
534b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!info.count) return -EINVAL;
535b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
536b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
537b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return -ENOMEM;
538b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
539b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
540b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	int retval = -errno;
541b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
542b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
543b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
544b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
545b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < info.count; i++) {
546b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].low_mark  = low  * info.list[i].count;
547b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].high_mark = high * info.list[i].count;
548b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (ioctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
549b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    int retval = -errno;
550b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
551b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return retval;
552b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
553b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
554b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(info.list);
555b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
556b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
557b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
558b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
559b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFreeBufs(int fd, int count, int *list)
560b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
561b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_free_t request;
562b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
563b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count = count;
564b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.list  = list;
565b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_FREE_BUFS, &request)) return -errno;
566b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
567b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
568b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
569b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmClose(int fd)
570b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
571b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key    = drmGetKeyFromFd(fd);
572b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
573b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
574b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDestroy(entry->tagTable);
575b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->fd       = 0;
576b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f        = NULL;
577b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->tagTable = NULL;
578b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
579b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDelete(drmHashTable, key);
580b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(entry);
581b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
582b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return close(fd);
583b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
584b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
585b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMap(int fd,
586b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	   drmHandle handle,
587b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	   drmSize size,
588b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	   drmAddressPtr address)
589b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
590b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (fd < 0) return -EINVAL;
591b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
592b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (*address == MAP_FAILED) return -errno;
593b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
594b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
595b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
596b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmap(drmAddress address, drmSize size)
597b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
598b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return munmap(address, size);
599b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
600b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
601b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufInfoPtr drmGetBufInfo(int fd)
602b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
603b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
604b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufInfoPtr  retval;
605b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
606b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
607b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.count = 0;
608b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.list  = NULL;
609b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
610b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) return NULL;
611b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
612b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (info.count) {
613b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
614b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
615b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
616b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (ioctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
617b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
618b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
619b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
620b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Now, copy it all back into the
621b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   client-visible data structure... */
622b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
623b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = info.count;
624b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
625b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < info.count; i++) {
626b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].count     = info.list[i].count;
627b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].size      = info.list[i].size;
628b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].low_mark  = info.list[i].low_mark;
629b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].high_mark = info.list[i].high_mark;
630b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
631b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
632b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
633b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
634b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return NULL;
635b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
636b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
637b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufMapPtr drmMapBufs(int fd)
638b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
639b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_map_t bufs;
640b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufMapPtr  retval;
641b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
642b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
643b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    bufs.count = 0;
644b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    bufs.list  = NULL;
645b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) return NULL;
646b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
647b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (bufs.count) {
648b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
649b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
650b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
651b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (ioctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
652b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(bufs.list);
653b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
654b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
655b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Now, copy it all back into the
656b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   client-visible data structure... */
657b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
658b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = bufs.count;
659b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
660b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < bufs.count; i++) {
661b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].idx     = bufs.list[i].idx;
662b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].total   = bufs.list[i].total;
663b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].used    = 0;
664b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].address = bufs.list[i].address;
665b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
666b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
667b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
668b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return NULL;
669b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
670b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
671b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmapBufs(drmBufMapPtr bufs)
672b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
673b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int i;
674b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
675b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < bufs->count; i++) {
676b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	munmap(bufs->list[i].address, bufs->list[i].total);
677b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
678b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
679b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
680b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
681b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDMA(int fd, drmDMAReqPtr request)
682b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
683b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_dma_t dma;
684b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
685b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Copy to hidden structure */
686b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.context         = request->context;
687b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_count      = request->send_count;
688b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_indices    = request->send_list;
689b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_sizes      = request->send_sizes;
690b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.flags           = request->flags;
691b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_count   = request->request_count;
692b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_size    = request->request_size;
693b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_indices = request->request_list;
694b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_sizes   = request->request_sizes;
695b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_DMA, &dma)) return -errno;
696b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request->granted_count = dma.granted_count;
697b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
698b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
699b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
700b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
701b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetLock(int fd, drmContext context, drmLockFlags flags)
702b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
703b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
704b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
705b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
706b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
707b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
708b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
709b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
710b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
711b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
712b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
713b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
714b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    while (ioctl(fd, DRM_IOCTL_LOCK, &lock))
715b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	;
716b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
717b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
718b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
719b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnlock(int fd, drmContext context)
720b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
721b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
722b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
723b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
724b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
725b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return ioctl(fd, DRM_IOCTL_UNLOCK, &lock);
726b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
727b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
728b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmContextPtr drmGetReservedContextList(int fd, int *count)
729b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
730b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_res_t res;
731b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t     *list;
732b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmContextPtr retval;
733b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
734b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
735b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.count    = 0;
736b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = NULL;
737b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
738b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
739b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!res.count) return NULL;
740b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
741b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(list   = drmMalloc(res.count * sizeof(*list)))) return NULL;
742b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
743b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(list);
744b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
745b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
746b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
747b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = list;
748b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_RES_CTX, &res)) return NULL;
749b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
750b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < res.count; i++) retval[i] = list[i].handle;
751b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(list);
752b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
753b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *count = res.count;
754b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
755b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
756b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
757b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeReservedContextList(drmContextPtr pt)
758b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
759b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(pt);
760b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
761b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
762b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCreateContext(int fd, drmContextPtr handle)
763b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
764b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
765b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
766b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.flags = 0;	/* Modified with functions below */
767b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) return -errno;
768b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = ctx.handle;
769b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
770b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
771b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
772b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmSwitchToContext(int fd, drmContext context)
773b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
774b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
775b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
776b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
777b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) return -errno;
778b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
779b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
780b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
781b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmSetContextFlags(int fd, drmContext context, drmContextFlags flags)
782b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
783b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
784b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
785b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss				/* Context preserving means that no context
786b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   switched are done between DMA buffers
787b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   from one context and the next.  This is
788b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   suitable for use in the X server (which
789b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   promises to maintain hardware context,
790b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   or in the client-side library when
791b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   buffers are swapped on behalf of two
792b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss                                   threads. */
793b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
794b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.flags  = 0;
795b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_CONTEXT_PRESERVED) ctx.flags |= _DRM_CONTEXT_PRESERVED;
796b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_CONTEXT_2DONLY)    ctx.flags |= _DRM_CONTEXT_2DONLY;
797b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) return -errno;
798b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
799b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
800b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
801b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetContextFlags(int fd, drmContext context, drmContextFlagsPtr flags)
802b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
803b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
804b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
805b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
806b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_GET_CTX, &ctx)) return -errno;
807b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *flags = 0;
808b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ctx.flags & _DRM_CONTEXT_PRESERVED) *flags |= DRM_CONTEXT_PRESERVED;
809b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ctx.flags & _DRM_CONTEXT_2DONLY)    *flags |= DRM_CONTEXT_2DONLY;
810b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
811b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
812b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
813b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDestroyContext(int fd, drmContext handle)
814b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
815b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
816b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = handle;
817b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_RM_CTX, &ctx)) return -errno;
818b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
819b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
820b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
821b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCreateDrawable(int fd, drmDrawablePtr handle)
822b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
823b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
824b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) return -errno;
825b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = draw.handle;
826b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
827b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
828b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
829b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDestroyDrawable(int fd, drmDrawable handle)
830b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
831b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
832b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    draw.handle = handle;
833b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_RM_DRAW, &draw)) return -errno;
834b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
835b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
836b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
837ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAcquire(int fd)
838ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
839ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) return -errno;
840ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
841ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
842ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
843ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpRelease(int fd)
844ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
845ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) return -errno;
846ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
847ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
848ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
849ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpEnable(int fd, unsigned long mode)
850ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
851ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_mode_t m;
852ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
853ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    m.mode = mode;
854ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) return -errno;
855ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
856ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
857ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
858ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAlloc(int fd, unsigned long size, unsigned long type,
859ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann		unsigned long *address, unsigned long *handle)
860ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
861ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
862ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    *handle = 0;
863ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = size;
864ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = 0;
865ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.type   = type;
866ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) return -errno;
867ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (address != 0UL) *address = b.physical;
868ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    *handle = b.handle;
869ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
870ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
871ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
872ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpFree(int fd, unsigned long handle)
873ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
874ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
875ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
876ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = 0;
877ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
878ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_FREE, &b)) return -errno;
879ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
880ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
881ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
882ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpBind(int fd, unsigned long handle, unsigned long offset)
883ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
884ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
885ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
886ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
887ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = offset;
888ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_BIND, &b)) return -errno;
889ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
890ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
891ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
892ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpUnbind(int fd, unsigned long handle)
893ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
894ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
895ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
896ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
897ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = 0;
898ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) return -errno;
899ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
900ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
901ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
902ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMajor(int fd)
903ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
904ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
905ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
906ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
907ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_major;
908ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
909ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
910ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMinor(int fd)
911ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
912ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
913ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
914ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return -errno;
915ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_minor;
916ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
917ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
918ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpGetMode(int fd)
919ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
920ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
921ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
922ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
923ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.mode;
924ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
925ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
926ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpBase(int fd)
927ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
928ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
929ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
930ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
931ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_base;
932ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
933ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
934ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpSize(int fd)
935ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
936ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
937ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
938ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
939ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_size;
940ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
941ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
942ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryUsed(int fd)
943ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
944ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
945ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
946ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
947ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_used;
948ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
949ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
950ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryAvail(int fd)
951ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
952ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
953ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
954ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
955ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_allowed;
956ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
957ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
958ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpVendorId(int fd)
959ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
960ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
961ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
962ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
963ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_vendor;
964ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
965ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
966ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpDeviceId(int fd)
967ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
968ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
969ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
970ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    if (ioctl(fd, DRM_IOCTL_AGP_INFO, &i)) return 0;
971ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_device;
972ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
973ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
974b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmError(int err, const char *label)
975b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
976b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    switch (err) {
977b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    case DRM_ERR_NO_DEVICE: fprintf(stderr, "%s: no device\n", label);   break;
978b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    case DRM_ERR_NO_ACCESS: fprintf(stderr, "%s: no access\n", label);   break;
979b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    case DRM_ERR_NOT_ROOT:  fprintf(stderr, "%s: not root\n", label);    break;
980b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    case DRM_ERR_INVALID:   fprintf(stderr, "%s: invalid args\n", label);break;
981b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    default:
982b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (err < 0) err = -err;
983b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
984b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	break;
985b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
986b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
987b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 1;
988b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
989b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
990b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlInstHandler(int fd, int irq)
991b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
992b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
993b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
994b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_INST_HANDLER;
995b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = irq;
996b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
997b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
998b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
999b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1000b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlUninstHandler(int fd)
1001b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1002b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
1003b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1004b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_UNINST_HANDLER;
1005b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = 0;
1006b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_CONTROL, &ctl)) return -errno;
1007b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1008b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1009b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1010b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFinish(int fd, int context, drmLockFlags flags)
1011b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1012b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1013b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1014b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
1015b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
1016b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
1017b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
1018b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
1019b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
1020b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1021b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1022b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_FINISH, &lock)) return -errno;
1023b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1024b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1025b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1026b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
1027b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1028b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_irq_busid_t p;
1029b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1030b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.busnum  = busnum;
1031b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.devnum  = devnum;
1032b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.funcnum = funcnum;
1033b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (ioctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) return -errno;
1034b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return p.irq;
1035b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1036b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1037b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmAddContextTag(int fd, drmContext context, void *tag)
1038b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1039b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1040b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1041b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashInsert(entry->tagTable, context, tag)) {
1042b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashDelete(entry->tagTable, context);
1043b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(entry->tagTable, context, tag);
1044b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1045b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1046b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1047b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1048b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDelContextTag(int fd, drmContext context)
1049b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1050b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1051b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1052b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return drmHashDelete(entry->tagTable, context);
1053b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1054b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1055b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmGetContextTag(int fd, drmContext context)
1056b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1057b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1058b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
1059b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1060b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashLookup(entry->tagTable, context, &value)) return NULL;
1061b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1062b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return value;
1063b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1064b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1065b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#if defined(XFree86Server) || defined(DRM_USE_MALLOC)
1066e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Straussstatic void drmSIGIOHandler(int interrupt, void *closure)
1067b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1068b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key;
1069b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
1070b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ssize_t       count;
1071b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t     ctx;
1072b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    typedef void  (*_drmCallback)(int, void *, void *);
1073b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    char          buf[256];
1074b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmContext    old;
1075b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmContext    new;
1076b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *oldctx;
1077b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *newctx;
1078b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    char          *pt;
1079b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry;
1080b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1081b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!drmHashTable) return;
1082b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashFirst(drmHashTable, &key, &value)) {
1083b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry = value;
1084b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	do {
1085b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#if 0
1086b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    fprintf(stderr, "Trying %d\n", entry->fd);
1087b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
1088b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    if ((count = read(entry->fd, buf, sizeof(buf)))) {
1089b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		buf[count] = '\0';
1090b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#if 0
1091b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		fprintf(stderr, "Got %s\n", buf);
1092b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
1093b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1094b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		for (pt = buf; *pt != ' '; ++pt); /* Find first space */
1095b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		++pt;
1096b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		old    = strtol(pt, &pt, 0);
1097b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		new    = strtol(pt, NULL, 0);
1098b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		oldctx = drmGetContextTag(entry->fd, old);
1099b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		newctx = drmGetContextTag(entry->fd, new);
1100b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#if 0
1101b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
1102b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
1103b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
1104b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		ctx.handle = new;
1105b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss		ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
1106b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    }
1107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	} while (drmHashNext(drmHashTable, &key, &value));
1108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1110b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
1112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1113b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry     *entry;
1114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1115b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry     = drmGetEntry(fd);
1116b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f  = f;
1117b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1118e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
1119b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmRemoveSIGIOHandler(int fd)
1122b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1123b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry     *entry = drmGetEntry(fd);
1124b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1125b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f = NULL;
1126b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1127b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return xf86RemoveSIGIOHandler(fd);
1128b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1129b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
1130