xf86drm.c revision ddbbdb13d80ea7f60e6f71356a444995b905366b
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>
4379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <fcntl.h>
4479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <errno.h>
4579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <signal.h>
46f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes#include <time.h>
4779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/types.h>
4879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/stat.h>
4979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#define stat_t struct stat
5079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/ioctl.h>
5179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/mman.h>
5279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/time.h>
5379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdarg.h>
54b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
55b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* Not all systems have MAP_FAILED defined */
56b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifndef MAP_FAILED
57b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#define MAP_FAILED ((void *)-1)
58b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
59b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
60b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "xf86drm.h"
61b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
6227c3785d3f12743a9e160238a4d00353060ec2f2Hasso Tepper#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
63cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 145
64cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#endif
65cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt
66cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifdef __NetBSD__
67cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 34
6888dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
6988dbee54ed400a3fd5594fab506518c171167805Rik Faith
70b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane# ifdef __OpenBSD__
71b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#  define DRM_MAJOR 81
72b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane# endif
73b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane
74cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifndef DRM_MAJOR
75cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 226		/* Linux */
7688dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
7788dbee54ed400a3fd5594fab506518c171167805Rik Faith
7822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson/*
7922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This definition needs to be changed on some systems if dev_t is a structure.
8022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * If there is a header file we can get it from, there would be best.
8122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson */
82569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#ifndef makedev
83569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#define makedev(x,y)    ((dev_t)(((x) << 8) | (y)))
84569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul#endif
85569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
8656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes#define DRM_MSG_VERBOSITY 3
8756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
88731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define DRM_NODE_CONTROL 0
89731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes#define DRM_NODE_RENDER 1
90731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
9179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic drmServerInfoPtr drm_server_info;
9279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
9379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid drmSetServerInfo(drmServerInfoPtr info)
9479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
95ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_server_info = info;
9679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
9779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
98d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
99d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Output a message to stderr.
100d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
101d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param format printf() like format string.
102d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around vfprintf().
105d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
10679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
10779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic int drmDebugPrint(const char *format, va_list ap)
10879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
109ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return vfprintf(stderr, format, ap);
11079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
11179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
11279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
11379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
114c4857429c716f35e1fa054d1990cae28055d96d7Eric Anholtvoid
11556bd9c207770d41a497f3e8237a1099dd9d4cd91David DawesdrmMsg(const char *format, ...)
11656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes{
11756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    va_list	ap;
11856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    const char *env;
11979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info)
12056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    {
12156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_start(ap, format);
12279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
12379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_server_info->debug_print(format,ap);
12479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	} else {
12579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_debug_print(format, ap);
12679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
12756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_end(ap);
12856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
12956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes}
13056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
13179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid
13279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave AirliedrmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
13379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
134ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_debug_print = debug_msg_ptr;
13579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
13679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
137b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void *drmHashTable = NULL; /* Context switch callbacks */
138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
13979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid *drmGetHashTable(void)
14079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
141ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return drmHashTable;
14279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
143b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
144b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmMalloc(int size)
145b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void *pt;
147ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((pt = malloc(size)))
148ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	memset(pt, 0, size);
149b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return pt;
150b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
151b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFree(void *pt)
153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
154ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (pt)
155ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	free(pt);
156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1588b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard/**
1598b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard * Call ioctl, restarting if it is interupted
1608b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard */
161731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint
16241b83a99583486ad4f8760a6537d34783769bfc3Coleman KanedrmIoctl(int fd, unsigned long request, void *arg)
1638b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard{
1648b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    int	ret;
1658b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard
1668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    do {
1678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	ret = ioctl(fd, request, arg);
1688b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1698b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return ret;
1708b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard}
171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic unsigned long drmGetKeyFromFd(int fd)
173b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
174fcc21069b7019a4a93e1ceacc175ccd682353861David Dawes    stat_t     st;
175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    st.st_rdev = 0;
177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    fstat(fd, &st);
178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return st.st_rdev;
179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
18179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave AirliedrmHashEntry *drmGetEntry(int fd)
182b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
183b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key = drmGetKeyFromFd(fd);
184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry;
186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
187ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!drmHashTable)
188ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drmHashTable = drmHashCreate();
189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashLookup(drmHashTable, key, &value)) {
191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry           = drmMalloc(sizeof(*entry));
192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->fd       = fd;
193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->f        = NULL;
194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->tagTable = drmHashCreate();
195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(drmHashTable, key, entry);
196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    } else {
197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry = value;
198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return entry;
200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
202d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
20306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Compare two busid strings
20406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
20506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param first
20606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param second
20706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
20806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return 1 if matched.
20906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
21106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * This function compares two bus ID strings.  It understands the older
21206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
21306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * domain, b is bus, d is device, f is function.
21406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
215b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidtstatic int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
21606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
21706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* First, check if the IDs are exactly the same */
21806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strcasecmp(id1, id2) == 0)
21906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	return 1;
22006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
22106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Try to match old/new-style PCI bus IDs. */
22206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strncasecmp(id1, "pci", 3) == 0) {
22390ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o1, b1, d1, f1;
22490ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o2, b2, d2, f2;
22506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	int ret;
22606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
22790ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
22806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
22906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o1 = 0;
23090ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
23106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
23206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
23306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
23406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
23590ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
23606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
23706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o2 = 0;
23890ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
23906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
24006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
24106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
24206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
243b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	/* If domains aren't properly supported by the kernel interface,
244b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * just ignore them, which sucks less than picking a totally random
245b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * card with "open by name"
246b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 */
247b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	if (!pci_domain_ok)
248b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		o1 = o2 = 0;
249b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt
25006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
25106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 0;
25206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	else
25306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 1;
25406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
25506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return 0;
25606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
25706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
25806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
259c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Handles error checking for chown call.
260c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
261c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param path to file.
262c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new owner.
263c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new group.
264c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
265c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \return zero if success or -1 if failure.
266c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
267c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \internal
268c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Checks for failure. If failure was caused by signal call chown again.
269c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * If any other failure happened then it will output error mesage using
270c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * drmMsg() call.
271c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen */
272c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminenstatic int chown_check_return(const char *path, uid_t owner, gid_t group)
273c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen{
274c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	int rv;
275c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
276c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	do {
277c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		rv = chown(path, owner, group);
278c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	} while (rv != 0 && errno == EINTR);
279c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
280c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	if (rv == 0)
281c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		return 0;
282c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
283c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	drmMsg("Failed to change owner or group for file %s! %d: %s\n",
284c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen			path, errno, strerror(errno));
285c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	return -1;
286c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen}
287c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
288c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen/**
289d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device, creating it if necessary.
290d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
291d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param dev major and minor numbers of the device.
292d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor minor number of the device.
293d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
294d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
295d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
296d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
297d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assembles the device name from \p minor and opens it, creating the device
298d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * special file node with the major and minor numbers specified by \p dev and
299d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parent directory if necessary and was called by root.
300d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
301731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic int drmOpenDevice(long dev, int minor, int type)
302b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
3039c775d0b2f303389c24aea5e8abc1473f0cf93e8David Dawes    stat_t          st;
30488dbee54ed400a3fd5594fab506518c171167805Rik Faith    char            buf[64];
30588dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             fd;
30679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    mode_t          devmode = DRM_DEV_MODE, serv_mode;
30788dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             isroot  = !geteuid();
30888dbee54ed400a3fd5594fab506518c171167805Rik Faith    uid_t           user    = DRM_DEV_UID;
30979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    gid_t           group   = DRM_DEV_GID, serv_group;
31079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
311731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
31206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenDevice: node name is %s\n", buf);
31356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
31479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
315ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drm_server_info->get_perms(&serv_group, &serv_mode);
316ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
317ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
318ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
31979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
320569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
3219101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#if !defined(UDEV)
32288dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (stat(DRM_DIR_NAME, &st)) {
323ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
324ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
325b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
326c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
327b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
328569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
329b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
33006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node exists and create it if necessary. */
331d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (stat(buf, &st)) {
332ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
333ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
33488dbee54ed400a3fd5594fab506518c171167805Rik Faith	remove(buf);
33588dbee54ed400a3fd5594fab506518c171167805Rik Faith	mknod(buf, S_IFCHR | devmode, dev);
336b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
33779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
33879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
339c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(buf, user, group);
340ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	chmod(buf, devmode);
34179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
3429101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#else
3439101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    /* if we modprobed then wait for udev */
3449101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    {
3459101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	int udev_count = 0;
3469101a0205c897fea28e6a3d875111a83ad7f7732Dave Airliewait_for_udev:
3479101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie        if (stat(DRM_DIR_NAME, &st)) {
3489101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3499101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3509101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3519101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3529101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3539101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3549101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	}
3559101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3569101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	if (stat(buf, &st)) {
3579101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3589101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3599101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3609101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3619101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3629101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3639101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	}
3649101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    }
3659101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#endif
36688dbee54ed400a3fd5594fab506518c171167805Rik Faith
36756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    fd = open(buf, O_RDWR, 0);
36856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
36956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		fd, fd < 0 ? strerror(errno) : "OK");
370ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
371ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
372d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
37339e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#if !defined(UDEV)
37406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node is not what we expect it to be, and recreate it
37506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     * and try again if so.
37606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     */
377d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (st.st_rdev != dev) {
378ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
379ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
380d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	remove(buf);
381d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	mknod(buf, S_IFCHR | devmode, dev);
38279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
383c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	    chown_check_return(buf, user, group);
384ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    chmod(buf, devmode);
38579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
386d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    }
387d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    fd = open(buf, O_RDWR, 0);
388d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
389d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt		fd, fd < 0 ? strerror(errno) : "OK");
390ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
391ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
392d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
39356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: Open failed\n");
39488dbee54ed400a3fd5594fab506518c171167805Rik Faith    remove(buf);
39539e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#endif
39688dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
397b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
398b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
399d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
400d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
401d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device
402d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
403d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor device minor number.
404d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param create allow to create the device if set.
405d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
406d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
407d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
408d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
409d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
410d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * name from \p minor and opens it.
411d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
412731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic int drmOpenMinor(int minor, int create, int type)
41388dbee54ed400a3fd5594fab506518c171167805Rik Faith{
41488dbee54ed400a3fd5594fab506518c171167805Rik Faith    int  fd;
41588dbee54ed400a3fd5594fab506518c171167805Rik Faith    char buf[64];
416db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
417ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (create)
418731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
41988dbee54ed400a3fd5594fab506518c171167805Rik Faith
420731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
421ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((fd = open(buf, O_RDWR, 0)) >= 0)
422ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
42388dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
42488dbee54ed400a3fd5594fab506518c171167805Rik Faith}
42588dbee54ed400a3fd5594fab506518c171167805Rik Faith
426569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
427d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
428d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine whether the DRM kernel driver has been loaded.
429d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
430d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return 1 if the DRM driver is loaded, 0 otherwise.
431d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
432d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
433d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine the presence of the kernel driver by attempting to open the 0
434d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * minor and get version information.  For backward compatibility with older
435d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Linux implementations, /proc/dri is also checked.
436d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
437569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulint drmAvailable(void)
438569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul{
439569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    drmVersionPtr version;
440569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           retval = 0;
441569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           fd;
442360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
443731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
444b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#ifdef __linux__
44522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	/* Try proc for backward Linux compatibility */
446ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!access("/proc/dri/0", R_OK))
447ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return 1;
448b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#endif
44988dbee54ed400a3fd5594fab506518c171167805Rik Faith	return 0;
450569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
45188dbee54ed400a3fd5594fab506518c171167805Rik Faith
45288dbee54ed400a3fd5594fab506518c171167805Rik Faith    if ((version = drmGetVersion(fd))) {
45388dbee54ed400a3fd5594fab506518c171167805Rik Faith	retval = 1;
45488dbee54ed400a3fd5594fab506518c171167805Rik Faith	drmFreeVersion(version);
45588dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
45688dbee54ed400a3fd5594fab506518c171167805Rik Faith    close(fd);
457569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
458569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    return retval;
459569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul}
460569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
461d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
462d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
463d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by bus ID.
464d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
465d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID.
466d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
467d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
468d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
469d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
470d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
471d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * comparing the device bus ID with the one supplied.
472d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
473d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor() and drmGetBusid().
474d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
475e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Straussstatic int drmOpenByBusid(const char *busid)
476e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss{
477b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt    int        i, pci_domain_ok = 1;
47888dbee54ed400a3fd5594fab506518c171167805Rik Faith    int        fd;
47988dbee54ed400a3fd5594fab506518c171167805Rik Faith    const char *buf;
48006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmSetVersion sv;
48106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
48206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
483db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie    for (i = 0; i < DRM_MAX_MINOR; i++) {
484731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
48556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
48656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	if (fd >= 0) {
487b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    /* We need to try for 1.4 first for proper PCI domain support
488b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     * and if that fails, we know the kernel is busted
489b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     */
49006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_di_major = 1;
491b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    sv.drm_di_minor = 4;
49206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_dd_major = -1;	/* Don't care */
49326462b9aa47179e724e78f0b3b1c86fd07f61d8dEric Anholt	    sv.drm_dd_minor = -1;	/* Don't care */
494b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (drmSetInterfaceVersion(fd, &sv)) {
495b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#ifndef __alpha__
496b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		pci_domain_ok = 0;
497b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#endif
498b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_major = 1;
499b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_minor = 1;
500b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_major = -1;       /* Don't care */
501b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_minor = -1;       /* Don't care */
502b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n",fd);
503b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		drmSetInterfaceVersion(fd, &sv);
504b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    }
505e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    buf = drmGetBusid(fd);
50656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
507b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
50888dbee54ed400a3fd5594fab506518c171167805Rik Faith		drmFreeBusid(buf);
50988dbee54ed400a3fd5594fab506518c171167805Rik Faith		return fd;
510e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    }
511ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (buf)
512ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmFreeBusid(buf);
513e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    close(fd);
514e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	}
515e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    }
516e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    return -1;
517e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss}
518e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss
519d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
520d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
521d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by name.
522d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
523d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name.
524d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
525d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
526d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
527d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
528d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function opens the first minor number that matches the driver name and
529d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * isn't already in use.  If it's in use it then it will already have a bus ID
530d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * assigned.
531d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
532d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
533d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
534b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussstatic int drmOpenByName(const char *name)
535b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss{
53688dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           i;
53788dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           fd;
53888dbee54ed400a3fd5594fab506518c171167805Rik Faith    drmVersionPtr version;
53956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    char *        id;
54088dbee54ed400a3fd5594fab506518c171167805Rik Faith
541db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie    if (!drmAvailable()) {
542db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	if (!drm_server_info) {
543db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	    return -1;
544db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	}
545db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	else {
546db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	    /* try to load the kernel module now */
547db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	    if (!drm_server_info->load_module(name)) {
548db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie		drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
549db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie		return -1;
550db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	    }
551db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie	}
552db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie    }
553db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
55456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    /*
55556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * Open the first minor number that matches the driver name and isn't
55656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * already in use.  If it's in use it will have a busid assigned already.
55756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     */
558db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie    for (i = 0; i < DRM_MAX_MINOR; i++) {
559731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
56088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    if ((version = drmGetVersion(fd))) {
56188dbee54ed400a3fd5594fab506518c171167805Rik Faith		if (!strcmp(version->name, name)) {
56288dbee54ed400a3fd5594fab506518c171167805Rik Faith		    drmFreeVersion(version);
56356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    id = drmGetBusid(fd);
56456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
56556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    if (!id || !*id) {
56622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			if (id)
56756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			    drmFreeBusid(id);
56856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			return fd;
56956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    } else {
57056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			drmFreeBusid(id);
57156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    }
57256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		} else {
57356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmFreeVersion(version);
57488dbee54ed400a3fd5594fab506518c171167805Rik Faith		}
57588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    }
57656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    close(fd);
57788dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
578b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
579b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
58088dbee54ed400a3fd5594fab506518c171167805Rik Faith#ifdef __linux__
58122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* Backward-compatibility /proc support */
582b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    for (i = 0; i < 8; i++) {
58388dbee54ed400a3fd5594fab506518c171167805Rik Faith	char proc_name[64], buf[512];
58488dbee54ed400a3fd5594fab506518c171167805Rik Faith	char *driver, *pt, *devstring;
58588dbee54ed400a3fd5594fab506518c171167805Rik Faith	int  retcode;
58688dbee54ed400a3fd5594fab506518c171167805Rik Faith
5870371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(proc_name, "/proc/dri/%d/name", i);
588b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if ((fd = open(proc_name, 0, 0)) >= 0) {
589b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    retcode = read(fd, buf, sizeof(buf)-1);
590b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    close(fd);
591b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    if (retcode) {
592b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		buf[retcode-1] = '\0';
593b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		for (driver = pt = buf; *pt && *pt != ' '; ++pt)
594b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    ;
59522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson		if (*pt) { /* Device is next */
596b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    *pt = '\0';
597b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    if (!strcmp(driver, name)) { /* Match */
598b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
599b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			    ;
600b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			if (*pt) { /* Found busid */
60188dbee54ed400a3fd5594fab506518c171167805Rik Faith			    return drmOpenByBusid(++pt);
60222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			} else { /* No busid */
603731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes			    return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
604b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			}
605b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    }
606b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		}
607b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    }
608569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
609b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
61088dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
61188dbee54ed400a3fd5594fab506518c171167805Rik Faith
612b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return -1;
613b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss}
614b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
615b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
616d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
617d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device.
618d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
619d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Looks up the specified name and bus ID, and opens the device found.  The
620d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * entry in /dev/dri is created if necessary and if called by root.
621d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
622d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name. Not referenced if bus ID is supplied.
623d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID. Zero if not known.
624d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
625d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
626d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
627d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
628d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
629d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * otherwise.
630d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
631b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmOpen(const char *name, const char *busid)
632b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
63379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (!drmAvailable() && name != NULL && drm_server_info) {
63406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	/* try to load the kernel */
63579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (!drm_server_info->load_module(name)) {
636ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
63706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return -1;
63806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
63906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
64006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
64106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (busid) {
642ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	int fd = drmOpenByBusid(busid);
64306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (fd >= 0)
64406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return fd;
64506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
64622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
64706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (name)
64806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	return drmOpenByName(name);
64922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
65006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return -1;
651b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
652b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
653731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmOpenControl(int minor)
654731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
655731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
656731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
657d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
658d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
659d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the version information returned by drmGetVersion().
660d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
661d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
662d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
663d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
664d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It frees the memory pointed by \p %v as well as all the non-null strings
665d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * pointers in it.
666d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
667b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeVersion(drmVersionPtr v)
668b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
669ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
670ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
6719d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
6729d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
6739d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
674b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
675b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
676b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
677d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
678d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
679d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the non-public version information returned by the kernel.
680d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
681d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
682d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
683d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
684d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
685d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the non-null strings pointers in it.
686d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
687b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void drmFreeKernelVersion(drm_version_t *v)
688b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
689ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
690ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
6919d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
6929d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
6939d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
694b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
695b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
696b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
697d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
698d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
699d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Copy version information.
700d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param d destination pointer.
702d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param s source pointer.
703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
704d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
705d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to translate the information returned by the ioctl
706d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * interface in a private structure into the public structure counterpart.
707d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
708569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulstatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
709b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
710b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_major      = s->version_major;
711b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_minor      = s->version_minor;
712b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_patchlevel = s->version_patchlevel;
713b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->name_len           = s->name_len;
7140a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->name               = strdup(s->name);
715b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->date_len           = s->date_len;
7160a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->date               = strdup(s->date);
717b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->desc_len           = s->desc_len;
7180a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->desc               = strdup(s->desc);
719b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
720b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
721b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
722d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
723d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Query the driver version information.
724d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
725d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
726d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
727d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return pointer to a drmVersion structure which should be freed with
728d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * drmFreeVersion().
729d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
730d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note Similar information is available via /proc/dri.
731d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
732d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
733d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
734d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * first with zeros to get the string lengths, and then the actually strings.
735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It also null-terminates them since they might not be already.
736d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
737b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmVersionPtr drmGetVersion(int fd)
738b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
739b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmVersionPtr retval;
740b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_version_t *version = drmMalloc(sizeof(*version));
741b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
742b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->name_len    = 0;
743b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->name        = NULL;
744b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->date_len    = 0;
745b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->date        = NULL;
746b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->desc_len    = 0;
747b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    version->desc        = NULL;
748360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
7498b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
750b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
751b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
752b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
753b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
754b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len)
755b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->name    = drmMalloc(version->name_len + 1);
756b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len)
757b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->date    = drmMalloc(version->date_len + 1);
758b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len)
759b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->desc    = drmMalloc(version->desc_len + 1);
760360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
7618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
762b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane	drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
763b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
764b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
765b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
766b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
76722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* The results might not be null-terminated strings, so terminate them. */
768b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len) version->name[version->name_len] = '\0';
769b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len) version->date[version->date_len] = '\0';
770b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len) version->desc[version->desc_len] = '\0';
771b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
772b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    retval = drmMalloc(sizeof(*retval));
773b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmCopyVersion(retval, version);
774b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFreeKernelVersion(version);
775b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
776b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
777b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
7783903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
779d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
780d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get version information for the DRM user space library.
781d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
782d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This version number is driver independent.
783d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
784d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
785d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
786d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return version information.
787d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
788d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function allocates and fills a drm_version structure with a hard coded
790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * version number.
791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
7923903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens OwendrmVersionPtr drmGetLibVersion(int fd)
7933903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
7943903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    drm_version_t *version = drmMalloc(sizeof(*version));
7953903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
7963903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    /* Version history:
79779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
7983903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.0.x = original DRM interface with no drmGetLibVersion
7993903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    entry point and many drm<Device> extensions
8003903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.1.x = added drmCommand entry points for device extensions
8013903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    added drmGetLibVersion to identify libdrm.a version
80206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *   revision 1.2.x = added drmSetInterfaceVersion
80306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *                    modified drmOpen to handle both busid and name
80479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   revision 1.3.x = added server + memory manager
8053903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     */
80679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_major      = 1;
80779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_minor      = 3;
8083903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    version->version_patchlevel = 0;
8093903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8103903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return (drmVersionPtr)version;
8113903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
8123903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8135c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggsint drmGetCap(int fd, uint64_t capability, uint64_t *value)
8145c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs{
8155c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	struct drm_get_cap cap = { capability, 0 };
8165c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	int ret;
8175c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
8185c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
8195c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	if (ret)
8205c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs		return ret;
8215c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
8225c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	*value = cap.value;
8233b04c73650b5e9bbcb602fdb8cea0b16ad82d0c0Dave Airlie	return 0;
8245c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs}
825d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
826ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiauint drmSetClientCap(int fd, uint64_t capability, uint64_t value)
827ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau{
828ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau	struct drm_set_client_cap cap  = { capability, value };
829ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
830ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau	return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
831ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau}
832ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
833d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
834d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the bus ID information.
835d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
836d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID information string as given by drmGetBusid().
837d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
838d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
839d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is just frees the memory pointed by \p busid.
840d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
841b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussvoid drmFreeBusid(const char *busid)
842b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
843b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drmFree((void *)busid);
844b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
845b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
846d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
847d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
848d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get the bus ID of the device.
849d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
850d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
852d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return bus ID string.
853d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
855d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
856d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * get the string length and data, passing the arguments in a drm_unique
857d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * structure.
858d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
859b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strausschar *drmGetBusid(int fd)
860b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
861b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
862b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
863b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = 0;
864b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = NULL;
865b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
8668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
867ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
868b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique = drmMalloc(u.unique_len + 1);
8698b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
870ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
871b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique[u.unique_len] = '\0';
87206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
873b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return u.unique;
874b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
875b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
876d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
877d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
878d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the bus ID of the device.
879d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
880d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
881d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID string.
882d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
883d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, negative on failure.
884d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
885d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
886d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
887d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_unique structure.
888d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
889b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmSetBusid(int fd, const char *busid)
890b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
891b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
892b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
893b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = (char *)busid;
894b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = strlen(busid);
895b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
8968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
89756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	return -errno;
89856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
899b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
900b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
901b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9028696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMagic(int fd, drm_magic_t * magic)
903b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
904b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
905b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
906b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = 0;
9078b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
908ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
909b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = auth.magic;
910b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
911b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
912b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9138696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAuthMagic(int fd, drm_magic_t magic)
914b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
915b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
916b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
917b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    auth.magic = magic;
9188b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
919ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
920b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
921b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
922b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
923d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
924d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Specifies a range of memory that is available for mapping by a
925d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * non-root process.
926d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
927d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
928d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset usually the physical address. The actual meaning depends of
929d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the \p type parameter. See below.
930d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size of the memory in bytes.
931d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of the memory to be mapped.
932d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags combination of several flags to modify the function actions.
933d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle will be set to a value that may be used as the offset
934d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parameter for mmap().
935d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
936d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success or a negative value on error.
937d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
938d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the frame buffer
939d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the frame buffer
940d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the frame buffer,
941d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the frame buffer in bytes, and
942d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_FRAME_BUFFER.
943d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
944d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
945d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached. If MTRR support is available in the
946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel, the frame buffer area will be set to write combining.
947d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
948d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the MMIO register area
949d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the MMIO register area,
950d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the register area,
951d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the register area bytes, and
952d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_REGISTERS.
953d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
954d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached.
955d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
956d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the SAREA
957d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the SAREA,
958d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be ignored and should be set to zero,
959d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the desired size of the SAREA in bytes,
960d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_SHM.
961d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
962d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
963d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * A shared memory area of the requested size will be created and locked in
964d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel memory. This area may be mapped into client-space by using the handle
965d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returned.
966d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
967d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
968d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
969d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
970d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
971d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_map structure.
972d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
97322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
97422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	      drmMapFlags flags, drm_handle_t *handle)
975b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
976b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_map_t map;
977b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
978b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.offset  = offset;
979b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.size    = size;
980b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.handle  = 0;
981b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.type    = type;
982b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.flags   = flags;
9838b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
984ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
985ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
986961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
987b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
988b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
989b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9908696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmRmMap(int fd, drm_handle_t handle)
99174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
99274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_map_t map;
99374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
994961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
99574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
9968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
997ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
99874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
99974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
100074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
1001d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1002d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Make buffers available for DMA transfers.
1003d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1004d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1005d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers.
1006d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of each buffer.
1007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags buffer allocation flags.
1008d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param agp_offset offset in the AGP aperture
1009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return number of buffers allocated, negative on error.
1011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1013d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
1014d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1015d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drm_buf_desc.
1016d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1017ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1018ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann	       int agp_offset)
1019b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1020b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_desc_t request;
1021360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1022b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count     = count;
1023b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.size      = size;
1024b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.low_mark  = 0;
1025b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.high_mark = 0;
1026b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.flags     = flags;
1027ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    request.agp_start = agp_offset;
1028360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
10298b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1030ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1031b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return request.count;
1032b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1033b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1034b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMarkBufs(int fd, double low, double high)
1035b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1036b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1037b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1038b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1039b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.count = 0;
1040b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.list  = NULL;
1041b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
10428b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1043ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1044b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1045ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!info.count)
1046ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1047360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1048b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1049b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return -ENOMEM;
1050360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
10518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1052b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	int retval = -errno;
1053b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1054b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1055b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1056360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1057b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < info.count; i++) {
1058b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].low_mark  = low  * info.list[i].count;
1059b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].high_mark = high * info.list[i].count;
10608b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1061b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    int retval = -errno;
1062b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1063b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return retval;
1064b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1065b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1066b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(info.list);
1067360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1068b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1069b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1070b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1071d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1072d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free buffers.
1073d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1074d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1075d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers to free.
1076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param list list of buffers to be freed.
1077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1078d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note This function is primarily used for debugging.
1081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1083d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1084d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_buf_free structure.
1085d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1086b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFreeBufs(int fd, int count, int *list)
1087b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1088b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_free_t request;
1089b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1090b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count = count;
1091b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.list  = list;
10928b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1093ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1094b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1095b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1096b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1097d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1098d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1099d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Close the device.
1100d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1101d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1102d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function closes the file descriptor.
1105d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1106b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmClose(int fd)
1107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key    = drmGetKeyFromFd(fd);
1109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1110b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDestroy(entry->tagTable);
1112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->fd       = 0;
1113b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f        = NULL;
1114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->tagTable = NULL;
1115b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1116b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDelete(drmHashTable, key);
1117b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(entry);
1118b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1119b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return close(fd);
1120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1122d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1123d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1124d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map a region of memory.
1125d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1126d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1127d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle returned by drmAddMap().
1128d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmAddMap().
1129d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address will contain the user-space virtual address where the mapping
1130d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * begins.
1131d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1132d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1133d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1134d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1135d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper for mmap().
1136d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
113722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1139c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    static unsigned long pagesize_mask = 0;
1140c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1141ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd < 0)
1142ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1143c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1144c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    if (!pagesize_mask)
1145c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane	pagesize_mask = getpagesize() - 1;
1146c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1147c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    size = (size + pagesize_mask) & ~pagesize_mask;
1148c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1149b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1150ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (*address == MAP_FAILED)
1151ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1154b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1155d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1156d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1157d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap mappings obtained with drmMap().
1158d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1159d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address address as given by drmMap().
1160d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmMap().
1161d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1162d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1163d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1164d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
116522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This function is a wrapper for munmap().
1166d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1167b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmap(drmAddress address, drmSize size)
1168b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1169b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return munmap(address, size);
1170b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufInfoPtr drmGetBufInfo(int fd)
1173b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1174b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufInfoPtr  retval;
1176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.count = 0;
1179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    info.list  = NULL;
1180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
11818b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1182ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1183b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (info.count) {
1185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1187360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
11888b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
119222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = info.count;
1195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
1196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < info.count; i++) {
1197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].count     = info.list[i].count;
1198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].size      = info.list[i].size;
1199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].low_mark  = info.list[i].low_mark;
1200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].high_mark = info.list[i].high_mark;
1201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1203b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return NULL;
1206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1207b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1208d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1209d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map all DMA buffers into client-virtual space.
1210d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1211d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1212d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1213d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a pointer to a ::drmBufMap structure.
1214d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1215d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note The client may not use these buffers until obtaining buffer indices
1216d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with drmDMA().
1217d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1218d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1219d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1220d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * information about the buffers in a drm_buf_map structure into the
1221d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * client-visible data structures.
1222d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1223b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufMapPtr drmMapBufs(int fd)
1224b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_map_t bufs;
1226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufMapPtr  retval;
1227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1228360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1229b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    bufs.count = 0;
1230b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    bufs.list  = NULL;
12318696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    bufs.virtual = NULL;
12328b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1233ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1234b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1235ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!bufs.count)
1236ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
12378696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1238b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1239b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1240b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
12418b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1242b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(bufs.list);
1243b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1244b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
124522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1246b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1247b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = bufs.count;
1248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
1249b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < bufs.count; i++) {
1250b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].idx     = bufs.list[i].idx;
1251b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].total   = bufs.list[i].total;
1252b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].used    = 0;
1253b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].address = bufs.list[i].address;
1254b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
12558696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
12568696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	drmFree(bufs.list);
12578696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1258b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1259b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1260b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1261d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1262d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1263d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap buffers allocated with drmMapBufs().
1264d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1265d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or negative value on failure.
1266d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1267d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
12688696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * Calls munmap() for every buffer stored in \p bufs and frees the
12698696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * memory allocated by drmMapBufs().
1270d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1271b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmapBufs(drmBufMapPtr bufs)
1272b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1273b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int i;
1274360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1275b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < bufs->count; i++) {
1276b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	munmap(bufs->list[i].address, bufs->list[i].total);
1277b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
12788696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
12798696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs->list);
12808696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs);
12818696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1282b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1283b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1284b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1285d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1286360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes#define DRM_DMA_RETRY		16
1287360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1288d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1289d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Reserve DMA buffers.
1290d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1291d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1292d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param request
1293d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1294d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1295d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1296d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1297d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assemble the arguments into a drm_dma structure and keeps issuing the
1298d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1299d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1300b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDMA(int fd, drmDMAReqPtr request)
1301b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1302b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_dma_t dma;
1303360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    int ret, i = 0;
1304b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1305b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.context         = request->context;
1306b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_count      = request->send_count;
1307b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_indices    = request->send_list;
1308b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_sizes      = request->send_sizes;
1309b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.flags           = request->flags;
1310b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_count   = request->request_count;
1311b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_size    = request->request_size;
1312b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_indices = request->request_list;
1313b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_sizes   = request->request_sizes;
13148696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    dma.granted_count   = 0;
1315360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1316360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    do {
1317360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1318360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1319360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1320360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    if ( ret == 0 ) {
1321360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	request->granted_count = dma.granted_count;
1322360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return 0;
1323360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } else {
1324360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return -errno;
1325360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    }
1326b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1327b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1328d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1329d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1330d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Obtain heavyweight hardware lock.
1331d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1332d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1333d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1334d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags flags that determine the sate of the hardware when the function
1335d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returns.
1336d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1337d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return always zero.
1338d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1339d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1340d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function translates the arguments into a drm_lock structure and issue
1341d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1342d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
13438696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1344b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1345b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1346b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1347b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
1348b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
1349b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
1350b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
1351b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
1352b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
1353b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1355360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
13568b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1357b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	;
1358b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1359b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1360b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1361d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1362d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the hardware lock.
1363d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1364d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1365d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1366d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1367d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1368d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1369d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1370d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1371d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_lock structure.
1372d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
13738696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmUnlock(int fd, drm_context_t context)
1374b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1375b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1376b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1377b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
1378b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
13798b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1380b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1381b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
138222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksondrm_context_t *drmGetReservedContextList(int fd, int *count)
1383b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1384b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_res_t res;
1385b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t     *list;
13868696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drm_context_t * retval;
1387b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1388b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1389b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.count    = 0;
1390b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = NULL;
13918b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1392ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1393b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1394ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!res.count)
1395ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1396b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1397ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!(list   = drmMalloc(res.count * sizeof(*list))))
1398ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1399b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1400b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(list);
1401b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
1402b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1403b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1404b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = list;
14058b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1406ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1407b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1408ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < res.count; i++)
1409ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	retval[i] = list[i].handle;
1410b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(list);
1411b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1412b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *count = res.count;
1413b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
1414b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1415b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
141622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonvoid drmFreeReservedContextList(drm_context_t *pt)
1417b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1418b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(pt);
1419b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1420b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1421d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1422d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Create context.
1423d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1424d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by the X server during GLXContext initialization. This causes
1425d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * per-context kernel-level resources to be allocated.
1426d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1427d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1428d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle is set on success. To be used by the client when requesting DMA
1429d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * dispatch with drmDMA().
1430d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1431d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1432d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1433d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1434d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1435d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1436d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1437d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1438d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
143922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateContext(int fd, drm_context_t *handle)
1440b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1441b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1442b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1443b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.flags = 0;	/* Modified with functions below */
14448b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1445ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1446b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = ctx.handle;
1447b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1448b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1449b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
14508696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSwitchToContext(int fd, drm_context_t context)
1451b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1452b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1453b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1454b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
14558b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1456ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1457b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1458b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1459b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
14608696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1461b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1462b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1463b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
146422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /*
146522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * Context preserving means that no context switches are done between DMA
146622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * buffers from one context and the next.  This is suitable for use in the
146722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * X server (which promises to maintain hardware context), or in the
146822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * client-side library when buffers are swapped on behalf of two threads.
146922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     */
1470b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
1471b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.flags  = 0;
1472ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_PRESERVED)
1473ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_PRESERVED;
1474ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_2DONLY)
1475ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_2DONLY;
14768b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
1477ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1478b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1479b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1480b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
148122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextFlags(int fd, drm_context_t context,
148222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                       drm_context_tFlagsPtr flags)
1483b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1484b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1485b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1486b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
14878b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1488ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1489b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *flags = 0;
1490ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1491ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_PRESERVED;
1492ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_2DONLY)
1493ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_2DONLY;
1494b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1495b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1496360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1497d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1498d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Destroy context.
1499d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1500d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free any kernel-level resources allocated with drmCreateContext() associated
1501d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with the context.
1502d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1503d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1504d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle given by drmCreateContext().
1505d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1506d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1507d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1508d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1509d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1510d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1511d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1512d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1513d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
15148696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyContext(int fd, drm_context_t handle)
1515b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1516b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1517b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = handle;
15188b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1519ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1520b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1521b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1522b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
152322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateDrawable(int fd, drm_drawable_t *handle)
1524b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1525b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
15268b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1527ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1528b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = draw.handle;
1529b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1530b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1531b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15328696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyDrawable(int fd, drm_drawable_t handle)
1533b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1534b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
1535b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    draw.handle = handle;
15368b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1537ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1538b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1539b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1540b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15419810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzerint drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
15429810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   drm_drawable_info_type_t type, unsigned int num,
15439810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   void *data)
15449810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer{
15459810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    drm_update_draw_t update;
15469810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
15479810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.handle = handle;
15489810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.type = type;
15499810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.num = num;
15509810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.data = (unsigned long long)(unsigned long)data;
15519810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
15528b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1553ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
15549810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
15559810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    return 0;
15569810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer}
15579810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
1558d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1559d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Acquire the AGP device.
1560d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1561d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Must be called before any of the other AGP related calls.
1562d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1563d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1564d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1565d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1566d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1567d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1568d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1569d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1570ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAcquire(int fd)
1571ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
15728b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1573ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1574ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1575ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1576ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1579d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the AGP device.
1580d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1581d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1582d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1583d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1584d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1585d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1586d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1587d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1588ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpRelease(int fd)
1589ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
15908b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1591ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1592ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1593ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1594ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1595d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1596d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1597d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the AGP mode.
1598d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1599d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1600d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param mode AGP mode.
1601d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1602d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1603d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1604d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1605d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1606d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_mode structure.
1607d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1608ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpEnable(int fd, unsigned long mode)
1609ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1610ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_mode_t m;
1611ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1612ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    m.mode = mode;
16138b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1614ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1615ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1616ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1617ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1618d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1619d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1620d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Allocate a chunk of AGP memory.
1621d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1622d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1623d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size requested memory size in bytes. Will be rounded to page boundary.
1624d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of memory to allocate.
1625d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address if not zero, will be set to the physical address of the
1626d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * allocated memory.
1627d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle on success will be set to a handle of the allocated memory.
1628d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1629d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1630d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1631d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1632d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1633d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_agp_buffer structure.
1634d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1635ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAlloc(int fd, unsigned long size, unsigned long type,
16367ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlie		unsigned long *address, drm_handle_t *handle)
1637ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1638ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1639b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane
1640b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane    *handle = DRM_AGP_NO_HANDLE;
1641ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = size;
1642ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = 0;
1643ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.type   = type;
16448b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1645ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1646ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (address != 0UL)
1647ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*address = b.physical;
1648ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    *handle = b.handle;
1649ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1650ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1651ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1652d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1653d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1654d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free a chunk of AGP memory.
1655d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1656d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1657d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1658d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1659d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1660d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1661d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1662d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1663d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_buffer structure.
1664d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
16657ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpFree(int fd, drm_handle_t handle)
1666ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1667ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1668ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1669ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = 0;
1670ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
16718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1672ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1673ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1674ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1675ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1676d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1677d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1678d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Bind a chunk of AGP memory.
1679d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1680d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1681d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1682d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset offset in bytes. It will round to page boundary.
1683d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1684d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1685d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1686d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1687d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1688d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_binding structure.
1689d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
16907ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1691ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1692ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1693ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1694ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
1695ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = offset;
16968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1697ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1698ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1699ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1700ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1702d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unbind a chunk of AGP memory.
1704d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1705d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1706d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1707d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1708d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1709d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1710d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1711d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1712d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the argument in a drm_agp_binding structure.
1713d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
17147ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpUnbind(int fd, drm_handle_t handle)
1715ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1716ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1717ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1718ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
1719ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = 0;
17208b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1721ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1722ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1723ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1724ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1725d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1726d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1727d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver major version number.
1728d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1729d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1730d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1731d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return major version number on success, or a negative value on failure..
1732d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1733d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1734d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1736d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1737ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMajor(int fd)
1738ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1739ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1740ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
17418b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1742ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1743ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_major;
1744ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1745ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1746d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1747d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1748d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver minor version number.
1749d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1750d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1751d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1752d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return minor version number on success, or a negative value on failure.
1753d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1754d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1755d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1756d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1757d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1758ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMinor(int fd)
1759ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1760ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1761ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
17628b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1763ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1764ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_minor;
1765ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1766ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1767d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1768d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP mode.
1770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1771d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1772d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1773d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return mode on success, or zero on failure.
1774d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1775d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1776d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1777d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1778d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1779ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpGetMode(int fd)
1780ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1781ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1782ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
17838b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1784ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1785ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.mode;
1786ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1787ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1788d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture base.
1791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1792d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1794d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture base on success, zero on failure.
1795d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1796d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1797d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1798d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1799d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1800ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpBase(int fd)
1801ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1802ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1803ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
18048b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1805ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1806ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_base;
1807ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1808ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1809d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1810d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1811d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture size.
1812d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1813d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1814d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1815d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture size on success, zero on failure.
1816d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1817d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1818d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1819d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1820d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1821ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpSize(int fd)
1822ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1823ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1824ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
18258b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1826ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1827ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_size;
1828ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1829ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1830d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1831d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1832d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get used AGP memory.
1833d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1834d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1835d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1836d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory used on success, or zero on failure.
1837d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1838d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1839d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1840d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1841d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1842ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryUsed(int fd)
1843ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1844ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1845ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
18468b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1847ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1848ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_used;
1849ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1850ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1852d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1853d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get available AGP memory.
1854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1855d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1856d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1857d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory available on success, or zero on failure.
1858d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1859d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1860d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1861d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1862d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1863ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryAvail(int fd)
1864ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1865ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1866ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
18678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1868ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1869ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_allowed;
1870ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1871ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1872d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1873d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1874d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware vendor ID.
1875d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1876d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1877d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1878d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return vendor ID on success, or zero on failure.
1879d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1880d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1881d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1882d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1883d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1884ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpVendorId(int fd)
1885ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1886ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1887ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
18888b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1889ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1890ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_vendor;
1891ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1892ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1893d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1894d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1895d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware device ID.
1896d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1897d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1898d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1899d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or zero on failure.
1900d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1901d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1902d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1903d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1904d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1905ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpDeviceId(int fd)
1906ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1907ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1908ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
19098b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1910ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1911ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_device;
1912ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1913ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
19147ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
19155d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
19165d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
19175d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
19185d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = 0;
19195d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.size   = size;
19205d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.handle = 0;
19218b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
1922ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
19235d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = sg.handle;
19245d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
19255d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
19265d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
19277ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherFree(int fd, drm_handle_t handle)
19285d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
19295d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
19305d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
19315d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.size   = 0;
19325d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.handle = handle;
19338b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
1934ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
19355d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
19365d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
19375d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
1938d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1939d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Wait for VBLANK.
1940d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1941d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1942d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param vbl pointer to a drmVBlank structure.
1943d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1944d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1945d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1947d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
1948d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
194955acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzerint drmWaitVBlank(int fd, drmVBlankPtr vbl)
195055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer{
1951f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    struct timespec timeout, cur;
195255acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    int ret;
195355acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
1954f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
1955f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    if (ret < 0) {
19561eb2860b4bd0306dddc5b2f2dc7403aa65c5e476Daniel Kurtz	fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
1957f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes	goto out;
1958f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    }
1959f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    timeout.tv_sec++;
1960f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes
196155acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    do {
1962f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
1963c7d471b6ae936127311a816a8d15b4565746af48Michel Daenzer       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
1964ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes       if (ret && errno == EINTR) {
1965ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       clock_gettime(CLOCK_MONOTONIC, &cur);
1966ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       /* Timeout after 1s */
1967ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       if (cur.tv_sec > timeout.tv_sec + 1 ||
1968ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		   (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
1969ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		    timeout.tv_nsec)) {
1970ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       errno = EBUSY;
1971ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       ret = -1;
1972ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       break;
1973ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       }
1974f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       }
197555acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    } while (ret && errno == EINTR);
197655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
1977f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnesout:
197855acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    return ret;
197955acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer}
198055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
1981b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmError(int err, const char *label)
1982b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1983b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    switch (err) {
1984ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_DEVICE:
1985ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no device\n", label);
1986ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
1987ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_ACCESS:
1988ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no access\n", label);
1989ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
1990ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NOT_ROOT:
1991ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: not root\n", label);
1992ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
1993ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_INVALID:
1994ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: invalid args\n", label);
1995ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
1996b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    default:
1997ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (err < 0)
1998ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    err = -err;
1999b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
2000b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	break;
2001b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2002b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2003b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 1;
2004b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2005b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2006d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Install IRQ handler.
2008d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param irq IRQ number.
2011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2013d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2014d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2015d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2016d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2017d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2018b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlInstHandler(int fd, int irq)
2019b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2020b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2021b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2022b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_INST_HANDLER;
2023b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = irq;
20248b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2025ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2026b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2027b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2028b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2029d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2030d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2031d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Uninstall IRQ handler.
2032d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2033d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2034d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2035d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2036d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2037d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2038d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2039d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2040d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2041b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlUninstHandler(int fd)
2042b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2043b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2044b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2045b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_UNINST_HANDLER;
2046b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = 0;
20478b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2048ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2049b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2050b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2051b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2052b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFinish(int fd, int context, drmLockFlags flags)
2053b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2054b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
2055b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2056b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
2057b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
2058b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
2059b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
2060b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
2061b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
2062b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2063b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
20648b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2065ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2066b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2067b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2068b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2069d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2070d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get IRQ from bus ID.
2071d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2072d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2073d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busnum bus number.
2074d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param devnum device number.
2075d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param funcnum function number.
2076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return IRQ number on success, or a negative value on failure.
2078d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_irq_busid structure.
2082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2083b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2084b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2085b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_irq_busid_t p;
2086b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2087b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.busnum  = busnum;
2088b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.devnum  = devnum;
2089b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.funcnum = funcnum;
20908b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2091ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2092b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return p.irq;
2093b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2094b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
20958696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAddContextTag(int fd, drm_context_t context, void *tag)
2096b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2097b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2098b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2099b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashInsert(entry->tagTable, context, tag)) {
2100b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashDelete(entry->tagTable, context);
2101b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(entry->tagTable, context, tag);
2102b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2103b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2104b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2105b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
21068696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDelContextTag(int fd, drm_context_t context)
2107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2110b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return drmHashDelete(entry->tagTable, context);
2111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
21138696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlvoid *drmGetContextTag(int fd, drm_context_t context)
2114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2115b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2116b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
2117360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
2118ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (drmHashLookup(entry->tagTable, context, &value))
2119ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
2120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return value;
2122b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2123b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
212422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
212522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t handle)
212674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
212774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
212874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
212974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
2130961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
213174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
21328b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2133ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
213474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
213574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
213674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
213722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
213822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t *handle)
213974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
214074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
214174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
214274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
214374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
21448b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2145ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2146ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
2147961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
214874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
214974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
215074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
215174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
21528696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
21538696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	      drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
215488dbee54ed400a3fd5594fab506518c171167805Rik Faith	      int *mtrr)
215588dbee54ed400a3fd5594fab506518c171167805Rik Faith{
215688dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_map_t map;
215788dbee54ed400a3fd5594fab506518c171167805Rik Faith
215888dbee54ed400a3fd5594fab506518c171167805Rik Faith    map.offset = idx;
21598b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2160ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
216188dbee54ed400a3fd5594fab506518c171167805Rik Faith    *offset = map.offset;
216288dbee54ed400a3fd5594fab506518c171167805Rik Faith    *size   = map.size;
216388dbee54ed400a3fd5594fab506518c171167805Rik Faith    *type   = map.type;
216488dbee54ed400a3fd5594fab506518c171167805Rik Faith    *flags  = map.flags;
216588dbee54ed400a3fd5594fab506518c171167805Rik Faith    *handle = (unsigned long)map.handle;
216688dbee54ed400a3fd5594fab506518c171167805Rik Faith    *mtrr   = map.mtrr;
216788dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
216888dbee54ed400a3fd5594fab506518c171167805Rik Faith}
216988dbee54ed400a3fd5594fab506518c171167805Rik Faith
217088dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
217188dbee54ed400a3fd5594fab506518c171167805Rik Faith		 unsigned long *magic, unsigned long *iocs)
217288dbee54ed400a3fd5594fab506518c171167805Rik Faith{
217388dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_client_t client;
217488dbee54ed400a3fd5594fab506518c171167805Rik Faith
217588dbee54ed400a3fd5594fab506518c171167805Rik Faith    client.idx = idx;
21768b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2177ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
217888dbee54ed400a3fd5594fab506518c171167805Rik Faith    *auth      = client.auth;
217988dbee54ed400a3fd5594fab506518c171167805Rik Faith    *pid       = client.pid;
218088dbee54ed400a3fd5594fab506518c171167805Rik Faith    *uid       = client.uid;
218188dbee54ed400a3fd5594fab506518c171167805Rik Faith    *magic     = client.magic;
218288dbee54ed400a3fd5594fab506518c171167805Rik Faith    *iocs      = client.iocs;
218388dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
218488dbee54ed400a3fd5594fab506518c171167805Rik Faith}
218588dbee54ed400a3fd5594fab506518c171167805Rik Faith
218688dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetStats(int fd, drmStatsT *stats)
218788dbee54ed400a3fd5594fab506518c171167805Rik Faith{
218888dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_stats_t s;
218988dbee54ed400a3fd5594fab506518c171167805Rik Faith    int         i;
219088dbee54ed400a3fd5594fab506518c171167805Rik Faith
21918b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2192ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
219388dbee54ed400a3fd5594fab506518c171167805Rik Faith
219488dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = 0;
219588dbee54ed400a3fd5594fab506518c171167805Rik Faith    memset(stats, 0, sizeof(*stats));
219688dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
219788dbee54ed400a3fd5594fab506518c171167805Rik Faith	return -1;
219888dbee54ed400a3fd5594fab506518c171167805Rik Faith
219988dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_VALUE                              \
220088dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
220188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%8.8s";      \
220288dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 1;            \
220388dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
220488dbee54ed400a3fd5594fab506518c171167805Rik Faith
220588dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_COUNT                              \
220688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
220788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
220888dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
220988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "kgm";        \
221088dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1000;         \
221188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
221288dbee54ed400a3fd5594fab506518c171167805Rik Faith
221388dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_BYTE                               \
221488dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
221588dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
221688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
221788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "KGM";        \
221888dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1024;         \
221988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
222088dbee54ed400a3fd5594fab506518c171167805Rik Faith
222188dbee54ed400a3fd5594fab506518c171167805Rik Faith
222288dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = s.count;
222388dbee54ed400a3fd5594fab506518c171167805Rik Faith    for (i = 0; i < s.count; i++) {
222488dbee54ed400a3fd5594fab506518c171167805Rik Faith	stats->data[i].value = s.data[i].value;
222588dbee54ed400a3fd5594fab506518c171167805Rik Faith	switch (s.data[i].type) {
222688dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCK:
222788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Lock";
222888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
222988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
223088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
223188dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_OPENS:
223288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Opens";
223388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "O";
223488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
223588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
223688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
223788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_CLOSES:
223888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Closes";
223988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
224088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
224188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
224288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
224388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IOCTLS:
224488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Ioctls";
224588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ioc/s";
224688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
224788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
224888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCKS:
224988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Locks";
225088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lck/s";
225188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
225288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
225388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_UNLOCKS:
225488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Unlocks";
225588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Unl/s";
225688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
225788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
225888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IRQ:
225988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "IRQs";
226088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "IRQ/s";
226188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
226288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
226388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_PRIMARY:
226488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Primary Bytes";
226588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "PB/s";
226688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
226788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
226888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SECONDARY:
226988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Secondary Bytes";
227088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "SB/s";
227188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
227288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
227388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_DMA:
227488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "DMA";
227588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "DMA/s";
227688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
227788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
227888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SPECIAL:
227988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Special DMA";
228088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "dma/s";
228188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
228288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
228388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_MISSED:
228488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Miss";
228588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ms/s";
228688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
228788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
228888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_VALUE:
228988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Value";
229088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Value";
229188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
229288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
229388dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_BYTE:
229488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Bytes";
229588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "B/s";
229688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
229788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
229888dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_COUNT:
229988dbee54ed400a3fd5594fab506518c171167805Rik Faith	default:
230088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Count";
230188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Cnt/s";
230288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
230388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
230488dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
230588dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
230688dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
230788dbee54ed400a3fd5594fab506518c171167805Rik Faith}
230888dbee54ed400a3fd5594fab506518c171167805Rik Faith
2309d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
231006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Issue a set-version ioctl.
231106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
231206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param fd file descriptor.
231306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param drmCommandIndex command index
231406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param data source pointer of the data to be read and written.
231506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param size size of the data to be read and written.
231606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
231706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return zero on success, or a negative value on failure.
231806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
231906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
232006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * It issues a read-write ioctl given by
232106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
232206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
232322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmSetInterfaceVersion(int fd, drmSetVersion *version)
232406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
232506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    int retcode = 0;
232606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drm_set_version_t sv;
232706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
232806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_major = version->drm_di_major;
232906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_minor = version->drm_di_minor;
233006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_major = version->drm_dd_major;
233106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_minor = version->drm_dd_minor;
233206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
23338b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
233406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	retcode = -errno;
233506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
233606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
233706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_major = sv.drm_di_major;
233806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_minor = sv.drm_di_minor;
233906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_major = sv.drm_dd_major;
234006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_minor = sv.drm_dd_minor;
234106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
234206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return retcode;
234306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
234406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
234506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
2346d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific command.
2347d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2348d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2349d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2350d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2351d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2352d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2353d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2354d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a ioctl given by
2355d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2356d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
23573903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owenint drmCommandNone(int fd, unsigned long drmCommandIndex)
23583903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
23593903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    void *data = NULL; /* dummy */
23603903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
23613903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
23623903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
23633903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
23648b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
23653903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
23663903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
23673903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
23683903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
23693903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2370d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2371d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2372d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read command.
2373d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2374d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2375d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2376d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data destination pointer of the data to be read.
2377d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read.
2378d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2379d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2380d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2381d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2382d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read ioctl given by
2383d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2384d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
238522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
238622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                   unsigned long size)
23873903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
23883903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
23893903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
239074ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
239174ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
23923903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
23938b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
23943903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
23953903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
23963903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
23973903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
23983903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2399d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2400d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2401d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific write command.
2402d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2403d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2404d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2405d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be written.
2406d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be written.
2407d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2408d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2409d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2410d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2411d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a write ioctl given by
2412d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2413d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
241422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
241522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                    unsigned long size)
24163903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
24173903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
24183903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
241974ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
242074ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
24213903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
24228b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
24233903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
24243903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
24253903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
24263903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
24273903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2428d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2429d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2430d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read-write command.
2431d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2432d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2433d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2434d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be read and written.
2435d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read and written.
2436d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2437d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2438d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2439d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2440d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read-write ioctl given by
2441d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2442d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
244322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
244422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                        unsigned long size)
24453903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
24463903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
24473903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
244874ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
244974ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
24503903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
24518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data))
24523903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
24533903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
24543903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
2455166da9355d95affe427a6cff3525df60e80a99dfThomas Hellstrom
2456d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie#define DRM_MAX_FDS 16
2457d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic struct {
2458ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    char *BusID;
2459ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2460ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int refcount;
2461d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} connection[DRM_MAX_FDS];
2462d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2463d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic int nr_fds = 0;
2464d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2465d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlieint drmOpenOnce(void *unused,
2466d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		const char *BusID,
2467d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		int *newlyopened)
2468d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2469ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2470ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2471d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2472ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++)
2473ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (strcmp(BusID, connection[i].BusID) == 0) {
2474ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    connection[i].refcount++;
2475ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    *newlyopened = 0;
2476ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return connection[i].fd;
2477ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2478ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian
2479ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    fd = drmOpen(unused, BusID);
2480ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd <= 0 || nr_fds == DRM_MAX_FDS)
2481ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
2482d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2483ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].BusID = strdup(BusID);
2484ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].fd = fd;
2485ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].refcount = 1;
2486ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    *newlyopened = 1;
2487d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2488ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (0)
2489ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "saved connection %d for %s %d\n",
2490ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		nr_fds, connection[nr_fds].BusID,
2491ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		strcmp(BusID, connection[nr_fds].BusID));
2492d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2493ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    nr_fds++;
2494d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2495ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return fd;
2496d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2497d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2498d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlievoid drmCloseOnce(int fd)
2499d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2500ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2501d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2502ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++) {
2503ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (fd == connection[i].fd) {
2504ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (--connection[i].refcount == 0) {
2505ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmClose(connection[i].fd);
2506ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		free(connection[i].BusID);
2507d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2508ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		if (i < --nr_fds)
2509ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		    connection[i] = connection[nr_fds];
2510d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2511ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		return;
2512ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    }
2513ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2514ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    }
2515d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2516731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2517731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmSetMaster(int fd)
2518731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2519fbc8b2d95f5da096ee771a3e2ef6f89306679e89Kristian Høgsberg	return ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
2520731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
2521731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2522731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmDropMaster(int fd)
2523731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2524fbc8b2d95f5da096ee771a3e2ef6f89306679e89Kristian Høgsberg	return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2525731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
252622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
252722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsbergchar *drmGetDeviceNameFromFd(int fd)
252822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg{
252922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	char name[128];
253022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	struct stat sbuf;
253122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	dev_t d;
253222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	int i;
253322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
253422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	/* The whole drmOpen thing is a fiasco and we need to find a way
253522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * back to just using open(2).  For now, however, lets just make
253622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * things worse with even more ad hoc directory walking code to
253722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * discover the device file name. */
253822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
253922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	fstat(fd, &sbuf);
254022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	d = sbuf.st_rdev;
254122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
254222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	for (i = 0; i < DRM_MAX_MINOR; i++) {
254322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
254422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
254522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg			break;
254622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	}
254722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	if (i == DRM_MAX_MINOR)
254822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		return NULL;
254922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
25500a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson	return strdup(name);
255122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg}
2552cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2553cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
2554cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2555cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2556cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2557cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2558cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.handle = handle;
2559cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = flags;
2560cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
2561cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2562cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2563cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2564cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*prime_fd = args.fd;
2565cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2566cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2567cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2568cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2569cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2570cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2571cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2572cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2573cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.fd = prime_fd;
2574cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = 0;
2575cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
2576cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2577cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2578cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2579cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*handle = args.handle;
2580cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2581cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2582cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2583