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