1d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \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> 39fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov#include <stdbool.h> 4079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <unistd.h> 4179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <string.h> 42015efd1bfa72ab8b80cc45f11eb22d7f1a1085f7Ian Romanick#include <strings.h> 4379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <ctype.h> 440ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#include <dirent.h> 450ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#include <stddef.h> 4679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <fcntl.h> 4779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <errno.h> 484031dc17bb728850c9b079c8d5f9cc0a379b9d46Felix Janda#include <limits.h> 4979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <signal.h> 50f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes#include <time.h> 5179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/types.h> 5279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/stat.h> 5379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#define stat_t struct stat 5479038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/ioctl.h> 5579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <sys/time.h> 5679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie#include <stdarg.h> 578c8d5dd76fb80637031e824a48ceaa0f9f65d2ddMike Frysinger#ifdef MAJOR_IN_MKDEV 588c8d5dd76fb80637031e824a48ceaa0f9f65d2ddMike Frysinger#include <sys/mkdev.h> 598c8d5dd76fb80637031e824a48ceaa0f9f65d2ddMike Frysinger#endif 608c8d5dd76fb80637031e824a48ceaa0f9f65d2ddMike Frysinger#ifdef MAJOR_IN_SYSMACROS 618c8d5dd76fb80637031e824a48ceaa0f9f65d2ddMike Frysinger#include <sys/sysmacros.h> 620e1135de5cbb783846a4f7e9ef8a5f953f7c77aeAlan Coopersmith#endif 63b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov#include <math.h> 64b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 65b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss/* Not all systems have MAP_FAILED defined */ 66b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#ifndef MAP_FAILED 67b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#define MAP_FAILED ((void *)-1) 68b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#endif 69b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 70b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss#include "xf86drm.h" 7142465feb9759ef5a6d79d7e628510cd0a081f913Emil Velikov#include "libdrm_macros.h" 72b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 735f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov#include "util_math.h" 745f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov 75fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray#ifdef __OpenBSD__ 7650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_PRIMARY_MINOR_NAME "drm" 7750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_CONTROL_MINOR_NAME "drmC" 7850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_RENDER_MINOR_NAME "drmR" 79fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray#else 8050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_PRIMARY_MINOR_NAME "card" 8150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_CONTROL_MINOR_NAME "controlD" 8250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_RENDER_MINOR_NAME "renderD" 83fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray#endif 84fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray 8527c3785d3f12743a9e160238a4d00353060ec2f2Hasso Tepper#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 86cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 145 87cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#endif 88cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt 89cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifdef __NetBSD__ 90cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#define DRM_MAJOR 34 9188dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif 9288dbee54ed400a3fd5594fab506518c171167805Rik Faith 9366c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#ifdef __OpenBSD__ 9466c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#ifdef __i386__ 9566c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#define DRM_MAJOR 88 9666c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#else 9766c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#define DRM_MAJOR 87 9866c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#endif 9966c3afb75fa993f2f8b00c2dd9c2ec37a3a9dfb6Jonathan Gray#endif /* __OpenBSD__ */ 100b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane 101cfa778af9c70faea8c13e5cb7f80029eee0d074eEric Anholt#ifndef DRM_MAJOR 10250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_MAJOR 226 /* Linux */ 10388dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif 10488dbee54ed400a3fd5594fab506518c171167805Rik Faith 105c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray#ifdef __OpenBSD__ 106c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Graystruct drm_pciinfo { 107c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint16_t domain; 108c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint8_t bus; 109c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint8_t dev; 110c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint8_t func; 111c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint16_t vendor_id; 112c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint16_t device_id; 113c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint16_t subvendor_id; 114c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint16_t subdevice_id; 115c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray uint8_t revision_id; 116c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray}; 117c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 118c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray#define DRM_IOCTL_GET_PCIINFO DRM_IOR(0x15, struct drm_pciinfo) 119c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray#endif 120c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 12156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes#define DRM_MSG_VERBOSITY 3 12256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes 123fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter#define memclear(s) memset(&s, 0, sizeof(s)) 124fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 12579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airliestatic drmServerInfoPtr drm_server_info; 12679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie 12779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid drmSetServerInfo(drmServerInfoPtr info) 12879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{ 129ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian drm_server_info = info; 13079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie} 13179038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie 132d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 133d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Output a message to stderr. 134d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 135d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param format printf() like format string. 136d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 137d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 138d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around vfprintf(). 139d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 14079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie 14144b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry Redingstatic int DRM_PRINTFLIKE(1, 0) 14244b08c0ddf7ced99a5914421f18b269a1dcaafaeThierry RedingdrmDebugPrint(const char *format, va_list ap) 14379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{ 144ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian return vfprintf(stderr, format, ap); 14579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie} 14679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie 147c4857429c716f35e1fa054d1990cae28055d96d7Eric Anholtvoid 14856bd9c207770d41a497f3e8237a1099dd9d4cd91David DawesdrmMsg(const char *format, ...) 14956bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes{ 15050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely va_list ap; 15156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes const char *env; 152eb7c2d5e63e0e9d133b16880e36c14676276d412Rob Clark if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || 153eb7c2d5e63e0e9d133b16880e36c14676276d412Rob Clark (drm_server_info && drm_server_info->debug_print)) 15456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes { 15550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely va_start(ap, format); 15650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drm_server_info) { 15750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drm_server_info->debug_print(format,ap); 15850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } else { 15950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmDebugPrint(format, ap); 16050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 16150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely va_end(ap); 16256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes } 16356bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes} 16456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes 165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void *drmHashTable = NULL; /* Context switch callbacks */ 166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 16779038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlievoid *drmGetHashTable(void) 16879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie{ 169ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian return drmHashTable; 17079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie} 171b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid *drmMalloc(int size) 173b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 174d0e592d4e9b59d9cc185f1d63b3c1dd818e95098Emil Velikov return calloc(1, size); 175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFree(void *pt) 178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 179d0e592d4e9b59d9cc185f1d63b3c1dd818e95098Emil Velikov free(pt); 180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1828b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard/** 1838b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard * Call ioctl, restarting if it is interupted 1848b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard */ 185731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint 18641b83a99583486ad4f8760a6537d34783769bfc3Coleman KanedrmIoctl(int fd, unsigned long request, void *arg) 1878b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard{ 18850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int ret; 1898b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard 1908b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard do { 19150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = ioctl(fd, request, arg); 1928b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); 1938b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard return ret; 1948b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard} 195b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic unsigned long drmGetKeyFromFd(int fd) 197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 198fcc21069b7019a4a93e1ceacc175ccd682353861David Dawes stat_t st; 199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss st.st_rdev = 0; 201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss fstat(fd, &st); 202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return st.st_rdev; 203b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 20579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave AirliedrmHashEntry *drmGetEntry(int fd) 206b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 207b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss unsigned long key = drmGetKeyFromFd(fd); 208b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss void *value; 209b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashEntry *entry; 210b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 211ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!drmHashTable) 21250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmHashTable = drmHashCreate(); 213b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 214b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (drmHashLookup(drmHashTable, key, &value)) { 21550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely entry = drmMalloc(sizeof(*entry)); 21650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely entry->fd = fd; 21750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely entry->f = NULL; 21850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely entry->tagTable = drmHashCreate(); 21950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmHashInsert(drmHashTable, key, entry); 220b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } else { 22150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely entry = value; 222b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 223b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return entry; 224b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 226d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 22706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Compare two busid strings 22806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * 22906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param first 23006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param second 23106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * 23206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return 1 if matched. 23306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * 23406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal 23506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * This function compares two bus ID strings. It understands the older 23606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is 23706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * domain, b is bus, d is device, f is function. 23806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */ 239b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidtstatic int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok) 24006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{ 24106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt /* First, check if the IDs are exactly the same */ 24206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt if (strcasecmp(id1, id2) == 0) 24350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 1; 24406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 24506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt /* Try to match old/new-style PCI bus IDs. */ 24606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt if (strncasecmp(id1, "pci", 3) == 0) { 24750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely unsigned int o1, b1, d1, f1; 24850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely unsigned int o2, b2, d2, f2; 24950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int ret; 25050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 25150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1); 25250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret != 4) { 25350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely o1 = 0; 25450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1); 25550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret != 3) 25650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 25750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 25850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 25950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2); 26050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret != 4) { 26150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely o2 = 0; 26250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2); 26350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret != 3) 26450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 26550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 26650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 26750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* If domains aren't properly supported by the kernel interface, 26850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * just ignore them, which sucks less than picking a totally random 26950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * card with "open by name" 27050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely */ 27150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!pci_domain_ok) 27250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely o1 = o2 = 0; 27350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 27450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2)) 27550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 27650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely else 27750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 1; 27806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt } 27906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt return 0; 28006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt} 28106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 28206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/** 283c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Handles error checking for chown call. 284c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * 285c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param path to file. 286c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new owner. 287c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \param id of the new group. 288c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * 289c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \return zero if success or -1 if failure. 290c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * 291c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * \internal 292c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * Checks for failure. If failure was caused by signal call chown again. 293c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * If any other failure happened then it will output error mesage using 294c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen * drmMsg() call. 295c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen */ 2966fc0e4ba1ea153ff949cba0002fc5ed544de0de0Jan Vesely#if !defined(UDEV) 297c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminenstatic int chown_check_return(const char *path, uid_t owner, gid_t group) 298c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen{ 29950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int rv; 300c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen 30150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely do { 30250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely rv = chown(path, owner, group); 30350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } while (rv != 0 && errno == EINTR); 304c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen 30550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (rv == 0) 30650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 307c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen 30850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("Failed to change owner or group for file %s! %d: %s\n", 30950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely path, errno, strerror(errno)); 31050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 311c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen} 3126fc0e4ba1ea153ff949cba0002fc5ed544de0de0Jan Vesely#endif 313c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen 314c5a5bbbe899400642795c1d95aef78deade9241fPauli Nieminen/** 315d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device, creating it if necessary. 316d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 317d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param dev major and minor numbers of the device. 318d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor minor number of the device. 31950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 320d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error. 321d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 322d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 323d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assembles the device name from \p minor and opens it, creating the device 324d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * special file node with the major and minor numbers specified by \p dev and 325d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parent directory if necessary and was called by root. 326d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 327de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Veselystatic int drmOpenDevice(dev_t dev, int minor, int type) 328b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 3299c775d0b2f303389c24aea5e8abc1473f0cf93e8David Dawes stat_t st; 3300c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns const char *dev_name; 33188dbee54ed400a3fd5594fab506518c171167805Rik Faith char buf[64]; 33288dbee54ed400a3fd5594fab506518c171167805Rik Faith int fd; 33379038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie mode_t devmode = DRM_DEV_MODE, serv_mode; 3340706c14e7cc5f1d996bb1c3c526f877c4f8fc215Jan Vesely gid_t serv_group; 3350706c14e7cc5f1d996bb1c3c526f877c4f8fc215Jan Vesely#if !defined(UDEV) 33688dbee54ed400a3fd5594fab506518c171167805Rik Faith int isroot = !geteuid(); 33788dbee54ed400a3fd5594fab506518c171167805Rik Faith uid_t user = DRM_DEV_UID; 3380706c14e7cc5f1d996bb1c3c526f877c4f8fc215Jan Vesely gid_t group = DRM_DEV_GID; 3390706c14e7cc5f1d996bb1c3c526f877c4f8fc215Jan Vesely#endif 3400706c14e7cc5f1d996bb1c3c526f877c4f8fc215Jan Vesely 3410c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns switch (type) { 3420c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_PRIMARY: 34350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_DEV_NAME; 34450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 3450c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_CONTROL: 34650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_CONTROL_DEV_NAME; 34750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 3480c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_RENDER: 34950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_RENDER_DEV_NAME; 35050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 3510c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns default: 35250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -EINVAL; 3530c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns }; 3540c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns 3550c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns sprintf(buf, dev_name, DRM_DIR_NAME, minor); 35606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt drmMsg("drmOpenDevice: node name is %s\n", buf); 35756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes 358eb7c2d5e63e0e9d133b16880e36c14676276d412Rob Clark if (drm_server_info && drm_server_info->get_perms) { 35950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drm_server_info->get_perms(&serv_group, &serv_mode); 36050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely devmode = serv_mode ? serv_mode : DRM_DEV_MODE; 36150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); 36279038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie } 363569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul 3649101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#if !defined(UDEV) 36588dbee54ed400a3fd5594fab506518c171167805Rik Faith if (stat(DRM_DIR_NAME, &st)) { 36650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!isroot) 36750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return DRM_ERR_NOT_ROOT; 36850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE); 36950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */ 37050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE); 371569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul } 372b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 37306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt /* Check if the device node exists and create it if necessary. */ 374d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt if (stat(buf, &st)) { 37550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!isroot) 37650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return DRM_ERR_NOT_ROOT; 37750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely remove(buf); 37850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely mknod(buf, S_IFCHR | devmode, dev); 379b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 38079038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie 381eb7c2d5e63e0e9d133b16880e36c14676276d412Rob Clark if (drm_server_info && drm_server_info->get_perms) { 38250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID; 38350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chown_check_return(buf, user, group); 38450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chmod(buf, devmode); 38579038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie } 3869101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#else 3879101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie /* if we modprobed then wait for udev */ 3889101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie { 38950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int udev_count = 0; 3909101a0205c897fea28e6a3d875111a83ad7f7732Dave Airliewait_for_udev: 3919101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie if (stat(DRM_DIR_NAME, &st)) { 39250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely usleep(20); 39350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely udev_count++; 39450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 39550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (udev_count == 50) 39650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 39750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely goto wait_for_udev; 39850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 39950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 40050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (stat(buf, &st)) { 40150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely usleep(20); 40250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely udev_count++; 40350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 40450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (udev_count == 50) 40550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 40650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely goto wait_for_udev; 40750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 4089101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie } 4099101a0205c897fea28e6a3d875111a83ad7f7732Dave Airlie#endif 41088dbee54ed400a3fd5594fab506518c171167805Rik Faith 41156bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes fd = open(buf, O_RDWR, 0); 41256bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes drmMsg("drmOpenDevice: open result is %d, (%s)\n", 41350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fd, fd < 0 ? strerror(errno) : "OK"); 414ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (fd >= 0) 41550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 416d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt 41739e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#if !defined(UDEV) 41806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt /* Check if the device node is not what we expect it to be, and recreate it 41906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * and try again if so. 42006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */ 421d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt if (st.st_rdev != dev) { 42250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!isroot) 42350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return DRM_ERR_NOT_ROOT; 42450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely remove(buf); 42550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely mknod(buf, S_IFCHR | devmode, dev); 42650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drm_server_info && drm_server_info->get_perms) { 42750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chown_check_return(buf, user, group); 42850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely chmod(buf, devmode); 42950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 430d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt } 431d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt fd = open(buf, O_RDWR, 0); 432d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt drmMsg("drmOpenDevice: open result is %d, (%s)\n", 43350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fd, fd < 0 ? strerror(errno) : "OK"); 434ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (fd >= 0) 43550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 436d2f2b42f1d206fd248ada48ce2c498e31351ab33Eric Anholt 43756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes drmMsg("drmOpenDevice: Open failed\n"); 43888dbee54ed400a3fd5594fab506518c171167805Rik Faith remove(buf); 43939e5e982242cd2b611a9dfc1e9b63f857d52da61Dave Airlie#endif 44088dbee54ed400a3fd5594fab506518c171167805Rik Faith return -errno; 441b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 442b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 443d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 444d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 445d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device 446d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 447d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param minor device minor number. 448d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param create allow to create the device if set. 449d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 450d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error. 45150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 452d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 453d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Calls drmOpenDevice() if \p create is set, otherwise assembles the device 454d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * name from \p minor and opens it. 455d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 456731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesstatic int drmOpenMinor(int minor, int create, int type) 45788dbee54ed400a3fd5594fab506518c171167805Rik Faith{ 45888dbee54ed400a3fd5594fab506518c171167805Rik Faith int fd; 45988dbee54ed400a3fd5594fab506518c171167805Rik Faith char buf[64]; 4600c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns const char *dev_name; 46150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 462ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (create) 46350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); 46450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 4650c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns switch (type) { 4660c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_PRIMARY: 46750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_DEV_NAME; 46850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 4690c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_CONTROL: 47050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_CONTROL_DEV_NAME; 47150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 4720c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns case DRM_NODE_RENDER: 47350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_name = DRM_RENDER_DEV_NAME; 47450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 4750c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns default: 47650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -EINVAL; 4770c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns }; 4780c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns 4790c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns sprintf(buf, dev_name, DRM_DIR_NAME, minor); 480ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if ((fd = open(buf, O_RDWR, 0)) >= 0) 48150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 48288dbee54ed400a3fd5594fab506518c171167805Rik Faith return -errno; 48388dbee54ed400a3fd5594fab506518c171167805Rik Faith} 48488dbee54ed400a3fd5594fab506518c171167805Rik Faith 485569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul 486d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 487d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine whether the DRM kernel driver has been loaded. 48850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 489d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return 1 if the DRM driver is loaded, 0 otherwise. 490d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 49150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \internal 492d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Determine the presence of the kernel driver by attempting to open the 0 493d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * minor and get version information. For backward compatibility with older 494d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Linux implementations, /proc/dri is also checked. 495d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 496569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulint drmAvailable(void) 497569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul{ 498569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul drmVersionPtr version; 499569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul int retval = 0; 500569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul int fd; 501360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 502ad8bbfd3c74466f088be8088d2d0524bed392b71Frank Binns if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) { 503b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#ifdef __linux__ 50450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* Try proc for backward Linux compatibility */ 50550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!access("/proc/dri/0", R_OK)) 50650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 1; 507b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane#endif 50850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 509569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul } 51050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 51188dbee54ed400a3fd5594fab506518c171167805Rik Faith if ((version = drmGetVersion(fd))) { 51250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval = 1; 51350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeVersion(version); 51488dbee54ed400a3fd5594fab506518c171167805Rik Faith } 51588dbee54ed400a3fd5594fab506518c171167805Rik Faith close(fd); 516569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul 517569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul return retval; 518569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul} 519569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paul 520f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmGetMinorBase(int type) 521f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{ 522f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou switch (type) { 523f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou case DRM_NODE_PRIMARY: 524f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return 0; 525f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou case DRM_NODE_CONTROL: 526f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return 64; 527f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou case DRM_NODE_RENDER: 528f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return 128; 529f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou default: 530f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return -1; 531f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou }; 532f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou} 533d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 5341f73578df32f895a678a41758f6c563f49484347Frank Binnsstatic int drmGetMinorType(int minor) 5351f73578df32f895a678a41758f6c563f49484347Frank Binns{ 5361f73578df32f895a678a41758f6c563f49484347Frank Binns int type = minor >> 6; 5371f73578df32f895a678a41758f6c563f49484347Frank Binns 5381f73578df32f895a678a41758f6c563f49484347Frank Binns if (minor < 0) 5391f73578df32f895a678a41758f6c563f49484347Frank Binns return -1; 5401f73578df32f895a678a41758f6c563f49484347Frank Binns 5411f73578df32f895a678a41758f6c563f49484347Frank Binns switch (type) { 5421f73578df32f895a678a41758f6c563f49484347Frank Binns case DRM_NODE_PRIMARY: 5431f73578df32f895a678a41758f6c563f49484347Frank Binns case DRM_NODE_CONTROL: 5441f73578df32f895a678a41758f6c563f49484347Frank Binns case DRM_NODE_RENDER: 5451f73578df32f895a678a41758f6c563f49484347Frank Binns return type; 5461f73578df32f895a678a41758f6c563f49484347Frank Binns default: 5471f73578df32f895a678a41758f6c563f49484347Frank Binns return -1; 5481f73578df32f895a678a41758f6c563f49484347Frank Binns } 5491f73578df32f895a678a41758f6c563f49484347Frank Binns} 5501f73578df32f895a678a41758f6c563f49484347Frank Binns 5510ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovstatic const char *drmGetMinorName(int type) 5520ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{ 5530ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov switch (type) { 5540ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov case DRM_NODE_PRIMARY: 555fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray return DRM_PRIMARY_MINOR_NAME; 5560ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov case DRM_NODE_CONTROL: 557fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray return DRM_CONTROL_MINOR_NAME; 5580ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov case DRM_NODE_RENDER: 559fc083322b0c8a58b51976adf23a582bce8bb75f1Jonathan Gray return DRM_RENDER_MINOR_NAME; 5600ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov default: 5610ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov return NULL; 5620ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov } 5630ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov} 5640ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 565d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 566d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by bus ID. 567d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 568d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID. 569f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type device node type. 570d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 571d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error. 572d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 573d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 574d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function attempts to open every possible minor (up to DRM_MAX_MINOR), 575d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * comparing the device bus ID with the one supplied. 576d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor() and drmGetBusid(). 578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 579f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByBusid(const char *busid, int type) 580e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss{ 581b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt int i, pci_domain_ok = 1; 58288dbee54ed400a3fd5594fab506518c171167805Rik Faith int fd; 58388dbee54ed400a3fd5594fab506518c171167805Rik Faith const char *buf; 58406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt drmSetVersion sv; 585f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou int base = drmGetMinorBase(type); 586f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou 587f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou if (base < 0) 588f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return -1; 58906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 59006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); 591f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou for (i = base; i < base + DRM_MAX_MINOR; i++) { 59250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fd = drmOpenMinor(i, 1, type); 59350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); 59450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (fd >= 0) { 59550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* We need to try for 1.4 first for proper PCI domain support 59650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * and if that fails, we know the kernel is busted 59750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely */ 59850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_di_major = 1; 59950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_di_minor = 4; 60050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_dd_major = -1; /* Don't care */ 60150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_dd_minor = -1; /* Don't care */ 60250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drmSetInterfaceVersion(fd, &sv)) { 603b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#ifndef __alpha__ 60450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely pci_domain_ok = 0; 605b04515c5d6c95f573457a94267b855cceb639105Benjamin Herrenschmidt#endif 60650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_di_major = 1; 60750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_di_minor = 1; 60850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_dd_major = -1; /* Don't care */ 60950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sv.drm_dd_minor = -1; /* Don't care */ 61050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n"); 61150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmSetInterfaceVersion(fd, &sv); 61250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 61350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely buf = drmGetBusid(fd); 61450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); 61550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) { 61650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeBusid(buf); 61750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 61850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 61950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (buf) 62050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeBusid(buf); 62150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely close(fd); 62250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 623e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss } 624e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss return -1; 625e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss} 626e1dba5c3a73078dec24f07a6d685435677db94a4Daryll Strauss 627d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 628d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 629d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the device by name. 630d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 631d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name. 632f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type. 63350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 634d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error. 63550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 636d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 637d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function opens the first minor number that matches the driver name and 638d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * isn't already in use. If it's in use it then it will already have a bus ID 639d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * assigned. 64050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 641d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). 642d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 643f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhoustatic int drmOpenByName(const char *name, int type) 644b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss{ 64588dbee54ed400a3fd5594fab506518c171167805Rik Faith int i; 64688dbee54ed400a3fd5594fab506518c171167805Rik Faith int fd; 64788dbee54ed400a3fd5594fab506518c171167805Rik Faith drmVersionPtr version; 64856bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes char * id; 649f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou int base = drmGetMinorBase(type); 650f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou 651f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou if (base < 0) 652f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return -1; 653db85ed25afc616acfaadb21facf6066354f9d490Dave Airlie 65456bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes /* 65556bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes * Open the first minor number that matches the driver name and isn't 65656bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes * already in use. If it's in use it will have a busid assigned already. 65756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes */ 658f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou for (i = base; i < base + DRM_MAX_MINOR; i++) { 65950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if ((fd = drmOpenMinor(i, 1, type)) >= 0) { 66050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if ((version = drmGetVersion(fd))) { 66150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!strcmp(version->name, name)) { 66250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeVersion(version); 66350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely id = drmGetBusid(fd); 66450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); 66550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!id || !*id) { 66650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (id) 66750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeBusid(id); 66850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 66950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } else { 67050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeBusid(id); 67150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 67250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } else { 67350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeVersion(version); 67450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 67550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 67650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely close(fd); 67750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 678b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss } 679b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss 68088dbee54ed400a3fd5594fab506518c171167805Rik Faith#ifdef __linux__ 68122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson /* Backward-compatibility /proc support */ 682b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss for (i = 0; i < 8; i++) { 68350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely char proc_name[64], buf[512]; 68450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely char *driver, *pt, *devstring; 68550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int retcode; 68650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 68750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sprintf(proc_name, "/proc/dri/%d/name", i); 68850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if ((fd = open(proc_name, 0, 0)) >= 0) { 68950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retcode = read(fd, buf, sizeof(buf)-1); 69050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely close(fd); 69150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (retcode) { 69250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely buf[retcode-1] = '\0'; 69350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely for (driver = pt = buf; *pt && *pt != ' '; ++pt) 69450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ; 69550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (*pt) { /* Device is next */ 69650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *pt = '\0'; 69750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!strcmp(driver, name)) { /* Match */ 69850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely for (devstring = ++pt; *pt && *pt != ' '; ++pt) 69950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ; 70050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (*pt) { /* Found busid */ 70150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmOpenByBusid(++pt, type); 70250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } else { /* No busid */ 70350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmOpenDevice(strtol(devstring, NULL, 0),i, type); 70450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 70550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 70650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 70750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 70850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 709b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss } 71088dbee54ed400a3fd5594fab506518c171167805Rik Faith#endif 71188dbee54ed400a3fd5594fab506518c171167805Rik Faith 712b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss return -1; 713b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss} 714b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 715b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss 716d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 717d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Open the DRM device. 718d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 719d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Looks up the specified name and bus ID, and opens the device found. The 720d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * entry in /dev/dri is created if necessary and if called by root. 721d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 722d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param name driver name. Not referenced if bus ID is supplied. 723d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID. Zero if not known. 72450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 725d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a file descriptor on success, or a negative value on error. 72650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 727d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 728d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() 729d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * otherwise. 730d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 731b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmOpen(const char *name, const char *busid) 732b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 733f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou return drmOpenWithType(name, busid, DRM_NODE_PRIMARY); 734f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou} 735f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou 736f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou/** 737f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Open the DRM device with specified type. 738f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * 739f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * Looks up the specified name and bus ID, and opens the device found. The 740f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * entry in /dev/dri is created if necessary and if called by root. 741f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * 742f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param name driver name. Not referenced if bus ID is supplied. 743f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param busid bus ID. Zero if not known. 744f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \param type the device node type to open, PRIMARY, CONTROL or RENDER 745f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * 746f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \return a file descriptor on success, or a negative value on error. 747f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * 748f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * \internal 749f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() 750f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou * otherwise. 751f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou */ 752f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhouint drmOpenWithType(const char *name, const char *busid, int type) 753f1adc4b375a16b07f560b86a34e617984049c422Jammy Zhou{ 7542f9aea0661550a43c3d2ac33a5bc286870edd34ePrabhanjan Kandula if (name != NULL && drm_server_info && 7552f9aea0661550a43c3d2ac33a5bc286870edd34ePrabhanjan Kandula drm_server_info->load_module && !drmAvailable()) { 75650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* try to load the kernel module */ 75750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!drm_server_info->load_module(name)) { 75850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("[drm] failed to load kernel module \"%s\"\n", name); 75950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 76050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 76106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt } 76206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 76306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt if (busid) { 76450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int fd = drmOpenByBusid(busid, type); 76550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (fd >= 0) 76650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 76706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt } 76850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 76906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt if (name) 77050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmOpenByName(name, type); 77122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson 77206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt return -1; 773b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 774b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 775731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmOpenControl(int minor) 776731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 777731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes return drmOpenMinor(minor, 0, DRM_NODE_CONTROL); 778731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 779d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 7800c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binnsint drmOpenRender(int minor) 7810c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns{ 7820c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns return drmOpenMinor(minor, 0, DRM_NODE_RENDER); 7830c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns} 7840c5aaeef51233aec89ee1f43f03d457f278f8fa0Frank Binns 785d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 786d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the version information returned by drmGetVersion(). 787d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 788d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information. 789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It frees the memory pointed by \p %v as well as all the non-null strings 792d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * pointers in it. 793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 794b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussvoid drmFreeVersion(drmVersionPtr v) 795b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 796ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!v) 79750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return; 7989d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->name); 7999d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->date); 8009d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->desc); 801b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(v); 802b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 803b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 804d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 805d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 806d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the non-public version information returned by the kernel. 807d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 808d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param v pointer to the version information. 809d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 810d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 811d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to free the memory pointed by \p %v as well as all 812d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the non-null strings pointers in it. 813d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 814b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussstatic void drmFreeKernelVersion(drm_version_t *v) 815b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 816ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!v) 81750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return; 8189d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->name); 8199d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->date); 8209d8ba2d0d479f53b996c0a0e366acfee52daab3bJakob Bornecrantz drmFree(v->desc); 821b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(v); 822b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 823b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 824d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 825d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 826d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Copy version information. 82750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 828d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param d destination pointer. 829d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param s source pointer. 83050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 831d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 832d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by drmGetVersion() to translate the information returned by the ioctl 833d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * interface in a private structure into the public structure counterpart. 834d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 835569da5a42ebf10c86d6c6ba81866a888e1c708dcBrian Paulstatic void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) 836b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 837b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->version_major = s->version_major; 838b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->version_minor = s->version_minor; 839b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->version_patchlevel = s->version_patchlevel; 840b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->name_len = s->name_len; 8410a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson d->name = strdup(s->name); 842b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->date_len = s->date_len; 8430a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson d->date = strdup(s->date); 844b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss d->desc_len = s->desc_len; 8450a1ff35c70730160973715b82112cd97c62ac13eAdam Jackson d->desc = strdup(s->desc); 846b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 847b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 848b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 849d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 850d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Query the driver version information. 851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 852d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 85350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 854d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return pointer to a drmVersion structure which should be freed with 855d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * drmFreeVersion(). 85650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 857d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note Similar information is available via /proc/dri. 85850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 859d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 860d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It gets the version information via successive DRM_IOCTL_VERSION ioctls, 861d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * first with zeros to get the string lengths, and then the actually strings. 862d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * It also null-terminates them since they might not be already. 863d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 864b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmVersionPtr drmGetVersion(int fd) 865b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 866b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmVersionPtr retval; 867b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_version_t *version = drmMalloc(sizeof(*version)); 868b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 86995f23cf894757d05a6b6c980062a46968dc069b1Daniel Vetter memclear(*version); 870360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 8718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 87250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeKernelVersion(version); 87350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 874b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 875b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 876b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->name_len) 87750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely version->name = drmMalloc(version->name_len + 1); 878b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->date_len) 87950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely version->date = drmMalloc(version->date_len + 1); 880b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->desc_len) 88150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely version->desc = drmMalloc(version->desc_len + 1); 882360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 8838b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 88450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno)); 88550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFreeKernelVersion(version); 88650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 887b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 888b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 88922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson /* The results might not be null-terminated strings, so terminate them. */ 890b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->name_len) version->name[version->name_len] = '\0'; 891b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->date_len) version->date[version->date_len] = '\0'; 892b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (version->desc_len) version->desc[version->desc_len] = '\0'; 893b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 894b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss retval = drmMalloc(sizeof(*retval)); 895b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmCopyVersion(retval, version); 896b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFreeKernelVersion(version); 897b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return retval; 898b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 899b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 9003903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 901d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 902d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get version information for the DRM user space library. 90350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 904d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This version number is driver independent. 90550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 906d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 907d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 908d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return version information. 90950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 910d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 911d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function allocates and fills a drm_version structure with a hard coded 912d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * version number. 913d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 9143903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens OwendrmVersionPtr drmGetLibVersion(int fd) 9153903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{ 9163903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen drm_version_t *version = drmMalloc(sizeof(*version)); 9173903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 9183903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen /* Version history: 91979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie * NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it 9203903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen * revision 1.0.x = original DRM interface with no drmGetLibVersion 9213903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen * entry point and many drm<Device> extensions 9223903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen * revision 1.1.x = added drmCommand entry points for device extensions 9233903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen * added drmGetLibVersion to identify libdrm.a version 92406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * revision 1.2.x = added drmSetInterfaceVersion 92506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * modified drmOpen to handle both busid and name 92679038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie * revision 1.3.x = added server + memory manager 9273903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen */ 92879038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie version->version_major = 1; 92979038751ffe47ed1ce82766e027d98fd2f0e2c6aDave Airlie version->version_minor = 3; 9303903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen version->version_patchlevel = 0; 9313903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 9323903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen return (drmVersionPtr)version; 9333903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen} 9343903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 9355c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggsint drmGetCap(int fd, uint64_t capability, uint64_t *value) 9365c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs{ 93750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct drm_get_cap cap; 93850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int ret; 9395c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs 94050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely memclear(cap); 94150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely cap.capability = capability; 942fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 94350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap); 94450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret) 94550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return ret; 9465c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs 94750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *value = cap.value; 94850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 9495c6c6913d1260024e5d156db7973c9e46fe1ff03Ben Skeggs} 950d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 951ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiauint drmSetClientCap(int fd, uint64_t capability, uint64_t value) 952ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau{ 95350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct drm_set_client_cap cap; 954fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 95550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely memclear(cap); 95650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely cap.capability = capability; 95750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely cap.value = value; 958ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau 95950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap); 960ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau} 961ddbbdb13d80ea7f60e6f71356a444995b905366bDamien Lespiau 962d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 963d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free the bus ID information. 964d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 965d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID information string as given by drmGetBusid(). 966d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 967d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 968d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is just frees the memory pointed by \p busid. 969d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 970b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussvoid drmFreeBusid(const char *busid) 971b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 972b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss drmFree((void *)busid); 973b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 974b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 975d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 976d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 977d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get the bus ID of the device. 978d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 979d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 980d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 981d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return bus ID string. 982d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 983d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 984d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to 985d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * get the string length and data, passing the arguments in a drm_unique 986d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * structure. 987d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 988b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strausschar *drmGetBusid(int fd) 989b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 990b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss drm_unique_t u; 991b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 992fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(u); 993b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 9948b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 99550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 996b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss u.unique = drmMalloc(u.unique_len + 1); 9978b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 99850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 999b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss u.unique[u.unique_len] = '\0'; 100006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 1001b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss return u.unique; 1002b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1003b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1004d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1005d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1006d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the bus ID of the device. 1007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1008d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busid bus ID string. 1010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, negative on failure. 1012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1013d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1014d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing 1015d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_unique structure. 1016d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1017b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmSetBusid(int fd, const char *busid) 1018b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1019b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss drm_unique_t u; 1020b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1021fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(u); 1022b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss u.unique = (char *)busid; 1023b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Strauss u.unique_len = strlen(busid); 1024b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 10258b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { 102650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 102756bd9c207770d41a497f3e8237a1099dd9d4cd91David Dawes } 1028b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1029b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1030b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 10318696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMagic(int fd, drm_magic_t * magic) 1032b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1033b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_auth_t auth; 1034b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1035fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(auth); 1036fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 1037b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *magic = 0; 10388b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) 103950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1040b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *magic = auth.magic; 1041b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1042b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1043b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 10448696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAuthMagic(int fd, drm_magic_t magic) 1045b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1046b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_auth_t auth; 1047b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1048fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(auth); 1049b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss auth.magic = magic; 10508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) 105150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1052b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1053b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1054b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1055d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1056d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Specifies a range of memory that is available for mapping by a 1057d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * non-root process. 1058d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1059d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1060d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset usually the physical address. The actual meaning depends of 1061d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the \p type parameter. See below. 1062d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size of the memory in bytes. 1063d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of the memory to be mapped. 1064d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags combination of several flags to modify the function actions. 1065d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle will be set to a value that may be used as the offset 1066d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * parameter for mmap(). 106750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1068d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success or a negative value on error. 1069d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1070d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the frame buffer 1071d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the frame buffer 1072d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the frame buffer, 1073d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the frame buffer in bytes, and 1074d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_FRAME_BUFFER. 1075d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1076d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par 1077d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * The area mapped will be uncached. If MTRR support is available in the 107850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * kernel, the frame buffer area will be set to write combining. 1079d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1080d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the MMIO register area 1081d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the MMIO register area, 1082d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be the physical address of the start of the register area, 1083d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the size of the register area bytes, and 1084d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_REGISTERS. 1085d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par 108650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * The area mapped will be uncached. 108750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1088d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par Mapping the SAREA 1089d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * For the SAREA, 1090d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p offset will be ignored and should be set to zero, 1091d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p size will be the desired size of the SAREA in bytes, 1092d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * - \p type will be DRM_SHM. 109350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1094d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \par 1095d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * A shared memory area of the requested size will be created and locked in 1096d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * kernel memory. This area may be mapped into client-space by using the handle 109750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * returned. 109850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1099d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root. 1100d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1101d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1102d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing 1103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_map structure. 1104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 110522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type, 110650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMapFlags flags, drm_handle_t *handle) 1107b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1108b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_map_t map; 1109b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1110fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(map); 1111b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss map.offset = offset; 1112b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss map.size = size; 1113b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss map.type = type; 1114b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss map.flags = flags; 11158b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map)) 111650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1117ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (handle) 111850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *handle = (drm_handle_t)(uintptr_t)map.handle; 1119b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1120b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1121b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 11228696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmRmMap(int fd, drm_handle_t handle) 112374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{ 112474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin drm_map_t map; 112574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 1126fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(map); 1127961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston map.handle = (void *)(uintptr_t)handle; 112874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 11298b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map)) 113050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 113174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin return 0; 113274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin} 113374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 1134d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1135d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Make buffers available for DMA transfers. 113650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1137d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1138d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers. 1139d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of each buffer. 1140d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags buffer allocation flags. 114150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param agp_offset offset in the AGP aperture 1142d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1143d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return number of buffers allocated, negative on error. 1144d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1145d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1146d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl. 1147d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1148d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \sa drm_buf_desc. 1149d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1150ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, 115150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int agp_offset) 1152b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_buf_desc_t request; 1154360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1155fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(request); 1156b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss request.count = count; 1157b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss request.size = size; 1158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss request.flags = flags; 1159ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann request.agp_start = agp_offset; 1160360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 11618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request)) 116250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1163b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return request.count; 1164b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1165b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1166b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmMarkBufs(int fd, double low, double high) 1167b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1168b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_buf_info_t info; 1169b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss int i; 1170b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1171fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(info); 1172b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 11738b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 117450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -EINVAL; 1175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1176ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!info.count) 117750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -EINVAL; 1178360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1179b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 118050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -ENOMEM; 1181360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 11828b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 118350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int retval = -errno; 118450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(info.list); 118550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return retval; 1186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 1187360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1188b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss for (i = 0; i < info.count; i++) { 118950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely info.list[i].low_mark = low * info.list[i].count; 119050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely info.list[i].high_mark = high * info.list[i].count; 119150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) { 119250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int retval = -errno; 119350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(info.list); 119450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return retval; 119550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 1196b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 1197b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(info.list); 1198360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1202d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1203d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free buffers. 1204d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1205d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1206d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param count number of buffers to free. 1207d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param list list of buffers to be freed. 1208d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1209d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 121050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1211d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note This function is primarily used for debugging. 121250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1213d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1214d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing 1215d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the arguments in a drm_buf_free structure. 1216d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1217b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFreeBufs(int fd, int count, int *list) 1218b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1219b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_buf_free_t request; 1220b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1221fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(request); 1222b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss request.count = count; 1223b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss request.list = list; 12248b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request)) 122550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1228b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1229d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1230d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1231d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Close the device. 1232d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1233d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1234d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1235d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1236d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function closes the file descriptor. 1237d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1238b6a28bfe98f2c89cfb91079bd3c7b63fb0144eb1Daryll Straussint drmClose(int fd) 1239b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1240b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss unsigned long key = drmGetKeyFromFd(fd); 1241b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashEntry *entry = drmGetEntry(fd); 1242b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1243b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashDestroy(entry->tagTable); 1244b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss entry->fd = 0; 1245b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss entry->f = NULL; 1246b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss entry->tagTable = NULL; 1247b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashDelete(drmHashTable, key); 1249b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(entry); 1250b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1251b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return close(fd); 1252b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1253b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1254d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1255d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1256d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map a region of memory. 1257d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1258d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1259d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle returned by drmAddMap(). 1260d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmAddMap(). 1261d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address will contain the user-space virtual address where the mapping 1262d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * begins. 1263d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1264d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 126550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1266d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1267d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper for mmap(). 1268d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 126922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address) 1270b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1271c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane static unsigned long pagesize_mask = 0; 1272c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane 1273ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (fd < 0) 127450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -EINVAL; 1275c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane 1276c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane if (!pagesize_mask) 127750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely pagesize_mask = getpagesize() - 1; 1278c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane 1279c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane size = (size + pagesize_mask) & ~pagesize_mask; 1280c7558d8fa4df805b7f7ff3d631432eadac9b8a1cAlan Hourihane 1281faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); 1282ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (*address == MAP_FAILED) 128350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1284b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1285b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1286b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1287d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1288d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1289d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap mappings obtained with drmMap(). 1290d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1291d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address address as given by drmMap(). 1292d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size in bytes. Must match the size used by drmMap(). 129350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1294d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 1295d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1296d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 129722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * This function is a wrapper for munmap(). 1298d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1299b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmap(drmAddress address, drmSize size) 1300b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1301faf51d5694e3f0ec12c7fa1fd2f87fc96a300fe3Emil Velikov return drm_munmap(address, size); 1302b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1303b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1304b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufInfoPtr drmGetBufInfo(int fd) 1305b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1306b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_buf_info_t info; 1307b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmBufInfoPtr retval; 1308b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss int i; 1309b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1310fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(info); 1311b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 13128b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 131350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1314b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1315b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (info.count) { 131650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 131750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 131850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 131950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 132050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(info.list); 132150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 132250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 132350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 132450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval = drmMalloc(sizeof(*retval)); 132550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->count = info.count; 132650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list = drmMalloc(info.count * sizeof(*retval->list)); 132750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely for (i = 0; i < info.count; i++) { 132850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].count = info.list[i].count; 132950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].size = info.list[i].size; 133050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].low_mark = info.list[i].low_mark; 133150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].high_mark = info.list[i].high_mark; 133250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 133350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(info.list); 133450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return retval; 1335b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 1336b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return NULL; 1337b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1338b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1339d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1340d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Map all DMA buffers into client-virtual space. 1341d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1342d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1343d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1344d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return a pointer to a ::drmBufMap structure. 1345d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1346d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note The client may not use these buffers until obtaining buffer indices 1347d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with drmDMA(). 134850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1349d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1350d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned 1351d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * information about the buffers in a drm_buf_map structure into the 1352d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * client-visible data structures. 135350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely */ 1354b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll StraussdrmBufMapPtr drmMapBufs(int fd) 1355b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1356b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_buf_map_t bufs; 1357b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmBufMapPtr retval; 1358b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss int i; 1359360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1360fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(bufs); 13618b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) 136250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1363b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1364ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!bufs.count) 136550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 13668696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl 136750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list)))) 136850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1369b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 137050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { 137150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(bufs.list); 137250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 137350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 137422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson 137550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval = drmMalloc(sizeof(*retval)); 137650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->count = bufs.count; 137750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list = drmMalloc(bufs.count * sizeof(*retval->list)); 137850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely for (i = 0; i < bufs.count; i++) { 137950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].idx = bufs.list[i].idx; 138050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].total = bufs.list[i].total; 138150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].used = 0; 138250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval->list[i].address = bufs.list[i].address; 138350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 13848696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl 138550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(bufs.list); 138650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return retval; 1387b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1388b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1389d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1390d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1391d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unmap buffers allocated with drmMapBufs(). 1392d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1393d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or negative value on failure. 1394d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1395d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 13968696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * Calls munmap() for every buffer stored in \p bufs and frees the 13978696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl * memory allocated by drmMapBufs(). 1398d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1399b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmUnmapBufs(drmBufMapPtr bufs) 1400b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1401b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss int i; 1402360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1403b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss for (i = 0; i < bufs->count; i++) { 140450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drm_munmap(bufs->list[i].address, bufs->list[i].total); 1405b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 14068696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl 14078696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl drmFree(bufs->list); 14088696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl drmFree(bufs); 1409b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1410b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1411b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1412d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 141350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely#define DRM_DMA_RETRY 16 1414360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1415d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1416d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Reserve DMA buffers. 1417d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1418d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 141950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param request 142050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1421d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 1422d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1423d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1424d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Assemble the arguments into a drm_dma structure and keeps issuing the 1425d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * DRM_IOCTL_DMA ioctl until success or until maximum number of retries. 1426d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1427b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmDMA(int fd, drmDMAReqPtr request) 1428b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1429b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_dma_t dma; 1430360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes int ret, i = 0; 1431b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1432b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.context = request->context; 1433b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.send_count = request->send_count; 1434b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.send_indices = request->send_list; 1435b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.send_sizes = request->send_sizes; 1436b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.flags = request->flags; 1437b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.request_count = request->request_count; 1438b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.request_size = request->request_size; 1439b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.request_indices = request->request_list; 1440b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss dma.request_sizes = request->request_sizes; 14418696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl dma.granted_count = 0; 1442360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1443360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes do { 144450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); 1445360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); 1446360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1447360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes if ( ret == 0 ) { 144850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely request->granted_count = dma.granted_count; 144950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 1450360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes } else { 145150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1452360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes } 1453b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1454b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1455d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1456d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1457d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Obtain heavyweight hardware lock. 1458d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1459d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1460d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context. 1461d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param flags flags that determine the sate of the hardware when the function 1462d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * returns. 146350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1464d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return always zero. 146550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1466d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1467d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function translates the arguments into a drm_lock structure and issue 1468d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. 1469d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 14708696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetLock(int fd, drm_context_t context, drmLockFlags flags) 1471b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1472b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_lock_t lock; 1473b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1474fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(lock); 1475b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss lock.context = context; 1476b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss lock.flags = 0; 1477b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 1478b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 1479b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 1480b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 1481b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 1482b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 1483360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 14848b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock)) 148550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ; 1486b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1487b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1488b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1489d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1490d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the hardware lock. 1491d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1492d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1493d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param context context. 149450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1495d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 149650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1497d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1498d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the 1499d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_lock structure. 1500d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 15018696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmUnlock(int fd, drm_context_t context) 1502b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1503b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_lock_t lock; 1504b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1505fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(lock); 1506b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss lock.context = context; 15078b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock); 1508b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1509b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 151022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksondrm_context_t *drmGetReservedContextList(int fd, int *count) 1511b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1512b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_res_t res; 1513b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t *list; 15148696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirl drm_context_t * retval; 1515b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss int i; 1516b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1517fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(res); 15188b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 151950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1520b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1521ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!res.count) 152250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1523b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1524ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (!(list = drmMalloc(res.count * sizeof(*list)))) 152550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1526b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (!(retval = drmMalloc(res.count * sizeof(*retval)))) { 152750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmFree(list); 152850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1529b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 1530b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1531b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss res.contexts = list; 15328b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 153350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 1534b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1535ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian for (i = 0; i < res.count; i++) 153650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retval[i] = list[i].handle; 1537b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(list); 1538b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1539b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *count = res.count; 1540b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return retval; 1541b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1542b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 154322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonvoid drmFreeReservedContextList(drm_context_t *pt) 1544b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1545b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmFree(pt); 1546b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1547b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1548d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1549d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Create context. 1550d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1551d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Used by the X server during GLXContext initialization. This causes 1552d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * per-context kernel-level resources to be allocated. 1553d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1554d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1555d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle is set on success. To be used by the client when requesting DMA 1556d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * dispatch with drmDMA(). 155750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1558d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 155950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1560d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root. 156150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1562d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1563d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the 1564d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure. 1565d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 156622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateContext(int fd, drm_context_t *handle) 1567b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1568b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t ctx; 1569b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1570fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctx); 15718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) 157250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1573b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *handle = ctx.handle; 1574b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1575b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1576b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 15778696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSwitchToContext(int fd, drm_context_t context) 1578b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1579b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t ctx; 1580b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1581fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctx); 1582b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctx.handle = context; 15838b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) 158450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1585b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1586b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1587b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 15888696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags) 1589b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1590b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t ctx; 1591b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 159222e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson /* 159322e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * Context preserving means that no context switches are done between DMA 159422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * buffers from one context and the next. This is suitable for use in the 159522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * X server (which promises to maintain hardware context), or in the 159622e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson * client-side library when buffers are swapped on behalf of two threads. 159722e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson */ 1598fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctx); 1599b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctx.handle = context; 1600ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (flags & DRM_CONTEXT_PRESERVED) 160150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ctx.flags |= _DRM_CONTEXT_PRESERVED; 1602ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (flags & DRM_CONTEXT_2DONLY) 160350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ctx.flags |= _DRM_CONTEXT_2DONLY; 16048b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) 160550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1606b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1607b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1608b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 160922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextFlags(int fd, drm_context_t context, 161022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson drm_context_tFlagsPtr flags) 1611b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1612b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t ctx; 1613b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 1614fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctx); 1615b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctx.handle = context; 16168b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx)) 161750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1618b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *flags = 0; 1619ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (ctx.flags & _DRM_CONTEXT_PRESERVED) 162050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *flags |= DRM_CONTEXT_PRESERVED; 1621ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (ctx.flags & _DRM_CONTEXT_2DONLY) 162250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *flags |= DRM_CONTEXT_2DONLY; 1623b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1624b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1625360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 1626d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1627d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Destroy context. 1628d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1629d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free any kernel-level resources allocated with drmCreateContext() associated 1630d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * with the context. 163150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1632d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1633d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle given by drmCreateContext(). 163450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1635d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 163650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1637d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \note May only be called by root. 163850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1639d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1640d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the 1641d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_ctx structure. 1642d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 16438696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyContext(int fd, drm_context_t handle) 1644b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1645b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_ctx_t ctx; 1646fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 1647fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctx); 1648b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctx.handle = handle; 16498b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx)) 165050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1651b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1652b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1653b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 165422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCreateDrawable(int fd, drm_drawable_t *handle) 1655b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1656b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_draw_t draw; 1657fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 1658fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(draw); 16598b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) 166050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1661b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss *handle = draw.handle; 1662b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1663b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1664b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 16658696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDestroyDrawable(int fd, drm_drawable_t handle) 1666b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 1667b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_draw_t draw; 1668fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 1669fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(draw); 1670b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss draw.handle = handle; 16718b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw)) 167250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1673b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 1674b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 1675b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 16769810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzerint drmUpdateDrawableInfo(int fd, drm_drawable_t handle, 167750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drm_drawable_info_type_t type, unsigned int num, 167850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely void *data) 16799810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer{ 16809810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer drm_update_draw_t update; 16819810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer 1682fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(update); 16839810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer update.handle = handle; 16849810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer update.type = type; 16859810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer update.num = num; 16869810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer update.data = (unsigned long long)(unsigned long)data; 16879810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer 16888b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) 168950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 16909810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer 16919810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer return 0; 16929810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer} 16939810ec2737de6aa81e764225f580e4ea39de437aMichel Dänzer 1694d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1695d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Acquire the AGP device. 1696d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1697d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Must be called before any of the other AGP related calls. 1698d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1699d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 170050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1701d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 170250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1703d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1704d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. 1705d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1706ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAcquire(int fd) 1707ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 17088b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) 170950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1710ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1711ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1712ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1713d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1714d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1715d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Release the AGP device. 1716d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1717d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 171850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1719d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 172050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1721d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1722d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. 1723d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1724ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpRelease(int fd) 1725ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 17268b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) 172750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1728ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1729ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1730ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1731d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1732d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1733d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Set the AGP mode. 1734d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1735d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1736d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param mode AGP mode. 173750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1738d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 173950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1740d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1741d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the 1742d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_mode structure. 1743d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1744ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpEnable(int fd, unsigned long mode) 1745ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1746ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_mode_t m; 1747ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 17481490055bc05fa941b59d10e89ef3fccd673af477Connor Behan memclear(m); 1749ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann m.mode = mode; 17508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) 175150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1752ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1753ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1754ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1755d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1756d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1757d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Allocate a chunk of AGP memory. 1758d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1759d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1760d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size requested memory size in bytes. Will be rounded to page boundary. 1761d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param type type of memory to allocate. 1762d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param address if not zero, will be set to the physical address of the 1763d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * allocated memory. 1764d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle on success will be set to a handle of the allocated memory. 176550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1766d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 176750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1768d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1769d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the 1770d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_agp_buffer structure. 1771d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1772ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpAlloc(int fd, unsigned long size, unsigned long type, 177350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely unsigned long *address, drm_handle_t *handle) 1774ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1775ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_buffer_t b; 1776b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane 1777fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(b); 1778b0a928557c91fec527f41ae8b2441174889bf32cAlan Hourihane *handle = DRM_AGP_NO_HANDLE; 1779ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.size = size; 1780ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.type = type; 17818b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) 178250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1783ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (address != 0UL) 178450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *address = b.physical; 1785ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann *handle = b.handle; 1786ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1787ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1788ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1789d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1790d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1791d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Free a chunk of AGP memory. 1792d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1793d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1794d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 179550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1796d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 179750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1798d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1799d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the 1800d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_buffer structure. 1801d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 18027ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpFree(int fd, drm_handle_t handle) 1803ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1804ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_buffer_t b; 1805ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1806fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(b); 1807ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.handle = handle; 18088b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b)) 180950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1810ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1811ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1812ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1813d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1814d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1815d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Bind a chunk of AGP memory. 1816d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1817d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1818d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1819d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param offset offset in bytes. It will round to page boundary. 182050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1821d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 182250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1823d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1824d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the 1825d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_agp_binding structure. 1826d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 18277ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpBind(int fd, drm_handle_t handle, unsigned long offset) 1828ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1829ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_binding_t b; 1830ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1831fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(b); 1832ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.handle = handle; 1833ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.offset = offset; 18348b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b)) 183550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1836ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1837ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1838ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1839d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1840d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1841d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Unbind a chunk of AGP memory. 1842d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1843d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 1844d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 184550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1846d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 184750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1848d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1849d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing 1850d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * the argument in a drm_agp_binding structure. 1851d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 18527ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmAgpUnbind(int fd, drm_handle_t handle) 1853ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1854ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_binding_t b; 1855ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1856fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(b); 1857ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann b.handle = handle; 18588b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) 185950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1860ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return 0; 1861ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1862ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1863d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1864d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1865d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver major version number. 1866d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1867d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 186850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1869d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return major version number on success, or a negative value on failure.. 187050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1871d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1872d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1873d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1874d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1875ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMajor(int fd) 1876ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1877ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1878ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1879fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1880fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 18818b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 188250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1883ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.agp_version_major; 1884ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1885ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1886d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1887d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1888d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP driver minor version number. 1889d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1890d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 189150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1892d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return minor version number on success, or a negative value on failure. 189350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1894d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1895d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1896d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1897d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1898ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannint drmAgpVersionMinor(int fd) 1899ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1900ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1901ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1902fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1903fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 19048b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 190550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 1906ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.agp_version_minor; 1907ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1908ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1909d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1910d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1911d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP mode. 1912d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1913d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 191450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1915d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return mode on success, or zero on failure. 191650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1917d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1918d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1919d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1920d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1921ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpGetMode(int fd) 1922ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1923ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1924ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1925fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1926fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 19278b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 192850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 1929ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.mode; 1930ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1931ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1932d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1933d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1934d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture base. 1935d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1936d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 193750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1938d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture base on success, zero on failure. 193950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1940d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1941d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1942d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1943d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1944ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpBase(int fd) 1945ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1946ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1947ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1948fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1949fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 19508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 195150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 1952ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.aperture_base; 1953ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1954ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1955d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1956d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1957d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get AGP aperture size. 1958d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1959d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 196050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1961d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return aperture size on success, zero on failure. 196250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1963d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1964d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1965d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1966d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1967ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpSize(int fd) 1968ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1969ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1970ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1971fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1972fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 19738b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 197450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 1975ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.aperture_size; 1976ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 1977ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1978d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 1979d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 1980d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get used AGP memory. 1981d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 1982d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 198350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1984d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory used on success, or zero on failure. 198550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 1986d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 1987d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1988d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 1989d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 1990ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryUsed(int fd) 1991ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 1992ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 1993ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 1994fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 1995fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 19968b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 199750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 1998ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.memory_used; 1999ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 2000ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2001d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2002d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2003d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get available AGP memory. 2004d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2005d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 200650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2007d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return memory available on success, or zero on failure. 200850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2009d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2010d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2011d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 2012d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2013ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned long drmAgpMemoryAvail(int fd) 2014ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 2015ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 2016ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2017fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 2018fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 20198b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 202050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 2021ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.memory_allowed; 2022ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 2023ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2024d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2025d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2026d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware vendor ID. 2027d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2028d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 202950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2030d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return vendor ID on success, or zero on failure. 203150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2032d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2033d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2034d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 2035d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2036ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpVendorId(int fd) 2037ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 2038ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 2039ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2040fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 2041fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 20428b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 204350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 2044ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.id_vendor; 2045ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 2046ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2047d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2048d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2049d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get hardware device ID. 2050d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2051d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 205250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2053d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or zero on failure. 205450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2055d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2056d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2057d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * necessary information in a drm_agp_info structure. 2058d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2059ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmannunsigned int drmAgpDeviceId(int fd) 2060ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann{ 2061ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann drm_agp_info_t i; 2062ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 2063fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(i); 2064fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 20658b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 206650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 2067ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann return i.id_device; 2068ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann} 2069ba1b1ae3806490cce16a9c8957b52cd74967f463Jeff Hartmann 20707ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle) 20715d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{ 20725d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin drm_scatter_gather_t sg; 20735d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin 2074fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(sg); 2075fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter 20765d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin *handle = 0; 20775d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin sg.size = size; 20788b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) 207950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 20805d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin *handle = sg.handle; 20815d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin return 0; 20825d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin} 20835d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin 20847ede209ce0cbbc65f79d02e2cc43cfcb3abb6e99Dave Airlieint drmScatterGatherFree(int fd, drm_handle_t handle) 20855d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin{ 20865d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin drm_scatter_gather_t sg; 20875d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin 2088fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(sg); 20895d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin sg.handle = handle; 20908b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg)) 209150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 20925d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin return 0; 20935d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin} 20945d6ddbca26d695561fb1d08d798a0cc254b805e7Kevin E Martin 2095d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2096d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Wait for VBLANK. 2097d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2098d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 2099d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param vbl pointer to a drmVBlank structure. 210050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2101d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 210250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2103d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2104d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. 2105d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 210655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzerint drmWaitVBlank(int fd, drmVBlankPtr vbl) 210755acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer{ 2108f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes struct timespec timeout, cur; 210955acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer int ret; 211055acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer 2111f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes ret = clock_gettime(CLOCK_MONOTONIC, &timeout); 2112f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes if (ret < 0) { 211350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno)); 211450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely goto out; 2115f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes } 2116f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes timeout.tv_sec++; 2117f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes 211855acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer do { 2119f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); 2120c7d471b6ae936127311a816a8d15b4565746af48Michel Daenzer vbl->request.type &= ~DRM_VBLANK_RELATIVE; 2121ca37077fb78b69a00500827f1db12b70affa1514Jesse Barnes if (ret && errno == EINTR) { 212250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely clock_gettime(CLOCK_MONOTONIC, &cur); 212350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* Timeout after 1s */ 212450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (cur.tv_sec > timeout.tv_sec + 1 || 212550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= 212650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely timeout.tv_nsec)) { 212750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely errno = EBUSY; 212850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = -1; 212950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 213050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 2131f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnes } 213255acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer } while (ret && errno == EINTR); 213355acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer 2134f4f76a6894b40abd77f0ffbf52972127608b9bcaJesse Barnesout: 213555acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer return ret; 213655acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer} 213755acd0d5a64a2ee6b0cecc75872fbf8c4bb42a0cMichel Daenzer 2138b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmError(int err, const char *label) 2139b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2140b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss switch (err) { 2141ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian case DRM_ERR_NO_DEVICE: 214250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "%s: no device\n", label); 214350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 2144ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian case DRM_ERR_NO_ACCESS: 214550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "%s: no access\n", label); 214650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 2147ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian case DRM_ERR_NOT_ROOT: 214850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "%s: not root\n", label); 214950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 2150ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian case DRM_ERR_INVALID: 215150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "%s: invalid args\n", label); 215250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 2153b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss default: 215450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (err < 0) 215550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely err = -err; 215650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) ); 215750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 2158b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 2159b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2160b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 1; 2161b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2162b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2163d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2164d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Install IRQ handler. 2165d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2166d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 2167d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param irq IRQ number. 216850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2169d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 217050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2171d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2172d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2173d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure. 2174d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2175b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlInstHandler(int fd, int irq) 2176b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2177b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_control_t ctl; 2178b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2179fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctl); 2180b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctl.func = DRM_INST_HANDLER; 2181b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctl.irq = irq; 21828b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 218350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 2184b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 2185b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2186b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2187d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2188d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2189d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Uninstall IRQ handler. 2190d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2191d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 219250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2193d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 219450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2195d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2196d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2197d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * argument in a drm_control structure. 2198d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2199b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmCtlUninstHandler(int fd) 2200b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2201b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_control_t ctl; 2202b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2203fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(ctl); 2204b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctl.func = DRM_UNINST_HANDLER; 2205b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss ctl.irq = 0; 22068b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 220750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 2208b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 2209b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2210b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2211b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmFinish(int fd, int context, drmLockFlags flags) 2212b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2213b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_lock_t lock; 2214b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2215fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(lock); 2216b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss lock.context = context; 2217b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 2218b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 2219b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 2220b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 2221b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 2222b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 22238b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock)) 222450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 2225b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 2226b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2227b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2228d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2229d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Get IRQ from bus ID. 2230d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2231d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 2232d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param busnum bus number. 2233d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param devnum device number. 2234d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param funcnum function number. 223550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2236d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return IRQ number on success, or a negative value on failure. 223750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2238d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 2239d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the 2240d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * arguments in a drm_irq_busid structure. 2241d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 2242b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Straussint drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum) 2243b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2244b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drm_irq_busid_t p; 2245b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2246fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(p); 2247b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss p.busnum = busnum; 2248b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss p.devnum = devnum; 2249b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss p.funcnum = funcnum; 22508b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) 225150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 2252b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return p.irq; 2253b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2254b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 22558696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmAddContextTag(int fd, drm_context_t context, void *tag) 2256b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2257b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashEntry *entry = drmGetEntry(fd); 2258b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2259b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss if (drmHashInsert(entry->tagTable, context, tag)) { 226050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmHashDelete(entry->tagTable, context); 226150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmHashInsert(entry->tagTable, context, tag); 2262b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss } 2263b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return 0; 2264b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2265b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 22668696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmDelContextTag(int fd, drm_context_t context) 2267b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2268b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashEntry *entry = drmGetEntry(fd); 2269b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2270b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return drmHashDelete(entry->tagTable, context); 2271b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2272b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 22738696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlvoid *drmGetContextTag(int fd, drm_context_t context) 2274b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss{ 2275b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss drmHashEntry *entry = drmGetEntry(fd); 2276b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss void *value; 2277360475376c5a597caf4a981c934a6b0d783fa94dGareth Hughes 2278ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (drmHashLookup(entry->tagTable, context, &value)) 227950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 2280b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 2281b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss return value; 2282b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss} 2283b3a5766992019fc5f44cc9afd01b2617b76f47aDaryll Strauss 228422e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, 228522e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson drm_handle_t handle) 228674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{ 228774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin drm_ctx_priv_map_t map; 228874e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 2289fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(map); 229074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin map.ctx_id = ctx_id; 2291961bf9b5c2866ccb4fedf2b45b29fb688519d0dbJeremy Huddleston map.handle = (void *)(uintptr_t)handle; 229274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 22938b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) 229450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 229574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin return 0; 229674e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin} 229774e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 229822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, 229922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson drm_handle_t *handle) 230074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin{ 230174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin drm_ctx_priv_map_t map; 230274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 2303fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(map); 230474e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin map.ctx_id = ctx_id; 230574e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 23068b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) 230750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 2308ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (handle) 230950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *handle = (drm_handle_t)(uintptr_t)map.handle; 231074e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 231174e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin return 0; 231274e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin} 231374e19a40187ac3b5907922e5dc01418135a5794bKevin E Martin 23148696e71db2d79eb318c00abde625d7b61d6800a1Jon Smirlint drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, 231550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmMapType *type, drmMapFlags *flags, drm_handle_t *handle, 231650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int *mtrr) 231788dbee54ed400a3fd5594fab506518c171167805Rik Faith{ 231888dbee54ed400a3fd5594fab506518c171167805Rik Faith drm_map_t map; 231988dbee54ed400a3fd5594fab506518c171167805Rik Faith 2320fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(map); 232188dbee54ed400a3fd5594fab506518c171167805Rik Faith map.offset = idx; 23228b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)) 232350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 232488dbee54ed400a3fd5594fab506518c171167805Rik Faith *offset = map.offset; 232588dbee54ed400a3fd5594fab506518c171167805Rik Faith *size = map.size; 232688dbee54ed400a3fd5594fab506518c171167805Rik Faith *type = map.type; 232788dbee54ed400a3fd5594fab506518c171167805Rik Faith *flags = map.flags; 232888dbee54ed400a3fd5594fab506518c171167805Rik Faith *handle = (unsigned long)map.handle; 232988dbee54ed400a3fd5594fab506518c171167805Rik Faith *mtrr = map.mtrr; 233088dbee54ed400a3fd5594fab506518c171167805Rik Faith return 0; 233188dbee54ed400a3fd5594fab506518c171167805Rik Faith} 233288dbee54ed400a3fd5594fab506518c171167805Rik Faith 233388dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, 233450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely unsigned long *magic, unsigned long *iocs) 233588dbee54ed400a3fd5594fab506518c171167805Rik Faith{ 233688dbee54ed400a3fd5594fab506518c171167805Rik Faith drm_client_t client; 233788dbee54ed400a3fd5594fab506518c171167805Rik Faith 2338fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(client); 233988dbee54ed400a3fd5594fab506518c171167805Rik Faith client.idx = idx; 23408b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client)) 234150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 234288dbee54ed400a3fd5594fab506518c171167805Rik Faith *auth = client.auth; 234388dbee54ed400a3fd5594fab506518c171167805Rik Faith *pid = client.pid; 234488dbee54ed400a3fd5594fab506518c171167805Rik Faith *uid = client.uid; 234588dbee54ed400a3fd5594fab506518c171167805Rik Faith *magic = client.magic; 234688dbee54ed400a3fd5594fab506518c171167805Rik Faith *iocs = client.iocs; 234788dbee54ed400a3fd5594fab506518c171167805Rik Faith return 0; 234888dbee54ed400a3fd5594fab506518c171167805Rik Faith} 234988dbee54ed400a3fd5594fab506518c171167805Rik Faith 235088dbee54ed400a3fd5594fab506518c171167805Rik Faithint drmGetStats(int fd, drmStatsT *stats) 235188dbee54ed400a3fd5594fab506518c171167805Rik Faith{ 235288dbee54ed400a3fd5594fab506518c171167805Rik Faith drm_stats_t s; 2353de8532dd8359dfdaba839ff61fc9e2f05eaf57d3Jan Vesely unsigned i; 235488dbee54ed400a3fd5594fab506518c171167805Rik Faith 2355fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(s); 23568b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s)) 235750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 235888dbee54ed400a3fd5594fab506518c171167805Rik Faith 235988dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->count = 0; 236088dbee54ed400a3fd5594fab506518c171167805Rik Faith memset(stats, 0, sizeof(*stats)); 236188dbee54ed400a3fd5594fab506518c171167805Rik Faith if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) 236250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 236388dbee54ed400a3fd5594fab506518c171167805Rik Faith 236488dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_VALUE \ 236588dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].long_format = "%-20.20s"; \ 236688dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].rate_format = "%8.8s"; \ 236788dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].isvalue = 1; \ 236888dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].verbose = 0 236988dbee54ed400a3fd5594fab506518c171167805Rik Faith 237088dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_COUNT \ 237188dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].long_format = "%-20.20s"; \ 237288dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].rate_format = "%5.5s"; \ 237388dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].isvalue = 0; \ 237488dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].mult_names = "kgm"; \ 237588dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].mult = 1000; \ 237688dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].verbose = 0 237788dbee54ed400a3fd5594fab506518c171167805Rik Faith 237888dbee54ed400a3fd5594fab506518c171167805Rik Faith#define SET_BYTE \ 237988dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].long_format = "%-20.20s"; \ 238088dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].rate_format = "%5.5s"; \ 238188dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].isvalue = 0; \ 238288dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].mult_names = "KGM"; \ 238388dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].mult = 1024; \ 238488dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->data[i].verbose = 0 238588dbee54ed400a3fd5594fab506518c171167805Rik Faith 238688dbee54ed400a3fd5594fab506518c171167805Rik Faith 238788dbee54ed400a3fd5594fab506518c171167805Rik Faith stats->count = s.count; 238888dbee54ed400a3fd5594fab506518c171167805Rik Faith for (i = 0; i < s.count; i++) { 238950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].value = s.data[i].value; 239050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely switch (s.data[i].type) { 239150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_LOCK: 239250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Lock"; 239350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Lock"; 239450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_VALUE; 239550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 239650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_OPENS: 239750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Opens"; 239850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "O"; 239950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 240050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].verbose = 1; 240150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 240250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_CLOSES: 240350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Closes"; 240450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Lock"; 240550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 240650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].verbose = 1; 240750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 240850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_IOCTLS: 240950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Ioctls"; 241050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Ioc/s"; 241150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 241250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 241350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_LOCKS: 241450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Locks"; 241550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Lck/s"; 241650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 241750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 241850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_UNLOCKS: 241950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Unlocks"; 242050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Unl/s"; 242150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 242250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 242350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_IRQ: 242450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "IRQs"; 242550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "IRQ/s"; 242650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 242750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 242850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_PRIMARY: 242950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Primary Bytes"; 243050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "PB/s"; 243150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_BYTE; 243250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 243350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_SECONDARY: 243450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Secondary Bytes"; 243550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "SB/s"; 243650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_BYTE; 243750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 243850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_DMA: 243950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "DMA"; 244050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "DMA/s"; 244150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 244250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 244350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_SPECIAL: 244450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Special DMA"; 244550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "dma/s"; 244650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 244750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 244850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_MISSED: 244950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Miss"; 245050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Ms/s"; 245150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 245250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 245350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_VALUE: 245450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Value"; 245550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Value"; 245650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_VALUE; 245750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 245850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_BYTE: 245950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Bytes"; 246050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "B/s"; 246150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_BYTE; 246250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 246350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely case _DRM_STAT_COUNT: 246450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely default: 246550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].long_name = "Count"; 246650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely stats->data[i].rate_name = "Cnt/s"; 246750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely SET_COUNT; 246850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 246950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 247088dbee54ed400a3fd5594fab506518c171167805Rik Faith } 247188dbee54ed400a3fd5594fab506518c171167805Rik Faith return 0; 247288dbee54ed400a3fd5594fab506518c171167805Rik Faith} 247388dbee54ed400a3fd5594fab506518c171167805Rik Faith 2474d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 247506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * Issue a set-version ioctl. 247606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * 247706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param fd file descriptor. 247850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param drmCommandIndex command index 247906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param data source pointer of the data to be read and written. 248006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \param size size of the data to be read and written. 248150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 248206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \return zero on success, or a negative value on failure. 248350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 248406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \internal 248550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * It issues a read-write ioctl given by 248606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 248706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt */ 248822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmSetInterfaceVersion(int fd, drmSetVersion *version) 248906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt{ 249006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt int retcode = 0; 249106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt drm_set_version_t sv; 249206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 2493fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter memclear(sv); 249406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt sv.drm_di_major = version->drm_di_major; 249506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt sv.drm_di_minor = version->drm_di_minor; 249606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt sv.drm_dd_major = version->drm_dd_major; 249706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt sv.drm_dd_minor = version->drm_dd_minor; 249806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 24998b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) { 250050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely retcode = -errno; 250106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt } 250206cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 250306cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt version->drm_di_major = sv.drm_di_major; 250406cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt version->drm_di_minor = sv.drm_di_minor; 250506cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt version->drm_dd_major = sv.drm_dd_major; 250606cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt version->drm_dd_minor = sv.drm_dd_minor; 250706cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 250806cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt return retcode; 250906cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt} 251006cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt 251106cb132e86dc4a04044c3c76725ba3037008ab34Eric Anholt/** 2512d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific command. 2513d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2514d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 251550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param drmCommandIndex command index 251650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2517d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 251850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2519d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 252050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * It issues a ioctl given by 2521d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2522d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 25233903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owenint drmCommandNone(int fd, unsigned long drmCommandIndex) 25243903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{ 25253903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen unsigned long request; 25263903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 25273903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); 25283903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 2529fd38794344f7211f45cc213344d0f5b9f9f98dd8Daniel Vetter if (drmIoctl(fd, request, NULL)) { 253050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 25313903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen } 25323903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen return 0; 25333903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen} 25343903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 2535d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2536d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2537d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read command. 2538d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2539d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 254050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param drmCommandIndex command index 2541d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data destination pointer of the data to be read. 2542d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read. 254350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2544d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 2545d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2546d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 254750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * It issues a read ioctl given by 2548d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2549d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 255022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandRead(int fd, unsigned long drmCommandIndex, void *data, 255122e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson unsigned long size) 25523903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{ 25533903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen unsigned long request; 25543903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 255550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, 255650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely DRM_COMMAND_BASE + drmCommandIndex, size); 25573903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 25588b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, request, data)) { 255950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 25603903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen } 25613903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen return 0; 25623903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen} 25633903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 2564d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2565d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2566d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific write command. 2567d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2568d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 256950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param drmCommandIndex command index 2570d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be written. 2571d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be written. 257250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2573d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 257450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2575d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 257650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * It issues a write ioctl given by 2577d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2578d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 257922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data, 258022e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson unsigned long size) 25813903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{ 25823903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen unsigned long request; 25833903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 258450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, 258550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely DRM_COMMAND_BASE + drmCommandIndex, size); 25863903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 25878b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, request, data)) { 258850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 25893903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen } 25903903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen return 0; 25913903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen} 25923903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 2593d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca 2594d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca/** 2595d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * Send a device-specific read-write command. 2596d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * 2597d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param fd file descriptor. 259850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * \param drmCommandIndex command index 2599d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param data source pointer of the data to be read and written. 2600d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \param size size of the data to be read and written. 260150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2602d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \return zero on success, or a negative value on failure. 260350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * 2604d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \internal 260550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * It issues a read-write ioctl given by 2606d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2607d2443b2186712dd7c977b47e06444396e1e493ffJose Fonseca */ 260822e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jacksonint drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, 260922e41ef08338ae6dd59acbe6d4d8e50d83672816Adam Jackson unsigned long size) 26103903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen{ 26113903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen unsigned long request; 26123903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 261350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, 261450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely DRM_COMMAND_BASE + drmCommandIndex, size); 26153903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen 26168b9ab108ec1f2ba2b503f713769c4946849b3cb2Keith Packard if (drmIoctl(fd, request, data)) 261750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -errno; 26183903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen return 0; 26193903e5ac94c07cf31f0bc24eff5011ef8cc7afbaJens Owen} 2620166da9355d95affe427a6cff3525df60e80a99dfThomas Hellstrom 2621d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie#define DRM_MAX_FDS 16 2622d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic struct { 2623ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian char *BusID; 2624ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian int fd; 2625ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian int refcount; 2626dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou int type; 2627d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} connection[DRM_MAX_FDS]; 2628d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2629d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airliestatic int nr_fds = 0; 2630d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 263150d3c85bdb4ac0b3d546336605a722889aff7066Jan Veselyint drmOpenOnce(void *unused, 263250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely const char *BusID, 263350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int *newlyopened) 2634d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{ 2635dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY); 2636dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou} 2637dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou 2638dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhouint drmOpenOnceWithType(const char *BusID, int *newlyopened, int type) 2639dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou{ 2640ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian int i; 2641ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian int fd; 264250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 2643ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian for (i = 0; i < nr_fds; i++) 264450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if ((strcmp(BusID, connection[i].BusID) == 0) && 264550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely (connection[i].type == type)) { 264650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely connection[i].refcount++; 264750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *newlyopened = 0; 264850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return connection[i].fd; 264950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 2650ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian 2651dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou fd = drmOpenWithType(NULL, BusID, type); 2652c1cd3d93881a9b4a27f7190393ccc7a0236d28a4Emil Velikov if (fd < 0 || nr_fds == DRM_MAX_FDS) 265350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return fd; 265450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 2655ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian connection[nr_fds].BusID = strdup(BusID); 2656ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian connection[nr_fds].fd = fd; 2657ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian connection[nr_fds].refcount = 1; 2658dbc8b11db6f3fcbe2a76487bb0b1930908226a17Jammy Zhou connection[nr_fds].type = type; 2659ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian *newlyopened = 1; 2660d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2661ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian if (0) 266250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fprintf(stderr, "saved connection %d for %s %d\n", 266350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely nr_fds, connection[nr_fds].BusID, 266450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely strcmp(BusID, connection[nr_fds].BusID)); 2665d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2666ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian nr_fds++; 2667d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2668ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian return fd; 2669d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} 2670d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2671d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlievoid drmCloseOnce(int fd) 2672d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie{ 2673ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian int i; 2674d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie 2675ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian for (i = 0; i < nr_fds; i++) { 267650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (fd == connection[i].fd) { 267750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (--connection[i].refcount == 0) { 267850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely drmClose(connection[i].fd); 267950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely free(connection[i].BusID); 268050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 268150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (i < --nr_fds) 268250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely connection[i] = connection[nr_fds]; 268350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 268450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return; 268550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 268650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 2687ccd7b6e8ddeac936518f626d2326ae439931b2bfBrian } 2688d51e1bb56ca2f7858cdeac6f61a7b747c1e15b1eDave Airlie} 2689731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 2690731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmSetMaster(int fd) 2691731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 269250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL); 2693731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 2694731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes 2695731cd5526e5c732d51307b26e784f454a724a699Jesse Barnesint drmDropMaster(int fd) 2696731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes{ 269750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL); 2698731cd5526e5c732d51307b26e784f454a724a699Jesse Barnes} 269922d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg 270022d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsbergchar *drmGetDeviceNameFromFd(int fd) 270122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg{ 270250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely char name[128]; 270350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct stat sbuf; 270450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely dev_t d; 270550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int i; 270622d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg 270750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely /* The whole drmOpen thing is a fiasco and we need to find a way 270850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * back to just using open(2). For now, however, lets just make 270950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * things worse with even more ad hoc directory walking code to 271050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely * discover the device file name. */ 271122d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg 271250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely fstat(fd, &sbuf); 271350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely d = sbuf.st_rdev; 271422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg 271550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely for (i = 0; i < DRM_MAX_MINOR; i++) { 271650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i); 271750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) 271850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely break; 271950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 272050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (i == DRM_MAX_MINOR) 272150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 272222d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg 272350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return strdup(name); 272422d46669043d38fcd16efca773f5ed5693c0fb58Kristian Høgsberg} 2725cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 27261f73578df32f895a678a41758f6c563f49484347Frank Binnsint drmGetNodeTypeFromFd(int fd) 27271f73578df32f895a678a41758f6c563f49484347Frank Binns{ 272850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct stat sbuf; 272950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int maj, min, type; 27301f73578df32f895a678a41758f6c563f49484347Frank Binns 273150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (fstat(fd, &sbuf)) 273250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 27331f73578df32f895a678a41758f6c563f49484347Frank Binns 273450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely maj = major(sbuf.st_rdev); 273550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely min = minor(sbuf.st_rdev); 27361f73578df32f895a678a41758f6c563f49484347Frank Binns 273750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) { 273850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely errno = EINVAL; 273950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return -1; 274050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 27411f73578df32f895a678a41758f6c563f49484347Frank Binns 274250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely type = drmGetMinorType(min); 274350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (type == -1) 274450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely errno = ENODEV; 274550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return type; 27461f73578df32f895a678a41758f6c563f49484347Frank Binns} 27471f73578df32f895a678a41758f6c563f49484347Frank Binns 2748cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) 2749cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{ 275050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct drm_prime_handle args; 275150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int ret; 2752cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 275350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely memclear(args); 275450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely args.fd = -1; 275550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely args.handle = handle; 275650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely args.flags = flags; 275750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); 275850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret) 275950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return ret; 2760cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 276150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *prime_fd = args.fd; 276250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 2763cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie} 2764cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 2765cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlieint drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) 2766cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie{ 276750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct drm_prime_handle args; 276850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int ret; 2769cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 277050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely memclear(args); 277150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely args.fd = prime_fd; 277250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args); 277350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (ret) 277450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return ret; 2775cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 277650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely *handle = args.handle; 277750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return 0; 2778cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie} 2779cc0a14575d9fd0aafe73cb4aa445eaf024436114Dave Airlie 27800ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovstatic char *drmGetMinorNameForFD(int fd, int type) 27810ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{ 27820ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#ifdef __linux__ 278350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely DIR *sysdir; 278450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct dirent *pent, *ent; 278550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely struct stat sbuf; 278650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely const char *name = drmGetMinorName(type); 278750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int len; 278850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely char dev_name[64], buf[64]; 278950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely long name_max; 279050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely int maj, min; 27910ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 279250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!name) 279350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 27940ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 279550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely len = strlen(name); 27960ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 279750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (fstat(fd, &sbuf)) 279850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 27990ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 280050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely maj = major(sbuf.st_rdev); 280150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely min = minor(sbuf.st_rdev); 28020ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 280350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 280450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 28050ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 280650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min); 28070ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 280850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely sysdir = opendir(buf); 280950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!sysdir) 281050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 28110ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 281250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX); 281350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (name_max == -1) 281450d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely goto out_close_dir; 28150ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 281650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely pent = malloc(offsetof(struct dirent, d_name) + name_max + 1); 281750d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (pent == NULL) 281850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely goto out_close_dir; 28190ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 282050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) { 282150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (strncmp(ent->d_name, name, len) == 0) { 282250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s", 282350d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely ent->d_name); 28245c42b5e36a4a02e579ec5dcdc3a95ce58538224cMathias Tillman 282550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely free(pent); 282650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely closedir(sysdir); 28270ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 282850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return strdup(dev_name); 282950d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 283050d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely } 28310ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 283250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely free(pent); 28330ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 28340ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovout_close_dir: 283550d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely closedir(sysdir); 28368415a00a3f2f5cb4827b58b86e974900d3892d29Emil Velikov#else 2837f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray struct stat sbuf; 2838f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray char buf[PATH_MAX + 1]; 2839f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray const char *dev_name; 2840f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray unsigned int maj, min; 2841d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray int n, base; 2842f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2843f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray if (fstat(fd, &sbuf)) 2844f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray return NULL; 2845f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2846f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray maj = major(sbuf.st_rdev); 2847f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray min = minor(sbuf.st_rdev); 2848f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2849f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 2850f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray return NULL; 2851f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2852f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray switch (type) { 2853f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray case DRM_NODE_PRIMARY: 2854f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray dev_name = DRM_DEV_NAME; 2855f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray break; 2856f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray case DRM_NODE_CONTROL: 2857f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray dev_name = DRM_CONTROL_DEV_NAME; 2858f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray break; 2859f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray case DRM_NODE_RENDER: 2860f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray dev_name = DRM_RENDER_DEV_NAME; 2861f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray break; 2862f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray default: 2863f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray return NULL; 2864f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray }; 2865f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2866d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray base = drmGetMinorBase(type); 2867d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray if (base < 0) 2868d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray return NULL; 2869d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray 2870d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min - base); 2871f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray if (n == -1 || n >= sizeof(buf)) 2872f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray return NULL; 2873f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray 2874f189011b362a2dff3ab914523e546cc96f53df39Jonathan Gray return strdup(buf); 28750ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov#endif 287650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return NULL; 28770ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov} 28780ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 28790ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovchar *drmGetPrimaryDeviceNameFromFd(int fd) 28800ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{ 288150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY); 28820ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov} 28830ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov 28840ca03a4087a550646de7f26b6b53a932e8546474Emil Velikovchar *drmGetRenderDeviceNameFromFd(int fd) 28850ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov{ 288650d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely return drmGetMinorNameForFD(fd, DRM_NODE_RENDER); 28870ca03a4087a550646de7f26b6b53a932e8546474Emil Velikov} 2888b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2889f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#ifdef __linux__ 2890f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingstatic char * DRM_PRINTFLIKE(2, 3) 2891f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingsysfs_uevent_get(const char *path, const char *fmt, ...) 2892f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding{ 2893f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding char filename[PATH_MAX + 1], *key, *line = NULL, *value = NULL; 2894f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding size_t size = 0, len; 2895f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ssize_t num; 2896f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding va_list ap; 2897f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding FILE *fp; 2898f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2899f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding va_start(ap, fmt); 2900f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding num = vasprintf(&key, fmt, ap); 2901f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding va_end(ap); 2902f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding len = num; 2903f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2904f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding snprintf(filename, sizeof(filename), "%s/uevent", path); 2905f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2906f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding fp = fopen(filename, "r"); 2907f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (!fp) { 2908f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(key); 2909f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return NULL; 2910f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding } 2911f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2912f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding while ((num = getline(&line, &size, fp)) >= 0) { 2913f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if ((strncmp(line, key, len) == 0) && (line[len] == '=')) { 2914f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding char *start = line + len + 1, *end = line + num - 1; 2915f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2916f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (*end != '\n') 2917f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding end++; 2918f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2919f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding value = strndup(start, end - start); 2920f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding break; 2921f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding } 2922f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding } 2923f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2924f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(line); 2925f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding fclose(fp); 2926f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2927f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(key); 2928f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2929f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return value; 2930f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding} 2931f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#endif 2932f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 2933a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikovstatic int drmParseSubsystemType(int maj, int min) 2934b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 2935291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#ifdef __linux__ 2936a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov char path[PATH_MAX + 1]; 2937b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov char link[PATH_MAX + 1] = ""; 2938b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov char *name; 2939b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2940a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/subsystem", 2941a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov maj, min); 2942a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov 2943a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov if (readlink(path, link, PATH_MAX) < 0) 2944a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov return -errno; 2945b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2946b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov name = strrchr(link, '/'); 2947b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (!name) 2948b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return -EINVAL; 2949b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2950a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov if (strncmp(name, "/pci", 4) == 0) 2951b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return DRM_BUS_PCI; 2952b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2953f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (strncmp(name, "/usb", 4) == 0) 2954f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return DRM_BUS_USB; 2955f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 29567b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (strncmp(name, "/platform", 9) == 0) 29577b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return DRM_BUS_PLATFORM; 29587b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 29597b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (strncmp(name, "/host1x", 7) == 0) 29607b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return DRM_BUS_HOST1X; 29617b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 2962b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return -EINVAL; 2963d05b9f2dde17e60996437332219b4b568f7edefaJonathan Gray#elif defined(__OpenBSD__) 2964e17cad1994d321a8279c124e7a85ddddcdd9e4cdThierry Reding return DRM_BUS_PCI; 2965291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#else 2966291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#warning "Missing implementation of drmParseSubsystemType" 2967291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov return -EINVAL; 2968291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#endif 2969b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 2970b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2971536e0deba3829e194aafda6d9a1d9e938ba8277aEmil Velikovstatic int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) 2972b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 2973291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#ifdef __linux__ 29745403cb39c124c444babec51bd4499971cd86ccfaThierry Reding unsigned int domain, bus, dev, func; 29755403cb39c124c444babec51bd4499971cd86ccfaThierry Reding char path[PATH_MAX + 1], *value; 29765403cb39c124c444babec51bd4499971cd86ccfaThierry Reding int num; 2977b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 29785403cb39c124c444babec51bd4499971cd86ccfaThierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 2979b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 29805403cb39c124c444babec51bd4499971cd86ccfaThierry Reding value = sysfs_uevent_get(path, "PCI_SLOT_NAME"); 29815403cb39c124c444babec51bd4499971cd86ccfaThierry Reding if (!value) 29825403cb39c124c444babec51bd4499971cd86ccfaThierry Reding return -ENOENT; 2983b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 29845403cb39c124c444babec51bd4499971cd86ccfaThierry Reding num = sscanf(value, "%04x:%02x:%02x.%1u", &domain, &bus, &dev, &func); 29855403cb39c124c444babec51bd4499971cd86ccfaThierry Reding free(value); 2986b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 29875403cb39c124c444babec51bd4499971cd86ccfaThierry Reding if (num != 4) 2988b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return -EINVAL; 2989b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2990b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov info->domain = domain; 2991b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov info->bus = bus; 2992b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov info->dev = dev; 2993b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov info->func = func; 2994b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 2995b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return 0; 2996fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray#elif defined(__OpenBSD__) 2997fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray struct drm_pciinfo pinfo; 2998fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray int fd, type; 2999fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray 3000fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray type = drmGetMinorType(min); 3001fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray if (type == -1) 3002fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray return -ENODEV; 3003fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray 3004fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray fd = drmOpenMinor(min, 0, type); 3005fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray if (fd < 0) 3006fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray return -errno; 3007fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray 3008fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) { 3009fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray close(fd); 3010fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray return -errno; 3011fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray } 3012fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray close(fd); 3013fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray 3014fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray info->domain = pinfo.domain; 3015fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray info->bus = pinfo.bus; 3016fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray info->dev = pinfo.dev; 3017fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray info->func = pinfo.func; 3018fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray 3019fd190564daa4cd530833a94606646730a5c0ee6cJonathan Gray return 0; 3020291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#else 3021291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#warning "Missing implementation of drmParsePciBusInfo" 3022291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov return -EINVAL; 3023291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#endif 3024b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3025b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3026bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikovstatic int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b) 3027b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 3028bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov if (a == NULL || b == NULL) 3029bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov return -1; 3030bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov 3031b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (a->bustype != b->bustype) 3032bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov return -1; 3033b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3034b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov switch (a->bustype) { 3035b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov case DRM_BUS_PCI: 3036bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)); 3037f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3038f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding case DRM_BUS_USB: 3039f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo)); 3040f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 30417b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_PLATFORM: 30427b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo)); 30437b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 30447b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_HOST1X: 30457b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo)); 30467b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 3047b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov default: 3048b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov break; 3049b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov } 3050b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3051bc2aca9e22bf2cc82874f3e44568c684eec9c5e1Emil Velikov return -1; 3052b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3053b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3054b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikovstatic int drmGetNodeType(const char *name) 3055b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 3056b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (strncmp(name, DRM_PRIMARY_MINOR_NAME, 3057b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov sizeof(DRM_PRIMARY_MINOR_NAME) - 1) == 0) 3058b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return DRM_NODE_PRIMARY; 3059b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3060b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (strncmp(name, DRM_CONTROL_MINOR_NAME, 3061b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov sizeof(DRM_CONTROL_MINOR_NAME ) - 1) == 0) 3062b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return DRM_NODE_CONTROL; 3063b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3064b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (strncmp(name, DRM_RENDER_MINOR_NAME, 3065b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov sizeof(DRM_RENDER_MINOR_NAME) - 1) == 0) 3066b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return DRM_NODE_RENDER; 3067b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3068b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return -EINVAL; 3069b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3070b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 30715f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikovstatic int drmGetMaxNodeName(void) 30725f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov{ 30735f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov return sizeof(DRM_DIR_NAME) + 30745f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), 30755f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov sizeof(DRM_CONTROL_MINOR_NAME), 30765f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov sizeof(DRM_RENDER_MINOR_NAME)) + 3077ce97507cfcbdbdc520872417b5605f3b807794ffEric Engestrom 3 /* length of the node number */; 30785f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov} 30795f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov 3080291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#ifdef __linux__ 3081aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikovstatic int parse_separate_sysfs_files(int maj, int min, 308211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov drmPciDeviceInfoPtr device, 308311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov bool ignore_revision) 3084aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov{ 3085aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 3086aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov static const char *attrs[] = { 3087aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov "revision", /* Older kernels are missing the file, so check for it first */ 3088aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov "vendor", 3089aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov "device", 3090aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov "subsystem_vendor", 3091aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov "subsystem_device", 3092aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov }; 3093aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov char path[PATH_MAX + 1]; 3094aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov unsigned int data[ARRAY_SIZE(attrs)]; 3095aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov FILE *fp; 3096aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov int ret; 3097aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 309811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) { 3099aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min, 3100aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov attrs[i]); 3101aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov fp = fopen(path, "r"); 3102aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov if (!fp) 3103aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov return -errno; 3104aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3105aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov ret = fscanf(fp, "%x", &data[i]); 3106aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov fclose(fp); 3107aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov if (ret != 1) 3108aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov return -errno; 3109aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3110aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov } 3111aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 311211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov device->revision_id = ignore_revision ? 0xff : data[0] & 0xff; 3113aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov device->vendor_id = data[1] & 0xffff; 3114aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov device->device_id = data[2] & 0xffff; 3115aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov device->subvendor_id = data[3] & 0xffff; 3116aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov device->subdevice_id = data[4] & 0xffff; 3117aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3118aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov return 0; 3119aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov} 3120aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3121aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikovstatic int parse_config_sysfs_file(int maj, int min, 3122aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov drmPciDeviceInfoPtr device) 3123aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov{ 3124ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov char path[PATH_MAX + 1]; 3125ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov unsigned char config[64]; 3126ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov int fd, ret; 3127ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov 3128b40a65d44857394966b25c5587f9dc978643f9c4Emil Velikov snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/config", maj, min); 3129ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov fd = open(path, O_RDONLY); 3130ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov if (fd < 0) 3131ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov return -errno; 3132ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov 3133ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov ret = read(fd, config, sizeof(config)); 3134ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov close(fd); 3135ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov if (ret < 0) 3136ef5192e9c7897c82da815a2c893b2e2562997a3aEmil Velikov return -errno; 3137b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3138b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov device->vendor_id = config[0] | (config[1] << 8); 3139b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov device->device_id = config[2] | (config[3] << 8); 3140b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov device->revision_id = config[8]; 3141b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov device->subvendor_id = config[44] | (config[45] << 8); 3142b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov device->subdevice_id = config[46] | (config[47] << 8); 3143b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3144b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return 0; 3145aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov} 3146aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov#endif 3147aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3148aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikovstatic int drmParsePciDeviceInfo(int maj, int min, 3149aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov drmPciDeviceInfoPtr device, 3150aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov uint32_t flags) 3151aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov{ 3152aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov#ifdef __linux__ 315311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov if (!(flags & DRM_DEVICE_GET_PCI_REVISION)) 315411687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return parse_separate_sysfs_files(maj, min, device, true); 315511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 315611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov if (parse_separate_sysfs_files(maj, min, device, false)) 3157aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov return parse_config_sysfs_file(maj, min, device); 3158aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov 3159aae3f318d5aca81b87a14360116bb766a51e82efEmil Velikov return 0; 3160c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray#elif defined(__OpenBSD__) 3161c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray struct drm_pciinfo pinfo; 3162c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray int fd, type; 3163c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 3164c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray type = drmGetMinorType(min); 3165c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray if (type == -1) 3166c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray return -ENODEV; 3167c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 3168c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray fd = drmOpenMinor(min, 0, type); 3169c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray if (fd < 0) 3170c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray return -errno; 3171c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 3172c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) { 3173c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray close(fd); 3174c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray return -errno; 3175c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray } 3176c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray close(fd); 3177c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 3178c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray device->vendor_id = pinfo.vendor_id; 3179c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray device->device_id = pinfo.device_id; 3180c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray device->revision_id = pinfo.revision_id; 3181c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray device->subvendor_id = pinfo.subvendor_id; 3182c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray device->subdevice_id = pinfo.subdevice_id; 3183c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray 3184c0ef1d078800a43611136e65be3c9c7472ac9d3fJonathan Gray return 0; 3185291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#else 3186291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#warning "Missing implementation of drmParsePciDeviceInfo" 3187291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov return -EINVAL; 3188291b2bb92c5fc90101417b80bbdc6c994be5fff2Emil Velikov#endif 3189b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3190b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 31917b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic void drmFreePlatformDevice(drmDevicePtr device) 31927b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 31937b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (device->deviceinfo.platform) { 31947b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (device->deviceinfo.platform->compatible) { 31957b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char **compatible = device->deviceinfo.platform->compatible; 31967b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 31977b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding while (*compatible) { 31987b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(*compatible); 31997b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding compatible++; 32007b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32017b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32027b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(device->deviceinfo.platform->compatible); 32037b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32047b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32057b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 32067b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32077b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic void drmFreeHost1xDevice(drmDevicePtr device) 32087b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 32097b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (device->deviceinfo.host1x) { 32107b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (device->deviceinfo.host1x->compatible) { 32117b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char **compatible = device->deviceinfo.host1x->compatible; 32127b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32137b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding while (*compatible) { 32147b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(*compatible); 32157b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding compatible++; 32167b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32177b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32187b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(device->deviceinfo.host1x->compatible); 32197b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32207b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32217b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 32227b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 3223ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikovvoid drmFreeDevice(drmDevicePtr *device) 3224b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 3225b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (device == NULL) 3226b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return; 3227b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 32287b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (*device) { 32297b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding switch ((*device)->bustype) { 32307b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_PLATFORM: 32317b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmFreePlatformDevice(*device); 32327b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 32337b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32347b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_HOST1X: 32357b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmFreeHost1xDevice(*device); 32367b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 32377b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32387b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 32397b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 32405f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov free(*device); 32415f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov *device = NULL; 3242b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3243b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3244b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikovvoid drmFreeDevices(drmDevicePtr devices[], int count) 3245b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 3246b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov int i; 3247b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3248b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (devices == NULL) 3249b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return; 3250b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 32516c056eecd56374b069ed24c81f59b6638cde2f3aQiang Yu for (i = 0; i < count; i++) 32526c056eecd56374b069ed24c81f59b6638cde2f3aQiang Yu if (devices[i]) 32536c056eecd56374b069ed24c81f59b6638cde2f3aQiang Yu drmFreeDevice(&devices[i]); 3254b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 3255b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 32562e57bba870399926e1a0d0be3f4918a0a8432474Thierry Redingstatic drmDevicePtr drmDeviceAlloc(unsigned int type, const char *node, 32572e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding size_t bus_size, size_t device_size, 32582e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding char **ptrp) 32592e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding{ 32602e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding size_t max_node_length, extra, size; 32612e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding drmDevicePtr device; 32622e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding unsigned int i; 32632e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding char *ptr; 32642e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32652e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *)); 32662e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length); 32672e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32682e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding size = sizeof(*device) + extra + bus_size + device_size; 32692e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32702e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding device = calloc(1, size); 32712e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding if (!device) 32722e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding return NULL; 32732e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32742e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding device->available_nodes = 1 << type; 32752e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32762e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding ptr = (char *)device + sizeof(*device); 32772e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding device->nodes = (char **)ptr; 32782e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32792e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding ptr += DRM_NODE_MAX * sizeof(void *); 32802e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32812e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding for (i = 0; i < DRM_NODE_MAX; i++) { 32822e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding device->nodes[i] = ptr; 32832e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding ptr += max_node_length; 32842e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding } 32852e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32862e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding memcpy(device->nodes[type], node, max_node_length); 32872e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32882e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding *ptrp = ptr; 32892e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 32902e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding return device; 32912e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding} 32922e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 3293b40a65d44857394966b25c5587f9dc978643f9c4Emil Velikovstatic int drmProcessPciDevice(drmDevicePtr *device, 3294fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov const char *node, int node_type, 3295138d23117c6b96f57aaa0072992e0480153cfebdEmil Velikov int maj, int min, bool fetch_deviceinfo, 3296138d23117c6b96f57aaa0072992e0480153cfebdEmil Velikov uint32_t flags) 3297fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov{ 32982e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding drmDevicePtr dev; 32993045523de214fb7df92ee3c8482e883637504bbeMichel Dänzer char *addr; 33002e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding int ret; 3301fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 33022e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding dev = drmDeviceAlloc(node_type, node, sizeof(drmPciBusInfo), 33032e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding sizeof(drmPciDeviceInfo), &addr); 33042e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding if (!dev) 3305fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov return -ENOMEM; 3306fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 33072e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding dev->bustype = DRM_BUS_PCI; 330850d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely 33092e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding dev->businfo.pci = (drmPciBusInfoPtr)addr; 3310fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 33112e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding ret = drmParsePciBusInfo(maj, min, dev->businfo.pci); 3312fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov if (ret) 3313fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov goto free_device; 3314fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 3315fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov // Fetch the device info if the user has requested it 3316fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov if (fetch_deviceinfo) { 3317fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov addr += sizeof(drmPciBusInfo); 33182e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr; 3319fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 33202e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags); 3321fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov if (ret) 3322fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov goto free_device; 3323fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov } 33242e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 33252e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding *device = dev; 33262e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding 3327fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov return 0; 3328fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 3329fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikovfree_device: 33302e57bba870399926e1a0d0be3f4918a0a8432474Thierry Reding free(dev); 3331fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov return ret; 3332fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov} 3333fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 3334f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingstatic int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info) 3335f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding{ 3336f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#ifdef __linux__ 3337f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding char path[PATH_MAX + 1], *value; 3338f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding unsigned int bus, dev; 3339f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding int ret; 3340f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3341f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 3342f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3343f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding value = sysfs_uevent_get(path, "BUSNUM"); 3344f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (!value) 3345f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -ENOENT; 3346f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3347f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = sscanf(value, "%03u", &bus); 3348f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(value); 3349f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3350f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret <= 0) 3351f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -errno; 3352f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3353f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding value = sysfs_uevent_get(path, "DEVNUM"); 3354f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (!value) 3355f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -ENOENT; 3356f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3357f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = sscanf(value, "%03u", &dev); 3358f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(value); 3359f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3360f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret <= 0) 3361f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -errno; 3362f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3363f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding info->bus = bus; 3364f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding info->dev = dev; 3365f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3366f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return 0; 3367f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#else 3368f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#warning "Missing implementation of drmParseUsbBusInfo" 3369f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -EINVAL; 3370f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#endif 3371f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding} 3372f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3373f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingstatic int drmParseUsbDeviceInfo(int maj, int min, drmUsbDeviceInfoPtr info) 3374f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding{ 3375f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#ifdef __linux__ 3376f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding char path[PATH_MAX + 1], *value; 3377f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding unsigned int vendor, product; 3378f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding int ret; 3379f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3380f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 3381f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3382f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding value = sysfs_uevent_get(path, "PRODUCT"); 3383f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (!value) 3384f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -ENOENT; 3385f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3386f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = sscanf(value, "%x/%x", &vendor, &product); 3387f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(value); 3388f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3389f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret <= 0) 3390f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -errno; 3391f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3392f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding info->vendor = vendor; 3393f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding info->product = product; 3394f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3395f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return 0; 3396f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#else 3397f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#warning "Missing implementation of drmParseUsbDeviceInfo" 3398f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -EINVAL; 3399f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding#endif 3400f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding} 3401f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3402f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingstatic int drmProcessUsbDevice(drmDevicePtr *device, const char *node, 3403f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding int node_type, int maj, int min, 3404f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding bool fetch_deviceinfo, uint32_t flags) 3405f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding{ 3406f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding drmDevicePtr dev; 3407f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding char *ptr; 3408f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding int ret; 3409f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3410f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding dev = drmDeviceAlloc(node_type, node, sizeof(drmUsbBusInfo), 3411f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding sizeof(drmUsbDeviceInfo), &ptr); 3412f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (!dev) 3413f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return -ENOMEM; 3414f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3415f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding dev->bustype = DRM_BUS_USB; 3416f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3417f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding dev->businfo.usb = (drmUsbBusInfoPtr)ptr; 3418f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3419f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = drmParseUsbBusInfo(maj, min, dev->businfo.usb); 3420f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret < 0) 3421f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding goto free_device; 3422f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3423f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (fetch_deviceinfo) { 3424f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ptr += sizeof(drmUsbBusInfo); 3425f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding dev->deviceinfo.usb = (drmUsbDeviceInfoPtr)ptr; 3426f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3427f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = drmParseUsbDeviceInfo(maj, min, dev->deviceinfo.usb); 3428f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret < 0) 3429f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding goto free_device; 3430f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding } 3431f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3432f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding *device = dev; 3433f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3434f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return 0; 3435f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3436f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Redingfree_device: 3437f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding free(dev); 3438f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding return ret; 3439f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding} 3440f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 34417b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmParsePlatformBusInfo(int maj, int min, drmPlatformBusInfoPtr info) 34427b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 34437b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#ifdef __linux__ 34447b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char path[PATH_MAX + 1], *name; 34457b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34467b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 34477b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34487b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding name = sysfs_uevent_get(path, "OF_FULLNAME"); 34497b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!name) 34507b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOENT; 34517b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34527b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding strncpy(info->fullname, name, DRM_PLATFORM_DEVICE_NAME_LEN); 34537b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->fullname[DRM_PLATFORM_DEVICE_NAME_LEN - 1] = '\0'; 34547b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(name); 34557b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34567b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 34577b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#else 34587b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#warning "Missing implementation of drmParsePlatformBusInfo" 34597b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -EINVAL; 34607b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#endif 34617b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 34627b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34637b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmParsePlatformDeviceInfo(int maj, int min, 34647b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmPlatformDeviceInfoPtr info) 34657b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 34667b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#ifdef __linux__ 34677b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char path[PATH_MAX + 1], *value; 34687b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding unsigned int count, i; 34697b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int err; 34707b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34717b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 34727b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34737b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding value = sysfs_uevent_get(path, "OF_COMPATIBLE_N"); 34747b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!value) 34757b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOENT; 34767b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34777b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding sscanf(value, "%u", &count); 34787b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(value); 34797b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34807b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->compatible = calloc(count + 1, sizeof(*info->compatible)); 34817b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!info->compatible) 34827b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOMEM; 34837b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34847b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding for (i = 0; i < count; i++) { 34857b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i); 34867b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!value) { 34877b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding err = -ENOENT; 34887b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free; 34897b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 34907b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34917b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->compatible[i] = value; 34927b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 34937b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34947b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 34957b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 34967b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingfree: 34977b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding while (i--) 34987b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(info->compatible[i]); 34997b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35007b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(info->compatible); 35017b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return err; 35027b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#else 35037b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#warning "Missing implementation of drmParsePlatformDeviceInfo" 35047b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -EINVAL; 35057b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#endif 35067b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 35077b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35087b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmProcessPlatformDevice(drmDevicePtr *device, 35097b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding const char *node, int node_type, 35107b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int maj, int min, bool fetch_deviceinfo, 35117b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding uint32_t flags) 35127b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 35137b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmDevicePtr dev; 35147b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char *ptr; 35157b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int ret; 35167b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35177b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev = drmDeviceAlloc(node_type, node, sizeof(drmPlatformBusInfo), 35187b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding sizeof(drmPlatformDeviceInfo), &ptr); 35197b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!dev) 35207b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOMEM; 35217b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35227b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->bustype = DRM_BUS_PLATFORM; 35237b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35247b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->businfo.platform = (drmPlatformBusInfoPtr)ptr; 35257b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35267b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmParsePlatformBusInfo(maj, min, dev->businfo.platform); 35277b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret < 0) 35287b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_device; 35297b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35307b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (fetch_deviceinfo) { 35317b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ptr += sizeof(drmPlatformBusInfo); 35327b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->deviceinfo.platform = (drmPlatformDeviceInfoPtr)ptr; 35337b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35347b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmParsePlatformDeviceInfo(maj, min, dev->deviceinfo.platform); 35357b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret < 0) 35367b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_device; 35377b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 35387b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35397b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding *device = dev; 35407b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35417b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 35427b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35437b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingfree_device: 35447b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(dev); 35457b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return ret; 35467b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 35477b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35487b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmParseHost1xBusInfo(int maj, int min, drmHost1xBusInfoPtr info) 35497b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 35507b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#ifdef __linux__ 35517b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char path[PATH_MAX + 1], *name; 35527b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35537b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 35547b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35557b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding name = sysfs_uevent_get(path, "OF_FULLNAME"); 35567b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!name) 35577b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOENT; 35587b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35597b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding strncpy(info->fullname, name, DRM_HOST1X_DEVICE_NAME_LEN); 35607b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->fullname[DRM_HOST1X_DEVICE_NAME_LEN - 1] = '\0'; 35617b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(name); 35627b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35637b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 35647b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#else 35657b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#warning "Missing implementation of drmParseHost1xBusInfo" 35667b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -EINVAL; 35677b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#endif 35687b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 35697b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35707b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmParseHost1xDeviceInfo(int maj, int min, 35717b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmHost1xDeviceInfoPtr info) 35727b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 35737b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#ifdef __linux__ 35747b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char path[PATH_MAX + 1], *value; 35757b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding unsigned int count, i; 35767b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int err; 35777b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35787b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min); 35797b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35807b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding value = sysfs_uevent_get(path, "OF_COMPATIBLE_N"); 35817b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!value) 35827b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOENT; 35837b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35847b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding sscanf(value, "%u", &count); 35857b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(value); 35867b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35877b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->compatible = calloc(count + 1, sizeof(*info->compatible)); 35887b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!info->compatible) 35897b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOMEM; 35907b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35917b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding for (i = 0; i < count; i++) { 35927b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i); 35937b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!value) { 35947b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding err = -ENOENT; 35957b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free; 35967b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 35977b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 35987b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding info->compatible[i] = value; 35997b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 36007b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36017b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 36027b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36037b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingfree: 36047b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding while (i--) 36057b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(info->compatible[i]); 36067b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36077b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(info->compatible); 36087b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return err; 36097b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#else 36107b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#warning "Missing implementation of drmParseHost1xDeviceInfo" 36117b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -EINVAL; 36127b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding#endif 36137b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 36147b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36157b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingstatic int drmProcessHost1xDevice(drmDevicePtr *device, 36167b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding const char *node, int node_type, 36177b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int maj, int min, bool fetch_deviceinfo, 36187b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding uint32_t flags) 36197b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding{ 36207b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding drmDevicePtr dev; 36217b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding char *ptr; 36227b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding int ret; 36237b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36247b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev = drmDeviceAlloc(node_type, node, sizeof(drmHost1xBusInfo), 36257b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding sizeof(drmHost1xDeviceInfo), &ptr); 36267b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (!dev) 36277b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return -ENOMEM; 36287b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36297b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->bustype = DRM_BUS_HOST1X; 36307b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36317b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->businfo.host1x = (drmHost1xBusInfoPtr)ptr; 36327b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36337b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmParseHost1xBusInfo(maj, min, dev->businfo.host1x); 36347b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret < 0) 36357b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_device; 36367b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36377b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (fetch_deviceinfo) { 36387b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ptr += sizeof(drmHost1xBusInfo); 36397b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding dev->deviceinfo.host1x = (drmHost1xDeviceInfoPtr)ptr; 36407b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36417b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmParseHost1xDeviceInfo(maj, min, dev->deviceinfo.host1x); 36427b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret < 0) 36437b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_device; 36447b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding } 36457b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36467b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding *device = dev; 36477b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36487b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return 0; 36497b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36507b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Redingfree_device: 36517b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding free(dev); 36527b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding return ret; 36537b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding} 36547b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 36553c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu/* Consider devices located on the same bus as duplicate and fold the respective 36563c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu * entries into a single one. 36573c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu * 36583c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu * Note: this leaves "gaps" in the array, while preserving the length. 36593c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu */ 3660fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikovstatic void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count) 3661fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov{ 3662fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov int node_type, i, j; 3663fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 3664fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov for (i = 0; i < count; i++) { 3665fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov for (j = i + 1; j < count; j++) { 3666fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov if (drmCompareBusInfo(local_devices[i], local_devices[j]) == 0) { 3667fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov local_devices[i]->available_nodes |= local_devices[j]->available_nodes; 3668fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov node_type = log2(local_devices[j]->available_nodes); 3669fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov memcpy(local_devices[i]->nodes[node_type], 3670fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov local_devices[j]->nodes[node_type], drmGetMaxNodeName()); 3671fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov drmFreeDevice(&local_devices[j]); 3672fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov } 3673fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov } 3674fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov } 3675fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov} 3676fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov 367711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov/* Check that the given flags are valid returning 0 on success */ 367811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovstatic int 367911687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovdrm_device_validate_flags(uint32_t flags) 368011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov{ 368111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return (flags & ~DRM_DEVICE_GET_PCI_REVISION); 368211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov} 368311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 3684b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov/** 3685ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * Get information about the opened drm device 3686ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * 3687ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * \param fd file descriptor of the drm device 368811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param flags feature/behaviour bitmask 3689ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * \param device the address of a drmDevicePtr where the information 3690ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * will be allocated in stored 3691ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * 3692ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov * \return zero on success, negative error code otherwise. 369311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 369411687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \note Unlike drmGetDevice it does not retrieve the pci device revision field 369511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set. 3696ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov */ 369711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovint drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device) 3698ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov{ 369908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray#ifdef __OpenBSD__ 370008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray /* 370108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray * DRI device nodes on OpenBSD are not in their own directory, they reside 370208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray * in /dev along with a large number of statically generated /dev nodes. 370308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray * Avoid stat'ing all of /dev needlessly by implementing this custom path. 370408257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray */ 370508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray drmDevicePtr d; 370608257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray struct stat sbuf; 370708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray char node[PATH_MAX + 1]; 370808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray const char *dev_name; 370908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray int node_type, subsystem_type; 3710d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray int maj, min, n, ret, base; 371108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 371208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (fd == -1 || device == NULL) 371308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -EINVAL; 371408257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 371508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (fstat(fd, &sbuf)) 371608257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -errno; 371708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 371808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray maj = major(sbuf.st_rdev); 371908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray min = minor(sbuf.st_rdev); 372008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 372108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 372208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -EINVAL; 372308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 372408257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray node_type = drmGetMinorType(min); 372508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (node_type == -1) 372608257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -ENODEV; 372708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 372808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray switch (node_type) { 372908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray case DRM_NODE_PRIMARY: 373008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray dev_name = DRM_DEV_NAME; 373108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray break; 373208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray case DRM_NODE_CONTROL: 373308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray dev_name = DRM_CONTROL_DEV_NAME; 373408257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray break; 373508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray case DRM_NODE_RENDER: 373608257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray dev_name = DRM_RENDER_DEV_NAME; 373708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray break; 373808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray default: 373908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -EINVAL; 374008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray }; 374108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 3742d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray base = drmGetMinorBase(node_type); 3743d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray if (base < 0) 3744d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray return -EINVAL; 3745d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray 3746d5cf3f98314c1b9d87216e00c30c9fef06ff24c3Jonathan Gray n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base); 374708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (n == -1 || n >= PATH_MAX) 374808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -errno; 374908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (stat(node, &sbuf)) 375008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -EINVAL; 375108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 375208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray subsystem_type = drmParseSubsystemType(maj, min); 375308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (subsystem_type != DRM_BUS_PCI) 375408257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return -ENODEV; 375508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 375608257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags); 375708257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray if (ret) 375808257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return ret; 375908257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 376008257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray *device = d; 376108257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray 376208257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray return 0; 376308257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray#else 3764ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov drmDevicePtr *local_devices; 3765ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov drmDevicePtr d; 3766ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov DIR *sysdir; 3767ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov struct dirent *dent; 3768ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov struct stat sbuf; 3769ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov char node[PATH_MAX + 1]; 3770ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov int node_type, subsystem_type; 3771ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov int maj, min; 3772ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov int ret, i, node_count; 3773ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov int max_count = 16; 37743c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu dev_t find_rdev; 377511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 377611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov if (drm_device_validate_flags(flags)) 377711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return -EINVAL; 3778ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3779ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (fd == -1 || device == NULL) 3780ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return -EINVAL; 3781ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3782ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (fstat(fd, &sbuf)) 3783ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return -errno; 3784ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 37853c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu find_rdev = sbuf.st_rdev; 3786ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov maj = major(sbuf.st_rdev); 3787ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov min = minor(sbuf.st_rdev); 3788ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3789ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 3790ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return -EINVAL; 3791ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3792ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov subsystem_type = drmParseSubsystemType(maj, min); 3793ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3794ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov local_devices = calloc(max_count, sizeof(drmDevicePtr)); 3795ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (local_devices == NULL) 3796ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return -ENOMEM; 3797ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3798ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov sysdir = opendir(DRM_DIR_NAME); 3799ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (!sysdir) { 3800ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov ret = -errno; 3801cf0f036e3d819fb7894562bfdfea95e5e5f57219Matt Roper goto free_locals; 3802ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov } 3803ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3804ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov i = 0; 3805ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov while ((dent = readdir(sysdir))) { 3806ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov node_type = drmGetNodeType(dent->d_name); 3807ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (node_type < 0) 3808ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov continue; 3809ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3810ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); 3811ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (stat(node, &sbuf)) 3812ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov continue; 3813ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3814ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov maj = major(sbuf.st_rdev); 3815ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov min = minor(sbuf.st_rdev); 3816ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3817ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 3818ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov continue; 3819ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3820ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (drmParseSubsystemType(maj, min) != subsystem_type) 3821ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov continue; 3822ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3823ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov switch (subsystem_type) { 3824ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov case DRM_BUS_PCI: 3825138d23117c6b96f57aaa0072992e0480153cfebdEmil Velikov ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags); 3826ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (ret) 3827eebefaf72c55fd2116f4c983ec6724a4d66ab413Jonathan Gray continue; 3828ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3829ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov break; 3830f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3831f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding case DRM_BUS_USB: 3832f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = drmProcessUsbDevice(&d, node, node_type, maj, min, true, flags); 3833f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret) 3834f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding continue; 3835f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3836f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding break; 3837f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 38387b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_PLATFORM: 38397b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmProcessPlatformDevice(&d, node, node_type, maj, min, true, flags); 38407b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret) 38417b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding continue; 38427b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 38437b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 38447b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 38457b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_HOST1X: 38467b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmProcessHost1xDevice(&d, node, node_type, maj, min, true, flags); 38477b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret) 38487b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding continue; 38497b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 38507b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 38517b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 3852ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov default: 3853ba5a6ecf81fc2e25a4c7b8c592143faadfdd63dbMatt Roper continue; 3854ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov } 3855ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3856ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (i >= max_count) { 3857ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov drmDevicePtr *temp; 3858ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3859ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov max_count += 16; 3860ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); 3861ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov if (!temp) 3862ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov goto free_devices; 3863ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov local_devices = temp; 3864ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov } 3865ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 38663c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu /* store target at local_devices[0] for ease to use below */ 38673c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu if (find_rdev == sbuf.st_rdev && i) { 38683c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu local_devices[i] = local_devices[0]; 38693c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu local_devices[0] = d; 38703c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu } 38713c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu else 38723c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu local_devices[i] = d; 3873ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov i++; 3874ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov } 3875ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov node_count = i; 3876ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3877ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov drmFoldDuplicatedDevices(local_devices, node_count); 3878ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3879ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov *device = local_devices[0]; 38803c20893daa0a56b91869d806ae0d3a8d5d8b4cbaQiang Yu drmFreeDevices(&local_devices[1], node_count - 1); 3881ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3882ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov closedir(sysdir); 3883cf0f036e3d819fb7894562bfdfea95e5e5f57219Matt Roper free(local_devices); 3884677cd97dc4a930af508388713f5016baf664ed18Rob Herring if (*device == NULL) 3885e17cad1994d321a8279c124e7a85ddddcdd9e4cdThierry Reding return -ENODEV; 3886ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return 0; 3887ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3888ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikovfree_devices: 3889ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov drmFreeDevices(local_devices, i); 3890ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov closedir(sysdir); 3891cf0f036e3d819fb7894562bfdfea95e5e5f57219Matt Roper 3892cf0f036e3d819fb7894562bfdfea95e5e5f57219Matt Roperfree_locals: 3893cf0f036e3d819fb7894562bfdfea95e5e5f57219Matt Roper free(local_devices); 3894ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov return ret; 389508257927231e4f51c38e1d2bdbb8db0c2d4aec40Jonathan Gray#endif 3896ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov} 3897ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov 3898ccedf66b65f6ab245aa6028d7fe9eb603a121b43Emil Velikov/** 389911687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * Get information about the opened drm device 390011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 390111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param fd file descriptor of the drm device 390211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param device the address of a drmDevicePtr where the information 390311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * will be allocated in stored 390411687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 390511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \return zero on success, negative error code otherwise. 390611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov */ 390711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovint drmGetDevice(int fd, drmDevicePtr *device) 390811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov{ 390911687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device); 391011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov} 391111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 391211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov/** 3913b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * Get drm devices on the system 3914b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * 391511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param flags feature/behaviour bitmask 3916b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * \param devices the array of devices with drmDevicePtr elements 3917b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * can be NULL to get the device number first 3918b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * \param max_devices the maximum number of devices for the array 3919b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * 3920b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * \return on error - negative error code, 3921b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * if devices is NULL - total number of devices available on the system, 3922b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * alternatively the number of devices stored in devices[], which is 3923b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov * capped by the max_devices. 392411687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 392511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \note Unlike drmGetDevices it does not retrieve the pci device revision field 392611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set. 3927b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov */ 392811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovint drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices) 3929b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov{ 39305f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov drmDevicePtr *local_devices; 39315f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov drmDevicePtr device; 39325f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov DIR *sysdir; 39335f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov struct dirent *dent; 39345f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov struct stat sbuf; 39355f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov char node[PATH_MAX + 1]; 3936b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov int node_type, subsystem_type; 3937b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov int maj, min; 3938fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov int ret, i, node_count, device_count; 3939b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov int max_count = 16; 394011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 394111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov if (drm_device_validate_flags(flags)) 394211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return -EINVAL; 3943b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 39445f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov local_devices = calloc(max_count, sizeof(drmDevicePtr)); 39455f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov if (local_devices == NULL) 3946b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return -ENOMEM; 3947b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3948b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov sysdir = opendir(DRM_DIR_NAME); 3949b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (!sysdir) { 3950b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov ret = -errno; 39518c4a1cbd98bd8d185d489395f33302a17db643a9Matt Roper goto free_locals; 3952b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov } 3953b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 39545f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov i = 0; 3955b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov while ((dent = readdir(sysdir))) { 3956b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov node_type = drmGetNodeType(dent->d_name); 3957b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (node_type < 0) 3958b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov continue; 3959b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3960b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov snprintf(node, PATH_MAX, "%s/%s", DRM_DIR_NAME, dent->d_name); 3961b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (stat(node, &sbuf)) 3962b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov continue; 3963b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3964b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov maj = major(sbuf.st_rdev); 3965b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov min = minor(sbuf.st_rdev); 3966b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3967b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 3968b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov continue; 3969b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3970a250fceaaa150363accaf3fb71a0e42bcecc40daEmil Velikov subsystem_type = drmParseSubsystemType(maj, min); 3971b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3972b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov if (subsystem_type < 0) 3973b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov continue; 3974b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3975b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov switch (subsystem_type) { 3976b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov case DRM_BUS_PCI: 3977b40a65d44857394966b25c5587f9dc978643f9c4Emil Velikov ret = drmProcessPciDevice(&device, node, node_type, 3978138d23117c6b96f57aaa0072992e0480153cfebdEmil Velikov maj, min, devices != NULL, flags); 39795f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov if (ret) 3980eebefaf72c55fd2116f4c983ec6724a4d66ab413Jonathan Gray continue; 3981b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 3982b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov break; 3983f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3984f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding case DRM_BUS_USB: 3985f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding ret = drmProcessUsbDevice(&device, node, node_type, maj, min, 3986f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding devices != NULL, flags); 3987f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding if (ret) 3988f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding goto free_devices; 3989f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 3990f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding break; 3991f8484ccbd12ba33ea5b3895efb7a39d986271be0Thierry Reding 39927b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_PLATFORM: 39937b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmProcessPlatformDevice(&device, node, node_type, maj, min, 39947b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding devices != NULL, flags); 39957b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret) 39967b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_devices; 39977b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 39987b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 39997b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 40007b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding case DRM_BUS_HOST1X: 40017b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding ret = drmProcessHost1xDevice(&device, node, node_type, maj, min, 40027b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding devices != NULL, flags); 40037b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding if (ret) 40047b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding goto free_devices; 40057b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 40067b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding break; 40077b1f37f474d6bdf09b0a7f17bdb89398dbcf0c74Thierry Reding 4008b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov default: 4009ba5a6ecf81fc2e25a4c7b8c592143faadfdd63dbMatt Roper continue; 4010b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov } 4011b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 40125f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov if (i >= max_count) { 40135f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov drmDevicePtr *temp; 4014b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 40155f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov max_count += 16; 40165f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov temp = realloc(local_devices, max_count * sizeof(drmDevicePtr)); 40175f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov if (!temp) 40185f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov goto free_devices; 40195f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov local_devices = temp; 40205f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov } 40215f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov 40225f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov local_devices[i] = device; 40235f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov i++; 4024b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov } 40255f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov node_count = i; 4026b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 4027fae59d7234caf4827bf5ca74c1b706cbfb70a460Emil Velikov drmFoldDuplicatedDevices(local_devices, node_count); 4028b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 40295f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov device_count = 0; 403070b64073f7d1bf56a30f7a809bd984d3ad688b9fQiang Yu for (i = 0; i < node_count; i++) { 403150d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely if (!local_devices[i]) 403250d3c85bdb4ac0b3d546336605a722889aff7066Jan Vesely continue; 403370b64073f7d1bf56a30f7a809bd984d3ad688b9fQiang Yu 40345f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov if ((devices != NULL) && (device_count < max_devices)) 40355f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov devices[device_count] = local_devices[i]; 40365f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov else 40375f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov drmFreeDevice(&local_devices[i]); 4038b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 40395f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov device_count++; 40405f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov } 4041b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov 4042b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov closedir(sysdir); 40438c4a1cbd98bd8d185d489395f33302a17db643a9Matt Roper free(local_devices); 40445f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov return device_count; 40455f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov 40465f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikovfree_devices: 40475f68d31820315ebda9b49e8bd50d1ab605efd7faEmil Velikov drmFreeDevices(local_devices, i); 4048b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov closedir(sysdir); 40498c4a1cbd98bd8d185d489395f33302a17db643a9Matt Roper 40508c4a1cbd98bd8d185d489395f33302a17db643a9Matt Roperfree_locals: 40518c4a1cbd98bd8d185d489395f33302a17db643a9Matt Roper free(local_devices); 4052b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov return ret; 4053b556ea127e004b734b2a7bf8e67cdcf56312171dEmil Velikov} 405437d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 405511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov/** 405611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * Get drm devices on the system 405711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 405811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param devices the array of devices with drmDevicePtr elements 405911687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * can be NULL to get the device number first 406011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \param max_devices the maximum number of devices for the array 406111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * 406211687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * \return on error - negative error code, 406311687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * if devices is NULL - total number of devices available on the system, 406411687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * alternatively the number of devices stored in devices[], which is 406511687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov * capped by the max_devices. 406611687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov */ 406711687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikovint drmGetDevices(drmDevicePtr devices[], int max_devices) 406811687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov{ 406911687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices); 407011687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov} 407111687bf4180f7e21045ed9c4730533c40fe01ea5Emil Velikov 407237d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikovchar *drmGetDeviceNameFromFd2(int fd) 407337d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov{ 407437d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov#ifdef __linux__ 407537d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov struct stat sbuf; 40765403cb39c124c444babec51bd4499971cd86ccfaThierry Reding char path[PATH_MAX + 1], *value; 407737d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov unsigned int maj, min; 407837d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 407937d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov if (fstat(fd, &sbuf)) 408037d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov return NULL; 408137d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 408237d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov maj = major(sbuf.st_rdev); 408337d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov min = minor(sbuf.st_rdev); 408437d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 408537d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 408637d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov return NULL; 408737d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 40885403cb39c124c444babec51bd4499971cd86ccfaThierry Reding snprintf(path, sizeof(path), "/sys/dev/char/%d:%d", maj, min); 408937d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 40905403cb39c124c444babec51bd4499971cd86ccfaThierry Reding value = sysfs_uevent_get(path, "DEVNAME"); 40915403cb39c124c444babec51bd4499971cd86ccfaThierry Reding if (!value) 40925403cb39c124c444babec51bd4499971cd86ccfaThierry Reding return NULL; 409337d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 40945403cb39c124c444babec51bd4499971cd86ccfaThierry Reding snprintf(path, sizeof(path), "/dev/%s", value); 40955403cb39c124c444babec51bd4499971cd86ccfaThierry Reding free(value); 409637d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov 40975403cb39c124c444babec51bd4499971cd86ccfaThierry Reding return strdup(path); 409837d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov#else 4099e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray struct stat sbuf; 4100e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray char node[PATH_MAX + 1]; 4101e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray const char *dev_name; 4102e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray int node_type; 4103e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray int maj, min, n, base; 4104e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4105e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray if (fstat(fd, &sbuf)) 4106e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4107e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4108e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray maj = major(sbuf.st_rdev); 4109e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray min = minor(sbuf.st_rdev); 4110e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4111e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 4112e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4113e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4114e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray node_type = drmGetMinorType(min); 4115e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray if (node_type == -1) 4116e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4117e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4118e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray switch (node_type) { 4119e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray case DRM_NODE_PRIMARY: 4120e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray dev_name = DRM_DEV_NAME; 4121e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray break; 4122e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray case DRM_NODE_CONTROL: 4123e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray dev_name = DRM_CONTROL_DEV_NAME; 4124e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray break; 4125e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray case DRM_NODE_RENDER: 4126e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray dev_name = DRM_RENDER_DEV_NAME; 4127e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray break; 4128e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray default: 4129e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4130e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray }; 4131e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4132e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray base = drmGetMinorBase(node_type); 4133e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray if (base < 0) 4134e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4135e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4136e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base); 4137e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray if (n == -1 || n >= PATH_MAX) 4138e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return NULL; 4139e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray 4140e2e766d5acdbb826f1cfe5643669db54ee86f456Jonathan Gray return strdup(node); 414137d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov#endif 414237d790f7d449874d0bf199d9ca9871d12b4d599aEmil Velikov} 4143