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