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