xf86drm.c revision 0e1135de5cbb783846a4f7e9ef8a5f953f7c77ae
1d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \file xf86drm.c
3d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * User-level interface to DRM device
4b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
5d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \author Rickard E. (Rik) Faith <faith@valinux.com>
6d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \author Kevin E. Martin <martin@valinux.com>
7d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
8d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
9d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/*
10569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * All Rights Reserved.
13b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *
14b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Permission is hereby granted, free of charge, to any person obtaining a
15b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * copy of this software and associated documentation files (the "Software"),
16b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * to deal in the Software without restriction, including without limitation
17b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * and/or sell copies of the Software, and to permit persons to whom the
19b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Software is furnished to do so, subject to the following conditions:
20360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes *
21b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * The above copyright notice and this permission notice (including the next
22b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * paragraph) shall be included in all copies or substantial portions of the
23b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * Software.
24360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes *
25b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
28b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss * DEALINGS IN THE SOFTWARE.
32b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss */
33b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
3479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#ifdef HAVE_CONFIG_H
3579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie# include <config.h>
36b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
3779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdio.h>
3879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdlib.h>
3979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <unistd.h>
4079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <string.h>
41015efd1bfa72ab8b80cc45f11eb22d7f1a1085f7Ian Romanick#include <strings.h>
4279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <ctype.h>
430ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#include <dirent.h>
440ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#include <stddef.h>
4579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <fcntl.h>
4679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <errno.h>
4779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <signal.h>
48f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes#include <time.h>
4979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/types.h>
5079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/stat.h>
5179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#define stat_t struct stat
5279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/ioctl.h>
5379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/time.h>
5479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdarg.h>
550e1135de5cbb783846a4f7e9ef8a5f953f7c77aeAlan Coopersmith#ifdef HAVE_SYS_MKDEV_H
560e1135de5cbb783846a4f7e9ef8a5f953f7c77aeAlan Coopersmith# include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */
570e1135de5cbb783846a4f7e9ef8a5f953f7c77aeAlan Coopersmith#endif
58b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
59b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* Not all systems have MAP_FAILED defined */
60b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifndef MAP_FAILED
61b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#define MAP_FAILED ((void *)-1)
62b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
63b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
64b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "xf86drm.h"
65faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov#include "libdrm.h"
66b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
6727c3785d3f12743a9e160238a4d00353060ec2f2Hasso Tepper#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
68cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 145
69cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#endif
70cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt
71cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifdef __NetBSD__
72cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 34
7388dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
7488dbee54ed400a3fd5594fab506518c171167805Rik Faith
75b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane# ifdef __OpenBSD__
76b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#  define DRM_MAJOR 81
77b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane# endif
78b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane
79cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifndef DRM_MAJOR
80cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 226		/* Linux */
8188dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
8288dbee54ed400a3fd5594fab506518c171167805Rik Faith
8322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson/*
8422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This definition needs to be changed on some systems if dev_t is a structure.
8522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * If there is a header file we can get it from, there would be best.
8622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson */
87569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#ifndef makedev
88569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#define makedev(x,y)    ((dev_t)(((x) << 8) | (y)))
89569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#endif
90569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
9156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes#define DRM_MSG_VERBOSITY 3
9256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
93fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter#define memclear(s) memset(&s, 0, sizeof(s))
94fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
9579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic drmServerInfoPtr drm_server_info;
9679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
9779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid drmSetServerInfo(drmServerInfoPtr info)
9879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
99ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_server_info = info;
10079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
10179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
102d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Output a message to stderr.
104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
105d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param format printf() like format string.
106d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
107d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
108d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around vfprintf().
109d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
11079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
11144b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingstatic int DRM_PRINTFLIKE(1, 0)
11244b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry RedingdrmDebugPrint(const char *format, va_list ap)
11379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
114ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return vfprintf(stderr, format, ap);
11579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
11679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
11744b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingtypedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
11844b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Reding						     va_list ap);
11944b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Reding
12044b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingstatic debug_msg_func_t drm_debug_print = drmDebugPrint;
12179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
122c4857429c716f35e1fa054d1990cae28055d96d7Eric Anholtvoid
12356bd9c207770d41a497f3e8237a1099dd9d4cd91David DawesdrmMsg(const char *format, ...)
12456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes{
12556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    va_list	ap;
12656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    const char *env;
12779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info)
12856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    {
12956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_start(ap, format);
13079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
13179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_server_info->debug_print(format,ap);
13279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	} else {
13379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_debug_print(format, ap);
13479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
13556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_end(ap);
13656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
13756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes}
13856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
13979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid
14044b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry RedingdrmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
14179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
142ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_debug_print = debug_msg_ptr;
14379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
14479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
145b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void *drmHashTable = NULL; /* Context switch callbacks */
146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
14779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid *drmGetHashTable(void)
14879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
149ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return drmHashTable;
15079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
151b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmMalloc(int size)
153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
154b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void *pt;
155ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((pt = malloc(size)))
156ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	memset(pt, 0, size);
157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return pt;
158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
159b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFree(void *pt)
161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
162ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (pt)
163ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	free(pt);
164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard/**
1678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard * Call ioctl, restarting if it is interupted
1688b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard */
169731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint
17041b83a99583486ad4f8760a6537d34783769bfc3Coleman KanedrmIoctl(int fd, unsigned long request, void *arg)
1718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard{
1728b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    int	ret;
1738b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard
1748b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    do {
1758b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	ret = ioctl(fd, request, arg);
1768b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1778b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return ret;
1788b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard}
179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic unsigned long drmGetKeyFromFd(int fd)
181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
182fcc21069b7019a4a93e1ceacc175ccd682353861David Dawes    stat_t     st;
183b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    st.st_rdev = 0;
185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    fstat(fd, &st);
186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return st.st_rdev;
187b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
18979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave AirliedrmHashEntry *drmGetEntry(int fd)
190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key = drmGetKeyFromFd(fd);
192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry;
194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
195ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!drmHashTable)
196ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drmHashTable = drmHashCreate();
197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashLookup(drmHashTable, key, &value)) {
199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry           = drmMalloc(sizeof(*entry));
200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->fd       = fd;
201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->f        = NULL;
202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->tagTable = drmHashCreate();
203b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(drmHashTable, key, entry);
204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    } else {
205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry = value;
206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
207b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return entry;
208b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
209b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
210d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
21106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Compare two busid strings
21206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param first
21406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param second
21506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return 1 if matched.
21706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
21906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * This function compares two bus ID strings.  It understands the older
22006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
22106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * domain, b is bus, d is device, f is function.
22206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
223b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidtstatic int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
22406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
22506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* First, check if the IDs are exactly the same */
22606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strcasecmp(id1, id2) == 0)
22706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	return 1;
22806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
22906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Try to match old/new-style PCI bus IDs. */
23006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strncasecmp(id1, "pci", 3) == 0) {
23190ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o1, b1, d1, f1;
23290ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o2, b2, d2, f2;
23306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	int ret;
23406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
23590ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
23606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
23706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o1 = 0;
23890ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
23906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
24006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
24106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
24206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
24390ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
24406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
24506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o2 = 0;
24690ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
24706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
24806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
24906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
25006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
251b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	/* If domains aren't properly supported by the kernel interface,
252b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * just ignore them, which sucks less than picking a totally random
253b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * card with "open by name"
254b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 */
255b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	if (!pci_domain_ok)
256b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		o1 = o2 = 0;
257b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt
25806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
25906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 0;
26006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	else
26106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 1;
26206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
26306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return 0;
26406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
26506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
26606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
267c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Handles error checking for chown call.
268c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
269c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param path to file.
270c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new owner.
271c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new group.
272c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
273c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \return zero if success or -1 if failure.
274c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
275c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \internal
276c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Checks for failure. If failure was caused by signal call chown again.
277c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * If any other failure happened then it will output error mesage using
278c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * drmMsg() call.
279c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen */
280c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminenstatic int chown_check_return(const char *path, uid_t owner, gid_t group)
281c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen{
282c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	int rv;
283c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
284c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	do {
285c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		rv = chown(path, owner, group);
286c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	} while (rv != 0 && errno == EINTR);
287c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
288c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	if (rv == 0)
289c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		return 0;
290c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
291c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	drmMsg("Failed to change owner or group for file %s! %d: %s\n",
292c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen			path, errno, strerror(errno));
293c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	return -1;
294c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen}
295c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
296c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen/**
297d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device, creating it if necessary.
298d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
299d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param dev major and minor numbers of the device.
300d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor minor number of the device.
301d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
302d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
303d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
304d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
305d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assembles the device name from \p minor and opens it, creating the device
306d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * special file node with the major and minor numbers specified by \p dev and
307d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parent directory if necessary and was called by root.
308d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
309de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Veselystatic int drmOpenDevice(dev_t dev, int minor, int type)
310b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
3119c775d0b2f303389c24aea5e8abc1473f0cf93e8David Dawes    stat_t          st;
3120c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    const char      *dev_name;
31388dbee54ed400a3fd5594fab506518c171167805Rik Faith    char            buf[64];
31488dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             fd;
31579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    mode_t          devmode = DRM_DEV_MODE, serv_mode;
31688dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             isroot  = !geteuid();
31788dbee54ed400a3fd5594fab506518c171167805Rik Faith    uid_t           user    = DRM_DEV_UID;
31879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    gid_t           group   = DRM_DEV_GID, serv_group;
31979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
3200c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    switch (type) {
3210c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_PRIMARY:
3220c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_DEV_NAME;
3230c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3240c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_CONTROL:
3250c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_CONTROL_DEV_NAME;
3260c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3270c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_RENDER:
3280c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_RENDER_DEV_NAME;
3290c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3300c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    default:
3310c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    return -EINVAL;
3320c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    };
3330c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
3340c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
33506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenDevice: node name is %s\n", buf);
33656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
33779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
338ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drm_server_info->get_perms(&serv_group, &serv_mode);
339ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
340ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
341ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
34279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
343569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
3449101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#if !defined(UDEV)
34588dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (stat(DRM_DIR_NAME, &st)) {
346ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
347ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
348b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
349c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
350b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
351569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
352b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
35306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node exists and create it if necessary. */
354d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (stat(buf, &st)) {
355ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
356ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
35788dbee54ed400a3fd5594fab506518c171167805Rik Faith	remove(buf);
35888dbee54ed400a3fd5594fab506518c171167805Rik Faith	mknod(buf, S_IFCHR | devmode, dev);
359b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
36079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
36179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
362c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(buf, user, group);
363ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	chmod(buf, devmode);
36479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
3659101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#else
3669101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    /* if we modprobed then wait for udev */
3679101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    {
3689101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	int udev_count = 0;
3699101a0205c897fea28e6a3d875111a83ad7f7732Dave Airliewait_for_udev:
3709101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie        if (stat(DRM_DIR_NAME, &st)) {
3719101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3729101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3739101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3749101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3759101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3769101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3779101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	}
3789101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3799101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	if (stat(buf, &st)) {
3809101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3819101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3829101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3839101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3849101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3859101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3869101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	}
3879101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    }
3889101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#endif
38988dbee54ed400a3fd5594fab506518c171167805Rik Faith
39056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    fd = open(buf, O_RDWR, 0);
39156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
39256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		fd, fd < 0 ? strerror(errno) : "OK");
393ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
394ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
395d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
39639e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#if !defined(UDEV)
39706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node is not what we expect it to be, and recreate it
39806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     * and try again if so.
39906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     */
400d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (st.st_rdev != dev) {
401ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
402ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
403d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	remove(buf);
404d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	mknod(buf, S_IFCHR | devmode, dev);
40579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
406c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	    chown_check_return(buf, user, group);
407ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    chmod(buf, devmode);
40879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
409d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    }
410d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    fd = open(buf, O_RDWR, 0);
411d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
412d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt		fd, fd < 0 ? strerror(errno) : "OK");
413ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
414ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
415d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
41656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: Open failed\n");
41788dbee54ed400a3fd5594fab506518c171167805Rik Faith    remove(buf);
41839e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#endif
41988dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
420b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
421b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
422d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
423d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
424d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device
425d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
426d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor device minor number.
427d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param create allow to create the device if set.
428d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
429d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
430d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
431d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
432d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
433d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * name from \p minor and opens it.
434d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
435731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic int drmOpenMinor(int minor, int create, int type)
43688dbee54ed400a3fd5594fab506518c171167805Rik Faith{
43788dbee54ed400a3fd5594fab506518c171167805Rik Faith    int  fd;
43888dbee54ed400a3fd5594fab506518c171167805Rik Faith    char buf[64];
4390c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    const char *dev_name;
440db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
441ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (create)
442731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
44388dbee54ed400a3fd5594fab506518c171167805Rik Faith
4440c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    switch (type) {
4450c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_PRIMARY:
4460c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_DEV_NAME;
4470c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4480c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_CONTROL:
4490c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_CONTROL_DEV_NAME;
4500c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4510c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_RENDER:
4520c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_RENDER_DEV_NAME;
4530c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4540c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    default:
4550c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    return -EINVAL;
4560c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    };
4570c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
4580c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
459ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((fd = open(buf, O_RDWR, 0)) >= 0)
460ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
46188dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
46288dbee54ed400a3fd5594fab506518c171167805Rik Faith}
46388dbee54ed400a3fd5594fab506518c171167805Rik Faith
464569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
465d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
466d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine whether the DRM kernel driver has been loaded.
467d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
468d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return 1 if the DRM driver is loaded, 0 otherwise.
469d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
470d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
471d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine the presence of the kernel driver by attempting to open the 0
472d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * minor and get version information.  For backward compatibility with older
473d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Linux implementations, /proc/dri is also checked.
474d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
475569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulint drmAvailable(void)
476569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul{
477569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    drmVersionPtr version;
478569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           retval = 0;
479569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           fd;
480360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
481ad8bbfd3c74466f088be8088d2d0524bed392b71Frank Binns    if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
482b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#ifdef __linux__
48322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	/* Try proc for backward Linux compatibility */
484ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!access("/proc/dri/0", R_OK))
485ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return 1;
486b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#endif
48788dbee54ed400a3fd5594fab506518c171167805Rik Faith	return 0;
488569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
48988dbee54ed400a3fd5594fab506518c171167805Rik Faith
49088dbee54ed400a3fd5594fab506518c171167805Rik Faith    if ((version = drmGetVersion(fd))) {
49188dbee54ed400a3fd5594fab506518c171167805Rik Faith	retval = 1;
49288dbee54ed400a3fd5594fab506518c171167805Rik Faith	drmFreeVersion(version);
49388dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
49488dbee54ed400a3fd5594fab506518c171167805Rik Faith    close(fd);
495569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
496569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    return retval;
497569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul}
498569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
499f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmGetMinorBase(int type)
500f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{
501f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    switch (type) {
502f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_PRIMARY:
503f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 0;
504f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_CONTROL:
505f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 64;
506f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_RENDER:
507f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 128;
508f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    default:
509f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
510f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    };
511f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou}
512d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
5131f73578df32f895a678a41758f6c563f49484347Frank Binnsstatic int drmGetMinorType(int minor)
5141f73578df32f895a678a41758f6c563f49484347Frank Binns{
5151f73578df32f895a678a41758f6c563f49484347Frank Binns    int type = minor >> 6;
5161f73578df32f895a678a41758f6c563f49484347Frank Binns
5171f73578df32f895a678a41758f6c563f49484347Frank Binns    if (minor < 0)
5181f73578df32f895a678a41758f6c563f49484347Frank Binns        return -1;
5191f73578df32f895a678a41758f6c563f49484347Frank Binns
5201f73578df32f895a678a41758f6c563f49484347Frank Binns    switch (type) {
5211f73578df32f895a678a41758f6c563f49484347Frank Binns    case DRM_NODE_PRIMARY:
5221f73578df32f895a678a41758f6c563f49484347Frank Binns    case DRM_NODE_CONTROL:
5231f73578df32f895a678a41758f6c563f49484347Frank Binns    case DRM_NODE_RENDER:
5241f73578df32f895a678a41758f6c563f49484347Frank Binns        return type;
5251f73578df32f895a678a41758f6c563f49484347Frank Binns    default:
5261f73578df32f895a678a41758f6c563f49484347Frank Binns        return -1;
5271f73578df32f895a678a41758f6c563f49484347Frank Binns    }
5281f73578df32f895a678a41758f6c563f49484347Frank Binns}
5291f73578df32f895a678a41758f6c563f49484347Frank Binns
5300ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovstatic const char *drmGetMinorName(int type)
5310ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{
5320ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    switch (type) {
5330ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    case DRM_NODE_PRIMARY:
5340ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov        return "card";
5350ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    case DRM_NODE_CONTROL:
5360ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov        return "controlD";
5370ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    case DRM_NODE_RENDER:
5380ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov        return "renderD";
5390ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    default:
5400ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov        return NULL;
5410ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov    }
5420ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov}
5430ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
544d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
545d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by bus ID.
546d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
547d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID.
548f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type device node type.
549d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
550d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
551d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
552d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
553d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
554d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * comparing the device bus ID with the one supplied.
555d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
556d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor() and drmGetBusid().
557d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
558f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByBusid(const char *busid, int type)
559e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss{
560b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt    int        i, pci_domain_ok = 1;
56188dbee54ed400a3fd5594fab506518c171167805Rik Faith    int        fd;
56288dbee54ed400a3fd5594fab506518c171167805Rik Faith    const char *buf;
56306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmSetVersion sv;
564f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    int        base = drmGetMinorBase(type);
565f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
566f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    if (base < 0)
567f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
56806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
56906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
570f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    for (i = base; i < base + DRM_MAX_MINOR; i++) {
571f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	fd = drmOpenMinor(i, 1, type);
57256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
57356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	if (fd >= 0) {
574b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    /* We need to try for 1.4 first for proper PCI domain support
575b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     * and if that fails, we know the kernel is busted
576b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     */
57706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_di_major = 1;
578b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    sv.drm_di_minor = 4;
57906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_dd_major = -1;	/* Don't care */
58026462b9aa47179e724e78f0b3b1c86fd07f61d8dEric Anholt	    sv.drm_dd_minor = -1;	/* Don't care */
581b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (drmSetInterfaceVersion(fd, &sv)) {
582b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#ifndef __alpha__
583b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		pci_domain_ok = 0;
584b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#endif
585b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_major = 1;
586b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_minor = 1;
587b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_major = -1;       /* Don't care */
588b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_minor = -1;       /* Don't care */
589303ff26311dc5efdf28676be34d86f501699acf3Thierry Reding		drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n");
590b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		drmSetInterfaceVersion(fd, &sv);
591b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    }
592e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    buf = drmGetBusid(fd);
59356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
594b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
59588dbee54ed400a3fd5594fab506518c171167805Rik Faith		drmFreeBusid(buf);
59688dbee54ed400a3fd5594fab506518c171167805Rik Faith		return fd;
597e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    }
598ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (buf)
599ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmFreeBusid(buf);
600e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    close(fd);
601e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	}
602e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    }
603e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    return -1;
604e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss}
605e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss
606d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
607d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
608d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by name.
609d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
610d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name.
611f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type.
612d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
613d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
614d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
615d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
616d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function opens the first minor number that matches the driver name and
617d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * isn't already in use.  If it's in use it then it will already have a bus ID
618d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * assigned.
619d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
620d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
621d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
622f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByName(const char *name, int type)
623b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss{
62488dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           i;
62588dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           fd;
62688dbee54ed400a3fd5594fab506518c171167805Rik Faith    drmVersionPtr version;
62756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    char *        id;
628f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    int           base = drmGetMinorBase(type);
629f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
630f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    if (base < 0)
631f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
632db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
63356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    /*
63456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * Open the first minor number that matches the driver name and isn't
63556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * already in use.  If it's in use it will have a busid assigned already.
63656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     */
637f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    for (i = base; i < base + DRM_MAX_MINOR; i++) {
638f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
63988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    if ((version = drmGetVersion(fd))) {
64088dbee54ed400a3fd5594fab506518c171167805Rik Faith		if (!strcmp(version->name, name)) {
64188dbee54ed400a3fd5594fab506518c171167805Rik Faith		    drmFreeVersion(version);
64256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    id = drmGetBusid(fd);
64356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
64456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    if (!id || !*id) {
64522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			if (id)
64656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			    drmFreeBusid(id);
64756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			return fd;
64856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    } else {
64956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			drmFreeBusid(id);
65056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    }
65156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		} else {
65256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmFreeVersion(version);
65388dbee54ed400a3fd5594fab506518c171167805Rik Faith		}
65488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    }
65556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    close(fd);
65688dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
657b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
658b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
65988dbee54ed400a3fd5594fab506518c171167805Rik Faith#ifdef __linux__
66022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* Backward-compatibility /proc support */
661b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    for (i = 0; i < 8; i++) {
66288dbee54ed400a3fd5594fab506518c171167805Rik Faith	char proc_name[64], buf[512];
66388dbee54ed400a3fd5594fab506518c171167805Rik Faith	char *driver, *pt, *devstring;
66488dbee54ed400a3fd5594fab506518c171167805Rik Faith	int  retcode;
66588dbee54ed400a3fd5594fab506518c171167805Rik Faith
6660371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(proc_name, "/proc/dri/%d/name", i);
667b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if ((fd = open(proc_name, 0, 0)) >= 0) {
668b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    retcode = read(fd, buf, sizeof(buf)-1);
669b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    close(fd);
670b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    if (retcode) {
671b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		buf[retcode-1] = '\0';
672b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		for (driver = pt = buf; *pt && *pt != ' '; ++pt)
673b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    ;
67422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson		if (*pt) { /* Device is next */
675b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    *pt = '\0';
676b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    if (!strcmp(driver, name)) { /* Match */
677b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
678b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			    ;
679b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			if (*pt) { /* Found busid */
680f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou			    return drmOpenByBusid(++pt, type);
68122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			} else { /* No busid */
682f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou			    return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
683b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			}
684b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    }
685b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		}
686b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    }
687569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
688b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
68988dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
69088dbee54ed400a3fd5594fab506518c171167805Rik Faith
691b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return -1;
692b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss}
693b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
694b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
695d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
696d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device.
697d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
698d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Looks up the specified name and bus ID, and opens the device found.  The
699d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * entry in /dev/dri is created if necessary and if called by root.
700d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name. Not referenced if bus ID is supplied.
702d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID. Zero if not known.
703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
704d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
705d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
706d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
707d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
708d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * otherwise.
709d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
710b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmOpen(const char *name, const char *busid)
711b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
712f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
713f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou}
714f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
715f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou/**
716f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Open the DRM device with specified type.
717f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
718f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Looks up the specified name and bus ID, and opens the device found.  The
719f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * entry in /dev/dri is created if necessary and if called by root.
720f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
721f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param name driver name. Not referenced if bus ID is supplied.
722f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param busid bus ID. Zero if not known.
723f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type to open, PRIMARY, CONTROL or RENDER
724f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
725f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \return a file descriptor on success, or a negative value on error.
726f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
727f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \internal
728f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
729f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * otherwise.
730f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou */
731f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhouint drmOpenWithType(const char *name, const char *busid, int type)
732f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{
73379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (!drmAvailable() && name != NULL && drm_server_info) {
734f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	/* try to load the kernel module */
73579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (!drm_server_info->load_module(name)) {
736ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
73706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return -1;
73806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
73906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
74006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
74106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (busid) {
742f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	int fd = drmOpenByBusid(busid, type);
74306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (fd >= 0)
74406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return fd;
74506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
74622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
74706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (name)
748f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	return drmOpenByName(name, type);
74922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
75006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return -1;
751b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
752b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
753731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmOpenControl(int minor)
754731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
755731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
756731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
757d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
7580c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binnsint drmOpenRender(int minor)
7590c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns{
7600c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
7610c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns}
7620c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
763d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
764d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the version information returned by drmGetVersion().
765d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
766d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
767d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
768d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It frees the memory pointed by \p %v as well as all the non-null strings
770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * pointers in it.
771d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
772b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeVersion(drmVersionPtr v)
773b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
774ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
775ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
7769d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
7779d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
7789d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
779b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
780b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
781b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
782d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
783d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
784d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the non-public version information returned by the kernel.
785d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
786d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
787d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
788d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the non-null strings pointers in it.
791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
792b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void drmFreeKernelVersion(drm_version_t *v)
793b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
794ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
795ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
7969d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
7979d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
7989d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
799b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
800b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
801b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
802d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
803d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
804d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Copy version information.
805d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
806d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param d destination pointer.
807d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param s source pointer.
808d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
809d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
810d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to translate the information returned by the ioctl
811d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * interface in a private structure into the public structure counterpart.
812d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
813569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulstatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
814b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
815b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_major      = s->version_major;
816b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_minor      = s->version_minor;
817b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_patchlevel = s->version_patchlevel;
818b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->name_len           = s->name_len;
8190a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->name               = strdup(s->name);
820b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->date_len           = s->date_len;
8210a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->date               = strdup(s->date);
822b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->desc_len           = s->desc_len;
8230a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->desc               = strdup(s->desc);
824b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
825b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
826b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
827d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
828d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Query the driver version information.
829d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
830d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
831d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
832d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return pointer to a drmVersion structure which should be freed with
833d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * drmFreeVersion().
834d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
835d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note Similar information is available via /proc/dri.
836d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
837d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
838d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
839d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * first with zeros to get the string lengths, and then the actually strings.
840d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It also null-terminates them since they might not be already.
841d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
842b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmVersionPtr drmGetVersion(int fd)
843b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
844b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmVersionPtr retval;
845b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_version_t *version = drmMalloc(sizeof(*version));
846b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
84795f23cf894757d05a6b6c980062a46968dc069b1Daniel Vetter    memclear(*version);
848360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
8498b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
850b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
851b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
852b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
853b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
854b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len)
855b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->name    = drmMalloc(version->name_len + 1);
856b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len)
857b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->date    = drmMalloc(version->date_len + 1);
858b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len)
859b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->desc    = drmMalloc(version->desc_len + 1);
860360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
8618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
862b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane	drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
863b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
864b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
865b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
866b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
86722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* The results might not be null-terminated strings, so terminate them. */
868b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len) version->name[version->name_len] = '\0';
869b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len) version->date[version->date_len] = '\0';
870b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len) version->desc[version->desc_len] = '\0';
871b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
872b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    retval = drmMalloc(sizeof(*retval));
873b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmCopyVersion(retval, version);
874b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFreeKernelVersion(version);
875b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
876b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
877b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
8783903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
879d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
880d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get version information for the DRM user space library.
881d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
882d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This version number is driver independent.
883d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
884d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
885d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
886d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return version information.
887d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
888d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
889d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function allocates and fills a drm_version structure with a hard coded
890d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * version number.
891d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
8923903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens OwendrmVersionPtr drmGetLibVersion(int fd)
8933903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
8943903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    drm_version_t *version = drmMalloc(sizeof(*version));
8953903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8963903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    /* Version history:
89779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
8983903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.0.x = original DRM interface with no drmGetLibVersion
8993903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    entry point and many drm<Device> extensions
9003903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.1.x = added drmCommand entry points for device extensions
9013903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    added drmGetLibVersion to identify libdrm.a version
90206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *   revision 1.2.x = added drmSetInterfaceVersion
90306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *                    modified drmOpen to handle both busid and name
90479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   revision 1.3.x = added server + memory manager
9053903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     */
90679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_major      = 1;
90779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_minor      = 3;
9083903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    version->version_patchlevel = 0;
9093903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
9103903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return (drmVersionPtr)version;
9113903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
9123903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
9135c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggsint drmGetCap(int fd, uint64_t capability, uint64_t *value)
9145c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs{
915fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	struct drm_get_cap cap;
9165c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	int ret;
9175c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
918fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	memclear(cap);
919fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.capability = capability;
920fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
9215c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
9225c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	if (ret)
9235c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs		return ret;
9245c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
9255c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	*value = cap.value;
9263b04c73650b5e9bbcb602fdb8cea0b16ad82d0c0Dave Airlie	return 0;
9275c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs}
928d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
929ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiauint drmSetClientCap(int fd, uint64_t capability, uint64_t value)
930ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau{
931fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	struct drm_set_client_cap cap;
932fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
933fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	memclear(cap);
934fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.capability = capability;
935fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.value = value;
936ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
937ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau	return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
938ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau}
939ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
940d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
941d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the bus ID information.
942d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
943d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID information string as given by drmGetBusid().
944d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
945d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is just frees the memory pointed by \p busid.
947d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
948b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussvoid drmFreeBusid(const char *busid)
949b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
950b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drmFree((void *)busid);
951b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
952b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
953d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
954d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
955d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get the bus ID of the device.
956d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
957d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
958d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
959d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return bus ID string.
960d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
961d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
962d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
963d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * get the string length and data, passing the arguments in a drm_unique
964d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * structure.
965d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
966b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strausschar *drmGetBusid(int fd)
967b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
968b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
969b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
970fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(u);
971b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9728b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
973ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
974b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique = drmMalloc(u.unique_len + 1);
9758b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
976ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
977b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique[u.unique_len] = '\0';
97806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
979b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return u.unique;
980b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
981b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
982d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
983d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
984d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the bus ID of the device.
985d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
986d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
987d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID string.
988d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
989d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, negative on failure.
990d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
991d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
992d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
993d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_unique structure.
994d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
995b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmSetBusid(int fd, const char *busid)
996b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
997b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
998b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
999fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(u);
1000b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = (char *)busid;
1001b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = strlen(busid);
1002b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
10038b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
100456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	return -errno;
100556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
1006b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1007b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1008b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
10098696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMagic(int fd, drm_magic_t * magic)
1010b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1011b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
1012b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1013fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(auth);
1014fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1015b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = 0;
10168b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
1017ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1018b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = auth.magic;
1019b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1020b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1021b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
10228696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAuthMagic(int fd, drm_magic_t magic)
1023b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1024b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
1025b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1026fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(auth);
1027b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    auth.magic = magic;
10288b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
1029ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1030b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1031b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1032b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1033d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1034d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Specifies a range of memory that is available for mapping by a
1035d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * non-root process.
1036d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1037d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1038d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset usually the physical address. The actual meaning depends of
1039d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the \p type parameter. See below.
1040d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size of the memory in bytes.
1041d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of the memory to be mapped.
1042d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags combination of several flags to modify the function actions.
1043d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle will be set to a value that may be used as the offset
1044d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parameter for mmap().
1045d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1046d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success or a negative value on error.
1047d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1048d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the frame buffer
1049d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the frame buffer
1050d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the frame buffer,
1051d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the frame buffer in bytes, and
1052d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_FRAME_BUFFER.
1053d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1054d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1055d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached. If MTRR support is available in the
1056d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel, the frame buffer area will be set to write combining.
1057d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1058d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the MMIO register area
1059d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the MMIO register area,
1060d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the register area,
1061d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the register area bytes, and
1062d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_REGISTERS.
1063d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1064d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached.
1065d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1066d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the SAREA
1067d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the SAREA,
1068d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be ignored and should be set to zero,
1069d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the desired size of the SAREA in bytes,
1070d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_SHM.
1071d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1072d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1073d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * A shared memory area of the requested size will be created and locked in
1074d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel memory. This area may be mapped into client-space by using the handle
1075d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returned.
1076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1078d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
1081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_map structure.
1082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
108322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
108422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	      drmMapFlags flags, drm_handle_t *handle)
1085b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1086b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_map_t map;
1087b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1088fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
1089b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.offset  = offset;
1090b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.size    = size;
1091b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.type    = type;
1092b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.flags   = flags;
10938b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
1094ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1095ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
1096961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
1097b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1098b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1099b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
11008696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmRmMap(int fd, drm_handle_t handle)
110174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
110274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_map_t map;
110374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
1104fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
1105961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
110674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
11078b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
1108ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
110974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
111074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
111174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
1112d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1113d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Make buffers available for DMA transfers.
1114d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1115d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1116d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers.
1117d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of each buffer.
1118d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags buffer allocation flags.
1119d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param agp_offset offset in the AGP aperture
1120d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1121d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return number of buffers allocated, negative on error.
1122d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1123d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1124d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
1125d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1126d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drm_buf_desc.
1127d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1128ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1129ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann	       int agp_offset)
1130b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1131b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_desc_t request;
1132360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1133fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(request);
1134b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count     = count;
1135b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.size      = size;
1136b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.flags     = flags;
1137ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    request.agp_start = agp_offset;
1138360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
11398b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1140ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1141b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return request.count;
1142b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1143b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1144b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMarkBufs(int fd, double low, double high)
1145b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1147b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1148b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1149fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(info);
1150b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
11518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1152ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1154ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!info.count)
1155ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1156360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return -ENOMEM;
1159360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
11608b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	int retval = -errno;
1162b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1163b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1165360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < info.count; i++) {
1167b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].low_mark  = low  * info.list[i].count;
1168b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].high_mark = high * info.list[i].count;
11698b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1170b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    int retval = -errno;
1171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return retval;
1173b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1174b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(info.list);
1176360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1180d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1181d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free buffers.
1182d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1183d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1184d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers to free.
1185d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param list list of buffers to be freed.
1186d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1187d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1188d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1189d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note This function is primarily used for debugging.
1190d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1191d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1192d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1193d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_buf_free structure.
1194d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFreeBufs(int fd, int count, int *list)
1196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_free_t request;
1198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1199fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(request);
1200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count = count;
1201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.list  = list;
12028b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1203ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1207d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1208d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1209d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Close the device.
1210d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1211d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1212d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1213d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1214d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function closes the file descriptor.
1215d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1216b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmClose(int fd)
1217b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1218b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key    = drmGetKeyFromFd(fd);
1219b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1220b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1221b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDestroy(entry->tagTable);
1222b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->fd       = 0;
1223b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f        = NULL;
1224b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->tagTable = NULL;
1225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDelete(drmHashTable, key);
1227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(entry);
1228b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1229b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return close(fd);
1230b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1231b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1232d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1233d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1234d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map a region of memory.
1235d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1236d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1237d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle returned by drmAddMap().
1238d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmAddMap().
1239d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address will contain the user-space virtual address where the mapping
1240d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * begins.
1241d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1242d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1243d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1244d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1245d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper for mmap().
1246d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
124722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1249c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    static unsigned long pagesize_mask = 0;
1250c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1251ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd < 0)
1252ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1253c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1254c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    if (!pagesize_mask)
1255c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane	pagesize_mask = getpagesize() - 1;
1256c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1257c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    size = (size + pagesize_mask) & ~pagesize_mask;
1258c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1259faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov    *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1260ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (*address == MAP_FAILED)
1261ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1262b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1263b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1264b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1265d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1266d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1267d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap mappings obtained with drmMap().
1268d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1269d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address address as given by drmMap().
1270d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmMap().
1271d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1272d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1273d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1274d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
127522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This function is a wrapper for munmap().
1276d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1277b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmap(drmAddress address, drmSize size)
1278b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1279faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov    return drm_munmap(address, size);
1280b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1281b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1282b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufInfoPtr drmGetBufInfo(int fd)
1283b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1284b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1285b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufInfoPtr  retval;
1286b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1287b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1288fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(info);
1289b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
12908b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1291ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1292b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1293b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (info.count) {
1294b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1295b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1296360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
12978b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1298b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1299b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1300b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
130122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1302b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1303b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = info.count;
1304b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
1305b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < info.count; i++) {
1306b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].count     = info.list[i].count;
1307b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].size      = info.list[i].size;
1308b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].low_mark  = info.list[i].low_mark;
1309b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].high_mark = info.list[i].high_mark;
1310b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1311b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1312b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1313b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1314b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return NULL;
1315b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1316b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1317d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1318d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map all DMA buffers into client-virtual space.
1319d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1320d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1321d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1322d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a pointer to a ::drmBufMap structure.
1323d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1324d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note The client may not use these buffers until obtaining buffer indices
1325d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with drmDMA().
1326d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1327d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1328d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1329d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * information about the buffers in a drm_buf_map structure into the
1330d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * client-visible data structures.
1331d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1332b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufMapPtr drmMapBufs(int fd)
1333b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1334b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_map_t bufs;
1335b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufMapPtr  retval;
1336b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1337360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1338fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(bufs);
13398b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1340ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1341b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1342ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!bufs.count)
1343ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
13448696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1345b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1346b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1347b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
13488b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1349b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(bufs.list);
1350b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1351b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
135222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1353b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = bufs.count;
1355b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
1356b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < bufs.count; i++) {
1357b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].idx     = bufs.list[i].idx;
1358b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].total   = bufs.list[i].total;
1359b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].used    = 0;
1360b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].address = bufs.list[i].address;
1361b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
13628696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
13638696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	drmFree(bufs.list);
13648696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1365b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1366b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1367b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1368d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1369d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1370d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap buffers allocated with drmMapBufs().
1371d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1372d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or negative value on failure.
1373d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1374d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
13758696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * Calls munmap() for every buffer stored in \p bufs and frees the
13768696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * memory allocated by drmMapBufs().
1377d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1378b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmapBufs(drmBufMapPtr bufs)
1379b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1380b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int i;
1381360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1382b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < bufs->count; i++) {
1383faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov	drm_munmap(bufs->list[i].address, bufs->list[i].total);
1384b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
13858696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
13868696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs->list);
13878696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs);
13888696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1389b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1390b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1391b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1392d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1393360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes#define DRM_DMA_RETRY		16
1394360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1395d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1396d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Reserve DMA buffers.
1397d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1398d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1399d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param request
1400d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1401d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1402d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1403d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1404d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assemble the arguments into a drm_dma structure and keeps issuing the
1405d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1406d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1407b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDMA(int fd, drmDMAReqPtr request)
1408b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1409b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_dma_t dma;
1410360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    int ret, i = 0;
1411b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1412b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.context         = request->context;
1413b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_count      = request->send_count;
1414b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_indices    = request->send_list;
1415b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_sizes      = request->send_sizes;
1416b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.flags           = request->flags;
1417b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_count   = request->request_count;
1418b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_size    = request->request_size;
1419b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_indices = request->request_list;
1420b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_sizes   = request->request_sizes;
14218696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    dma.granted_count   = 0;
1422360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1423360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    do {
1424360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1425360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1426360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1427360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    if ( ret == 0 ) {
1428360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	request->granted_count = dma.granted_count;
1429360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return 0;
1430360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } else {
1431360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return -errno;
1432360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    }
1433b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1434b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1435d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1436d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1437d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Obtain heavyweight hardware lock.
1438d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1439d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1440d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1441d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags flags that determine the sate of the hardware when the function
1442d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returns.
1443d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1444d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return always zero.
1445d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1446d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1447d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function translates the arguments into a drm_lock structure and issue
1448d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1449d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
14508696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1451b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1452b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1453b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1454fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
1455b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
1456b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
1457b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
1458b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
1459b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
1460b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
1461b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1462b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1463360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
14648b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1465b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	;
1466b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1467b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1468b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1469d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1470d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the hardware lock.
1471d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1472d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1473d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1474d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1475d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1476d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1477d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1478d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1479d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_lock structure.
1480d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
14818696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmUnlock(int fd, drm_context_t context)
1482b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1483b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1484b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1485fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
1486b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
14878b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1488b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1489b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
149022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksondrm_context_t *drmGetReservedContextList(int fd, int *count)
1491b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1492b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_res_t res;
1493b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t     *list;
14948696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drm_context_t * retval;
1495b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1496b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1497fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(res);
14988b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1499ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1500b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1501ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!res.count)
1502ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1503b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1504ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!(list   = drmMalloc(res.count * sizeof(*list))))
1505ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1506b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1507b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(list);
1508b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
1509b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1510b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1511b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = list;
15128b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1513ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1514b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1515ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < res.count; i++)
1516ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	retval[i] = list[i].handle;
1517b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(list);
1518b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1519b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *count = res.count;
1520b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
1521b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1522b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
152322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonvoid drmFreeReservedContextList(drm_context_t *pt)
1524b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1525b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(pt);
1526b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1527b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1528d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1529d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Create context.
1530d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1531d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by the X server during GLXContext initialization. This causes
1532d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * per-context kernel-level resources to be allocated.
1533d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1534d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1535d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle is set on success. To be used by the client when requesting DMA
1536d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * dispatch with drmDMA().
1537d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1538d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1539d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1540d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1541d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1542d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1543d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1544d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1545d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
154622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateContext(int fd, drm_context_t *handle)
1547b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1548b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1549b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1550fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
15518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1552ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1553b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = ctx.handle;
1554b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1555b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1556b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15578696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSwitchToContext(int fd, drm_context_t context)
1558b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1559b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1560b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1561fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1562b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
15638b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1564ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1565b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1566b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1567b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15688696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1569b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1570b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1571b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
157222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /*
157322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * Context preserving means that no context switches are done between DMA
157422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * buffers from one context and the next.  This is suitable for use in the
157522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * X server (which promises to maintain hardware context), or in the
157622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * client-side library when buffers are swapped on behalf of two threads.
157722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     */
1578fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1579b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
1580ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_PRESERVED)
1581ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_PRESERVED;
1582ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_2DONLY)
1583ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_2DONLY;
15848b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
1585ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1586b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1587b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1588b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
158922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextFlags(int fd, drm_context_t context,
159022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                       drm_context_tFlagsPtr flags)
1591b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1592b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1593b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1594fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1595b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
15968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1597ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1598b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *flags = 0;
1599ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1600ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_PRESERVED;
1601ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_2DONLY)
1602ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_2DONLY;
1603b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1604b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1605360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1606d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1607d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Destroy context.
1608d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1609d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free any kernel-level resources allocated with drmCreateContext() associated
1610d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with the context.
1611d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1612d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1613d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle given by drmCreateContext().
1614d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1615d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1616d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1617d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1618d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1619d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1620d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1621d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1622d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
16238696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyContext(int fd, drm_context_t handle)
1624b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1625b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1626fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1627fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1628b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = handle;
16298b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1630ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1631b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1632b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1633b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
163422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateDrawable(int fd, drm_drawable_t *handle)
1635b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1636b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
1637fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1638fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(draw);
16398b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1640ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1641b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = draw.handle;
1642b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1643b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1644b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
16458696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyDrawable(int fd, drm_drawable_t handle)
1646b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1647b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
1648fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1649fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(draw);
1650b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    draw.handle = handle;
16518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1652ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1653b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1654b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1655b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
16569810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzerint drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
16579810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   drm_drawable_info_type_t type, unsigned int num,
16589810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   void *data)
16599810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer{
16609810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    drm_update_draw_t update;
16619810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
1662fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(update);
16639810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.handle = handle;
16649810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.type = type;
16659810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.num = num;
16669810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.data = (unsigned long long)(unsigned long)data;
16679810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
16688b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1669ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
16709810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
16719810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    return 0;
16729810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer}
16739810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
1674d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1675d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Acquire the AGP device.
1676d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1677d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Must be called before any of the other AGP related calls.
1678d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1679d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1680d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1681d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1682d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1683d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1684d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1685d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1686ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAcquire(int fd)
1687ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
16888b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1689ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1690ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1691ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1692ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1693d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1694d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1695d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the AGP device.
1696d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1697d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1698d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1699d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1700d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1702d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1704ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpRelease(int fd)
1705ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
17068b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1707ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1708ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1709ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1710ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1711d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1712d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1713d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the AGP mode.
1714d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1715d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1716d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param mode AGP mode.
1717d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1718d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1719d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1720d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1721d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1722d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_mode structure.
1723d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1724ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpEnable(int fd, unsigned long mode)
1725ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1726ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_mode_t m;
1727ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1728fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(mode);
1729ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    m.mode = mode;
17308b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1731ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1732ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1733ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1734ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1736d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1737d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Allocate a chunk of AGP memory.
1738d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1739d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1740d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size requested memory size in bytes. Will be rounded to page boundary.
1741d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of memory to allocate.
1742d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address if not zero, will be set to the physical address of the
1743d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * allocated memory.
1744d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle on success will be set to a handle of the allocated memory.
1745d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1746d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1747d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1748d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1749d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1750d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_agp_buffer structure.
1751d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1752ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAlloc(int fd, unsigned long size, unsigned long type,
17537ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlie		unsigned long *address, drm_handle_t *handle)
1754ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1755ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1756b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane
1757fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1758b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane    *handle = DRM_AGP_NO_HANDLE;
1759ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = size;
1760ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.type   = type;
17618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1762ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1763ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (address != 0UL)
1764ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*address = b.physical;
1765ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    *handle = b.handle;
1766ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1767ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1768ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1771d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free a chunk of AGP memory.
1772d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1773d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1774d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1775d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1776d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1777d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1778d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1779d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1780d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_buffer structure.
1781d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
17827ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpFree(int fd, drm_handle_t handle)
1783ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1784ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1785ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1786fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1787ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
17888b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1789ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1790ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1791ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1792ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1794d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1795d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Bind a chunk of AGP memory.
1796d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1797d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1798d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1799d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset offset in bytes. It will round to page boundary.
1800d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1801d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1802d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1803d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1804d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1805d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_binding structure.
1806d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
18077ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1808ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1809ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1810ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1811fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1812ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
1813ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = offset;
18148b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1815ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1816ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1817ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1818ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1819d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1820d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1821d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unbind a chunk of AGP memory.
1822d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1823d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1824d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1825d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1826d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1827d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1828d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1829d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1830d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the argument in a drm_agp_binding structure.
1831d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
18327ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpUnbind(int fd, drm_handle_t handle)
1833ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1834ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1835ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1836fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1837ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
18388b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1839ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1840ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1841ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1842ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1843d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1844d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1845d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver major version number.
1846d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1847d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1848d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1849d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return major version number on success, or a negative value on failure..
1850d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1852d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1853d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1855ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMajor(int fd)
1856ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1857ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1858ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1859fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1860fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1862ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1863ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_major;
1864ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1865ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1866d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1867d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1868d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver minor version number.
1869d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1870d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1871d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1872d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return minor version number on success, or a negative value on failure.
1873d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1874d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1875d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1876d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1877d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1878ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMinor(int fd)
1879ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1880ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1881ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1882fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1883fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18848b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1885ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1886ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_minor;
1887ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1888ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1889d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1890d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1891d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP mode.
1892d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1893d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1894d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1895d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return mode on success, or zero on failure.
1896d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1897d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1898d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1899d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1900d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1901ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpGetMode(int fd)
1902ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1903ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1904ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1905fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1906fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19078b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1908ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1909ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.mode;
1910ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1911ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1912d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1913d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1914d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture base.
1915d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1916d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1917d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1918d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture base on success, zero on failure.
1919d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1920d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1921d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1922d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1923d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1924ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpBase(int fd)
1925ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1926ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1927ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1928fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1929fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19308b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1931ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1932ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_base;
1933ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1934ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1935d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1936d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1937d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture size.
1938d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1939d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1940d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1941d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture size on success, zero on failure.
1942d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1943d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1944d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1945d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1947ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpSize(int fd)
1948ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1949ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1950ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1951fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1952fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19538b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1954ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1955ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_size;
1956ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1957ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1958d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1959d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1960d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get used AGP memory.
1961d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1962d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1963d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1964d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory used on success, or zero on failure.
1965d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1966d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1967d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1968d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1969d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1970ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryUsed(int fd)
1971ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1972ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1973ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1974fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1975fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19768b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1977ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1978ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_used;
1979ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1980ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1981d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1982d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1983d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get available AGP memory.
1984d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1985d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1986d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1987d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory available on success, or zero on failure.
1988d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1989d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1990d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1991d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1992d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1993ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryAvail(int fd)
1994ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1995ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1996ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1997fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1998fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19998b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2000ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
2001ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_allowed;
2002ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
2003ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
2004d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2005d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2006d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware vendor ID.
2007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2008d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return vendor ID on success, or zero on failure.
2011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2013d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2014d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
2015d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2016ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpVendorId(int fd)
2017ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
2018ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
2019ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
2020fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
2021fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
20228b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2023ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
2024ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_vendor;
2025ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
2026ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
2027d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2028d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2029d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware device ID.
2030d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2031d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2032d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2033d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or zero on failure.
2034d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2035d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2036d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2037d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
2038d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2039ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpDeviceId(int fd)
2040ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
2041ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
2042ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
2043fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
2044fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
20458b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2046ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
2047ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_device;
2048ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
2049ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
20507ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
20515d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
20525d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
20535d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2054fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sg);
2055fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
20565d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = 0;
20575d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.size   = size;
20588b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
2059ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
20605d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = sg.handle;
20615d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
20625d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
20635d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
20647ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherFree(int fd, drm_handle_t handle)
20655d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
20665d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
20675d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2068fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sg);
20695d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.handle = handle;
20708b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
2071ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
20725d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
20735d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
20745d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2075d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Wait for VBLANK.
2077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2078d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param vbl pointer to a drmVBlank structure.
2080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2083d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2084d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
2085d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
208655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzerint drmWaitVBlank(int fd, drmVBlankPtr vbl)
208755acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer{
2088f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    struct timespec timeout, cur;
208955acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    int ret;
209055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2091f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
2092f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    if (ret < 0) {
20931eb2860b4bd0306dddc5b2f2dc7403aa65c5e476Daniel Kurtz	fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
2094f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes	goto out;
2095f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    }
2096f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    timeout.tv_sec++;
2097f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes
209855acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    do {
2099f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
2100c7d471b6ae936127311a816a8d15b4565746af48Michel Daenzer       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
2101ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes       if (ret && errno == EINTR) {
2102ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       clock_gettime(CLOCK_MONOTONIC, &cur);
2103ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       /* Timeout after 1s */
2104ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       if (cur.tv_sec > timeout.tv_sec + 1 ||
2105ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		   (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
2106ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		    timeout.tv_nsec)) {
2107ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       errno = EBUSY;
2108ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       ret = -1;
2109ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       break;
2110ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       }
2111f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       }
211255acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    } while (ret && errno == EINTR);
211355acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2114f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnesout:
211555acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    return ret;
211655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer}
211755acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2118b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmError(int err, const char *label)
2119b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    switch (err) {
2121ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_DEVICE:
2122ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no device\n", label);
2123ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2124ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_ACCESS:
2125ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no access\n", label);
2126ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2127ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NOT_ROOT:
2128ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: not root\n", label);
2129ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2130ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_INVALID:
2131ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: invalid args\n", label);
2132ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2133b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    default:
2134ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (err < 0)
2135ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    err = -err;
2136b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
2137b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	break;
2138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2139b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2140b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 1;
2141b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2142b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2143d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2144d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Install IRQ handler.
2145d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2146d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2147d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param irq IRQ number.
2148d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2149d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2150d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2151d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2152d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2153d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2154d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2155b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlInstHandler(int fd, int irq)
2156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2159fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctl);
2160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_INST_HANDLER;
2161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = irq;
21628b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2163ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2167d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2168d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2169d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Uninstall IRQ handler.
2170d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2171d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2172d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2173d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2174d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2175d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2176d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2177d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2178d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlUninstHandler(int fd)
2180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2182b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2183fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctl);
2184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_UNINST_HANDLER;
2185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = 0;
21868b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2187ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFinish(int fd, int context, drmLockFlags flags)
2192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
2194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2195fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
2196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
2197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
2198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
2199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
2200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
2201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
22038b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2204ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2207b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2208d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2209d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get IRQ from bus ID.
2210d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2211d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2212d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busnum bus number.
2213d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param devnum device number.
2214d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param funcnum function number.
2215d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2216d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return IRQ number on success, or a negative value on failure.
2217d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2218d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2219d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2220d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_irq_busid structure.
2221d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2222b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2223b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2224b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_irq_busid_t p;
2225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2226fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(p);
2227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.busnum  = busnum;
2228b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.devnum  = devnum;
2229b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.funcnum = funcnum;
22308b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2231ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2232b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return p.irq;
2233b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2234b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
22358696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAddContextTag(int fd, drm_context_t context, void *tag)
2236b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2237b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2238b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2239b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashInsert(entry->tagTable, context, tag)) {
2240b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashDelete(entry->tagTable, context);
2241b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(entry->tagTable, context, tag);
2242b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2243b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2244b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2245b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
22468696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDelContextTag(int fd, drm_context_t context)
2247b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2249b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2250b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return drmHashDelete(entry->tagTable, context);
2251b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2252b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
22538696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlvoid *drmGetContextTag(int fd, drm_context_t context)
2254b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2255b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2256b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
2257360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
2258ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (drmHashLookup(entry->tagTable, context, &value))
2259ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
2260b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2261b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return value;
2262b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2263b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
226422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
226522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t handle)
226674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
226774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
226874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
2269fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
227074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
2271961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
227274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22738b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2274ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
227574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
227674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
227774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
227822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
227922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t *handle)
228074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
228174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
228274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
2283fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
228474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
228574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22868b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2287ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2288ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
2289961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
229074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
229174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
229274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
229374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22948696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
22958696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	      drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
229688dbee54ed400a3fd5594fab506518c171167805Rik Faith	      int *mtrr)
229788dbee54ed400a3fd5594fab506518c171167805Rik Faith{
229888dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_map_t map;
229988dbee54ed400a3fd5594fab506518c171167805Rik Faith
2300fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
230188dbee54ed400a3fd5594fab506518c171167805Rik Faith    map.offset = idx;
23028b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2303ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
230488dbee54ed400a3fd5594fab506518c171167805Rik Faith    *offset = map.offset;
230588dbee54ed400a3fd5594fab506518c171167805Rik Faith    *size   = map.size;
230688dbee54ed400a3fd5594fab506518c171167805Rik Faith    *type   = map.type;
230788dbee54ed400a3fd5594fab506518c171167805Rik Faith    *flags  = map.flags;
230888dbee54ed400a3fd5594fab506518c171167805Rik Faith    *handle = (unsigned long)map.handle;
230988dbee54ed400a3fd5594fab506518c171167805Rik Faith    *mtrr   = map.mtrr;
231088dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
231188dbee54ed400a3fd5594fab506518c171167805Rik Faith}
231288dbee54ed400a3fd5594fab506518c171167805Rik Faith
231388dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
231488dbee54ed400a3fd5594fab506518c171167805Rik Faith		 unsigned long *magic, unsigned long *iocs)
231588dbee54ed400a3fd5594fab506518c171167805Rik Faith{
231688dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_client_t client;
231788dbee54ed400a3fd5594fab506518c171167805Rik Faith
2318fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(client);
231988dbee54ed400a3fd5594fab506518c171167805Rik Faith    client.idx = idx;
23208b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2321ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
232288dbee54ed400a3fd5594fab506518c171167805Rik Faith    *auth      = client.auth;
232388dbee54ed400a3fd5594fab506518c171167805Rik Faith    *pid       = client.pid;
232488dbee54ed400a3fd5594fab506518c171167805Rik Faith    *uid       = client.uid;
232588dbee54ed400a3fd5594fab506518c171167805Rik Faith    *magic     = client.magic;
232688dbee54ed400a3fd5594fab506518c171167805Rik Faith    *iocs      = client.iocs;
232788dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
232888dbee54ed400a3fd5594fab506518c171167805Rik Faith}
232988dbee54ed400a3fd5594fab506518c171167805Rik Faith
233088dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetStats(int fd, drmStatsT *stats)
233188dbee54ed400a3fd5594fab506518c171167805Rik Faith{
233288dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_stats_t s;
2333de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Vesely    unsigned    i;
233488dbee54ed400a3fd5594fab506518c171167805Rik Faith
2335fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(s);
23368b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2337ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
233888dbee54ed400a3fd5594fab506518c171167805Rik Faith
233988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = 0;
234088dbee54ed400a3fd5594fab506518c171167805Rik Faith    memset(stats, 0, sizeof(*stats));
234188dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
234288dbee54ed400a3fd5594fab506518c171167805Rik Faith	return -1;
234388dbee54ed400a3fd5594fab506518c171167805Rik Faith
234488dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_VALUE                              \
234588dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
234688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%8.8s";      \
234788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 1;            \
234888dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
234988dbee54ed400a3fd5594fab506518c171167805Rik Faith
235088dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_COUNT                              \
235188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
235288dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
235388dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
235488dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "kgm";        \
235588dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1000;         \
235688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
235788dbee54ed400a3fd5594fab506518c171167805Rik Faith
235888dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_BYTE                               \
235988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
236088dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
236188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
236288dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "KGM";        \
236388dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1024;         \
236488dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
236588dbee54ed400a3fd5594fab506518c171167805Rik Faith
236688dbee54ed400a3fd5594fab506518c171167805Rik Faith
236788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = s.count;
236888dbee54ed400a3fd5594fab506518c171167805Rik Faith    for (i = 0; i < s.count; i++) {
236988dbee54ed400a3fd5594fab506518c171167805Rik Faith	stats->data[i].value = s.data[i].value;
237088dbee54ed400a3fd5594fab506518c171167805Rik Faith	switch (s.data[i].type) {
237188dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCK:
237288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Lock";
237388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
237488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
237588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
237688dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_OPENS:
237788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Opens";
237888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "O";
237988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
238088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
238188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
238288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_CLOSES:
238388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Closes";
238488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
238588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
238688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
238788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
238888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IOCTLS:
238988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Ioctls";
239088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ioc/s";
239188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
239288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
239388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCKS:
239488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Locks";
239588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lck/s";
239688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
239788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
239888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_UNLOCKS:
239988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Unlocks";
240088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Unl/s";
240188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
240288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
240388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IRQ:
240488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "IRQs";
240588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "IRQ/s";
240688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
240788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
240888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_PRIMARY:
240988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Primary Bytes";
241088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "PB/s";
241188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
241288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
241388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SECONDARY:
241488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Secondary Bytes";
241588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "SB/s";
241688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
241788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
241888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_DMA:
241988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "DMA";
242088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "DMA/s";
242188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
242288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
242388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SPECIAL:
242488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Special DMA";
242588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "dma/s";
242688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
242788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
242888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_MISSED:
242988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Miss";
243088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ms/s";
243188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
243288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
243388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_VALUE:
243488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Value";
243588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Value";
243688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
243788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
243888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_BYTE:
243988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Bytes";
244088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "B/s";
244188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
244288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
244388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_COUNT:
244488dbee54ed400a3fd5594fab506518c171167805Rik Faith	default:
244588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Count";
244688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Cnt/s";
244788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
244888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
244988dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
245088dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
245188dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
245288dbee54ed400a3fd5594fab506518c171167805Rik Faith}
245388dbee54ed400a3fd5594fab506518c171167805Rik Faith
2454d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
245506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Issue a set-version ioctl.
245606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
245706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param fd file descriptor.
245806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param drmCommandIndex command index
245906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param data source pointer of the data to be read and written.
246006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param size size of the data to be read and written.
246106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
246206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return zero on success, or a negative value on failure.
246306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
246406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
246506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * It issues a read-write ioctl given by
246606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
246706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
246822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmSetInterfaceVersion(int fd, drmSetVersion *version)
246906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
247006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    int retcode = 0;
247106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drm_set_version_t sv;
247206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
2473fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sv);
247406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_major = version->drm_di_major;
247506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_minor = version->drm_di_minor;
247606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_major = version->drm_dd_major;
247706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_minor = version->drm_dd_minor;
247806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
24798b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
248006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	retcode = -errno;
248106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
248206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
248306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_major = sv.drm_di_major;
248406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_minor = sv.drm_di_minor;
248506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_major = sv.drm_dd_major;
248606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_minor = sv.drm_dd_minor;
248706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
248806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return retcode;
248906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
249006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
249106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
2492d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific command.
2493d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2494d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2495d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2496d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2497d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2498d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2499d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2500d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a ioctl given by
2501d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2502d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
25033903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owenint drmCommandNone(int fd, unsigned long drmCommandIndex)
25043903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25053903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25063903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25073903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
25083903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2509fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    if (drmIoctl(fd, request, NULL)) {
25103903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25113903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
25123903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25133903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
25143903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2515d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2516d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2517d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read command.
2518d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2519d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2520d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2521d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data destination pointer of the data to be read.
2522d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read.
2523d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2524d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2525d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2526d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2527d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read ioctl given by
2528d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2529d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
253022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
253122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                   unsigned long size)
25323903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25333903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25343903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
253574ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
253674ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25373903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25388b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
25393903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25403903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
25413903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25423903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
25433903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2544d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2545d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2546d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific write command.
2547d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2548d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2549d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2550d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be written.
2551d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be written.
2552d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2553d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2554d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2555d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2556d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a write ioctl given by
2557d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2558d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
255922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
256022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                    unsigned long size)
25613903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25623903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25633903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
256474ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
256574ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25663903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
25683903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25693903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
25703903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25713903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
25723903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2573d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2574d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2575d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read-write command.
2576d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2579d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be read and written.
2580d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read and written.
2581d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2582d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2583d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2584d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2585d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read-write ioctl given by
2586d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2587d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
258822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
258922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                        unsigned long size)
25903903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25913903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25923903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
259374ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
259474ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25953903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data))
25973903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25983903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25993903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
2600166da9355d95affe427a6cff3525df60e80a99dfThomas Hellstrom
2601d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie#define DRM_MAX_FDS 16
2602d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic struct {
2603ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    char *BusID;
2604ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2605ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int refcount;
2606dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou    int type;
2607d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} connection[DRM_MAX_FDS];
2608d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2609d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic int nr_fds = 0;
2610d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2611d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlieint drmOpenOnce(void *unused,
2612d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		const char *BusID,
2613d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		int *newlyopened)
2614d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2615dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou    return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
2616dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou}
2617dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou
2618dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhouint drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
2619dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou{
2620ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2621ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2622d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2623ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++)
2624dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou	if ((strcmp(BusID, connection[i].BusID) == 0) &&
2625dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou	    (connection[i].type == type)) {
2626ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    connection[i].refcount++;
2627ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    *newlyopened = 0;
2628ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return connection[i].fd;
2629ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2630ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian
2631dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou    fd = drmOpenWithType(NULL, BusID, type);
2632ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd <= 0 || nr_fds == DRM_MAX_FDS)
2633ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
2634d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2635ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].BusID = strdup(BusID);
2636ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].fd = fd;
2637ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].refcount = 1;
2638dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou    connection[nr_fds].type = type;
2639ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    *newlyopened = 1;
2640d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2641ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (0)
2642ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "saved connection %d for %s %d\n",
2643ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		nr_fds, connection[nr_fds].BusID,
2644ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		strcmp(BusID, connection[nr_fds].BusID));
2645d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2646ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    nr_fds++;
2647d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2648ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return fd;
2649d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2650d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2651d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlievoid drmCloseOnce(int fd)
2652d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2653ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2654d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2655ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++) {
2656ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (fd == connection[i].fd) {
2657ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (--connection[i].refcount == 0) {
2658ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmClose(connection[i].fd);
2659ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		free(connection[i].BusID);
2660d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2661ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		if (i < --nr_fds)
2662ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		    connection[i] = connection[nr_fds];
2663d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2664ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		return;
2665ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    }
2666ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2667ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    }
2668d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2669731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2670731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmSetMaster(int fd)
2671731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2672fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
2673731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
2674731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2675731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmDropMaster(int fd)
2676731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2677fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
2678731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
267922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
268022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsbergchar *drmGetDeviceNameFromFd(int fd)
268122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg{
268222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	char name[128];
268322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	struct stat sbuf;
268422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	dev_t d;
268522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	int i;
268622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
268722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	/* The whole drmOpen thing is a fiasco and we need to find a way
268822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * back to just using open(2).  For now, however, lets just make
268922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * things worse with even more ad hoc directory walking code to
269022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * discover the device file name. */
269122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
269222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	fstat(fd, &sbuf);
269322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	d = sbuf.st_rdev;
269422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
269522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	for (i = 0; i < DRM_MAX_MINOR; i++) {
269622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
269722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
269822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg			break;
269922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	}
270022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	if (i == DRM_MAX_MINOR)
270122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		return NULL;
270222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
27030a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson	return strdup(name);
270422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg}
2705cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
27061f73578df32f895a678a41758f6c563f49484347Frank Binnsint drmGetNodeTypeFromFd(int fd)
27071f73578df32f895a678a41758f6c563f49484347Frank Binns{
27081f73578df32f895a678a41758f6c563f49484347Frank Binns	struct stat sbuf;
27091f73578df32f895a678a41758f6c563f49484347Frank Binns	int maj, min, type;
27101f73578df32f895a678a41758f6c563f49484347Frank Binns
27111f73578df32f895a678a41758f6c563f49484347Frank Binns	if (fstat(fd, &sbuf))
27121f73578df32f895a678a41758f6c563f49484347Frank Binns		return -1;
27131f73578df32f895a678a41758f6c563f49484347Frank Binns
27141f73578df32f895a678a41758f6c563f49484347Frank Binns	maj = major(sbuf.st_rdev);
27151f73578df32f895a678a41758f6c563f49484347Frank Binns	min = minor(sbuf.st_rdev);
27161f73578df32f895a678a41758f6c563f49484347Frank Binns
27171f73578df32f895a678a41758f6c563f49484347Frank Binns	if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
27181f73578df32f895a678a41758f6c563f49484347Frank Binns		errno = EINVAL;
27191f73578df32f895a678a41758f6c563f49484347Frank Binns		return -1;
27201f73578df32f895a678a41758f6c563f49484347Frank Binns	}
27211f73578df32f895a678a41758f6c563f49484347Frank Binns
27221f73578df32f895a678a41758f6c563f49484347Frank Binns	type = drmGetMinorType(min);
27231f73578df32f895a678a41758f6c563f49484347Frank Binns	if (type == -1)
27241f73578df32f895a678a41758f6c563f49484347Frank Binns		errno = ENODEV;
27251f73578df32f895a678a41758f6c563f49484347Frank Binns	return type;
27261f73578df32f895a678a41758f6c563f49484347Frank Binns}
27271f73578df32f895a678a41758f6c563f49484347Frank Binns
2728cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
2729cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2730cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2731cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2732cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2733cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.handle = handle;
2734cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = flags;
2735cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
2736cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2737cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2738cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2739cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*prime_fd = args.fd;
2740cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2741cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2742cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2743cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2744cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2745cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2746cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2747cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2748cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.fd = prime_fd;
2749cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = 0;
2750cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
2751cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2752cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2753cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2754cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*handle = args.handle;
2755cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2756cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2757cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
27580ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovstatic char *drmGetMinorNameForFD(int fd, int type)
27590ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{
27600ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#ifdef __linux__
27610ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	DIR *sysdir;
27620ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	struct dirent *pent, *ent;
27630ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	struct stat sbuf;
27640ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	const char *name = drmGetMinorName(type);
27650ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	int len;
27660ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	char dev_name[64], buf[64];
27670ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	long name_max;
27680ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	int maj, min;
27690ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27700ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (!name)
27710ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		return NULL;
27720ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27730ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	len = strlen(name);
27740ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27750ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (fstat(fd, &sbuf))
27760ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		return NULL;
27770ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27780ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	maj = major(sbuf.st_rdev);
27790ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	min = minor(sbuf.st_rdev);
27800ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27810ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
27820ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		return NULL;
27830ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27840ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
27850ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27860ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	sysdir = opendir(buf);
27870ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (!sysdir)
27880ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		return NULL;
27890ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27900ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
27910ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (name_max == -1)
27920ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		goto out_close_dir;
27930ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27940ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
27950ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	if (pent == NULL)
27960ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		 goto out_close_dir;
27970ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
27980ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
27990ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		if (strncmp(ent->d_name, name, len) == 0) {
28000ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov			free(pent);
28010ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov			closedir(sysdir);
28020ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
28030ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov			snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
28040ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov				 ent->d_name);
28050ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov			return strdup(dev_name);
28060ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov		}
28070ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	}
28080ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
28090ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	free(pent);
28100ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
28110ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovout_close_dir:
28120ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	closedir(sysdir);
28130ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#endif
28140ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	return NULL;
28150ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov}
28160ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
28170ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovchar *drmGetPrimaryDeviceNameFromFd(int fd)
28180ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{
28190ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
28200ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov}
28210ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov
28220ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovchar *drmGetRenderDeviceNameFromFd(int fd)
28230ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{
28240ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov	return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
28250ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov}
2826