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