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