xf86drm.c revision 1eb2860b4bd0306dddc5b2f2dc7403aa65c5e476
1/** 2 * \file xf86drm.c 3 * User-level interface to DRM device 4 * 5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 6 * \author Kevin E. Martin <martin@valinux.com> 7 */ 8 9/* 10 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 12 * All Rights Reserved. 13 * 14 * Permission is hereby granted, free of charge, to any person obtaining a 15 * copy of this software and associated documentation files (the "Software"), 16 * to deal in the Software without restriction, including without limitation 17 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 18 * and/or sell copies of the Software, and to permit persons to whom the 19 * Software is furnished to do so, subject to the following conditions: 20 * 21 * The above copyright notice and this permission notice (including the next 22 * paragraph) shall be included in all copies or substantial portions of the 23 * Software. 24 * 25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 28 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 31 * DEALINGS IN THE SOFTWARE. 32 */ 33 34#ifdef HAVE_CONFIG_H 35# include <config.h> 36#endif 37#include <stdio.h> 38#include <stdlib.h> 39#include <unistd.h> 40#include <string.h> 41#include <strings.h> 42#include <ctype.h> 43#include <fcntl.h> 44#include <errno.h> 45#include <signal.h> 46#include <time.h> 47#include <sys/types.h> 48#include <sys/stat.h> 49#define stat_t struct stat 50#include <sys/ioctl.h> 51#include <sys/mman.h> 52#include <sys/time.h> 53#include <stdarg.h> 54 55/* Not all systems have MAP_FAILED defined */ 56#ifndef MAP_FAILED 57#define MAP_FAILED ((void *)-1) 58#endif 59 60#include "xf86drm.h" 61 62#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 63#define DRM_MAJOR 145 64#endif 65 66#ifdef __NetBSD__ 67#define DRM_MAJOR 34 68#endif 69 70# ifdef __OpenBSD__ 71# define DRM_MAJOR 81 72# endif 73 74#ifndef DRM_MAJOR 75#define DRM_MAJOR 226 /* Linux */ 76#endif 77 78/* 79 * This definition needs to be changed on some systems if dev_t is a structure. 80 * If there is a header file we can get it from, there would be best. 81 */ 82#ifndef makedev 83#define makedev(x,y) ((dev_t)(((x) << 8) | (y))) 84#endif 85 86#define DRM_MSG_VERBOSITY 3 87 88#define DRM_NODE_CONTROL 0 89#define DRM_NODE_RENDER 1 90 91static drmServerInfoPtr drm_server_info; 92 93void drmSetServerInfo(drmServerInfoPtr info) 94{ 95 drm_server_info = info; 96} 97 98/** 99 * Output a message to stderr. 100 * 101 * \param format printf() like format string. 102 * 103 * \internal 104 * This function is a wrapper around vfprintf(). 105 */ 106 107static int drmDebugPrint(const char *format, va_list ap) 108{ 109 return vfprintf(stderr, format, ap); 110} 111 112static int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint; 113 114void 115drmMsg(const char *format, ...) 116{ 117 va_list ap; 118 const char *env; 119 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info) 120 { 121 va_start(ap, format); 122 if (drm_server_info) { 123 drm_server_info->debug_print(format,ap); 124 } else { 125 drm_debug_print(format, ap); 126 } 127 va_end(ap); 128 } 129} 130 131void 132drmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap)) 133{ 134 drm_debug_print = debug_msg_ptr; 135} 136 137static void *drmHashTable = NULL; /* Context switch callbacks */ 138 139void *drmGetHashTable(void) 140{ 141 return drmHashTable; 142} 143 144void *drmMalloc(int size) 145{ 146 void *pt; 147 if ((pt = malloc(size))) 148 memset(pt, 0, size); 149 return pt; 150} 151 152void drmFree(void *pt) 153{ 154 if (pt) 155 free(pt); 156} 157 158/** 159 * Call ioctl, restarting if it is interupted 160 */ 161int 162drmIoctl(int fd, unsigned long request, void *arg) 163{ 164 int ret; 165 166 do { 167 ret = ioctl(fd, request, arg); 168 } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); 169 return ret; 170} 171 172static unsigned long drmGetKeyFromFd(int fd) 173{ 174 stat_t st; 175 176 st.st_rdev = 0; 177 fstat(fd, &st); 178 return st.st_rdev; 179} 180 181drmHashEntry *drmGetEntry(int fd) 182{ 183 unsigned long key = drmGetKeyFromFd(fd); 184 void *value; 185 drmHashEntry *entry; 186 187 if (!drmHashTable) 188 drmHashTable = drmHashCreate(); 189 190 if (drmHashLookup(drmHashTable, key, &value)) { 191 entry = drmMalloc(sizeof(*entry)); 192 entry->fd = fd; 193 entry->f = NULL; 194 entry->tagTable = drmHashCreate(); 195 drmHashInsert(drmHashTable, key, entry); 196 } else { 197 entry = value; 198 } 199 return entry; 200} 201 202/** 203 * Compare two busid strings 204 * 205 * \param first 206 * \param second 207 * 208 * \return 1 if matched. 209 * 210 * \internal 211 * This function compares two bus ID strings. It understands the older 212 * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is 213 * domain, b is bus, d is device, f is function. 214 */ 215static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok) 216{ 217 /* First, check if the IDs are exactly the same */ 218 if (strcasecmp(id1, id2) == 0) 219 return 1; 220 221 /* Try to match old/new-style PCI bus IDs. */ 222 if (strncasecmp(id1, "pci", 3) == 0) { 223 unsigned int o1, b1, d1, f1; 224 unsigned int o2, b2, d2, f2; 225 int ret; 226 227 ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1); 228 if (ret != 4) { 229 o1 = 0; 230 ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1); 231 if (ret != 3) 232 return 0; 233 } 234 235 ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2); 236 if (ret != 4) { 237 o2 = 0; 238 ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2); 239 if (ret != 3) 240 return 0; 241 } 242 243 /* If domains aren't properly supported by the kernel interface, 244 * just ignore them, which sucks less than picking a totally random 245 * card with "open by name" 246 */ 247 if (!pci_domain_ok) 248 o1 = o2 = 0; 249 250 if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2)) 251 return 0; 252 else 253 return 1; 254 } 255 return 0; 256} 257 258/** 259 * Handles error checking for chown call. 260 * 261 * \param path to file. 262 * \param id of the new owner. 263 * \param id of the new group. 264 * 265 * \return zero if success or -1 if failure. 266 * 267 * \internal 268 * Checks for failure. If failure was caused by signal call chown again. 269 * If any other failure happened then it will output error mesage using 270 * drmMsg() call. 271 */ 272static int chown_check_return(const char *path, uid_t owner, gid_t group) 273{ 274 int rv; 275 276 do { 277 rv = chown(path, owner, group); 278 } while (rv != 0 && errno == EINTR); 279 280 if (rv == 0) 281 return 0; 282 283 drmMsg("Failed to change owner or group for file %s! %d: %s\n", 284 path, errno, strerror(errno)); 285 return -1; 286} 287 288/** 289 * Open the DRM device, creating it if necessary. 290 * 291 * \param dev major and minor numbers of the device. 292 * \param minor minor number of the device. 293 * 294 * \return a file descriptor on success, or a negative value on error. 295 * 296 * \internal 297 * Assembles the device name from \p minor and opens it, creating the device 298 * special file node with the major and minor numbers specified by \p dev and 299 * parent directory if necessary and was called by root. 300 */ 301static int drmOpenDevice(long dev, int minor, int type) 302{ 303 stat_t st; 304 char buf[64]; 305 int fd; 306 mode_t devmode = DRM_DEV_MODE, serv_mode; 307 int isroot = !geteuid(); 308 uid_t user = DRM_DEV_UID; 309 gid_t group = DRM_DEV_GID, serv_group; 310 311 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); 312 drmMsg("drmOpenDevice: node name is %s\n", buf); 313 314 if (drm_server_info) { 315 drm_server_info->get_perms(&serv_group, &serv_mode); 316 devmode = serv_mode ? serv_mode : DRM_DEV_MODE; 317 devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); 318 group = (serv_group >= 0) ? serv_group : DRM_DEV_GID; 319 } 320 321#if !defined(UDEV) 322 if (stat(DRM_DIR_NAME, &st)) { 323 if (!isroot) 324 return DRM_ERR_NOT_ROOT; 325 mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE); 326 chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */ 327 chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE); 328 } 329 330 /* Check if the device node exists and create it if necessary. */ 331 if (stat(buf, &st)) { 332 if (!isroot) 333 return DRM_ERR_NOT_ROOT; 334 remove(buf); 335 mknod(buf, S_IFCHR | devmode, dev); 336 } 337 338 if (drm_server_info) { 339 chown_check_return(buf, user, group); 340 chmod(buf, devmode); 341 } 342#else 343 /* if we modprobed then wait for udev */ 344 { 345 int udev_count = 0; 346wait_for_udev: 347 if (stat(DRM_DIR_NAME, &st)) { 348 usleep(20); 349 udev_count++; 350 351 if (udev_count == 50) 352 return -1; 353 goto wait_for_udev; 354 } 355 356 if (stat(buf, &st)) { 357 usleep(20); 358 udev_count++; 359 360 if (udev_count == 50) 361 return -1; 362 goto wait_for_udev; 363 } 364 } 365#endif 366 367 fd = open(buf, O_RDWR, 0); 368 drmMsg("drmOpenDevice: open result is %d, (%s)\n", 369 fd, fd < 0 ? strerror(errno) : "OK"); 370 if (fd >= 0) 371 return fd; 372 373#if !defined(UDEV) 374 /* Check if the device node is not what we expect it to be, and recreate it 375 * and try again if so. 376 */ 377 if (st.st_rdev != dev) { 378 if (!isroot) 379 return DRM_ERR_NOT_ROOT; 380 remove(buf); 381 mknod(buf, S_IFCHR | devmode, dev); 382 if (drm_server_info) { 383 chown_check_return(buf, user, group); 384 chmod(buf, devmode); 385 } 386 } 387 fd = open(buf, O_RDWR, 0); 388 drmMsg("drmOpenDevice: open result is %d, (%s)\n", 389 fd, fd < 0 ? strerror(errno) : "OK"); 390 if (fd >= 0) 391 return fd; 392 393 drmMsg("drmOpenDevice: Open failed\n"); 394 remove(buf); 395#endif 396 return -errno; 397} 398 399 400/** 401 * Open the DRM device 402 * 403 * \param minor device minor number. 404 * \param create allow to create the device if set. 405 * 406 * \return a file descriptor on success, or a negative value on error. 407 * 408 * \internal 409 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device 410 * name from \p minor and opens it. 411 */ 412static int drmOpenMinor(int minor, int create, int type) 413{ 414 int fd; 415 char buf[64]; 416 417 if (create) 418 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); 419 420 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor); 421 if ((fd = open(buf, O_RDWR, 0)) >= 0) 422 return fd; 423 return -errno; 424} 425 426 427/** 428 * Determine whether the DRM kernel driver has been loaded. 429 * 430 * \return 1 if the DRM driver is loaded, 0 otherwise. 431 * 432 * \internal 433 * Determine the presence of the kernel driver by attempting to open the 0 434 * minor and get version information. For backward compatibility with older 435 * Linux implementations, /proc/dri is also checked. 436 */ 437int drmAvailable(void) 438{ 439 drmVersionPtr version; 440 int retval = 0; 441 int fd; 442 443 if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) { 444#ifdef __linux__ 445 /* Try proc for backward Linux compatibility */ 446 if (!access("/proc/dri/0", R_OK)) 447 return 1; 448#endif 449 return 0; 450 } 451 452 if ((version = drmGetVersion(fd))) { 453 retval = 1; 454 drmFreeVersion(version); 455 } 456 close(fd); 457 458 return retval; 459} 460 461 462/** 463 * Open the device by bus ID. 464 * 465 * \param busid bus ID. 466 * 467 * \return a file descriptor on success, or a negative value on error. 468 * 469 * \internal 470 * This function attempts to open every possible minor (up to DRM_MAX_MINOR), 471 * comparing the device bus ID with the one supplied. 472 * 473 * \sa drmOpenMinor() and drmGetBusid(). 474 */ 475static int drmOpenByBusid(const char *busid) 476{ 477 int i, pci_domain_ok = 1; 478 int fd; 479 const char *buf; 480 drmSetVersion sv; 481 482 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); 483 for (i = 0; i < DRM_MAX_MINOR; i++) { 484 fd = drmOpenMinor(i, 1, DRM_NODE_RENDER); 485 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); 486 if (fd >= 0) { 487 /* We need to try for 1.4 first for proper PCI domain support 488 * and if that fails, we know the kernel is busted 489 */ 490 sv.drm_di_major = 1; 491 sv.drm_di_minor = 4; 492 sv.drm_dd_major = -1; /* Don't care */ 493 sv.drm_dd_minor = -1; /* Don't care */ 494 if (drmSetInterfaceVersion(fd, &sv)) { 495#ifndef __alpha__ 496 pci_domain_ok = 0; 497#endif 498 sv.drm_di_major = 1; 499 sv.drm_di_minor = 1; 500 sv.drm_dd_major = -1; /* Don't care */ 501 sv.drm_dd_minor = -1; /* Don't care */ 502 drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n",fd); 503 drmSetInterfaceVersion(fd, &sv); 504 } 505 buf = drmGetBusid(fd); 506 drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); 507 if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) { 508 drmFreeBusid(buf); 509 return fd; 510 } 511 if (buf) 512 drmFreeBusid(buf); 513 close(fd); 514 } 515 } 516 return -1; 517} 518 519 520/** 521 * Open the device by name. 522 * 523 * \param name driver name. 524 * 525 * \return a file descriptor on success, or a negative value on error. 526 * 527 * \internal 528 * This function opens the first minor number that matches the driver name and 529 * isn't already in use. If it's in use it then it will already have a bus ID 530 * assigned. 531 * 532 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). 533 */ 534static int drmOpenByName(const char *name) 535{ 536 int i; 537 int fd; 538 drmVersionPtr version; 539 char * id; 540 541 if (!drmAvailable()) { 542 if (!drm_server_info) { 543 return -1; 544 } 545 else { 546 /* try to load the kernel module now */ 547 if (!drm_server_info->load_module(name)) { 548 drmMsg("[drm] failed to load kernel module \"%s\"\n", name); 549 return -1; 550 } 551 } 552 } 553 554 /* 555 * Open the first minor number that matches the driver name and isn't 556 * already in use. If it's in use it will have a busid assigned already. 557 */ 558 for (i = 0; i < DRM_MAX_MINOR; i++) { 559 if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) { 560 if ((version = drmGetVersion(fd))) { 561 if (!strcmp(version->name, name)) { 562 drmFreeVersion(version); 563 id = drmGetBusid(fd); 564 drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); 565 if (!id || !*id) { 566 if (id) 567 drmFreeBusid(id); 568 return fd; 569 } else { 570 drmFreeBusid(id); 571 } 572 } else { 573 drmFreeVersion(version); 574 } 575 } 576 close(fd); 577 } 578 } 579 580#ifdef __linux__ 581 /* Backward-compatibility /proc support */ 582 for (i = 0; i < 8; i++) { 583 char proc_name[64], buf[512]; 584 char *driver, *pt, *devstring; 585 int retcode; 586 587 sprintf(proc_name, "/proc/dri/%d/name", i); 588 if ((fd = open(proc_name, 0, 0)) >= 0) { 589 retcode = read(fd, buf, sizeof(buf)-1); 590 close(fd); 591 if (retcode) { 592 buf[retcode-1] = '\0'; 593 for (driver = pt = buf; *pt && *pt != ' '; ++pt) 594 ; 595 if (*pt) { /* Device is next */ 596 *pt = '\0'; 597 if (!strcmp(driver, name)) { /* Match */ 598 for (devstring = ++pt; *pt && *pt != ' '; ++pt) 599 ; 600 if (*pt) { /* Found busid */ 601 return drmOpenByBusid(++pt); 602 } else { /* No busid */ 603 return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER); 604 } 605 } 606 } 607 } 608 } 609 } 610#endif 611 612 return -1; 613} 614 615 616/** 617 * Open the DRM device. 618 * 619 * Looks up the specified name and bus ID, and opens the device found. The 620 * entry in /dev/dri is created if necessary and if called by root. 621 * 622 * \param name driver name. Not referenced if bus ID is supplied. 623 * \param busid bus ID. Zero if not known. 624 * 625 * \return a file descriptor on success, or a negative value on error. 626 * 627 * \internal 628 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() 629 * otherwise. 630 */ 631int drmOpen(const char *name, const char *busid) 632{ 633 if (!drmAvailable() && name != NULL && drm_server_info) { 634 /* try to load the kernel */ 635 if (!drm_server_info->load_module(name)) { 636 drmMsg("[drm] failed to load kernel module \"%s\"\n", name); 637 return -1; 638 } 639 } 640 641 if (busid) { 642 int fd = drmOpenByBusid(busid); 643 if (fd >= 0) 644 return fd; 645 } 646 647 if (name) 648 return drmOpenByName(name); 649 650 return -1; 651} 652 653int drmOpenControl(int minor) 654{ 655 return drmOpenMinor(minor, 0, DRM_NODE_CONTROL); 656} 657 658/** 659 * Free the version information returned by drmGetVersion(). 660 * 661 * \param v pointer to the version information. 662 * 663 * \internal 664 * It frees the memory pointed by \p %v as well as all the non-null strings 665 * pointers in it. 666 */ 667void drmFreeVersion(drmVersionPtr v) 668{ 669 if (!v) 670 return; 671 drmFree(v->name); 672 drmFree(v->date); 673 drmFree(v->desc); 674 drmFree(v); 675} 676 677 678/** 679 * Free the non-public version information returned by the kernel. 680 * 681 * \param v pointer to the version information. 682 * 683 * \internal 684 * Used by drmGetVersion() to free the memory pointed by \p %v as well as all 685 * the non-null strings pointers in it. 686 */ 687static void drmFreeKernelVersion(drm_version_t *v) 688{ 689 if (!v) 690 return; 691 drmFree(v->name); 692 drmFree(v->date); 693 drmFree(v->desc); 694 drmFree(v); 695} 696 697 698/** 699 * Copy version information. 700 * 701 * \param d destination pointer. 702 * \param s source pointer. 703 * 704 * \internal 705 * Used by drmGetVersion() to translate the information returned by the ioctl 706 * interface in a private structure into the public structure counterpart. 707 */ 708static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s) 709{ 710 d->version_major = s->version_major; 711 d->version_minor = s->version_minor; 712 d->version_patchlevel = s->version_patchlevel; 713 d->name_len = s->name_len; 714 d->name = strdup(s->name); 715 d->date_len = s->date_len; 716 d->date = strdup(s->date); 717 d->desc_len = s->desc_len; 718 d->desc = strdup(s->desc); 719} 720 721 722/** 723 * Query the driver version information. 724 * 725 * \param fd file descriptor. 726 * 727 * \return pointer to a drmVersion structure which should be freed with 728 * drmFreeVersion(). 729 * 730 * \note Similar information is available via /proc/dri. 731 * 732 * \internal 733 * It gets the version information via successive DRM_IOCTL_VERSION ioctls, 734 * first with zeros to get the string lengths, and then the actually strings. 735 * It also null-terminates them since they might not be already. 736 */ 737drmVersionPtr drmGetVersion(int fd) 738{ 739 drmVersionPtr retval; 740 drm_version_t *version = drmMalloc(sizeof(*version)); 741 742 version->name_len = 0; 743 version->name = NULL; 744 version->date_len = 0; 745 version->date = NULL; 746 version->desc_len = 0; 747 version->desc = NULL; 748 749 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 750 drmFreeKernelVersion(version); 751 return NULL; 752 } 753 754 if (version->name_len) 755 version->name = drmMalloc(version->name_len + 1); 756 if (version->date_len) 757 version->date = drmMalloc(version->date_len + 1); 758 if (version->desc_len) 759 version->desc = drmMalloc(version->desc_len + 1); 760 761 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 762 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno)); 763 drmFreeKernelVersion(version); 764 return NULL; 765 } 766 767 /* The results might not be null-terminated strings, so terminate them. */ 768 if (version->name_len) version->name[version->name_len] = '\0'; 769 if (version->date_len) version->date[version->date_len] = '\0'; 770 if (version->desc_len) version->desc[version->desc_len] = '\0'; 771 772 retval = drmMalloc(sizeof(*retval)); 773 drmCopyVersion(retval, version); 774 drmFreeKernelVersion(version); 775 return retval; 776} 777 778 779/** 780 * Get version information for the DRM user space library. 781 * 782 * This version number is driver independent. 783 * 784 * \param fd file descriptor. 785 * 786 * \return version information. 787 * 788 * \internal 789 * This function allocates and fills a drm_version structure with a hard coded 790 * version number. 791 */ 792drmVersionPtr drmGetLibVersion(int fd) 793{ 794 drm_version_t *version = drmMalloc(sizeof(*version)); 795 796 /* Version history: 797 * NOTE THIS MUST NOT GO ABOVE VERSION 1.X due to drivers needing it 798 * revision 1.0.x = original DRM interface with no drmGetLibVersion 799 * entry point and many drm<Device> extensions 800 * revision 1.1.x = added drmCommand entry points for device extensions 801 * added drmGetLibVersion to identify libdrm.a version 802 * revision 1.2.x = added drmSetInterfaceVersion 803 * modified drmOpen to handle both busid and name 804 * revision 1.3.x = added server + memory manager 805 */ 806 version->version_major = 1; 807 version->version_minor = 3; 808 version->version_patchlevel = 0; 809 810 return (drmVersionPtr)version; 811} 812 813int drmGetCap(int fd, uint64_t capability, uint64_t *value) 814{ 815 struct drm_get_cap cap = { capability, 0 }; 816 int ret; 817 818 ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap); 819 if (ret) 820 return ret; 821 822 *value = cap.value; 823 return 0; 824} 825 826/** 827 * Free the bus ID information. 828 * 829 * \param busid bus ID information string as given by drmGetBusid(). 830 * 831 * \internal 832 * This function is just frees the memory pointed by \p busid. 833 */ 834void drmFreeBusid(const char *busid) 835{ 836 drmFree((void *)busid); 837} 838 839 840/** 841 * Get the bus ID of the device. 842 * 843 * \param fd file descriptor. 844 * 845 * \return bus ID string. 846 * 847 * \internal 848 * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to 849 * get the string length and data, passing the arguments in a drm_unique 850 * structure. 851 */ 852char *drmGetBusid(int fd) 853{ 854 drm_unique_t u; 855 856 u.unique_len = 0; 857 u.unique = NULL; 858 859 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 860 return NULL; 861 u.unique = drmMalloc(u.unique_len + 1); 862 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 863 return NULL; 864 u.unique[u.unique_len] = '\0'; 865 866 return u.unique; 867} 868 869 870/** 871 * Set the bus ID of the device. 872 * 873 * \param fd file descriptor. 874 * \param busid bus ID string. 875 * 876 * \return zero on success, negative on failure. 877 * 878 * \internal 879 * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing 880 * the arguments in a drm_unique structure. 881 */ 882int drmSetBusid(int fd, const char *busid) 883{ 884 drm_unique_t u; 885 886 u.unique = (char *)busid; 887 u.unique_len = strlen(busid); 888 889 if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { 890 return -errno; 891 } 892 return 0; 893} 894 895int drmGetMagic(int fd, drm_magic_t * magic) 896{ 897 drm_auth_t auth; 898 899 *magic = 0; 900 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) 901 return -errno; 902 *magic = auth.magic; 903 return 0; 904} 905 906int drmAuthMagic(int fd, drm_magic_t magic) 907{ 908 drm_auth_t auth; 909 910 auth.magic = magic; 911 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) 912 return -errno; 913 return 0; 914} 915 916/** 917 * Specifies a range of memory that is available for mapping by a 918 * non-root process. 919 * 920 * \param fd file descriptor. 921 * \param offset usually the physical address. The actual meaning depends of 922 * the \p type parameter. See below. 923 * \param size of the memory in bytes. 924 * \param type type of the memory to be mapped. 925 * \param flags combination of several flags to modify the function actions. 926 * \param handle will be set to a value that may be used as the offset 927 * parameter for mmap(). 928 * 929 * \return zero on success or a negative value on error. 930 * 931 * \par Mapping the frame buffer 932 * For the frame buffer 933 * - \p offset will be the physical address of the start of the frame buffer, 934 * - \p size will be the size of the frame buffer in bytes, and 935 * - \p type will be DRM_FRAME_BUFFER. 936 * 937 * \par 938 * The area mapped will be uncached. If MTRR support is available in the 939 * kernel, the frame buffer area will be set to write combining. 940 * 941 * \par Mapping the MMIO register area 942 * For the MMIO register area, 943 * - \p offset will be the physical address of the start of the register area, 944 * - \p size will be the size of the register area bytes, and 945 * - \p type will be DRM_REGISTERS. 946 * \par 947 * The area mapped will be uncached. 948 * 949 * \par Mapping the SAREA 950 * For the SAREA, 951 * - \p offset will be ignored and should be set to zero, 952 * - \p size will be the desired size of the SAREA in bytes, 953 * - \p type will be DRM_SHM. 954 * 955 * \par 956 * A shared memory area of the requested size will be created and locked in 957 * kernel memory. This area may be mapped into client-space by using the handle 958 * returned. 959 * 960 * \note May only be called by root. 961 * 962 * \internal 963 * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing 964 * the arguments in a drm_map structure. 965 */ 966int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type, 967 drmMapFlags flags, drm_handle_t *handle) 968{ 969 drm_map_t map; 970 971 map.offset = offset; 972 map.size = size; 973 map.handle = 0; 974 map.type = type; 975 map.flags = flags; 976 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map)) 977 return -errno; 978 if (handle) 979 *handle = (drm_handle_t)(uintptr_t)map.handle; 980 return 0; 981} 982 983int drmRmMap(int fd, drm_handle_t handle) 984{ 985 drm_map_t map; 986 987 map.handle = (void *)(uintptr_t)handle; 988 989 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map)) 990 return -errno; 991 return 0; 992} 993 994/** 995 * Make buffers available for DMA transfers. 996 * 997 * \param fd file descriptor. 998 * \param count number of buffers. 999 * \param size size of each buffer. 1000 * \param flags buffer allocation flags. 1001 * \param agp_offset offset in the AGP aperture 1002 * 1003 * \return number of buffers allocated, negative on error. 1004 * 1005 * \internal 1006 * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl. 1007 * 1008 * \sa drm_buf_desc. 1009 */ 1010int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, 1011 int agp_offset) 1012{ 1013 drm_buf_desc_t request; 1014 1015 request.count = count; 1016 request.size = size; 1017 request.low_mark = 0; 1018 request.high_mark = 0; 1019 request.flags = flags; 1020 request.agp_start = agp_offset; 1021 1022 if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request)) 1023 return -errno; 1024 return request.count; 1025} 1026 1027int drmMarkBufs(int fd, double low, double high) 1028{ 1029 drm_buf_info_t info; 1030 int i; 1031 1032 info.count = 0; 1033 info.list = NULL; 1034 1035 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1036 return -EINVAL; 1037 1038 if (!info.count) 1039 return -EINVAL; 1040 1041 if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 1042 return -ENOMEM; 1043 1044 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 1045 int retval = -errno; 1046 drmFree(info.list); 1047 return retval; 1048 } 1049 1050 for (i = 0; i < info.count; i++) { 1051 info.list[i].low_mark = low * info.list[i].count; 1052 info.list[i].high_mark = high * info.list[i].count; 1053 if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) { 1054 int retval = -errno; 1055 drmFree(info.list); 1056 return retval; 1057 } 1058 } 1059 drmFree(info.list); 1060 1061 return 0; 1062} 1063 1064/** 1065 * Free buffers. 1066 * 1067 * \param fd file descriptor. 1068 * \param count number of buffers to free. 1069 * \param list list of buffers to be freed. 1070 * 1071 * \return zero on success, or a negative value on failure. 1072 * 1073 * \note This function is primarily used for debugging. 1074 * 1075 * \internal 1076 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing 1077 * the arguments in a drm_buf_free structure. 1078 */ 1079int drmFreeBufs(int fd, int count, int *list) 1080{ 1081 drm_buf_free_t request; 1082 1083 request.count = count; 1084 request.list = list; 1085 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request)) 1086 return -errno; 1087 return 0; 1088} 1089 1090 1091/** 1092 * Close the device. 1093 * 1094 * \param fd file descriptor. 1095 * 1096 * \internal 1097 * This function closes the file descriptor. 1098 */ 1099int drmClose(int fd) 1100{ 1101 unsigned long key = drmGetKeyFromFd(fd); 1102 drmHashEntry *entry = drmGetEntry(fd); 1103 1104 drmHashDestroy(entry->tagTable); 1105 entry->fd = 0; 1106 entry->f = NULL; 1107 entry->tagTable = NULL; 1108 1109 drmHashDelete(drmHashTable, key); 1110 drmFree(entry); 1111 1112 return close(fd); 1113} 1114 1115 1116/** 1117 * Map a region of memory. 1118 * 1119 * \param fd file descriptor. 1120 * \param handle handle returned by drmAddMap(). 1121 * \param size size in bytes. Must match the size used by drmAddMap(). 1122 * \param address will contain the user-space virtual address where the mapping 1123 * begins. 1124 * 1125 * \return zero on success, or a negative value on failure. 1126 * 1127 * \internal 1128 * This function is a wrapper for mmap(). 1129 */ 1130int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address) 1131{ 1132 static unsigned long pagesize_mask = 0; 1133 1134 if (fd < 0) 1135 return -EINVAL; 1136 1137 if (!pagesize_mask) 1138 pagesize_mask = getpagesize() - 1; 1139 1140 size = (size + pagesize_mask) & ~pagesize_mask; 1141 1142 *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); 1143 if (*address == MAP_FAILED) 1144 return -errno; 1145 return 0; 1146} 1147 1148 1149/** 1150 * Unmap mappings obtained with drmMap(). 1151 * 1152 * \param address address as given by drmMap(). 1153 * \param size size in bytes. Must match the size used by drmMap(). 1154 * 1155 * \return zero on success, or a negative value on failure. 1156 * 1157 * \internal 1158 * This function is a wrapper for munmap(). 1159 */ 1160int drmUnmap(drmAddress address, drmSize size) 1161{ 1162 return munmap(address, size); 1163} 1164 1165drmBufInfoPtr drmGetBufInfo(int fd) 1166{ 1167 drm_buf_info_t info; 1168 drmBufInfoPtr retval; 1169 int i; 1170 1171 info.count = 0; 1172 info.list = NULL; 1173 1174 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1175 return NULL; 1176 1177 if (info.count) { 1178 if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 1179 return NULL; 1180 1181 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 1182 drmFree(info.list); 1183 return NULL; 1184 } 1185 1186 retval = drmMalloc(sizeof(*retval)); 1187 retval->count = info.count; 1188 retval->list = drmMalloc(info.count * sizeof(*retval->list)); 1189 for (i = 0; i < info.count; i++) { 1190 retval->list[i].count = info.list[i].count; 1191 retval->list[i].size = info.list[i].size; 1192 retval->list[i].low_mark = info.list[i].low_mark; 1193 retval->list[i].high_mark = info.list[i].high_mark; 1194 } 1195 drmFree(info.list); 1196 return retval; 1197 } 1198 return NULL; 1199} 1200 1201/** 1202 * Map all DMA buffers into client-virtual space. 1203 * 1204 * \param fd file descriptor. 1205 * 1206 * \return a pointer to a ::drmBufMap structure. 1207 * 1208 * \note The client may not use these buffers until obtaining buffer indices 1209 * with drmDMA(). 1210 * 1211 * \internal 1212 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned 1213 * information about the buffers in a drm_buf_map structure into the 1214 * client-visible data structures. 1215 */ 1216drmBufMapPtr drmMapBufs(int fd) 1217{ 1218 drm_buf_map_t bufs; 1219 drmBufMapPtr retval; 1220 int i; 1221 1222 bufs.count = 0; 1223 bufs.list = NULL; 1224 bufs.virtual = NULL; 1225 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) 1226 return NULL; 1227 1228 if (!bufs.count) 1229 return NULL; 1230 1231 if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list)))) 1232 return NULL; 1233 1234 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { 1235 drmFree(bufs.list); 1236 return NULL; 1237 } 1238 1239 retval = drmMalloc(sizeof(*retval)); 1240 retval->count = bufs.count; 1241 retval->list = drmMalloc(bufs.count * sizeof(*retval->list)); 1242 for (i = 0; i < bufs.count; i++) { 1243 retval->list[i].idx = bufs.list[i].idx; 1244 retval->list[i].total = bufs.list[i].total; 1245 retval->list[i].used = 0; 1246 retval->list[i].address = bufs.list[i].address; 1247 } 1248 1249 drmFree(bufs.list); 1250 1251 return retval; 1252} 1253 1254 1255/** 1256 * Unmap buffers allocated with drmMapBufs(). 1257 * 1258 * \return zero on success, or negative value on failure. 1259 * 1260 * \internal 1261 * Calls munmap() for every buffer stored in \p bufs and frees the 1262 * memory allocated by drmMapBufs(). 1263 */ 1264int drmUnmapBufs(drmBufMapPtr bufs) 1265{ 1266 int i; 1267 1268 for (i = 0; i < bufs->count; i++) { 1269 munmap(bufs->list[i].address, bufs->list[i].total); 1270 } 1271 1272 drmFree(bufs->list); 1273 drmFree(bufs); 1274 1275 return 0; 1276} 1277 1278 1279#define DRM_DMA_RETRY 16 1280 1281/** 1282 * Reserve DMA buffers. 1283 * 1284 * \param fd file descriptor. 1285 * \param request 1286 * 1287 * \return zero on success, or a negative value on failure. 1288 * 1289 * \internal 1290 * Assemble the arguments into a drm_dma structure and keeps issuing the 1291 * DRM_IOCTL_DMA ioctl until success or until maximum number of retries. 1292 */ 1293int drmDMA(int fd, drmDMAReqPtr request) 1294{ 1295 drm_dma_t dma; 1296 int ret, i = 0; 1297 1298 dma.context = request->context; 1299 dma.send_count = request->send_count; 1300 dma.send_indices = request->send_list; 1301 dma.send_sizes = request->send_sizes; 1302 dma.flags = request->flags; 1303 dma.request_count = request->request_count; 1304 dma.request_size = request->request_size; 1305 dma.request_indices = request->request_list; 1306 dma.request_sizes = request->request_sizes; 1307 dma.granted_count = 0; 1308 1309 do { 1310 ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); 1311 } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); 1312 1313 if ( ret == 0 ) { 1314 request->granted_count = dma.granted_count; 1315 return 0; 1316 } else { 1317 return -errno; 1318 } 1319} 1320 1321 1322/** 1323 * Obtain heavyweight hardware lock. 1324 * 1325 * \param fd file descriptor. 1326 * \param context context. 1327 * \param flags flags that determine the sate of the hardware when the function 1328 * returns. 1329 * 1330 * \return always zero. 1331 * 1332 * \internal 1333 * This function translates the arguments into a drm_lock structure and issue 1334 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. 1335 */ 1336int drmGetLock(int fd, drm_context_t context, drmLockFlags flags) 1337{ 1338 drm_lock_t lock; 1339 1340 lock.context = context; 1341 lock.flags = 0; 1342 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 1343 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 1344 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 1345 if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 1346 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 1347 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 1348 1349 while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock)) 1350 ; 1351 return 0; 1352} 1353 1354/** 1355 * Release the hardware lock. 1356 * 1357 * \param fd file descriptor. 1358 * \param context context. 1359 * 1360 * \return zero on success, or a negative value on failure. 1361 * 1362 * \internal 1363 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the 1364 * argument in a drm_lock structure. 1365 */ 1366int drmUnlock(int fd, drm_context_t context) 1367{ 1368 drm_lock_t lock; 1369 1370 lock.context = context; 1371 lock.flags = 0; 1372 return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock); 1373} 1374 1375drm_context_t *drmGetReservedContextList(int fd, int *count) 1376{ 1377 drm_ctx_res_t res; 1378 drm_ctx_t *list; 1379 drm_context_t * retval; 1380 int i; 1381 1382 res.count = 0; 1383 res.contexts = NULL; 1384 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1385 return NULL; 1386 1387 if (!res.count) 1388 return NULL; 1389 1390 if (!(list = drmMalloc(res.count * sizeof(*list)))) 1391 return NULL; 1392 if (!(retval = drmMalloc(res.count * sizeof(*retval)))) { 1393 drmFree(list); 1394 return NULL; 1395 } 1396 1397 res.contexts = list; 1398 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1399 return NULL; 1400 1401 for (i = 0; i < res.count; i++) 1402 retval[i] = list[i].handle; 1403 drmFree(list); 1404 1405 *count = res.count; 1406 return retval; 1407} 1408 1409void drmFreeReservedContextList(drm_context_t *pt) 1410{ 1411 drmFree(pt); 1412} 1413 1414/** 1415 * Create context. 1416 * 1417 * Used by the X server during GLXContext initialization. This causes 1418 * per-context kernel-level resources to be allocated. 1419 * 1420 * \param fd file descriptor. 1421 * \param handle is set on success. To be used by the client when requesting DMA 1422 * dispatch with drmDMA(). 1423 * 1424 * \return zero on success, or a negative value on failure. 1425 * 1426 * \note May only be called by root. 1427 * 1428 * \internal 1429 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the 1430 * argument in a drm_ctx structure. 1431 */ 1432int drmCreateContext(int fd, drm_context_t *handle) 1433{ 1434 drm_ctx_t ctx; 1435 1436 ctx.flags = 0; /* Modified with functions below */ 1437 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) 1438 return -errno; 1439 *handle = ctx.handle; 1440 return 0; 1441} 1442 1443int drmSwitchToContext(int fd, drm_context_t context) 1444{ 1445 drm_ctx_t ctx; 1446 1447 ctx.handle = context; 1448 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) 1449 return -errno; 1450 return 0; 1451} 1452 1453int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags) 1454{ 1455 drm_ctx_t ctx; 1456 1457 /* 1458 * Context preserving means that no context switches are done between DMA 1459 * buffers from one context and the next. This is suitable for use in the 1460 * X server (which promises to maintain hardware context), or in the 1461 * client-side library when buffers are swapped on behalf of two threads. 1462 */ 1463 ctx.handle = context; 1464 ctx.flags = 0; 1465 if (flags & DRM_CONTEXT_PRESERVED) 1466 ctx.flags |= _DRM_CONTEXT_PRESERVED; 1467 if (flags & DRM_CONTEXT_2DONLY) 1468 ctx.flags |= _DRM_CONTEXT_2DONLY; 1469 if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) 1470 return -errno; 1471 return 0; 1472} 1473 1474int drmGetContextFlags(int fd, drm_context_t context, 1475 drm_context_tFlagsPtr flags) 1476{ 1477 drm_ctx_t ctx; 1478 1479 ctx.handle = context; 1480 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx)) 1481 return -errno; 1482 *flags = 0; 1483 if (ctx.flags & _DRM_CONTEXT_PRESERVED) 1484 *flags |= DRM_CONTEXT_PRESERVED; 1485 if (ctx.flags & _DRM_CONTEXT_2DONLY) 1486 *flags |= DRM_CONTEXT_2DONLY; 1487 return 0; 1488} 1489 1490/** 1491 * Destroy context. 1492 * 1493 * Free any kernel-level resources allocated with drmCreateContext() associated 1494 * with the context. 1495 * 1496 * \param fd file descriptor. 1497 * \param handle handle given by drmCreateContext(). 1498 * 1499 * \return zero on success, or a negative value on failure. 1500 * 1501 * \note May only be called by root. 1502 * 1503 * \internal 1504 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the 1505 * argument in a drm_ctx structure. 1506 */ 1507int drmDestroyContext(int fd, drm_context_t handle) 1508{ 1509 drm_ctx_t ctx; 1510 ctx.handle = handle; 1511 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx)) 1512 return -errno; 1513 return 0; 1514} 1515 1516int drmCreateDrawable(int fd, drm_drawable_t *handle) 1517{ 1518 drm_draw_t draw; 1519 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) 1520 return -errno; 1521 *handle = draw.handle; 1522 return 0; 1523} 1524 1525int drmDestroyDrawable(int fd, drm_drawable_t handle) 1526{ 1527 drm_draw_t draw; 1528 draw.handle = handle; 1529 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw)) 1530 return -errno; 1531 return 0; 1532} 1533 1534int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, 1535 drm_drawable_info_type_t type, unsigned int num, 1536 void *data) 1537{ 1538 drm_update_draw_t update; 1539 1540 update.handle = handle; 1541 update.type = type; 1542 update.num = num; 1543 update.data = (unsigned long long)(unsigned long)data; 1544 1545 if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) 1546 return -errno; 1547 1548 return 0; 1549} 1550 1551/** 1552 * Acquire the AGP device. 1553 * 1554 * Must be called before any of the other AGP related calls. 1555 * 1556 * \param fd file descriptor. 1557 * 1558 * \return zero on success, or a negative value on failure. 1559 * 1560 * \internal 1561 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. 1562 */ 1563int drmAgpAcquire(int fd) 1564{ 1565 if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) 1566 return -errno; 1567 return 0; 1568} 1569 1570 1571/** 1572 * Release the AGP device. 1573 * 1574 * \param fd file descriptor. 1575 * 1576 * \return zero on success, or a negative value on failure. 1577 * 1578 * \internal 1579 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. 1580 */ 1581int drmAgpRelease(int fd) 1582{ 1583 if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) 1584 return -errno; 1585 return 0; 1586} 1587 1588 1589/** 1590 * Set the AGP mode. 1591 * 1592 * \param fd file descriptor. 1593 * \param mode AGP mode. 1594 * 1595 * \return zero on success, or a negative value on failure. 1596 * 1597 * \internal 1598 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the 1599 * argument in a drm_agp_mode structure. 1600 */ 1601int drmAgpEnable(int fd, unsigned long mode) 1602{ 1603 drm_agp_mode_t m; 1604 1605 m.mode = mode; 1606 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) 1607 return -errno; 1608 return 0; 1609} 1610 1611 1612/** 1613 * Allocate a chunk of AGP memory. 1614 * 1615 * \param fd file descriptor. 1616 * \param size requested memory size in bytes. Will be rounded to page boundary. 1617 * \param type type of memory to allocate. 1618 * \param address if not zero, will be set to the physical address of the 1619 * allocated memory. 1620 * \param handle on success will be set to a handle of the allocated memory. 1621 * 1622 * \return zero on success, or a negative value on failure. 1623 * 1624 * \internal 1625 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the 1626 * arguments in a drm_agp_buffer structure. 1627 */ 1628int drmAgpAlloc(int fd, unsigned long size, unsigned long type, 1629 unsigned long *address, drm_handle_t *handle) 1630{ 1631 drm_agp_buffer_t b; 1632 1633 *handle = DRM_AGP_NO_HANDLE; 1634 b.size = size; 1635 b.handle = 0; 1636 b.type = type; 1637 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) 1638 return -errno; 1639 if (address != 0UL) 1640 *address = b.physical; 1641 *handle = b.handle; 1642 return 0; 1643} 1644 1645 1646/** 1647 * Free a chunk of AGP memory. 1648 * 1649 * \param fd file descriptor. 1650 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1651 * 1652 * \return zero on success, or a negative value on failure. 1653 * 1654 * \internal 1655 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the 1656 * argument in a drm_agp_buffer structure. 1657 */ 1658int drmAgpFree(int fd, drm_handle_t handle) 1659{ 1660 drm_agp_buffer_t b; 1661 1662 b.size = 0; 1663 b.handle = handle; 1664 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b)) 1665 return -errno; 1666 return 0; 1667} 1668 1669 1670/** 1671 * Bind a chunk of AGP memory. 1672 * 1673 * \param fd file descriptor. 1674 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1675 * \param offset offset in bytes. It will round to page boundary. 1676 * 1677 * \return zero on success, or a negative value on failure. 1678 * 1679 * \internal 1680 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the 1681 * argument in a drm_agp_binding structure. 1682 */ 1683int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset) 1684{ 1685 drm_agp_binding_t b; 1686 1687 b.handle = handle; 1688 b.offset = offset; 1689 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b)) 1690 return -errno; 1691 return 0; 1692} 1693 1694 1695/** 1696 * Unbind a chunk of AGP memory. 1697 * 1698 * \param fd file descriptor. 1699 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1700 * 1701 * \return zero on success, or a negative value on failure. 1702 * 1703 * \internal 1704 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing 1705 * the argument in a drm_agp_binding structure. 1706 */ 1707int drmAgpUnbind(int fd, drm_handle_t handle) 1708{ 1709 drm_agp_binding_t b; 1710 1711 b.handle = handle; 1712 b.offset = 0; 1713 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) 1714 return -errno; 1715 return 0; 1716} 1717 1718 1719/** 1720 * Get AGP driver major version number. 1721 * 1722 * \param fd file descriptor. 1723 * 1724 * \return major version number on success, or a negative value on failure.. 1725 * 1726 * \internal 1727 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1728 * necessary information in a drm_agp_info structure. 1729 */ 1730int drmAgpVersionMajor(int fd) 1731{ 1732 drm_agp_info_t i; 1733 1734 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1735 return -errno; 1736 return i.agp_version_major; 1737} 1738 1739 1740/** 1741 * Get AGP driver minor version number. 1742 * 1743 * \param fd file descriptor. 1744 * 1745 * \return minor version number on success, or a negative value on failure. 1746 * 1747 * \internal 1748 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1749 * necessary information in a drm_agp_info structure. 1750 */ 1751int drmAgpVersionMinor(int fd) 1752{ 1753 drm_agp_info_t i; 1754 1755 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1756 return -errno; 1757 return i.agp_version_minor; 1758} 1759 1760 1761/** 1762 * Get AGP mode. 1763 * 1764 * \param fd file descriptor. 1765 * 1766 * \return mode on success, or zero on failure. 1767 * 1768 * \internal 1769 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1770 * necessary information in a drm_agp_info structure. 1771 */ 1772unsigned long drmAgpGetMode(int fd) 1773{ 1774 drm_agp_info_t i; 1775 1776 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1777 return 0; 1778 return i.mode; 1779} 1780 1781 1782/** 1783 * Get AGP aperture base. 1784 * 1785 * \param fd file descriptor. 1786 * 1787 * \return aperture base on success, zero on failure. 1788 * 1789 * \internal 1790 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1791 * necessary information in a drm_agp_info structure. 1792 */ 1793unsigned long drmAgpBase(int fd) 1794{ 1795 drm_agp_info_t i; 1796 1797 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1798 return 0; 1799 return i.aperture_base; 1800} 1801 1802 1803/** 1804 * Get AGP aperture size. 1805 * 1806 * \param fd file descriptor. 1807 * 1808 * \return aperture size on success, zero on failure. 1809 * 1810 * \internal 1811 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1812 * necessary information in a drm_agp_info structure. 1813 */ 1814unsigned long drmAgpSize(int fd) 1815{ 1816 drm_agp_info_t i; 1817 1818 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1819 return 0; 1820 return i.aperture_size; 1821} 1822 1823 1824/** 1825 * Get used AGP memory. 1826 * 1827 * \param fd file descriptor. 1828 * 1829 * \return memory used on success, or zero on failure. 1830 * 1831 * \internal 1832 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1833 * necessary information in a drm_agp_info structure. 1834 */ 1835unsigned long drmAgpMemoryUsed(int fd) 1836{ 1837 drm_agp_info_t i; 1838 1839 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1840 return 0; 1841 return i.memory_used; 1842} 1843 1844 1845/** 1846 * Get available AGP memory. 1847 * 1848 * \param fd file descriptor. 1849 * 1850 * \return memory available on success, or zero on failure. 1851 * 1852 * \internal 1853 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1854 * necessary information in a drm_agp_info structure. 1855 */ 1856unsigned long drmAgpMemoryAvail(int fd) 1857{ 1858 drm_agp_info_t i; 1859 1860 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1861 return 0; 1862 return i.memory_allowed; 1863} 1864 1865 1866/** 1867 * Get hardware vendor ID. 1868 * 1869 * \param fd file descriptor. 1870 * 1871 * \return vendor ID on success, or zero on failure. 1872 * 1873 * \internal 1874 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1875 * necessary information in a drm_agp_info structure. 1876 */ 1877unsigned int drmAgpVendorId(int fd) 1878{ 1879 drm_agp_info_t i; 1880 1881 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1882 return 0; 1883 return i.id_vendor; 1884} 1885 1886 1887/** 1888 * Get hardware device ID. 1889 * 1890 * \param fd file descriptor. 1891 * 1892 * \return zero on success, or zero on failure. 1893 * 1894 * \internal 1895 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1896 * necessary information in a drm_agp_info structure. 1897 */ 1898unsigned int drmAgpDeviceId(int fd) 1899{ 1900 drm_agp_info_t i; 1901 1902 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1903 return 0; 1904 return i.id_device; 1905} 1906 1907int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle) 1908{ 1909 drm_scatter_gather_t sg; 1910 1911 *handle = 0; 1912 sg.size = size; 1913 sg.handle = 0; 1914 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) 1915 return -errno; 1916 *handle = sg.handle; 1917 return 0; 1918} 1919 1920int drmScatterGatherFree(int fd, drm_handle_t handle) 1921{ 1922 drm_scatter_gather_t sg; 1923 1924 sg.size = 0; 1925 sg.handle = handle; 1926 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg)) 1927 return -errno; 1928 return 0; 1929} 1930 1931/** 1932 * Wait for VBLANK. 1933 * 1934 * \param fd file descriptor. 1935 * \param vbl pointer to a drmVBlank structure. 1936 * 1937 * \return zero on success, or a negative value on failure. 1938 * 1939 * \internal 1940 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. 1941 */ 1942int drmWaitVBlank(int fd, drmVBlankPtr vbl) 1943{ 1944 struct timespec timeout, cur; 1945 int ret; 1946 1947 ret = clock_gettime(CLOCK_MONOTONIC, &timeout); 1948 if (ret < 0) { 1949 fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno)); 1950 goto out; 1951 } 1952 timeout.tv_sec++; 1953 1954 do { 1955 ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); 1956 vbl->request.type &= ~DRM_VBLANK_RELATIVE; 1957 if (ret && errno == EINTR) { 1958 clock_gettime(CLOCK_MONOTONIC, &cur); 1959 /* Timeout after 1s */ 1960 if (cur.tv_sec > timeout.tv_sec + 1 || 1961 (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= 1962 timeout.tv_nsec)) { 1963 errno = EBUSY; 1964 ret = -1; 1965 break; 1966 } 1967 } 1968 } while (ret && errno == EINTR); 1969 1970out: 1971 return ret; 1972} 1973 1974int drmError(int err, const char *label) 1975{ 1976 switch (err) { 1977 case DRM_ERR_NO_DEVICE: 1978 fprintf(stderr, "%s: no device\n", label); 1979 break; 1980 case DRM_ERR_NO_ACCESS: 1981 fprintf(stderr, "%s: no access\n", label); 1982 break; 1983 case DRM_ERR_NOT_ROOT: 1984 fprintf(stderr, "%s: not root\n", label); 1985 break; 1986 case DRM_ERR_INVALID: 1987 fprintf(stderr, "%s: invalid args\n", label); 1988 break; 1989 default: 1990 if (err < 0) 1991 err = -err; 1992 fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) ); 1993 break; 1994 } 1995 1996 return 1; 1997} 1998 1999/** 2000 * Install IRQ handler. 2001 * 2002 * \param fd file descriptor. 2003 * \param irq IRQ number. 2004 * 2005 * \return zero on success, or a negative value on failure. 2006 * 2007 * \internal 2008 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2009 * argument in a drm_control structure. 2010 */ 2011int drmCtlInstHandler(int fd, int irq) 2012{ 2013 drm_control_t ctl; 2014 2015 ctl.func = DRM_INST_HANDLER; 2016 ctl.irq = irq; 2017 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2018 return -errno; 2019 return 0; 2020} 2021 2022 2023/** 2024 * Uninstall IRQ handler. 2025 * 2026 * \param fd file descriptor. 2027 * 2028 * \return zero on success, or a negative value on failure. 2029 * 2030 * \internal 2031 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2032 * argument in a drm_control structure. 2033 */ 2034int drmCtlUninstHandler(int fd) 2035{ 2036 drm_control_t ctl; 2037 2038 ctl.func = DRM_UNINST_HANDLER; 2039 ctl.irq = 0; 2040 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2041 return -errno; 2042 return 0; 2043} 2044 2045int drmFinish(int fd, int context, drmLockFlags flags) 2046{ 2047 drm_lock_t lock; 2048 2049 lock.context = context; 2050 lock.flags = 0; 2051 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 2052 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 2053 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 2054 if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 2055 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 2056 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 2057 if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock)) 2058 return -errno; 2059 return 0; 2060} 2061 2062/** 2063 * Get IRQ from bus ID. 2064 * 2065 * \param fd file descriptor. 2066 * \param busnum bus number. 2067 * \param devnum device number. 2068 * \param funcnum function number. 2069 * 2070 * \return IRQ number on success, or a negative value on failure. 2071 * 2072 * \internal 2073 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the 2074 * arguments in a drm_irq_busid structure. 2075 */ 2076int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum) 2077{ 2078 drm_irq_busid_t p; 2079 2080 p.busnum = busnum; 2081 p.devnum = devnum; 2082 p.funcnum = funcnum; 2083 if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) 2084 return -errno; 2085 return p.irq; 2086} 2087 2088int drmAddContextTag(int fd, drm_context_t context, void *tag) 2089{ 2090 drmHashEntry *entry = drmGetEntry(fd); 2091 2092 if (drmHashInsert(entry->tagTable, context, tag)) { 2093 drmHashDelete(entry->tagTable, context); 2094 drmHashInsert(entry->tagTable, context, tag); 2095 } 2096 return 0; 2097} 2098 2099int drmDelContextTag(int fd, drm_context_t context) 2100{ 2101 drmHashEntry *entry = drmGetEntry(fd); 2102 2103 return drmHashDelete(entry->tagTable, context); 2104} 2105 2106void *drmGetContextTag(int fd, drm_context_t context) 2107{ 2108 drmHashEntry *entry = drmGetEntry(fd); 2109 void *value; 2110 2111 if (drmHashLookup(entry->tagTable, context, &value)) 2112 return NULL; 2113 2114 return value; 2115} 2116 2117int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, 2118 drm_handle_t handle) 2119{ 2120 drm_ctx_priv_map_t map; 2121 2122 map.ctx_id = ctx_id; 2123 map.handle = (void *)(uintptr_t)handle; 2124 2125 if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) 2126 return -errno; 2127 return 0; 2128} 2129 2130int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, 2131 drm_handle_t *handle) 2132{ 2133 drm_ctx_priv_map_t map; 2134 2135 map.ctx_id = ctx_id; 2136 2137 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) 2138 return -errno; 2139 if (handle) 2140 *handle = (drm_handle_t)(uintptr_t)map.handle; 2141 2142 return 0; 2143} 2144 2145int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, 2146 drmMapType *type, drmMapFlags *flags, drm_handle_t *handle, 2147 int *mtrr) 2148{ 2149 drm_map_t map; 2150 2151 map.offset = idx; 2152 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)) 2153 return -errno; 2154 *offset = map.offset; 2155 *size = map.size; 2156 *type = map.type; 2157 *flags = map.flags; 2158 *handle = (unsigned long)map.handle; 2159 *mtrr = map.mtrr; 2160 return 0; 2161} 2162 2163int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, 2164 unsigned long *magic, unsigned long *iocs) 2165{ 2166 drm_client_t client; 2167 2168 client.idx = idx; 2169 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client)) 2170 return -errno; 2171 *auth = client.auth; 2172 *pid = client.pid; 2173 *uid = client.uid; 2174 *magic = client.magic; 2175 *iocs = client.iocs; 2176 return 0; 2177} 2178 2179int drmGetStats(int fd, drmStatsT *stats) 2180{ 2181 drm_stats_t s; 2182 int i; 2183 2184 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s)) 2185 return -errno; 2186 2187 stats->count = 0; 2188 memset(stats, 0, sizeof(*stats)); 2189 if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) 2190 return -1; 2191 2192#define SET_VALUE \ 2193 stats->data[i].long_format = "%-20.20s"; \ 2194 stats->data[i].rate_format = "%8.8s"; \ 2195 stats->data[i].isvalue = 1; \ 2196 stats->data[i].verbose = 0 2197 2198#define SET_COUNT \ 2199 stats->data[i].long_format = "%-20.20s"; \ 2200 stats->data[i].rate_format = "%5.5s"; \ 2201 stats->data[i].isvalue = 0; \ 2202 stats->data[i].mult_names = "kgm"; \ 2203 stats->data[i].mult = 1000; \ 2204 stats->data[i].verbose = 0 2205 2206#define SET_BYTE \ 2207 stats->data[i].long_format = "%-20.20s"; \ 2208 stats->data[i].rate_format = "%5.5s"; \ 2209 stats->data[i].isvalue = 0; \ 2210 stats->data[i].mult_names = "KGM"; \ 2211 stats->data[i].mult = 1024; \ 2212 stats->data[i].verbose = 0 2213 2214 2215 stats->count = s.count; 2216 for (i = 0; i < s.count; i++) { 2217 stats->data[i].value = s.data[i].value; 2218 switch (s.data[i].type) { 2219 case _DRM_STAT_LOCK: 2220 stats->data[i].long_name = "Lock"; 2221 stats->data[i].rate_name = "Lock"; 2222 SET_VALUE; 2223 break; 2224 case _DRM_STAT_OPENS: 2225 stats->data[i].long_name = "Opens"; 2226 stats->data[i].rate_name = "O"; 2227 SET_COUNT; 2228 stats->data[i].verbose = 1; 2229 break; 2230 case _DRM_STAT_CLOSES: 2231 stats->data[i].long_name = "Closes"; 2232 stats->data[i].rate_name = "Lock"; 2233 SET_COUNT; 2234 stats->data[i].verbose = 1; 2235 break; 2236 case _DRM_STAT_IOCTLS: 2237 stats->data[i].long_name = "Ioctls"; 2238 stats->data[i].rate_name = "Ioc/s"; 2239 SET_COUNT; 2240 break; 2241 case _DRM_STAT_LOCKS: 2242 stats->data[i].long_name = "Locks"; 2243 stats->data[i].rate_name = "Lck/s"; 2244 SET_COUNT; 2245 break; 2246 case _DRM_STAT_UNLOCKS: 2247 stats->data[i].long_name = "Unlocks"; 2248 stats->data[i].rate_name = "Unl/s"; 2249 SET_COUNT; 2250 break; 2251 case _DRM_STAT_IRQ: 2252 stats->data[i].long_name = "IRQs"; 2253 stats->data[i].rate_name = "IRQ/s"; 2254 SET_COUNT; 2255 break; 2256 case _DRM_STAT_PRIMARY: 2257 stats->data[i].long_name = "Primary Bytes"; 2258 stats->data[i].rate_name = "PB/s"; 2259 SET_BYTE; 2260 break; 2261 case _DRM_STAT_SECONDARY: 2262 stats->data[i].long_name = "Secondary Bytes"; 2263 stats->data[i].rate_name = "SB/s"; 2264 SET_BYTE; 2265 break; 2266 case _DRM_STAT_DMA: 2267 stats->data[i].long_name = "DMA"; 2268 stats->data[i].rate_name = "DMA/s"; 2269 SET_COUNT; 2270 break; 2271 case _DRM_STAT_SPECIAL: 2272 stats->data[i].long_name = "Special DMA"; 2273 stats->data[i].rate_name = "dma/s"; 2274 SET_COUNT; 2275 break; 2276 case _DRM_STAT_MISSED: 2277 stats->data[i].long_name = "Miss"; 2278 stats->data[i].rate_name = "Ms/s"; 2279 SET_COUNT; 2280 break; 2281 case _DRM_STAT_VALUE: 2282 stats->data[i].long_name = "Value"; 2283 stats->data[i].rate_name = "Value"; 2284 SET_VALUE; 2285 break; 2286 case _DRM_STAT_BYTE: 2287 stats->data[i].long_name = "Bytes"; 2288 stats->data[i].rate_name = "B/s"; 2289 SET_BYTE; 2290 break; 2291 case _DRM_STAT_COUNT: 2292 default: 2293 stats->data[i].long_name = "Count"; 2294 stats->data[i].rate_name = "Cnt/s"; 2295 SET_COUNT; 2296 break; 2297 } 2298 } 2299 return 0; 2300} 2301 2302/** 2303 * Issue a set-version ioctl. 2304 * 2305 * \param fd file descriptor. 2306 * \param drmCommandIndex command index 2307 * \param data source pointer of the data to be read and written. 2308 * \param size size of the data to be read and written. 2309 * 2310 * \return zero on success, or a negative value on failure. 2311 * 2312 * \internal 2313 * It issues a read-write ioctl given by 2314 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2315 */ 2316int drmSetInterfaceVersion(int fd, drmSetVersion *version) 2317{ 2318 int retcode = 0; 2319 drm_set_version_t sv; 2320 2321 sv.drm_di_major = version->drm_di_major; 2322 sv.drm_di_minor = version->drm_di_minor; 2323 sv.drm_dd_major = version->drm_dd_major; 2324 sv.drm_dd_minor = version->drm_dd_minor; 2325 2326 if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) { 2327 retcode = -errno; 2328 } 2329 2330 version->drm_di_major = sv.drm_di_major; 2331 version->drm_di_minor = sv.drm_di_minor; 2332 version->drm_dd_major = sv.drm_dd_major; 2333 version->drm_dd_minor = sv.drm_dd_minor; 2334 2335 return retcode; 2336} 2337 2338/** 2339 * Send a device-specific command. 2340 * 2341 * \param fd file descriptor. 2342 * \param drmCommandIndex command index 2343 * 2344 * \return zero on success, or a negative value on failure. 2345 * 2346 * \internal 2347 * It issues a ioctl given by 2348 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2349 */ 2350int drmCommandNone(int fd, unsigned long drmCommandIndex) 2351{ 2352 void *data = NULL; /* dummy */ 2353 unsigned long request; 2354 2355 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); 2356 2357 if (drmIoctl(fd, request, data)) { 2358 return -errno; 2359 } 2360 return 0; 2361} 2362 2363 2364/** 2365 * Send a device-specific read command. 2366 * 2367 * \param fd file descriptor. 2368 * \param drmCommandIndex command index 2369 * \param data destination pointer of the data to be read. 2370 * \param size size of the data to be read. 2371 * 2372 * \return zero on success, or a negative value on failure. 2373 * 2374 * \internal 2375 * It issues a read ioctl given by 2376 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2377 */ 2378int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data, 2379 unsigned long size) 2380{ 2381 unsigned long request; 2382 2383 request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, 2384 DRM_COMMAND_BASE + drmCommandIndex, size); 2385 2386 if (drmIoctl(fd, request, data)) { 2387 return -errno; 2388 } 2389 return 0; 2390} 2391 2392 2393/** 2394 * Send a device-specific write command. 2395 * 2396 * \param fd file descriptor. 2397 * \param drmCommandIndex command index 2398 * \param data source pointer of the data to be written. 2399 * \param size size of the data to be written. 2400 * 2401 * \return zero on success, or a negative value on failure. 2402 * 2403 * \internal 2404 * It issues a write ioctl given by 2405 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2406 */ 2407int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data, 2408 unsigned long size) 2409{ 2410 unsigned long request; 2411 2412 request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, 2413 DRM_COMMAND_BASE + drmCommandIndex, size); 2414 2415 if (drmIoctl(fd, request, data)) { 2416 return -errno; 2417 } 2418 return 0; 2419} 2420 2421 2422/** 2423 * Send a device-specific read-write command. 2424 * 2425 * \param fd file descriptor. 2426 * \param drmCommandIndex command index 2427 * \param data source pointer of the data to be read and written. 2428 * \param size size of the data to be read and written. 2429 * 2430 * \return zero on success, or a negative value on failure. 2431 * 2432 * \internal 2433 * It issues a read-write ioctl given by 2434 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2435 */ 2436int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, 2437 unsigned long size) 2438{ 2439 unsigned long request; 2440 2441 request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, 2442 DRM_COMMAND_BASE + drmCommandIndex, size); 2443 2444 if (drmIoctl(fd, request, data)) 2445 return -errno; 2446 return 0; 2447} 2448 2449#define DRM_MAX_FDS 16 2450static struct { 2451 char *BusID; 2452 int fd; 2453 int refcount; 2454} connection[DRM_MAX_FDS]; 2455 2456static int nr_fds = 0; 2457 2458int drmOpenOnce(void *unused, 2459 const char *BusID, 2460 int *newlyopened) 2461{ 2462 int i; 2463 int fd; 2464 2465 for (i = 0; i < nr_fds; i++) 2466 if (strcmp(BusID, connection[i].BusID) == 0) { 2467 connection[i].refcount++; 2468 *newlyopened = 0; 2469 return connection[i].fd; 2470 } 2471 2472 fd = drmOpen(unused, BusID); 2473 if (fd <= 0 || nr_fds == DRM_MAX_FDS) 2474 return fd; 2475 2476 connection[nr_fds].BusID = strdup(BusID); 2477 connection[nr_fds].fd = fd; 2478 connection[nr_fds].refcount = 1; 2479 *newlyopened = 1; 2480 2481 if (0) 2482 fprintf(stderr, "saved connection %d for %s %d\n", 2483 nr_fds, connection[nr_fds].BusID, 2484 strcmp(BusID, connection[nr_fds].BusID)); 2485 2486 nr_fds++; 2487 2488 return fd; 2489} 2490 2491void drmCloseOnce(int fd) 2492{ 2493 int i; 2494 2495 for (i = 0; i < nr_fds; i++) { 2496 if (fd == connection[i].fd) { 2497 if (--connection[i].refcount == 0) { 2498 drmClose(connection[i].fd); 2499 free(connection[i].BusID); 2500 2501 if (i < --nr_fds) 2502 connection[i] = connection[nr_fds]; 2503 2504 return; 2505 } 2506 } 2507 } 2508} 2509 2510int drmSetMaster(int fd) 2511{ 2512 return ioctl(fd, DRM_IOCTL_SET_MASTER, 0); 2513} 2514 2515int drmDropMaster(int fd) 2516{ 2517 return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); 2518} 2519 2520char *drmGetDeviceNameFromFd(int fd) 2521{ 2522 char name[128]; 2523 struct stat sbuf; 2524 dev_t d; 2525 int i; 2526 2527 /* The whole drmOpen thing is a fiasco and we need to find a way 2528 * back to just using open(2). For now, however, lets just make 2529 * things worse with even more ad hoc directory walking code to 2530 * discover the device file name. */ 2531 2532 fstat(fd, &sbuf); 2533 d = sbuf.st_rdev; 2534 2535 for (i = 0; i < DRM_MAX_MINOR; i++) { 2536 snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i); 2537 if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) 2538 break; 2539 } 2540 if (i == DRM_MAX_MINOR) 2541 return NULL; 2542 2543 return strdup(name); 2544} 2545 2546int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) 2547{ 2548 struct drm_prime_handle args; 2549 int ret; 2550 2551 args.handle = handle; 2552 args.flags = flags; 2553 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); 2554 if (ret) 2555 return ret; 2556 2557 *prime_fd = args.fd; 2558 return 0; 2559} 2560 2561int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) 2562{ 2563 struct drm_prime_handle args; 2564 int ret; 2565 2566 args.fd = prime_fd; 2567 args.flags = 0; 2568 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args); 2569 if (ret) 2570 return ret; 2571 2572 *handle = args.handle; 2573 return 0; 2574} 2575 2576