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