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