xf86drm.c revision f1adc4b375a16b07f560b86a34e617984049c422
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/time.h>
5279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdarg.h>
53b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
54b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* Not all systems have MAP_FAILED defined */
55b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifndef MAP_FAILED
56b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#define MAP_FAILED ((void *)-1)
57b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif
58b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
59b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "xf86drm.h"
60faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov#include "libdrm.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
88fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter#define memclear(s) memset(&s, 0, sizeof(s))
89fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
9079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic drmServerInfoPtr drm_server_info;
9179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
9279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid drmSetServerInfo(drmServerInfoPtr info)
9379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
94ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_server_info = info;
9579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
9679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
97d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
98d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Output a message to stderr.
99d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
100d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param format printf() like format string.
101d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
102d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around vfprintf().
104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
10579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
10644b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingstatic int DRM_PRINTFLIKE(1, 0)
10744b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry RedingdrmDebugPrint(const char *format, va_list ap)
10879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
109ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return vfprintf(stderr, format, ap);
11079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
11179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
11244b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingtypedef int DRM_PRINTFLIKE(1, 0) (*debug_msg_func_t)(const char *format,
11344b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Reding						     va_list ap);
11444b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Reding
11544b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingstatic debug_msg_func_t drm_debug_print = drmDebugPrint;
11679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
117c4857429c716f35e1fa054d1990cae28055d96d7Eric Anholtvoid
11856bd9c207770d41a497f3e8237a1099dd9d4cd91David DawesdrmMsg(const char *format, ...)
11956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes{
12056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    va_list	ap;
12156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    const char *env;
12279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info)
12356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    {
12456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_start(ap, format);
12579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
12679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_server_info->debug_print(format,ap);
12779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	} else {
12879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	  drm_debug_print(format, ap);
12979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
13056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	va_end(ap);
13156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
13256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes}
13356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
13479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid
13544b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry RedingdrmSetDebugMsgFunction(debug_msg_func_t debug_msg_ptr)
13679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
137ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    drm_debug_print = debug_msg_ptr;
13879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
13979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
140b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void *drmHashTable = NULL; /* Context switch callbacks */
141b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
14279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid *drmGetHashTable(void)
14379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{
144ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return drmHashTable;
14579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie}
146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
147b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmMalloc(int size)
148b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
149b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void *pt;
150ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((pt = malloc(size)))
151ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	memset(pt, 0, size);
152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return pt;
153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
154b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
155b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFree(void *pt)
156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
157ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (pt)
158ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	free(pt);
159b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard/**
1628b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard * Call ioctl, restarting if it is interupted
1638b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard */
164731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint
16541b83a99583486ad4f8760a6537d34783769bfc3Coleman KanedrmIoctl(int fd, unsigned long request, void *arg)
1668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard{
1678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    int	ret;
1688b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard
1698b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    do {
1708b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	ret = ioctl(fd, request, arg);
1718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
1728b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return ret;
1738b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard}
174b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic unsigned long drmGetKeyFromFd(int fd)
176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
177fcc21069b7019a4a93e1ceacc175ccd682353861David Dawes    stat_t     st;
178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    st.st_rdev = 0;
180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    fstat(fd, &st);
181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return st.st_rdev;
182b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
183b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
18479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave AirliedrmHashEntry *drmGetEntry(int fd)
185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key = drmGetKeyFromFd(fd);
187b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry;
189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
190ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!drmHashTable)
191ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drmHashTable = drmHashCreate();
192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashLookup(drmHashTable, key, &value)) {
194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry           = drmMalloc(sizeof(*entry));
195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->fd       = fd;
196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->f        = NULL;
197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry->tagTable = drmHashCreate();
198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(drmHashTable, key, entry);
199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    } else {
200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	entry = value;
201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return entry;
203b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
205d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
20606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Compare two busid strings
20706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
20806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param first
20906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param second
21006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return 1 if matched.
21206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
21306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
21406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * This function compares two bus ID strings.  It understands the older
21506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format.  In the format, o is
21606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * domain, b is bus, d is device, f is function.
21706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
218b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidtstatic int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
21906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
22006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* First, check if the IDs are exactly the same */
22106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strcasecmp(id1, id2) == 0)
22206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	return 1;
22306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
22406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Try to match old/new-style PCI bus IDs. */
22506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (strncasecmp(id1, "pci", 3) == 0) {
22690ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o1, b1, d1, f1;
22790ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	unsigned int o2, b2, d2, f2;
22806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	int ret;
22906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
23090ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
23106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
23206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o1 = 0;
23390ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
23406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
23506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
23606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
23706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
23890ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
23906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (ret != 4) {
24006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    o2 = 0;
24190ae0f2bb8d53500f5c9d06e2dc1a18d5a5d0cf5Pauli Nieminen	    ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
24206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    if (ret != 3)
24306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt		return 0;
24406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
24506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
246b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	/* If domains aren't properly supported by the kernel interface,
247b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * just ignore them, which sucks less than picking a totally random
248b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 * card with "open by name"
249b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	 */
250b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	if (!pci_domain_ok)
251b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		o1 = o2 = 0;
252b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt
25306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
25406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 0;
25506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	else
25606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return 1;
25706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
25806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return 0;
25906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
26006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
26106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
262c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Handles error checking for chown call.
263c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
264c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param path to file.
265c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new owner.
266c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new group.
267c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
268c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \return zero if success or -1 if failure.
269c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen *
270c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \internal
271c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Checks for failure. If failure was caused by signal call chown again.
272c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * If any other failure happened then it will output error mesage using
273c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * drmMsg() call.
274c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen */
275c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminenstatic int chown_check_return(const char *path, uid_t owner, gid_t group)
276c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen{
277c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	int rv;
278c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
279c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	do {
280c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		rv = chown(path, owner, group);
281c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	} while (rv != 0 && errno == EINTR);
282c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
283c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	if (rv == 0)
284c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen		return 0;
285c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
286c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	drmMsg("Failed to change owner or group for file %s! %d: %s\n",
287c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen			path, errno, strerror(errno));
288c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	return -1;
289c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen}
290c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen
291c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen/**
292d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device, creating it if necessary.
293d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
294d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param dev major and minor numbers of the device.
295d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor minor number of the device.
296d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
297d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
298d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
299d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
300d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assembles the device name from \p minor and opens it, creating the device
301d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * special file node with the major and minor numbers specified by \p dev and
302d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parent directory if necessary and was called by root.
303d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
304de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Veselystatic int drmOpenDevice(dev_t dev, int minor, int type)
305b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
3069c775d0b2f303389c24aea5e8abc1473f0cf93e8David Dawes    stat_t          st;
3070c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    const char      *dev_name;
30888dbee54ed400a3fd5594fab506518c171167805Rik Faith    char            buf[64];
30988dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             fd;
31079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    mode_t          devmode = DRM_DEV_MODE, serv_mode;
31188dbee54ed400a3fd5594fab506518c171167805Rik Faith    int             isroot  = !geteuid();
31288dbee54ed400a3fd5594fab506518c171167805Rik Faith    uid_t           user    = DRM_DEV_UID;
31379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    gid_t           group   = DRM_DEV_GID, serv_group;
31479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
3150c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    switch (type) {
3160c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_PRIMARY:
3170c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_DEV_NAME;
3180c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3190c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_CONTROL:
3200c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_CONTROL_DEV_NAME;
3210c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3220c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_RENDER:
3230c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_RENDER_DEV_NAME;
3240c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
3250c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    default:
3260c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    return -EINVAL;
3270c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    };
3280c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
3290c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
33006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenDevice: node name is %s\n", buf);
33156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes
33279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
333ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	drm_server_info->get_perms(&serv_group, &serv_mode);
334ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode  = serv_mode ? serv_mode : DRM_DEV_MODE;
335ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
336ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	group = (serv_group >= 0) ? serv_group : DRM_DEV_GID;
33779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
338569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
3399101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#if !defined(UDEV)
34088dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (stat(DRM_DIR_NAME, &st)) {
341ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
342ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
343b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
344c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
345b3a20ce219b353aa3e2b7f3b47ffd28b279557c7Alan Hourihane	chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
346569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
347b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
34806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node exists and create it if necessary. */
349d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (stat(buf, &st)) {
350ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
351ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
35288dbee54ed400a3fd5594fab506518c171167805Rik Faith	remove(buf);
35388dbee54ed400a3fd5594fab506518c171167805Rik Faith	mknod(buf, S_IFCHR | devmode, dev);
354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
35579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie
35679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (drm_server_info) {
357c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	chown_check_return(buf, user, group);
358ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	chmod(buf, devmode);
35979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    }
3609101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#else
3619101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    /* if we modprobed then wait for udev */
3629101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    {
3639101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	int udev_count = 0;
3649101a0205c897fea28e6a3d875111a83ad7f7732Dave Airliewait_for_udev:
3659101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie        if (stat(DRM_DIR_NAME, &st)) {
3669101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3679101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3689101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3699101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3709101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3719101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3729101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie	}
3739101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3749101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	if (stat(buf, &st)) {
3759101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		usleep(20);
3769101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		udev_count++;
3779101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie
3789101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		if (udev_count == 50)
3799101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie			return -1;
3809101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie		goto wait_for_udev;
3819101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    	}
3829101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie    }
3839101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#endif
38488dbee54ed400a3fd5594fab506518c171167805Rik Faith
38556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    fd = open(buf, O_RDWR, 0);
38656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
38756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		fd, fd < 0 ? strerror(errno) : "OK");
388ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
389ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
390d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
39139e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#if !defined(UDEV)
39206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    /* Check if the device node is not what we expect it to be, and recreate it
39306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     * and try again if so.
39406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     */
395d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    if (st.st_rdev != dev) {
396ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!isroot)
397ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return DRM_ERR_NOT_ROOT;
398d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	remove(buf);
399d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt	mknod(buf, S_IFCHR | devmode, dev);
40079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (drm_server_info) {
401c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen	    chown_check_return(buf, user, group);
402ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    chmod(buf, devmode);
40379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	}
404d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    }
405d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    fd = open(buf, O_RDWR, 0);
406d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt    drmMsg("drmOpenDevice: open result is %d, (%s)\n",
407d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt		fd, fd < 0 ? strerror(errno) : "OK");
408ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd >= 0)
409ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
410d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt
41156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    drmMsg("drmOpenDevice: Open failed\n");
41288dbee54ed400a3fd5594fab506518c171167805Rik Faith    remove(buf);
41339e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#endif
41488dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
415b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
416b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
417d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
418d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
419d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device
420d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
421d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor device minor number.
422d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param create allow to create the device if set.
423d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
424d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
425d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
426d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
427d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
428d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * name from \p minor and opens it.
429d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
430731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic int drmOpenMinor(int minor, int create, int type)
43188dbee54ed400a3fd5594fab506518c171167805Rik Faith{
43288dbee54ed400a3fd5594fab506518c171167805Rik Faith    int  fd;
43388dbee54ed400a3fd5594fab506518c171167805Rik Faith    char buf[64];
4340c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    const char *dev_name;
435db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
436ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (create)
437731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes	return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
43888dbee54ed400a3fd5594fab506518c171167805Rik Faith
4390c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    switch (type) {
4400c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_PRIMARY:
4410c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_DEV_NAME;
4420c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4430c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_CONTROL:
4440c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_CONTROL_DEV_NAME;
4450c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4460c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    case DRM_NODE_RENDER:
4470c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    dev_name = DRM_RENDER_DEV_NAME;
4480c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    break;
4490c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    default:
4500c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns	    return -EINVAL;
4510c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    };
4520c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
4530c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    sprintf(buf, dev_name, DRM_DIR_NAME, minor);
454ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if ((fd = open(buf, O_RDWR, 0)) >= 0)
455ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
45688dbee54ed400a3fd5594fab506518c171167805Rik Faith    return -errno;
45788dbee54ed400a3fd5594fab506518c171167805Rik Faith}
45888dbee54ed400a3fd5594fab506518c171167805Rik Faith
459569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
460d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
461d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine whether the DRM kernel driver has been loaded.
462d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
463d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return 1 if the DRM driver is loaded, 0 otherwise.
464d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
465d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
466d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine the presence of the kernel driver by attempting to open the 0
467d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * minor and get version information.  For backward compatibility with older
468d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Linux implementations, /proc/dri is also checked.
469d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
470569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulint drmAvailable(void)
471569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul{
472569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    drmVersionPtr version;
473569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           retval = 0;
474569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    int           fd;
475360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
476ad8bbfd3c74466f088be8088d2d0524bed392b71Frank Binns    if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
477b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#ifdef __linux__
47822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	/* Try proc for backward Linux compatibility */
479ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (!access("/proc/dri/0", R_OK))
480ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return 1;
481b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#endif
48288dbee54ed400a3fd5594fab506518c171167805Rik Faith	return 0;
483569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    }
48488dbee54ed400a3fd5594fab506518c171167805Rik Faith
48588dbee54ed400a3fd5594fab506518c171167805Rik Faith    if ((version = drmGetVersion(fd))) {
48688dbee54ed400a3fd5594fab506518c171167805Rik Faith	retval = 1;
48788dbee54ed400a3fd5594fab506518c171167805Rik Faith	drmFreeVersion(version);
48888dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
48988dbee54ed400a3fd5594fab506518c171167805Rik Faith    close(fd);
490569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
491569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul    return retval;
492569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul}
493569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul
494f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmGetMinorBase(int type)
495f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{
496f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    switch (type) {
497f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_PRIMARY:
498f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 0;
499f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_CONTROL:
500f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 64;
501f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    case DRM_NODE_RENDER:
502f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return 128;
503f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    default:
504f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
505f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    };
506f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou}
507d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
508d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
509d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by bus ID.
510d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
511d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID.
512f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type device node type.
513d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
514d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
515d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
516d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
517d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
518d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * comparing the device bus ID with the one supplied.
519d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
520d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor() and drmGetBusid().
521d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
522f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByBusid(const char *busid, int type)
523e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss{
524b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt    int        i, pci_domain_ok = 1;
52588dbee54ed400a3fd5594fab506518c171167805Rik Faith    int        fd;
52688dbee54ed400a3fd5594fab506518c171167805Rik Faith    const char *buf;
52706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmSetVersion sv;
528f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    int        base = drmGetMinorBase(type);
529f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
530f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    if (base < 0)
531f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
53206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
53306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
534f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    for (i = base; i < base + DRM_MAX_MINOR; i++) {
535f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	fd = drmOpenMinor(i, 1, type);
53656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
53756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	if (fd >= 0) {
538b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    /* We need to try for 1.4 first for proper PCI domain support
539b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     * and if that fails, we know the kernel is busted
540b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	     */
54106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_di_major = 1;
542b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    sv.drm_di_minor = 4;
54306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    sv.drm_dd_major = -1;	/* Don't care */
54426462b9aa47179e724e78f0b3b1c86fd07f61d8dEric Anholt	    sv.drm_dd_minor = -1;	/* Don't care */
545b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (drmSetInterfaceVersion(fd, &sv)) {
546b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#ifndef __alpha__
547b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		pci_domain_ok = 0;
548b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#endif
549b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_major = 1;
550b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_di_minor = 1;
551b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_major = -1;       /* Don't care */
552b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		sv.drm_dd_minor = -1;       /* Don't care */
553303ff26311dc5efdf28676be34d86f501699acf3Thierry Reding		drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n");
554b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt		drmSetInterfaceVersion(fd, &sv);
555b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    }
556e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    buf = drmGetBusid(fd);
55756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
558b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt	    if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
55988dbee54ed400a3fd5594fab506518c171167805Rik Faith		drmFreeBusid(buf);
56088dbee54ed400a3fd5594fab506518c171167805Rik Faith		return fd;
561e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    }
562ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (buf)
563ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmFreeBusid(buf);
564e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	    close(fd);
565e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss	}
566e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    }
567e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss    return -1;
568e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss}
569e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss
570d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
571d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
572d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by name.
573d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
574d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name.
575f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type.
576d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
579d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
580d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function opens the first minor number that matches the driver name and
581d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * isn't already in use.  If it's in use it then it will already have a bus ID
582d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * assigned.
583d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
584d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
585d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
586f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByName(const char *name, int type)
587b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss{
58888dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           i;
58988dbee54ed400a3fd5594fab506518c171167805Rik Faith    int           fd;
59088dbee54ed400a3fd5594fab506518c171167805Rik Faith    drmVersionPtr version;
59156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    char *        id;
592f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    int           base = drmGetMinorBase(type);
593f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
594f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    if (base < 0)
595f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou        return -1;
596db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie
59756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    /*
59856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * Open the first minor number that matches the driver name and isn't
59956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     * already in use.  If it's in use it will have a busid assigned already.
60056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes     */
601f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    for (i = base; i < base + DRM_MAX_MINOR; i++) {
602f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
60388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    if ((version = drmGetVersion(fd))) {
60488dbee54ed400a3fd5594fab506518c171167805Rik Faith		if (!strcmp(version->name, name)) {
60588dbee54ed400a3fd5594fab506518c171167805Rik Faith		    drmFreeVersion(version);
60656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    id = drmGetBusid(fd);
60756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
60856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    if (!id || !*id) {
60922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			if (id)
61056bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			    drmFreeBusid(id);
61156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			return fd;
61256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    } else {
61356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes			drmFreeBusid(id);
61456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    }
61556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		} else {
61656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes		    drmFreeVersion(version);
61788dbee54ed400a3fd5594fab506518c171167805Rik Faith		}
61888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    }
61956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	    close(fd);
62088dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
621b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
622b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
62388dbee54ed400a3fd5594fab506518c171167805Rik Faith#ifdef __linux__
62422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* Backward-compatibility /proc support */
625b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    for (i = 0; i < 8; i++) {
62688dbee54ed400a3fd5594fab506518c171167805Rik Faith	char proc_name[64], buf[512];
62788dbee54ed400a3fd5594fab506518c171167805Rik Faith	char *driver, *pt, *devstring;
62888dbee54ed400a3fd5594fab506518c171167805Rik Faith	int  retcode;
62988dbee54ed400a3fd5594fab506518c171167805Rik Faith
6300371c290a12f75d36c9c1e7c947bf98fe210908bDaryll Strauss	sprintf(proc_name, "/proc/dri/%d/name", i);
631b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	if ((fd = open(proc_name, 0, 0)) >= 0) {
632b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    retcode = read(fd, buf, sizeof(buf)-1);
633b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    close(fd);
634b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    if (retcode) {
635b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		buf[retcode-1] = '\0';
636b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		for (driver = pt = buf; *pt && *pt != ' '; ++pt)
637b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    ;
63822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson		if (*pt) { /* Device is next */
639b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    *pt = '\0';
640b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    if (!strcmp(driver, name)) { /* Match */
641b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			for (devstring = ++pt; *pt && *pt != ' '; ++pt)
642b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			    ;
643b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			if (*pt) { /* Found busid */
644f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou			    return drmOpenByBusid(++pt, type);
64522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson			} else { /* No busid */
646f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou			    return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
647b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss			}
648b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		    }
649b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss		}
650b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss	    }
651569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul	}
652b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    }
65388dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif
65488dbee54ed400a3fd5594fab506518c171167805Rik Faith
655b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return -1;
656b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss}
657b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
658b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss
659d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
660d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device.
661d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
662d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Looks up the specified name and bus ID, and opens the device found.  The
663d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * entry in /dev/dri is created if necessary and if called by root.
664d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
665d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name. Not referenced if bus ID is supplied.
666d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID. Zero if not known.
667d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
668d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error.
669d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
670d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
671d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
672d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * otherwise.
673d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
674b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmOpen(const char *name, const char *busid)
675b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
676f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou    return drmOpenWithType(name, busid, DRM_NODE_PRIMARY);
677f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou}
678f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou
679f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou/**
680f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Open the DRM device with specified type.
681f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
682f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Looks up the specified name and bus ID, and opens the device found.  The
683f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * entry in /dev/dri is created if necessary and if called by root.
684f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
685f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param name driver name. Not referenced if bus ID is supplied.
686f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param busid bus ID. Zero if not known.
687f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type to open, PRIMARY, CONTROL or RENDER
688f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
689f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \return a file descriptor on success, or a negative value on error.
690f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou *
691f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \internal
692f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
693f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * otherwise.
694f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou */
695f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhouint drmOpenWithType(const char *name, const char *busid, int type)
696f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{
69779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    if (!drmAvailable() && name != NULL && drm_server_info) {
698f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	/* try to load the kernel module */
69979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie	if (!drm_server_info->load_module(name)) {
700ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
70106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return -1;
70206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	}
70306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
70406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
70506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (busid) {
706f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	int fd = drmOpenByBusid(busid, type);
70706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	if (fd >= 0)
70806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	    return fd;
70906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
71022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
71106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    if (name)
712f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou	return drmOpenByName(name, type);
71322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
71406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return -1;
715b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
716b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
717731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmOpenControl(int minor)
718731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
719731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes    return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
720731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
721d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
7220c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binnsint drmOpenRender(int minor)
7230c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns{
7240c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns    return drmOpenMinor(minor, 0, DRM_NODE_RENDER);
7250c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns}
7260c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns
727d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
728d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the version information returned by drmGetVersion().
729d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
730d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
731d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
732d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
733d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It frees the memory pointed by \p %v as well as all the non-null strings
734d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * pointers in it.
735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
736b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeVersion(drmVersionPtr v)
737b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
738ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
739ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
7409d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
7419d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
7429d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
743b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
744b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
745b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
746d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
747d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
748d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the non-public version information returned by the kernel.
749d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
750d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information.
751d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
752d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
753d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
754d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the non-null strings pointers in it.
755d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
756b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void drmFreeKernelVersion(drm_version_t *v)
757b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
758ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!v)
759ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return;
7609d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->name);
7619d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->date);
7629d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz    drmFree(v->desc);
763b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(v);
764b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
765b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
766d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
767d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
768d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Copy version information.
769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param d destination pointer.
771d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param s source pointer.
772d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
773d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
774d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to translate the information returned by the ioctl
775d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * interface in a private structure into the public structure counterpart.
776d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
777569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulstatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
778b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
779b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_major      = s->version_major;
780b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_minor      = s->version_minor;
781b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->version_patchlevel = s->version_patchlevel;
782b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->name_len           = s->name_len;
7830a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->name               = strdup(s->name);
784b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->date_len           = s->date_len;
7850a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->date               = strdup(s->date);
786b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    d->desc_len           = s->desc_len;
7870a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson    d->desc               = strdup(s->desc);
788b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
789b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
790b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
792d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Query the driver version information.
793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
794d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
795d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
796d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return pointer to a drmVersion structure which should be freed with
797d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * drmFreeVersion().
798d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
799d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note Similar information is available via /proc/dri.
800d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
801d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
802d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
803d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * first with zeros to get the string lengths, and then the actually strings.
804d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It also null-terminates them since they might not be already.
805d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
806b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmVersionPtr drmGetVersion(int fd)
807b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
808b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmVersionPtr retval;
809b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_version_t *version = drmMalloc(sizeof(*version));
810b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
81195f23cf894757d05a6b6c980062a46968dc069b1Daniel Vetter    memclear(*version);
812360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
8138b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
814b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
815b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
816b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
817b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
818b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len)
819b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->name    = drmMalloc(version->name_len + 1);
820b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len)
821b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->date    = drmMalloc(version->date_len + 1);
822b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len)
823b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	version->desc    = drmMalloc(version->desc_len + 1);
824360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
8258b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
826b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane	drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
827b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFreeKernelVersion(version);
828b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
829b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
830b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
83122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /* The results might not be null-terminated strings, so terminate them. */
832b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->name_len) version->name[version->name_len] = '\0';
833b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->date_len) version->date[version->date_len] = '\0';
834b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (version->desc_len) version->desc[version->desc_len] = '\0';
835b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
836b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    retval = drmMalloc(sizeof(*retval));
837b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmCopyVersion(retval, version);
838b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFreeKernelVersion(version);
839b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
840b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
841b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
8423903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
843d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
844d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get version information for the DRM user space library.
845d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
846d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This version number is driver independent.
847d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
848d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
849d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
850d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return version information.
851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
852d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
853d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function allocates and fills a drm_version structure with a hard coded
854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * version number.
855d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
8563903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens OwendrmVersionPtr drmGetLibVersion(int fd)
8573903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
8583903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    drm_version_t *version = drmMalloc(sizeof(*version));
8593903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8603903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    /* Version history:
86179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it
8623903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.0.x = original DRM interface with no drmGetLibVersion
8633903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    entry point and many drm<Device> extensions
8643903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *   revision 1.1.x = added drmCommand entry points for device extensions
8653903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     *                    added drmGetLibVersion to identify libdrm.a version
86606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *   revision 1.2.x = added drmSetInterfaceVersion
86706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt     *                    modified drmOpen to handle both busid and name
86879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie     *   revision 1.3.x = added server + memory manager
8693903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen     */
87079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_major      = 1;
87179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie    version->version_minor      = 3;
8723903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    version->version_patchlevel = 0;
8733903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8743903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return (drmVersionPtr)version;
8753903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
8763903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
8775c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggsint drmGetCap(int fd, uint64_t capability, uint64_t *value)
8785c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs{
879fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	struct drm_get_cap cap;
8805c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	int ret;
8815c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
882fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	memclear(cap);
883fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.capability = capability;
884fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
8855c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
8865c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	if (ret)
8875c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs		return ret;
8885c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs
8895c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs	*value = cap.value;
8903b04c73650b5e9bbcb602fdb8cea0b16ad82d0c0Dave Airlie	return 0;
8915c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs}
892d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
893ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiauint drmSetClientCap(int fd, uint64_t capability, uint64_t value)
894ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau{
895fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	struct drm_set_client_cap cap;
896fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
897fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	memclear(cap);
898fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.capability = capability;
899fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	cap.value = value;
900ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
901ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau	return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
902ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau}
903ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau
904d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
905d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the bus ID information.
906d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
907d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID information string as given by drmGetBusid().
908d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
909d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
910d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is just frees the memory pointed by \p busid.
911d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
912b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussvoid drmFreeBusid(const char *busid)
913b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
914b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drmFree((void *)busid);
915b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
916b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
917d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
918d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
919d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get the bus ID of the device.
920d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
921d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
922d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
923d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return bus ID string.
924d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
925d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
926d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
927d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * get the string length and data, passing the arguments in a drm_unique
928d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * structure.
929d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
930b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strausschar *drmGetBusid(int fd)
931b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
932b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
933b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
934fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(u);
935b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9368b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
937ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
938b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique = drmMalloc(u.unique_len + 1);
9398b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
940ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
941b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique[u.unique_len] = '\0';
94206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
943b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    return u.unique;
944b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
945b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
947d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
948d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the bus ID of the device.
949d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
950d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
951d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID string.
952d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
953d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, negative on failure.
954d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
955d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
956d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
957d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_unique structure.
958d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
959b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmSetBusid(int fd, const char *busid)
960b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
961b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    drm_unique_t u;
962b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
963fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(u);
964b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique     = (char *)busid;
965b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss    u.unique_len = strlen(busid);
966b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
96856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes	return -errno;
96956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes    }
970b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
971b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
972b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9738696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMagic(int fd, drm_magic_t * magic)
974b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
975b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
976b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
977fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(auth);
978fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
979b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = 0;
9808b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
981ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
982b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *magic = auth.magic;
983b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
984b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
985b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
9868696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAuthMagic(int fd, drm_magic_t magic)
987b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
988b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_auth_t auth;
989b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
990fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(auth);
991b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    auth.magic = magic;
9928b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
993ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
994b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
995b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
996b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
997d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
998d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Specifies a range of memory that is available for mapping by a
999d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * non-root process.
1000d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1001d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1002d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset usually the physical address. The actual meaning depends of
1003d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the \p type parameter. See below.
1004d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size of the memory in bytes.
1005d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of the memory to be mapped.
1006d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags combination of several flags to modify the function actions.
1007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle will be set to a value that may be used as the offset
1008d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parameter for mmap().
1009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success or a negative value on error.
1011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the frame buffer
1013d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the frame buffer
1014d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the frame buffer,
1015d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the frame buffer in bytes, and
1016d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_FRAME_BUFFER.
1017d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1018d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1019d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached. If MTRR support is available in the
1020d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel, the frame buffer area will be set to write combining.
1021d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1022d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the MMIO register area
1023d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the MMIO register area,
1024d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the register area,
1025d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the register area bytes, and
1026d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_REGISTERS.
1027d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1028d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached.
1029d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1030d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the SAREA
1031d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the SAREA,
1032d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be ignored and should be set to zero,
1033d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the desired size of the SAREA in bytes,
1034d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_SHM.
1035d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1036d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par
1037d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * A shared memory area of the requested size will be created and locked in
1038d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel memory. This area may be mapped into client-space by using the handle
1039d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returned.
1040d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1041d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1042d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1043d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1044d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
1045d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_map structure.
1046d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
104722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
104822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson	      drmMapFlags flags, drm_handle_t *handle)
1049b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1050b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_map_t map;
1051b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1052fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
1053b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.offset  = offset;
1054b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.size    = size;
1055b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.type    = type;
1056b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    map.flags   = flags;
10578b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
1058ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1059ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
1060961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
1061b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1062b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1063b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
10648696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmRmMap(int fd, drm_handle_t handle)
106574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
106674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_map_t map;
106774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
1068fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
1069961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
107074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
10718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
1072ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
107374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
107474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
107574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
1076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Make buffers available for DMA transfers.
1078d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers.
1081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of each buffer.
1082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags buffer allocation flags.
1083d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param agp_offset offset in the AGP aperture
1084d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1085d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return number of buffers allocated, negative on error.
1086d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1087d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1088d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
1089d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1090d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drm_buf_desc.
1091d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1092ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1093ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann	       int agp_offset)
1094b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1095b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_desc_t request;
1096360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1097fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(request);
1098b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count     = count;
1099b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.size      = size;
1100b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.flags     = flags;
1101ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    request.agp_start = agp_offset;
1102360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
11038b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1104ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1105b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return request.count;
1106b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMarkBufs(int fd, double low, double high)
1109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1110b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1113fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(info);
1114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
11158b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1116ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1117b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1118ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!info.count)
1119ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1120360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1122b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return -ENOMEM;
1123360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
11248b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1125b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	int retval = -errno;
1126b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1127b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1128b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1129360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1130b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < info.count; i++) {
1131b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].low_mark  = low  * info.list[i].count;
1132b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	info.list[i].high_mark = high * info.list[i].count;
11338b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1134b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    int retval = -errno;
1135b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1136b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return retval;
1137b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1139b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(info.list);
1140360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1141b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1142b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1143b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1144d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1145d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free buffers.
1146d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1147d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1148d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers to free.
1149d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param list list of buffers to be freed.
1150d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1151d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1152d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1153d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note This function is primarily used for debugging.
1154d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1155d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1156d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1157d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_buf_free structure.
1158d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1159b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFreeBufs(int fd, int count, int *list)
1160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_free_t request;
1162b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1163fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(request);
1164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.count = count;
1165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    request.list  = list;
11668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1167ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1168b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1169b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1170b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1171d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1172d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1173d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Close the device.
1174d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1175d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1176d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1177d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1178d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function closes the file descriptor.
1179d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1180b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmClose(int fd)
1181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1182b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    unsigned long key    = drmGetKeyFromFd(fd);
1183b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
1184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDestroy(entry->tagTable);
1186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->fd       = 0;
1187b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->f        = NULL;
1188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    entry->tagTable = NULL;
1189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1190b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashDelete(drmHashTable, key);
1191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(entry);
1192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return close(fd);
1194b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1196d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1197d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1198d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map a region of memory.
1199d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1200d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1201d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle returned by drmAddMap().
1202d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmAddMap().
1203d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address will contain the user-space virtual address where the mapping
1204d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * begins.
1205d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1206d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1207d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1208d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1209d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper for mmap().
1210d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
121122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1212b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1213c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    static unsigned long pagesize_mask = 0;
1214c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1215ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd < 0)
1216ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -EINVAL;
1217c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1218c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    if (!pagesize_mask)
1219c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane	pagesize_mask = getpagesize() - 1;
1220c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1221c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane    size = (size + pagesize_mask) & ~pagesize_mask;
1222c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane
1223faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov    *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1224ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (*address == MAP_FAILED)
1225ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1228b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1229d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1230d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1231d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap mappings obtained with drmMap().
1232d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1233d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address address as given by drmMap().
1234d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmMap().
1235d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1236d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1237d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1238d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
123922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This function is a wrapper for munmap().
1240d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1241b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmap(drmAddress address, drmSize size)
1242b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1243faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov    return drm_munmap(address, size);
1244b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1245b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1246b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufInfoPtr drmGetBufInfo(int fd)
1247b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_info_t info;
1249b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufInfoPtr  retval;
1250b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int            i;
1251b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1252fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(info);
1253b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
12548b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1255ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1256b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1257b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (info.count) {
1258b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1259b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1260360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
12618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1262b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(info.list);
1263b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1264b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
126522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1266b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1267b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = info.count;
1268b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(info.count * sizeof(*retval->list));
1269b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < info.count; i++) {
1270b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].count     = info.list[i].count;
1271b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].size      = info.list[i].size;
1272b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].low_mark  = info.list[i].low_mark;
1273b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].high_mark = info.list[i].high_mark;
1274b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
1275b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(info.list);
1276b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1277b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1278b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return NULL;
1279b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1280b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1281d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1282d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map all DMA buffers into client-virtual space.
1283d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1284d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1285d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1286d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a pointer to a ::drmBufMap structure.
1287d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1288d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note The client may not use these buffers until obtaining buffer indices
1289d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with drmDMA().
1290d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1291d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1292d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1293d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * information about the buffers in a drm_buf_map structure into the
1294d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * client-visible data structures.
1295d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1296b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufMapPtr drmMapBufs(int fd)
1297b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1298b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_buf_map_t bufs;
1299b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmBufMapPtr  retval;
1300b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1301360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1302fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(bufs);
13038b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1304ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1305b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1306ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!bufs.count)
1307ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
13088696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1309b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1310b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1311b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
13128b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard	if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1313b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    drmFree(bufs.list);
1314b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    return NULL;
1315b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
131622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson
1317b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval = drmMalloc(sizeof(*retval));
1318b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->count = bufs.count;
1319b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	retval->list  = drmMalloc(bufs.count * sizeof(*retval->list));
1320b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	for (i = 0; i < bufs.count; i++) {
1321b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].idx     = bufs.list[i].idx;
1322b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].total   = bufs.list[i].total;
1323b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].used    = 0;
1324b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	    retval->list[i].address = bufs.list[i].address;
1325b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	}
13268696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
13278696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	drmFree(bufs.list);
13288696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1329b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return retval;
1330b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1331b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1332d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1333d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1334d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap buffers allocated with drmMapBufs().
1335d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1336d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or negative value on failure.
1337d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1338d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
13398696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * Calls munmap() for every buffer stored in \p bufs and frees the
13408696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * memory allocated by drmMapBufs().
1341d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1342b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmapBufs(drmBufMapPtr bufs)
1343b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1344b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int i;
1345360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1346b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    for (i = 0; i < bufs->count; i++) {
1347faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov	drm_munmap(bufs->list[i].address, bufs->list[i].total);
1348b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
13498696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
13508696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs->list);
13518696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drmFree(bufs);
13528696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl
1353b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1355b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1356d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1357360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes#define DRM_DMA_RETRY		16
1358360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1359d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1360d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Reserve DMA buffers.
1361d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1362d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1363d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param request
1364d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1365d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1366d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1367d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1368d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assemble the arguments into a drm_dma structure and keeps issuing the
1369d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1370d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1371b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDMA(int fd, drmDMAReqPtr request)
1372b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1373b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_dma_t dma;
1374360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    int ret, i = 0;
1375b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1376b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.context         = request->context;
1377b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_count      = request->send_count;
1378b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_indices    = request->send_list;
1379b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.send_sizes      = request->send_sizes;
1380b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.flags           = request->flags;
1381b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_count   = request->request_count;
1382b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_size    = request->request_size;
1383b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_indices = request->request_list;
1384b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    dma.request_sizes   = request->request_sizes;
13858696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    dma.granted_count   = 0;
1386360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1387360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    do {
1388360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1389360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1390360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1391360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    if ( ret == 0 ) {
1392360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	request->granted_count = dma.granted_count;
1393360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return 0;
1394360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    } else {
1395360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes	return -errno;
1396360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes    }
1397b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1398b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1399d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1400d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1401d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Obtain heavyweight hardware lock.
1402d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1403d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1404d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1405d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags flags that determine the sate of the hardware when the function
1406d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returns.
1407d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1408d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return always zero.
1409d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1410d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1411d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function translates the arguments into a drm_lock structure and issue
1412d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1413d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
14148696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1415b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1416b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1417b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1418fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
1419b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
1420b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.flags   = 0;
1421b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
1422b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
1423b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
1424b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
1425b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
1426b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1427360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
14288b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1429b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	;
1430b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1431b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1432b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1433d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1434d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the hardware lock.
1435d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1436d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1437d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context.
1438d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1439d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1440d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1441d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1442d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1443d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_lock structure.
1444d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
14458696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmUnlock(int fd, drm_context_t context)
1446b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1447b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
1448b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1449fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
1450b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
14518b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1452b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1453b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
145422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksondrm_context_t *drmGetReservedContextList(int fd, int *count)
1455b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1456b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_res_t res;
1457b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t     *list;
14588696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl    drm_context_t * retval;
1459b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    int           i;
1460b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1461fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(res);
14628b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1463ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1464b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1465ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!res.count)
1466ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1467b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1468ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (!(list   = drmMalloc(res.count * sizeof(*list))))
1469ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1470b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1471b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmFree(list);
1472b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	return NULL;
1473b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
1474b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1475b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    res.contexts = list;
14768b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1477ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
1478b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1479ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < res.count; i++)
1480ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	retval[i] = list[i].handle;
1481b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(list);
1482b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1483b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *count = res.count;
1484b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return retval;
1485b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1486b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
148722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonvoid drmFreeReservedContextList(drm_context_t *pt)
1488b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1489b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmFree(pt);
1490b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1491b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1492d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1493d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Create context.
1494d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1495d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by the X server during GLXContext initialization. This causes
1496d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * per-context kernel-level resources to be allocated.
1497d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1498d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1499d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle is set on success. To be used by the client when requesting DMA
1500d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * dispatch with drmDMA().
1501d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1502d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1503d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1504d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1505d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1506d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1507d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1508d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1509d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
151022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateContext(int fd, drm_context_t *handle)
1511b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1512b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1513b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1514fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
15158b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1516ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1517b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = ctx.handle;
1518b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1519b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1520b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15218696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSwitchToContext(int fd, drm_context_t context)
1522b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1523b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1524b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1525fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1526b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
15278b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1528ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1529b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1530b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1531b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
15328696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1533b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1534b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1535b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
153622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson    /*
153722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * Context preserving means that no context switches are done between DMA
153822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * buffers from one context and the next.  This is suitable for use in the
153922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * X server (which promises to maintain hardware context), or in the
154022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     * client-side library when buffers are swapped on behalf of two threads.
154122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson     */
1542fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1543b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
1544ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_PRESERVED)
1545ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_PRESERVED;
1546ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (flags & DRM_CONTEXT_2DONLY)
1547ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	ctx.flags |= _DRM_CONTEXT_2DONLY;
15488b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
1549ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1550b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1551b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1552b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
155322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextFlags(int fd, drm_context_t context,
155422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                       drm_context_tFlagsPtr flags)
1555b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1556b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1557b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
1558fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1559b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = context;
15608b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1561ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1562b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *flags = 0;
1563ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1564ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_PRESERVED;
1565ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (ctx.flags & _DRM_CONTEXT_2DONLY)
1566ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*flags |= DRM_CONTEXT_2DONLY;
1567b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1568b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1569360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
1570d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1571d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Destroy context.
1572d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1573d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free any kernel-level resources allocated with drmCreateContext() associated
1574d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with the context.
1575d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1576d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle given by drmCreateContext().
1578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1579d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1580d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1581d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root.
1582d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1583d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1584d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1585d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure.
1586d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
15878696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyContext(int fd, drm_context_t handle)
1588b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1589b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_ctx_t ctx;
1590fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1591fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctx);
1592b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctx.handle = handle;
15938b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1594ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1595b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1596b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1597b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
159822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateDrawable(int fd, drm_drawable_t *handle)
1599b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1600b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
1601fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1602fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(draw);
16038b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1604ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1605b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    *handle = draw.handle;
1606b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1607b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1608b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
16098696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyDrawable(int fd, drm_drawable_t handle)
1610b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
1611b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_draw_t draw;
1612fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
1613fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(draw);
1614b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    draw.handle = handle;
16158b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1616ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1617b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
1618b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
1619b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
16209810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzerint drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
16219810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   drm_drawable_info_type_t type, unsigned int num,
16229810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer			   void *data)
16239810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer{
16249810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    drm_update_draw_t update;
16259810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
1626fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(update);
16279810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.handle = handle;
16289810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.type = type;
16299810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.num = num;
16309810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    update.data = (unsigned long long)(unsigned long)data;
16319810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
16328b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1633ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
16349810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
16359810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer    return 0;
16369810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer}
16379810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer
1638d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1639d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Acquire the AGP device.
1640d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1641d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Must be called before any of the other AGP related calls.
1642d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1643d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1644d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1645d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1646d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1647d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1648d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1649d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1650ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAcquire(int fd)
1651ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
16528b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1653ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1654ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1655ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1656ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1657d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1658d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1659d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the AGP device.
1660d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1661d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1662d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1663d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1664d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1665d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1666d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1667d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1668ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpRelease(int fd)
1669ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
16708b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1671ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1672ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1673ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1674ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1675d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1676d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1677d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the AGP mode.
1678d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1679d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1680d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param mode AGP mode.
1681d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1682d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1683d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1684d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1685d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1686d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_mode structure.
1687d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1688ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpEnable(int fd, unsigned long mode)
1689ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1690ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_mode_t m;
1691ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1692fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(mode);
1693ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    m.mode = mode;
16948b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1695ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1696ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1697ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1698ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1699d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1700d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Allocate a chunk of AGP memory.
1702d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1704d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size requested memory size in bytes. Will be rounded to page boundary.
1705d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of memory to allocate.
1706d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address if not zero, will be set to the physical address of the
1707d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * allocated memory.
1708d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle on success will be set to a handle of the allocated memory.
1709d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1710d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1711d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1712d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1713d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1714d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_agp_buffer structure.
1715d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1716ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAlloc(int fd, unsigned long size, unsigned long type,
17177ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlie		unsigned long *address, drm_handle_t *handle)
1718ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1719ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1720b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane
1721fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1722b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane    *handle = DRM_AGP_NO_HANDLE;
1723ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.size   = size;
1724ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.type   = type;
17258b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1726ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1727ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (address != 0UL)
1728ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	*address = b.physical;
1729ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    *handle = b.handle;
1730ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1731ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1732ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1733d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1734d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free a chunk of AGP memory.
1736d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1737d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1738d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1739d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1740d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1741d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1742d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1743d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1744d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_buffer structure.
1745d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
17467ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpFree(int fd, drm_handle_t handle)
1747ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1748ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_buffer_t b;
1749ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1750fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1751ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
17528b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1753ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1754ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1755ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1756ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1757d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1758d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1759d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Bind a chunk of AGP memory.
1760d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1761d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1762d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1763d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset offset in bytes. It will round to page boundary.
1764d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1765d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1766d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1767d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1768d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_binding structure.
1770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
17717ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1772ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1773ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1774ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1775fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1776ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
1777ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.offset = offset;
17788b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1779ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1780ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1781ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1782ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1783d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1784d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1785d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unbind a chunk of AGP memory.
1786d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1787d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1788d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
1791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1792d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1794d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the argument in a drm_agp_binding structure.
1795d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
17967ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpUnbind(int fd, drm_handle_t handle)
1797ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1798ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_binding_t b;
1799ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1800fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(b);
1801ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    b.handle = handle;
18028b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1803ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1804ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return 0;
1805ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1806ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1807d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1808d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1809d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver major version number.
1810d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1811d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1812d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1813d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return major version number on success, or a negative value on failure..
1814d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1815d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1816d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1817d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1818d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1819ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMajor(int fd)
1820ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1821ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1822ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1823fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1824fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18258b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1826ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1827ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_major;
1828ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1829ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1830d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1831d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1832d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver minor version number.
1833d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1834d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1835d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1836d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return minor version number on success, or a negative value 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 Hartmannint drmAgpVersionMinor(int fd)
1843ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1844ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1845ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1846fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1847fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18488b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1849ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
1850ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.agp_version_minor;
1851ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1852ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1853d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1855d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP mode.
1856d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1857d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1858d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1859d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return mode on success, or zero on failure.
1860d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1861d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1862d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1863d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1864d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1865ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpGetMode(int fd)
1866ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1867ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1868ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1869fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1870fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1872ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1873ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.mode;
1874ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1875ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1876d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1877d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1878d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture base.
1879d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1880d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1881d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1882d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture base on success, zero on failure.
1883d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1884d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1885d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1886d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1887d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1888ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpBase(int fd)
1889ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1890ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1891ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1892fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1893fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
18948b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1895ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1896ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_base;
1897ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1898ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1899d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1900d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1901d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture size.
1902d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1903d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1904d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1905d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture size on success, zero on failure.
1906d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1907d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1908d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1909d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1910d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1911ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpSize(int fd)
1912ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1913ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1914ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1915fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1916fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19178b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1918ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1919ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.aperture_size;
1920ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1921ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1922d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1923d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1924d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get used AGP memory.
1925d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1926d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1927d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1928d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory used on success, or zero on failure.
1929d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1930d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1931d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1932d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1933d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1934ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryUsed(int fd)
1935ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1936ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1937ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1938fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1939fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19408b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1941ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1942ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_used;
1943ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1944ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1945d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1946d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1947d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get available AGP memory.
1948d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1949d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1950d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1951d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory available on success, or zero on failure.
1952d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1953d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1954d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1955d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1956d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1957ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryAvail(int fd)
1958ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1959ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1960ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1961fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1962fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19638b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1964ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1965ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.memory_allowed;
1966ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1967ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1968d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1969d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1970d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware vendor ID.
1971d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1972d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1973d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1974d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return vendor ID on success, or zero on failure.
1975d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1976d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
1977d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1978d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
1979d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
1980ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpVendorId(int fd)
1981ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
1982ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
1983ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1984fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
1985fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
19868b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1987ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
1988ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_vendor;
1989ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
1990ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
1991d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
1992d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
1993d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware device ID.
1994d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1995d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
1996d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1997d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or zero on failure.
1998d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
1999d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2000d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2001d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure.
2002d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2003ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpDeviceId(int fd)
2004ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{
2005ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    drm_agp_info_t i;
2006ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
2007fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(i);
2008fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
20098b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2010ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return 0;
2011ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann    return i.id_device;
2012ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann}
2013ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann
20147ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
20155d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
20165d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
20175d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2018fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sg);
2019fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter
20205d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = 0;
20215d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.size   = size;
20228b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
2023ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
20245d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    *handle = sg.handle;
20255d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
20265d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
20275d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
20287ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherFree(int fd, drm_handle_t handle)
20295d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{
20305d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    drm_scatter_gather_t sg;
20315d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2032fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sg);
20335d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    sg.handle = handle;
20348b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
2035ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
20365d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin    return 0;
20375d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin}
20385d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin
2039d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2040d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Wait for VBLANK.
2041d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2042d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2043d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param vbl pointer to a drmVBlank structure.
2044d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2045d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2046d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2047d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2048d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
2049d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
205055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzerint drmWaitVBlank(int fd, drmVBlankPtr vbl)
205155acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer{
2052f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    struct timespec timeout, cur;
205355acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    int ret;
205455acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2055f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
2056f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    if (ret < 0) {
20571eb2860b4bd0306dddc5b2f2dc7403aa65c5e476Daniel Kurtz	fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
2058f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes	goto out;
2059f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    }
2060f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes    timeout.tv_sec++;
2061f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes
206255acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    do {
2063f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
2064c7d471b6ae936127311a816a8d15b4565746af48Michel Daenzer       vbl->request.type &= ~DRM_VBLANK_RELATIVE;
2065ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes       if (ret && errno == EINTR) {
2066ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       clock_gettime(CLOCK_MONOTONIC, &cur);
2067ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       /* Timeout after 1s */
2068ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       if (cur.tv_sec > timeout.tv_sec + 1 ||
2069ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		   (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
2070ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		    timeout.tv_nsec)) {
2071ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       errno = EBUSY;
2072ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       ret = -1;
2073ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes		       break;
2074ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes	       }
2075f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes       }
207655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    } while (ret && errno == EINTR);
207755acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2078f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnesout:
207955acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer    return ret;
208055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer}
208155acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer
2082b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmError(int err, const char *label)
2083b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2084b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    switch (err) {
2085ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_DEVICE:
2086ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no device\n", label);
2087ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2088ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NO_ACCESS:
2089ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: no access\n", label);
2090ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2091ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_NOT_ROOT:
2092ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: not root\n", label);
2093ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2094ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    case DRM_ERR_INVALID:
2095ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "%s: invalid args\n", label);
2096ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	break;
2097b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    default:
2098ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (err < 0)
2099ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    err = -err;
2100b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
2101b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	break;
2102b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2103b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2104b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 1;
2105b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2106b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2107d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2108d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Install IRQ handler.
2109d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2110d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2111d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param irq IRQ number.
2112d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2113d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2114d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2115d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2116d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2117d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2118d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2119b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlInstHandler(int fd, int irq)
2120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2122b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2123fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctl);
2124b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_INST_HANDLER;
2125b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = irq;
21268b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2127ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2128b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2129b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2130b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2131d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2132d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2133d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Uninstall IRQ handler.
2134d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2135d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2136d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2137d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2138d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2139d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2140d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2141d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure.
2142d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2143b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlUninstHandler(int fd)
2144b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2145b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_control_t ctl;
2146b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2147fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(ctl);
2148b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.func  = DRM_UNINST_HANDLER;
2149b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    ctl.irq   = 0;
21508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2151ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2154b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2155b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFinish(int fd, int context, drmLockFlags flags)
2156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_lock_t lock;
2158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2159fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(lock);
2160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    lock.context = context;
2161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_READY)      lock.flags |= _DRM_LOCK_READY;
2162b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_QUIESCENT)  lock.flags |= _DRM_LOCK_QUIESCENT;
2163b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH)      lock.flags |= _DRM_LOCK_FLUSH;
2164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_LOCK_FLUSH_ALL)  lock.flags |= _DRM_LOCK_FLUSH_ALL;
2165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
21678b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2168ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2169b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2170b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2172d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2173d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get IRQ from bus ID.
2174d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2175d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2176d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busnum bus number.
2177d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param devnum device number.
2178d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param funcnum function number.
2179d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2180d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return IRQ number on success, or a negative value on failure.
2181d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2182d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2183d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2184d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_irq_busid structure.
2185d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
2186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2187b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drm_irq_busid_t p;
2189b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2190fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(p);
2191b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.busnum  = busnum;
2192b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.devnum  = devnum;
2193b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    p.funcnum = funcnum;
21948b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2195ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return p.irq;
2197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2198b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
21998696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAddContextTag(int fd, drm_context_t context, void *tag)
2200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2203b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    if (drmHashInsert(entry->tagTable, context, tag)) {
2204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashDelete(entry->tagTable, context);
2205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss	drmHashInsert(entry->tagTable, context, tag);
2206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    }
2207b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return 0;
2208b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2209b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
22108696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDelContextTag(int fd, drm_context_t context)
2211b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2212b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2213b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2214b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return drmHashDelete(entry->tagTable, context);
2215b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2216b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
22178696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlvoid *drmGetContextTag(int fd, drm_context_t context)
2218b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{
2219b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    drmHashEntry  *entry = drmGetEntry(fd);
2220b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    void          *value;
2221360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes
2222ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (drmHashLookup(entry->tagTable, context, &value))
2223ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return NULL;
2224b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
2225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss    return value;
2226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss}
2227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss
222822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
222922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t handle)
223074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
223174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
223274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
2233fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
223474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
2235961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston    map.handle = (void *)(uintptr_t)handle;
223674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22378b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2238ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
223974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
224074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
224174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
224222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
224322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                                drm_handle_t *handle)
224474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{
224574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    drm_ctx_priv_map_t map;
224674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
2247fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
224874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    map.ctx_id = ctx_id;
224974e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2251ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
2252ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (handle)
2253961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston	*handle = (drm_handle_t)(uintptr_t)map.handle;
225474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
225574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin    return 0;
225674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin}
225774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin
22588696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
22598696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl	      drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
226088dbee54ed400a3fd5594fab506518c171167805Rik Faith	      int *mtrr)
226188dbee54ed400a3fd5594fab506518c171167805Rik Faith{
226288dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_map_t map;
226388dbee54ed400a3fd5594fab506518c171167805Rik Faith
2264fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(map);
226588dbee54ed400a3fd5594fab506518c171167805Rik Faith    map.offset = idx;
22668b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2267ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
226888dbee54ed400a3fd5594fab506518c171167805Rik Faith    *offset = map.offset;
226988dbee54ed400a3fd5594fab506518c171167805Rik Faith    *size   = map.size;
227088dbee54ed400a3fd5594fab506518c171167805Rik Faith    *type   = map.type;
227188dbee54ed400a3fd5594fab506518c171167805Rik Faith    *flags  = map.flags;
227288dbee54ed400a3fd5594fab506518c171167805Rik Faith    *handle = (unsigned long)map.handle;
227388dbee54ed400a3fd5594fab506518c171167805Rik Faith    *mtrr   = map.mtrr;
227488dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
227588dbee54ed400a3fd5594fab506518c171167805Rik Faith}
227688dbee54ed400a3fd5594fab506518c171167805Rik Faith
227788dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
227888dbee54ed400a3fd5594fab506518c171167805Rik Faith		 unsigned long *magic, unsigned long *iocs)
227988dbee54ed400a3fd5594fab506518c171167805Rik Faith{
228088dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_client_t client;
228188dbee54ed400a3fd5594fab506518c171167805Rik Faith
2282fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(client);
228388dbee54ed400a3fd5594fab506518c171167805Rik Faith    client.idx = idx;
22848b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2285ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
228688dbee54ed400a3fd5594fab506518c171167805Rik Faith    *auth      = client.auth;
228788dbee54ed400a3fd5594fab506518c171167805Rik Faith    *pid       = client.pid;
228888dbee54ed400a3fd5594fab506518c171167805Rik Faith    *uid       = client.uid;
228988dbee54ed400a3fd5594fab506518c171167805Rik Faith    *magic     = client.magic;
229088dbee54ed400a3fd5594fab506518c171167805Rik Faith    *iocs      = client.iocs;
229188dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
229288dbee54ed400a3fd5594fab506518c171167805Rik Faith}
229388dbee54ed400a3fd5594fab506518c171167805Rik Faith
229488dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetStats(int fd, drmStatsT *stats)
229588dbee54ed400a3fd5594fab506518c171167805Rik Faith{
229688dbee54ed400a3fd5594fab506518c171167805Rik Faith    drm_stats_t s;
2297de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Vesely    unsigned    i;
229888dbee54ed400a3fd5594fab506518c171167805Rik Faith
2299fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(s);
23008b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2301ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return -errno;
230288dbee54ed400a3fd5594fab506518c171167805Rik Faith
230388dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = 0;
230488dbee54ed400a3fd5594fab506518c171167805Rik Faith    memset(stats, 0, sizeof(*stats));
230588dbee54ed400a3fd5594fab506518c171167805Rik Faith    if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
230688dbee54ed400a3fd5594fab506518c171167805Rik Faith	return -1;
230788dbee54ed400a3fd5594fab506518c171167805Rik Faith
230888dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_VALUE                              \
230988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
231088dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%8.8s";      \
231188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 1;            \
231288dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
231388dbee54ed400a3fd5594fab506518c171167805Rik Faith
231488dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_COUNT                              \
231588dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
231688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
231788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
231888dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "kgm";        \
231988dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1000;         \
232088dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
232188dbee54ed400a3fd5594fab506518c171167805Rik Faith
232288dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_BYTE                               \
232388dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].long_format = "%-20.20s";   \
232488dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].rate_format = "%5.5s";      \
232588dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].isvalue     = 0;            \
232688dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult_names  = "KGM";        \
232788dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].mult        = 1024;         \
232888dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->data[i].verbose     = 0
232988dbee54ed400a3fd5594fab506518c171167805Rik Faith
233088dbee54ed400a3fd5594fab506518c171167805Rik Faith
233188dbee54ed400a3fd5594fab506518c171167805Rik Faith    stats->count = s.count;
233288dbee54ed400a3fd5594fab506518c171167805Rik Faith    for (i = 0; i < s.count; i++) {
233388dbee54ed400a3fd5594fab506518c171167805Rik Faith	stats->data[i].value = s.data[i].value;
233488dbee54ed400a3fd5594fab506518c171167805Rik Faith	switch (s.data[i].type) {
233588dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCK:
233688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Lock";
233788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
233888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
233988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
234088dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_OPENS:
234188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Opens";
234288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "O";
234388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
234488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
234588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
234688dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_CLOSES:
234788dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Closes";
234888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lock";
234988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
235088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].verbose   = 1;
235188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
235288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IOCTLS:
235388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Ioctls";
235488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ioc/s";
235588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
235688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
235788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_LOCKS:
235888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Locks";
235988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Lck/s";
236088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
236188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
236288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_UNLOCKS:
236388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Unlocks";
236488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Unl/s";
236588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
236688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
236788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_IRQ:
236888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "IRQs";
236988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "IRQ/s";
237088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
237188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
237288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_PRIMARY:
237388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Primary Bytes";
237488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "PB/s";
237588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
237688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
237788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SECONDARY:
237888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Secondary Bytes";
237988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "SB/s";
238088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
238188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
238288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_DMA:
238388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "DMA";
238488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "DMA/s";
238588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
238688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
238788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_SPECIAL:
238888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Special DMA";
238988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "dma/s";
239088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
239188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
239288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_MISSED:
239388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Miss";
239488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Ms/s";
239588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
239688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
239788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_VALUE:
239888dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Value";
239988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Value";
240088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_VALUE;
240188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
240288dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_BYTE:
240388dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Bytes";
240488dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "B/s";
240588dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_BYTE;
240688dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
240788dbee54ed400a3fd5594fab506518c171167805Rik Faith	case _DRM_STAT_COUNT:
240888dbee54ed400a3fd5594fab506518c171167805Rik Faith	default:
240988dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].long_name = "Count";
241088dbee54ed400a3fd5594fab506518c171167805Rik Faith	    stats->data[i].rate_name = "Cnt/s";
241188dbee54ed400a3fd5594fab506518c171167805Rik Faith	    SET_COUNT;
241288dbee54ed400a3fd5594fab506518c171167805Rik Faith	    break;
241388dbee54ed400a3fd5594fab506518c171167805Rik Faith	}
241488dbee54ed400a3fd5594fab506518c171167805Rik Faith    }
241588dbee54ed400a3fd5594fab506518c171167805Rik Faith    return 0;
241688dbee54ed400a3fd5594fab506518c171167805Rik Faith}
241788dbee54ed400a3fd5594fab506518c171167805Rik Faith
2418d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
241906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Issue a set-version ioctl.
242006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
242106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param fd file descriptor.
242206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param drmCommandIndex command index
242306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param data source pointer of the data to be read and written.
242406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param size size of the data to be read and written.
242506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
242606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return zero on success, or a negative value on failure.
242706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt *
242806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal
242906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * It issues a read-write ioctl given by
243006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
243106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */
243222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmSetInterfaceVersion(int fd, drmSetVersion *version)
243306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{
243406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    int retcode = 0;
243506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    drm_set_version_t sv;
243606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
2437fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    memclear(sv);
243806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_major = version->drm_di_major;
243906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_di_minor = version->drm_di_minor;
244006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_major = version->drm_dd_major;
244106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    sv.drm_dd_minor = version->drm_dd_minor;
244206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
24438b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
244406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt	retcode = -errno;
244506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    }
244606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
244706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_major = sv.drm_di_major;
244806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_di_minor = sv.drm_di_minor;
244906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_major = sv.drm_dd_major;
245006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    version->drm_dd_minor = sv.drm_dd_minor;
245106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
245206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt    return retcode;
245306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt}
245406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt
245506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/**
2456d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific command.
2457d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2458d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2459d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2460d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2461d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2462d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2463d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2464d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a ioctl given by
2465d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2466d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
24673903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owenint drmCommandNone(int fd, unsigned long drmCommandIndex)
24683903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
24693903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
24703903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
24713903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
24723903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2473fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter    if (drmIoctl(fd, request, NULL)) {
24743903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
24753903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
24763903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
24773903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
24783903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2479d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2480d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2481d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read command.
2482d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2483d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2484d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2485d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data destination pointer of the data to be read.
2486d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read.
2487d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2488d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2489d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2490d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2491d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read ioctl given by
2492d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2493d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
249422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
249522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                   unsigned long size)
24963903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
24973903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
24983903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
249974ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
250074ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25013903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25028b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
25033903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25043903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
25053903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25063903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
25073903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2508d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2509d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2510d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific write command.
2511d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2512d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2513d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2514d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be written.
2515d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be written.
2516d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2517d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2518d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2519d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2520d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a write ioctl given by
2521d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2522d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
252322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
252422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                    unsigned long size)
25253903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25263903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25273903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
252874ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
252974ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25303903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25318b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data)) {
25323903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25333903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    }
25343903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25353903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
25363903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
2537d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca
2538d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/**
2539d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read-write command.
2540d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2541d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor.
2542d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param drmCommandIndex command index
2543d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be read and written.
2544d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read and written.
2545d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2546d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure.
2547d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca *
2548d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal
2549d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It issues a read-write ioctl given by
2550d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2551d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */
255222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
255322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson                        unsigned long size)
25543903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{
25553903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    unsigned long request;
25563903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
255774ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane    request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
255874ef13fd009b9e37956e4207d0a5ed92f4b5e39aAlan Hourihane	DRM_COMMAND_BASE + drmCommandIndex, size);
25593903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen
25608b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard    if (drmIoctl(fd, request, data))
25613903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen	return -errno;
25623903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen    return 0;
25633903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen}
2564166da9355d95affe427a6cff3525df60e80a99dfThomas Hellstrom
2565d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie#define DRM_MAX_FDS 16
2566d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic struct {
2567ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    char *BusID;
2568ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2569ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int refcount;
2570d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} connection[DRM_MAX_FDS];
2571d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2572d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic int nr_fds = 0;
2573d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2574d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlieint drmOpenOnce(void *unused,
2575d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		const char *BusID,
2576d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie		int *newlyopened)
2577d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2578ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2579ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int fd;
2580d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2581ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++)
2582ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (strcmp(BusID, connection[i].BusID) == 0) {
2583ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    connection[i].refcount++;
2584ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    *newlyopened = 0;
2585ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    return connection[i].fd;
2586ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2587ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian
2588ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    fd = drmOpen(unused, BusID);
2589ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (fd <= 0 || nr_fds == DRM_MAX_FDS)
2590ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	return fd;
2591d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2592ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].BusID = strdup(BusID);
2593ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].fd = fd;
2594ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    connection[nr_fds].refcount = 1;
2595ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    *newlyopened = 1;
2596d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2597ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    if (0)
2598ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	fprintf(stderr, "saved connection %d for %s %d\n",
2599ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		nr_fds, connection[nr_fds].BusID,
2600ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		strcmp(BusID, connection[nr_fds].BusID));
2601d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2602ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    nr_fds++;
2603d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2604ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    return fd;
2605d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2606d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2607d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlievoid drmCloseOnce(int fd)
2608d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{
2609ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    int i;
2610d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2611ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    for (i = 0; i < nr_fds; i++) {
2612ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	if (fd == connection[i].fd) {
2613ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    if (--connection[i].refcount == 0) {
2614ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		drmClose(connection[i].fd);
2615ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		free(connection[i].BusID);
2616d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2617ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		if (i < --nr_fds)
2618ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		    connection[i] = connection[nr_fds];
2619d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie
2620ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian		return;
2621ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	    }
2622ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian	}
2623ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian    }
2624d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie}
2625731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2626731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmSetMaster(int fd)
2627731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2628fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
2629731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
2630731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes
2631731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmDropMaster(int fd)
2632731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{
2633fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter	return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
2634731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes}
263522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
263622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsbergchar *drmGetDeviceNameFromFd(int fd)
263722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg{
263822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	char name[128];
263922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	struct stat sbuf;
264022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	dev_t d;
264122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	int i;
264222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
264322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	/* The whole drmOpen thing is a fiasco and we need to find a way
264422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * back to just using open(2).  For now, however, lets just make
264522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * things worse with even more ad hoc directory walking code to
264622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	 * discover the device file name. */
264722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
264822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	fstat(fd, &sbuf);
264922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	d = sbuf.st_rdev;
265022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
265122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	for (i = 0; i < DRM_MAX_MINOR; i++) {
265222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
265322d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
265422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg			break;
265522d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	}
265622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg	if (i == DRM_MAX_MINOR)
265722d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg		return NULL;
265822d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg
26590a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson	return strdup(name);
266022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg}
2661cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2662cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
2663cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2664cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2665cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2666cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2667cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.handle = handle;
2668cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = flags;
2669cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
2670cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2671cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2672cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2673cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*prime_fd = args.fd;
2674cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2675cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2676cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2677cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2678cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{
2679cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	struct drm_prime_handle args;
2680cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	int ret;
2681cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2682cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.fd = prime_fd;
2683cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	args.flags = 0;
2684cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
2685cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	if (ret)
2686cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie		return ret;
2687cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2688cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	*handle = args.handle;
2689cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie	return 0;
2690cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie}
2691cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie
2692