xf86drm.c revision a884aba1
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#ifdef DRM_IOCTL_MMAP 1133 struct drm_mmap mmap_req = {0}; 1134#endif 1135 1136 if (fd < 0) 1137 return -EINVAL; 1138 1139 if (!pagesize_mask) 1140 pagesize_mask = getpagesize() - 1; 1141 1142 size = (size + pagesize_mask) & ~pagesize_mask; 1143 1144#ifdef DRM_IOCTL_MMAP 1145 mmap_req.dnm_addr = NULL; 1146 mmap_req.dnm_size = size; 1147 mmap_req.dnm_prot = (PROT_READ | PROT_WRITE); 1148 mmap_req.dnm_flags = MAP_SHARED; 1149 mmap_req.dnm_offset = handle; 1150 if (drmIoctl(fd, DRM_IOCTL_MMAP, &mmap_req) == 0) { 1151 *address = mmap_req.dnm_addr; 1152 return 0; 1153 } 1154#endif 1155 *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); 1156 if (*address == MAP_FAILED) 1157 return -errno; 1158 return 0; 1159} 1160 1161 1162/** 1163 * Unmap mappings obtained with drmMap(). 1164 * 1165 * \param address address as given by drmMap(). 1166 * \param size size in bytes. Must match the size used by drmMap(). 1167 * 1168 * \return zero on success, or a negative value on failure. 1169 * 1170 * \internal 1171 * This function is a wrapper for munmap(). 1172 */ 1173int drmUnmap(drmAddress address, drmSize size) 1174{ 1175 return drm_munmap(address, size); 1176} 1177 1178drmBufInfoPtr drmGetBufInfo(int fd) 1179{ 1180 drm_buf_info_t info; 1181 drmBufInfoPtr retval; 1182 int i; 1183 1184 info.count = 0; 1185 info.list = NULL; 1186 1187 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1188 return NULL; 1189 1190 if (info.count) { 1191 if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 1192 return NULL; 1193 1194 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 1195 drmFree(info.list); 1196 return NULL; 1197 } 1198 1199 retval = drmMalloc(sizeof(*retval)); 1200 retval->count = info.count; 1201 retval->list = drmMalloc(info.count * sizeof(*retval->list)); 1202 for (i = 0; i < info.count; i++) { 1203 retval->list[i].count = info.list[i].count; 1204 retval->list[i].size = info.list[i].size; 1205 retval->list[i].low_mark = info.list[i].low_mark; 1206 retval->list[i].high_mark = info.list[i].high_mark; 1207 } 1208 drmFree(info.list); 1209 return retval; 1210 } 1211 return NULL; 1212} 1213 1214/** 1215 * Map all DMA buffers into client-virtual space. 1216 * 1217 * \param fd file descriptor. 1218 * 1219 * \return a pointer to a ::drmBufMap structure. 1220 * 1221 * \note The client may not use these buffers until obtaining buffer indices 1222 * with drmDMA(). 1223 * 1224 * \internal 1225 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned 1226 * information about the buffers in a drm_buf_map structure into the 1227 * client-visible data structures. 1228 */ 1229drmBufMapPtr drmMapBufs(int fd) 1230{ 1231 drm_buf_map_t bufs; 1232 drmBufMapPtr retval; 1233 int i; 1234 1235 bufs.count = 0; 1236 bufs.list = NULL; 1237 bufs.virtual = NULL; 1238 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) 1239 return NULL; 1240 1241 if (!bufs.count) 1242 return NULL; 1243 1244 if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list)))) 1245 return NULL; 1246 1247 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { 1248 drmFree(bufs.list); 1249 return NULL; 1250 } 1251 1252 retval = drmMalloc(sizeof(*retval)); 1253 retval->count = bufs.count; 1254 retval->list = drmMalloc(bufs.count * sizeof(*retval->list)); 1255 for (i = 0; i < bufs.count; i++) { 1256 retval->list[i].idx = bufs.list[i].idx; 1257 retval->list[i].total = bufs.list[i].total; 1258 retval->list[i].used = 0; 1259 retval->list[i].address = bufs.list[i].address; 1260 } 1261 1262 drmFree(bufs.list); 1263 1264 return retval; 1265} 1266 1267 1268/** 1269 * Unmap buffers allocated with drmMapBufs(). 1270 * 1271 * \return zero on success, or negative value on failure. 1272 * 1273 * \internal 1274 * Calls munmap() for every buffer stored in \p bufs and frees the 1275 * memory allocated by drmMapBufs(). 1276 */ 1277int drmUnmapBufs(drmBufMapPtr bufs) 1278{ 1279 int i; 1280 1281 for (i = 0; i < bufs->count; i++) { 1282 drm_munmap(bufs->list[i].address, bufs->list[i].total); 1283 } 1284 1285 drmFree(bufs->list); 1286 drmFree(bufs); 1287 1288 return 0; 1289} 1290 1291 1292#define DRM_DMA_RETRY 16 1293 1294/** 1295 * Reserve DMA buffers. 1296 * 1297 * \param fd file descriptor. 1298 * \param request 1299 * 1300 * \return zero on success, or a negative value on failure. 1301 * 1302 * \internal 1303 * Assemble the arguments into a drm_dma structure and keeps issuing the 1304 * DRM_IOCTL_DMA ioctl until success or until maximum number of retries. 1305 */ 1306int drmDMA(int fd, drmDMAReqPtr request) 1307{ 1308 drm_dma_t dma; 1309 int ret, i = 0; 1310 1311 dma.context = request->context; 1312 dma.send_count = request->send_count; 1313 dma.send_indices = request->send_list; 1314 dma.send_sizes = request->send_sizes; 1315 dma.flags = request->flags; 1316 dma.request_count = request->request_count; 1317 dma.request_size = request->request_size; 1318 dma.request_indices = request->request_list; 1319 dma.request_sizes = request->request_sizes; 1320 dma.granted_count = 0; 1321 1322 do { 1323 ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); 1324 } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); 1325 1326 if ( ret == 0 ) { 1327 request->granted_count = dma.granted_count; 1328 return 0; 1329 } else { 1330 return -errno; 1331 } 1332} 1333 1334 1335/** 1336 * Obtain heavyweight hardware lock. 1337 * 1338 * \param fd file descriptor. 1339 * \param context context. 1340 * \param flags flags that determine the sate of the hardware when the function 1341 * returns. 1342 * 1343 * \return always zero. 1344 * 1345 * \internal 1346 * This function translates the arguments into a drm_lock structure and issue 1347 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. 1348 */ 1349int drmGetLock(int fd, drm_context_t context, drmLockFlags flags) 1350{ 1351 drm_lock_t lock; 1352 1353 lock.context = context; 1354 lock.flags = 0; 1355 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 1356 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 1357 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 1358 if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 1359 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 1360 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 1361 1362 while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock)) 1363 ; 1364 return 0; 1365} 1366 1367/** 1368 * Release the hardware lock. 1369 * 1370 * \param fd file descriptor. 1371 * \param context context. 1372 * 1373 * \return zero on success, or a negative value on failure. 1374 * 1375 * \internal 1376 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the 1377 * argument in a drm_lock structure. 1378 */ 1379int drmUnlock(int fd, drm_context_t context) 1380{ 1381 drm_lock_t lock; 1382 1383 lock.context = context; 1384 lock.flags = 0; 1385 return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock); 1386} 1387 1388drm_context_t *drmGetReservedContextList(int fd, int *count) 1389{ 1390 drm_ctx_res_t res; 1391 drm_ctx_t *list; 1392 drm_context_t * retval; 1393 int i; 1394 1395 res.count = 0; 1396 res.contexts = NULL; 1397 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1398 return NULL; 1399 1400 if (!res.count) 1401 return NULL; 1402 1403 if (!(list = drmMalloc(res.count * sizeof(*list)))) 1404 return NULL; 1405 if (!(retval = drmMalloc(res.count * sizeof(*retval)))) { 1406 drmFree(list); 1407 return NULL; 1408 } 1409 1410 res.contexts = list; 1411 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1412 return NULL; 1413 1414 for (i = 0; i < res.count; i++) 1415 retval[i] = list[i].handle; 1416 drmFree(list); 1417 1418 *count = res.count; 1419 return retval; 1420} 1421 1422void drmFreeReservedContextList(drm_context_t *pt) 1423{ 1424 drmFree(pt); 1425} 1426 1427/** 1428 * Create context. 1429 * 1430 * Used by the X server during GLXContext initialization. This causes 1431 * per-context kernel-level resources to be allocated. 1432 * 1433 * \param fd file descriptor. 1434 * \param handle is set on success. To be used by the client when requesting DMA 1435 * dispatch with drmDMA(). 1436 * 1437 * \return zero on success, or a negative value on failure. 1438 * 1439 * \note May only be called by root. 1440 * 1441 * \internal 1442 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the 1443 * argument in a drm_ctx structure. 1444 */ 1445int drmCreateContext(int fd, drm_context_t *handle) 1446{ 1447 drm_ctx_t ctx; 1448 1449 ctx.flags = 0; /* Modified with functions below */ 1450 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) 1451 return -errno; 1452 *handle = ctx.handle; 1453 return 0; 1454} 1455 1456int drmSwitchToContext(int fd, drm_context_t context) 1457{ 1458 drm_ctx_t ctx; 1459 1460 ctx.handle = context; 1461 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) 1462 return -errno; 1463 return 0; 1464} 1465 1466int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags) 1467{ 1468 drm_ctx_t ctx; 1469 1470 /* 1471 * Context preserving means that no context switches are done between DMA 1472 * buffers from one context and the next. This is suitable for use in the 1473 * X server (which promises to maintain hardware context), or in the 1474 * client-side library when buffers are swapped on behalf of two threads. 1475 */ 1476 ctx.handle = context; 1477 ctx.flags = 0; 1478 if (flags & DRM_CONTEXT_PRESERVED) 1479 ctx.flags |= _DRM_CONTEXT_PRESERVED; 1480 if (flags & DRM_CONTEXT_2DONLY) 1481 ctx.flags |= _DRM_CONTEXT_2DONLY; 1482 if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) 1483 return -errno; 1484 return 0; 1485} 1486 1487int drmGetContextFlags(int fd, drm_context_t context, 1488 drm_context_tFlagsPtr flags) 1489{ 1490 drm_ctx_t ctx; 1491 1492 ctx.handle = context; 1493 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx)) 1494 return -errno; 1495 *flags = 0; 1496 if (ctx.flags & _DRM_CONTEXT_PRESERVED) 1497 *flags |= DRM_CONTEXT_PRESERVED; 1498 if (ctx.flags & _DRM_CONTEXT_2DONLY) 1499 *flags |= DRM_CONTEXT_2DONLY; 1500 return 0; 1501} 1502 1503/** 1504 * Destroy context. 1505 * 1506 * Free any kernel-level resources allocated with drmCreateContext() associated 1507 * with the context. 1508 * 1509 * \param fd file descriptor. 1510 * \param handle handle given by drmCreateContext(). 1511 * 1512 * \return zero on success, or a negative value on failure. 1513 * 1514 * \note May only be called by root. 1515 * 1516 * \internal 1517 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the 1518 * argument in a drm_ctx structure. 1519 */ 1520int drmDestroyContext(int fd, drm_context_t handle) 1521{ 1522 drm_ctx_t ctx; 1523 ctx.handle = handle; 1524 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx)) 1525 return -errno; 1526 return 0; 1527} 1528 1529int drmCreateDrawable(int fd, drm_drawable_t *handle) 1530{ 1531 drm_draw_t draw; 1532 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) 1533 return -errno; 1534 *handle = draw.handle; 1535 return 0; 1536} 1537 1538int drmDestroyDrawable(int fd, drm_drawable_t handle) 1539{ 1540 drm_draw_t draw; 1541 draw.handle = handle; 1542 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw)) 1543 return -errno; 1544 return 0; 1545} 1546 1547int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, 1548 drm_drawable_info_type_t type, unsigned int num, 1549 void *data) 1550{ 1551 drm_update_draw_t update; 1552 1553 update.handle = handle; 1554 update.type = type; 1555 update.num = num; 1556 update.data = (unsigned long long)(unsigned long)data; 1557 1558 if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) 1559 return -errno; 1560 1561 return 0; 1562} 1563 1564/** 1565 * Acquire the AGP device. 1566 * 1567 * Must be called before any of the other AGP related calls. 1568 * 1569 * \param fd file descriptor. 1570 * 1571 * \return zero on success, or a negative value on failure. 1572 * 1573 * \internal 1574 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. 1575 */ 1576int drmAgpAcquire(int fd) 1577{ 1578 if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) 1579 return -errno; 1580 return 0; 1581} 1582 1583 1584/** 1585 * Release the AGP device. 1586 * 1587 * \param fd file descriptor. 1588 * 1589 * \return zero on success, or a negative value on failure. 1590 * 1591 * \internal 1592 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. 1593 */ 1594int drmAgpRelease(int fd) 1595{ 1596 if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) 1597 return -errno; 1598 return 0; 1599} 1600 1601 1602/** 1603 * Set the AGP mode. 1604 * 1605 * \param fd file descriptor. 1606 * \param mode AGP mode. 1607 * 1608 * \return zero on success, or a negative value on failure. 1609 * 1610 * \internal 1611 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the 1612 * argument in a drm_agp_mode structure. 1613 */ 1614int drmAgpEnable(int fd, unsigned long mode) 1615{ 1616 drm_agp_mode_t m; 1617 1618 m.mode = mode; 1619 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) 1620 return -errno; 1621 return 0; 1622} 1623 1624 1625/** 1626 * Allocate a chunk of AGP memory. 1627 * 1628 * \param fd file descriptor. 1629 * \param size requested memory size in bytes. Will be rounded to page boundary. 1630 * \param type type of memory to allocate. 1631 * \param address if not zero, will be set to the physical address of the 1632 * allocated memory. 1633 * \param handle on success will be set to a handle of the allocated memory. 1634 * 1635 * \return zero on success, or a negative value on failure. 1636 * 1637 * \internal 1638 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the 1639 * arguments in a drm_agp_buffer structure. 1640 */ 1641int drmAgpAlloc(int fd, unsigned long size, unsigned long type, 1642 unsigned long *address, drm_handle_t *handle) 1643{ 1644 drm_agp_buffer_t b; 1645 1646 *handle = DRM_AGP_NO_HANDLE; 1647 b.size = size; 1648 b.handle = 0; 1649 b.type = type; 1650 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) 1651 return -errno; 1652 if (address != 0UL) 1653 *address = b.physical; 1654 *handle = b.handle; 1655 return 0; 1656} 1657 1658 1659/** 1660 * Free a chunk of AGP memory. 1661 * 1662 * \param fd file descriptor. 1663 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1664 * 1665 * \return zero on success, or a negative value on failure. 1666 * 1667 * \internal 1668 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the 1669 * argument in a drm_agp_buffer structure. 1670 */ 1671int drmAgpFree(int fd, drm_handle_t handle) 1672{ 1673 drm_agp_buffer_t b; 1674 1675 b.size = 0; 1676 b.handle = handle; 1677 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b)) 1678 return -errno; 1679 return 0; 1680} 1681 1682 1683/** 1684 * Bind a chunk of AGP memory. 1685 * 1686 * \param fd file descriptor. 1687 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1688 * \param offset offset in bytes. It will round to page boundary. 1689 * 1690 * \return zero on success, or a negative value on failure. 1691 * 1692 * \internal 1693 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the 1694 * argument in a drm_agp_binding structure. 1695 */ 1696int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset) 1697{ 1698 drm_agp_binding_t b; 1699 1700 b.handle = handle; 1701 b.offset = offset; 1702 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b)) 1703 return -errno; 1704 return 0; 1705} 1706 1707 1708/** 1709 * Unbind a chunk of AGP memory. 1710 * 1711 * \param fd file descriptor. 1712 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1713 * 1714 * \return zero on success, or a negative value on failure. 1715 * 1716 * \internal 1717 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing 1718 * the argument in a drm_agp_binding structure. 1719 */ 1720int drmAgpUnbind(int fd, drm_handle_t handle) 1721{ 1722 drm_agp_binding_t b; 1723 1724 b.handle = handle; 1725 b.offset = 0; 1726 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) 1727 return -errno; 1728 return 0; 1729} 1730 1731 1732/** 1733 * Get AGP driver major version number. 1734 * 1735 * \param fd file descriptor. 1736 * 1737 * \return major version number on success, or a negative value on failure.. 1738 * 1739 * \internal 1740 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1741 * necessary information in a drm_agp_info structure. 1742 */ 1743int drmAgpVersionMajor(int fd) 1744{ 1745 drm_agp_info_t i; 1746 1747 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1748 return -errno; 1749 return i.agp_version_major; 1750} 1751 1752 1753/** 1754 * Get AGP driver minor version number. 1755 * 1756 * \param fd file descriptor. 1757 * 1758 * \return minor 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 drmAgpVersionMinor(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_minor; 1771} 1772 1773 1774/** 1775 * Get AGP mode. 1776 * 1777 * \param fd file descriptor. 1778 * 1779 * \return mode on success, or zero 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 */ 1785unsigned long drmAgpGetMode(int fd) 1786{ 1787 drm_agp_info_t i; 1788 1789 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1790 return 0; 1791 return i.mode; 1792} 1793 1794 1795/** 1796 * Get AGP aperture base. 1797 * 1798 * \param fd file descriptor. 1799 * 1800 * \return aperture base on success, 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 drmAgpBase(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.aperture_base; 1813} 1814 1815 1816/** 1817 * Get AGP aperture size. 1818 * 1819 * \param fd file descriptor. 1820 * 1821 * \return aperture size 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 drmAgpSize(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_size; 1834} 1835 1836 1837/** 1838 * Get used AGP memory. 1839 * 1840 * \param fd file descriptor. 1841 * 1842 * \return memory used on success, or 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 drmAgpMemoryUsed(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.memory_used; 1855} 1856 1857 1858/** 1859 * Get available AGP memory. 1860 * 1861 * \param fd file descriptor. 1862 * 1863 * \return memory available 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 drmAgpMemoryAvail(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_allowed; 1876} 1877 1878 1879/** 1880 * Get hardware vendor ID. 1881 * 1882 * \param fd file descriptor. 1883 * 1884 * \return vendor ID 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 int drmAgpVendorId(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.id_vendor; 1897} 1898 1899 1900/** 1901 * Get hardware device ID. 1902 * 1903 * \param fd file descriptor. 1904 * 1905 * \return zero 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 drmAgpDeviceId(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_device; 1918} 1919 1920int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle) 1921{ 1922 drm_scatter_gather_t sg; 1923 1924 *handle = 0; 1925 sg.size = size; 1926 sg.handle = 0; 1927 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) 1928 return -errno; 1929 *handle = sg.handle; 1930 return 0; 1931} 1932 1933int drmScatterGatherFree(int fd, drm_handle_t handle) 1934{ 1935 drm_scatter_gather_t sg; 1936 1937 sg.size = 0; 1938 sg.handle = handle; 1939 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg)) 1940 return -errno; 1941 return 0; 1942} 1943 1944/** 1945 * Wait for VBLANK. 1946 * 1947 * \param fd file descriptor. 1948 * \param vbl pointer to a drmVBlank structure. 1949 * 1950 * \return zero on success, or a negative value on failure. 1951 * 1952 * \internal 1953 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. 1954 */ 1955int drmWaitVBlank(int fd, drmVBlankPtr vbl) 1956{ 1957 struct timespec timeout, cur; 1958 int ret; 1959 1960 ret = clock_gettime(CLOCK_MONOTONIC, &timeout); 1961 if (ret < 0) { 1962 fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno)); 1963 goto out; 1964 } 1965 timeout.tv_sec++; 1966 1967 do { 1968 ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); 1969 vbl->request.type &= ~DRM_VBLANK_RELATIVE; 1970 if (ret && errno == EINTR) { 1971 clock_gettime(CLOCK_MONOTONIC, &cur); 1972 /* Timeout after 1s */ 1973 if (cur.tv_sec > timeout.tv_sec + 1 || 1974 (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= 1975 timeout.tv_nsec)) { 1976 errno = EBUSY; 1977 ret = -1; 1978 break; 1979 } 1980 } 1981 } while (ret && errno == EINTR); 1982 1983out: 1984 return ret; 1985} 1986 1987int drmError(int err, const char *label) 1988{ 1989 switch (err) { 1990 case DRM_ERR_NO_DEVICE: 1991 fprintf(stderr, "%s: no device\n", label); 1992 break; 1993 case DRM_ERR_NO_ACCESS: 1994 fprintf(stderr, "%s: no access\n", label); 1995 break; 1996 case DRM_ERR_NOT_ROOT: 1997 fprintf(stderr, "%s: not root\n", label); 1998 break; 1999 case DRM_ERR_INVALID: 2000 fprintf(stderr, "%s: invalid args\n", label); 2001 break; 2002 default: 2003 if (err < 0) 2004 err = -err; 2005 fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) ); 2006 break; 2007 } 2008 2009 return 1; 2010} 2011 2012/** 2013 * Install IRQ handler. 2014 * 2015 * \param fd file descriptor. 2016 * \param irq IRQ number. 2017 * 2018 * \return zero on success, or a negative value on failure. 2019 * 2020 * \internal 2021 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2022 * argument in a drm_control structure. 2023 */ 2024int drmCtlInstHandler(int fd, int irq) 2025{ 2026 drm_control_t ctl; 2027 2028 ctl.func = DRM_INST_HANDLER; 2029 ctl.irq = irq; 2030 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2031 return -errno; 2032 return 0; 2033} 2034 2035 2036/** 2037 * Uninstall IRQ handler. 2038 * 2039 * \param fd file descriptor. 2040 * 2041 * \return zero on success, or a negative value on failure. 2042 * 2043 * \internal 2044 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2045 * argument in a drm_control structure. 2046 */ 2047int drmCtlUninstHandler(int fd) 2048{ 2049 drm_control_t ctl; 2050 2051 ctl.func = DRM_UNINST_HANDLER; 2052 ctl.irq = 0; 2053 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2054 return -errno; 2055 return 0; 2056} 2057 2058int drmFinish(int fd, int context, drmLockFlags flags) 2059{ 2060 drm_lock_t lock; 2061 2062 lock.context = context; 2063 lock.flags = 0; 2064 if (flags & DRM_LOCK_READY) lock.flags |= _DRM_LOCK_READY; 2065 if (flags & DRM_LOCK_QUIESCENT) lock.flags |= _DRM_LOCK_QUIESCENT; 2066 if (flags & DRM_LOCK_FLUSH) lock.flags |= _DRM_LOCK_FLUSH; 2067 if (flags & DRM_LOCK_FLUSH_ALL) lock.flags |= _DRM_LOCK_FLUSH_ALL; 2068 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 2069 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 2070 if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock)) 2071 return -errno; 2072 return 0; 2073} 2074 2075/** 2076 * Get IRQ from bus ID. 2077 * 2078 * \param fd file descriptor. 2079 * \param busnum bus number. 2080 * \param devnum device number. 2081 * \param funcnum function number. 2082 * 2083 * \return IRQ number on success, or a negative value on failure. 2084 * 2085 * \internal 2086 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the 2087 * arguments in a drm_irq_busid structure. 2088 */ 2089int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum) 2090{ 2091 drm_irq_busid_t p; 2092 2093 p.busnum = busnum; 2094 p.devnum = devnum; 2095 p.funcnum = funcnum; 2096 if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) 2097 return -errno; 2098 return p.irq; 2099} 2100 2101int drmAddContextTag(int fd, drm_context_t context, void *tag) 2102{ 2103 drmHashEntry *entry = drmGetEntry(fd); 2104 2105 if (drmHashInsert(entry->tagTable, context, tag)) { 2106 drmHashDelete(entry->tagTable, context); 2107 drmHashInsert(entry->tagTable, context, tag); 2108 } 2109 return 0; 2110} 2111 2112int drmDelContextTag(int fd, drm_context_t context) 2113{ 2114 drmHashEntry *entry = drmGetEntry(fd); 2115 2116 return drmHashDelete(entry->tagTable, context); 2117} 2118 2119void *drmGetContextTag(int fd, drm_context_t context) 2120{ 2121 drmHashEntry *entry = drmGetEntry(fd); 2122 void *value; 2123 2124 if (drmHashLookup(entry->tagTable, context, &value)) 2125 return NULL; 2126 2127 return value; 2128} 2129 2130int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id, 2131 drm_handle_t handle) 2132{ 2133 drm_ctx_priv_map_t map; 2134 2135 map.ctx_id = ctx_id; 2136 map.handle = (void *)(uintptr_t)handle; 2137 2138 if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) 2139 return -errno; 2140 return 0; 2141} 2142 2143int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id, 2144 drm_handle_t *handle) 2145{ 2146 drm_ctx_priv_map_t map; 2147 2148 map.ctx_id = ctx_id; 2149 2150 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) 2151 return -errno; 2152 if (handle) 2153 *handle = (drm_handle_t)(uintptr_t)map.handle; 2154 2155 return 0; 2156} 2157 2158int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, 2159 drmMapType *type, drmMapFlags *flags, drm_handle_t *handle, 2160 int *mtrr) 2161{ 2162 drm_map_t map; 2163 2164 map.offset = idx; 2165 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)) 2166 return -errno; 2167 *offset = map.offset; 2168 *size = map.size; 2169 *type = map.type; 2170 *flags = map.flags; 2171 *handle = (unsigned long)map.handle; 2172 *mtrr = map.mtrr; 2173 return 0; 2174} 2175 2176int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, 2177 unsigned long *magic, unsigned long *iocs) 2178{ 2179 drm_client_t client; 2180 2181 client.idx = idx; 2182 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client)) 2183 return -errno; 2184 *auth = client.auth; 2185 *pid = client.pid; 2186 *uid = client.uid; 2187 *magic = client.magic; 2188 *iocs = client.iocs; 2189 return 0; 2190} 2191 2192int drmGetStats(int fd, drmStatsT *stats) 2193{ 2194 drm_stats_t s; 2195 int i; 2196 2197 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s)) 2198 return -errno; 2199 2200 stats->count = 0; 2201 memset(stats, 0, sizeof(*stats)); 2202 if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) 2203 return -1; 2204 2205#define SET_VALUE \ 2206 stats->data[i].long_format = "%-20.20s"; \ 2207 stats->data[i].rate_format = "%8.8s"; \ 2208 stats->data[i].isvalue = 1; \ 2209 stats->data[i].verbose = 0 2210 2211#define SET_COUNT \ 2212 stats->data[i].long_format = "%-20.20s"; \ 2213 stats->data[i].rate_format = "%5.5s"; \ 2214 stats->data[i].isvalue = 0; \ 2215 stats->data[i].mult_names = "kgm"; \ 2216 stats->data[i].mult = 1000; \ 2217 stats->data[i].verbose = 0 2218 2219#define SET_BYTE \ 2220 stats->data[i].long_format = "%-20.20s"; \ 2221 stats->data[i].rate_format = "%5.5s"; \ 2222 stats->data[i].isvalue = 0; \ 2223 stats->data[i].mult_names = "KGM"; \ 2224 stats->data[i].mult = 1024; \ 2225 stats->data[i].verbose = 0 2226 2227 2228 stats->count = s.count; 2229 for (i = 0; i < s.count; i++) { 2230 stats->data[i].value = s.data[i].value; 2231 switch (s.data[i].type) { 2232 case _DRM_STAT_LOCK: 2233 stats->data[i].long_name = "Lock"; 2234 stats->data[i].rate_name = "Lock"; 2235 SET_VALUE; 2236 break; 2237 case _DRM_STAT_OPENS: 2238 stats->data[i].long_name = "Opens"; 2239 stats->data[i].rate_name = "O"; 2240 SET_COUNT; 2241 stats->data[i].verbose = 1; 2242 break; 2243 case _DRM_STAT_CLOSES: 2244 stats->data[i].long_name = "Closes"; 2245 stats->data[i].rate_name = "Lock"; 2246 SET_COUNT; 2247 stats->data[i].verbose = 1; 2248 break; 2249 case _DRM_STAT_IOCTLS: 2250 stats->data[i].long_name = "Ioctls"; 2251 stats->data[i].rate_name = "Ioc/s"; 2252 SET_COUNT; 2253 break; 2254 case _DRM_STAT_LOCKS: 2255 stats->data[i].long_name = "Locks"; 2256 stats->data[i].rate_name = "Lck/s"; 2257 SET_COUNT; 2258 break; 2259 case _DRM_STAT_UNLOCKS: 2260 stats->data[i].long_name = "Unlocks"; 2261 stats->data[i].rate_name = "Unl/s"; 2262 SET_COUNT; 2263 break; 2264 case _DRM_STAT_IRQ: 2265 stats->data[i].long_name = "IRQs"; 2266 stats->data[i].rate_name = "IRQ/s"; 2267 SET_COUNT; 2268 break; 2269 case _DRM_STAT_PRIMARY: 2270 stats->data[i].long_name = "Primary Bytes"; 2271 stats->data[i].rate_name = "PB/s"; 2272 SET_BYTE; 2273 break; 2274 case _DRM_STAT_SECONDARY: 2275 stats->data[i].long_name = "Secondary Bytes"; 2276 stats->data[i].rate_name = "SB/s"; 2277 SET_BYTE; 2278 break; 2279 case _DRM_STAT_DMA: 2280 stats->data[i].long_name = "DMA"; 2281 stats->data[i].rate_name = "DMA/s"; 2282 SET_COUNT; 2283 break; 2284 case _DRM_STAT_SPECIAL: 2285 stats->data[i].long_name = "Special DMA"; 2286 stats->data[i].rate_name = "dma/s"; 2287 SET_COUNT; 2288 break; 2289 case _DRM_STAT_MISSED: 2290 stats->data[i].long_name = "Miss"; 2291 stats->data[i].rate_name = "Ms/s"; 2292 SET_COUNT; 2293 break; 2294 case _DRM_STAT_VALUE: 2295 stats->data[i].long_name = "Value"; 2296 stats->data[i].rate_name = "Value"; 2297 SET_VALUE; 2298 break; 2299 case _DRM_STAT_BYTE: 2300 stats->data[i].long_name = "Bytes"; 2301 stats->data[i].rate_name = "B/s"; 2302 SET_BYTE; 2303 break; 2304 case _DRM_STAT_COUNT: 2305 default: 2306 stats->data[i].long_name = "Count"; 2307 stats->data[i].rate_name = "Cnt/s"; 2308 SET_COUNT; 2309 break; 2310 } 2311 } 2312 return 0; 2313} 2314 2315/** 2316 * Issue a set-version ioctl. 2317 * 2318 * \param fd file descriptor. 2319 * \param drmCommandIndex command index 2320 * \param data source pointer of the data to be read and written. 2321 * \param size size of the data to be read and written. 2322 * 2323 * \return zero on success, or a negative value on failure. 2324 * 2325 * \internal 2326 * It issues a read-write ioctl given by 2327 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2328 */ 2329int drmSetInterfaceVersion(int fd, drmSetVersion *version) 2330{ 2331 int retcode = 0; 2332 drm_set_version_t sv; 2333 2334 sv.drm_di_major = version->drm_di_major; 2335 sv.drm_di_minor = version->drm_di_minor; 2336 sv.drm_dd_major = version->drm_dd_major; 2337 sv.drm_dd_minor = version->drm_dd_minor; 2338 2339 if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) { 2340 retcode = -errno; 2341 } 2342 2343 version->drm_di_major = sv.drm_di_major; 2344 version->drm_di_minor = sv.drm_di_minor; 2345 version->drm_dd_major = sv.drm_dd_major; 2346 version->drm_dd_minor = sv.drm_dd_minor; 2347 2348 return retcode; 2349} 2350 2351/** 2352 * Send a device-specific command. 2353 * 2354 * \param fd file descriptor. 2355 * \param drmCommandIndex command index 2356 * 2357 * \return zero on success, or a negative value on failure. 2358 * 2359 * \internal 2360 * It issues a ioctl given by 2361 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2362 */ 2363int drmCommandNone(int fd, unsigned long drmCommandIndex) 2364{ 2365 void *data = NULL; /* dummy */ 2366 unsigned long request; 2367 2368 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); 2369 2370 if (drmIoctl(fd, request, data)) { 2371 return -errno; 2372 } 2373 return 0; 2374} 2375 2376 2377/** 2378 * Send a device-specific read command. 2379 * 2380 * \param fd file descriptor. 2381 * \param drmCommandIndex command index 2382 * \param data destination pointer of the data to be read. 2383 * \param size size of the data to be read. 2384 * 2385 * \return zero on success, or a negative value on failure. 2386 * 2387 * \internal 2388 * It issues a read ioctl given by 2389 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2390 */ 2391int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data, 2392 unsigned long size) 2393{ 2394 unsigned long request; 2395 2396 request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, 2397 DRM_COMMAND_BASE + drmCommandIndex, size); 2398 2399 if (drmIoctl(fd, request, data)) { 2400 return -errno; 2401 } 2402 return 0; 2403} 2404 2405 2406/** 2407 * Send a device-specific write command. 2408 * 2409 * \param fd file descriptor. 2410 * \param drmCommandIndex command index 2411 * \param data source pointer of the data to be written. 2412 * \param size size of the data to be written. 2413 * 2414 * \return zero on success, or a negative value on failure. 2415 * 2416 * \internal 2417 * It issues a write ioctl given by 2418 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2419 */ 2420int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data, 2421 unsigned long size) 2422{ 2423 unsigned long request; 2424 2425 request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, 2426 DRM_COMMAND_BASE + drmCommandIndex, size); 2427 2428 if (drmIoctl(fd, request, data)) { 2429 return -errno; 2430 } 2431 return 0; 2432} 2433 2434 2435/** 2436 * Send a device-specific read-write command. 2437 * 2438 * \param fd file descriptor. 2439 * \param drmCommandIndex command index 2440 * \param data source pointer of the data to be read and written. 2441 * \param size size of the data to be read and written. 2442 * 2443 * \return zero on success, or a negative value on failure. 2444 * 2445 * \internal 2446 * It issues a read-write ioctl given by 2447 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2448 */ 2449int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, 2450 unsigned long size) 2451{ 2452 unsigned long request; 2453 2454 request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, 2455 DRM_COMMAND_BASE + drmCommandIndex, size); 2456 2457 if (drmIoctl(fd, request, data)) 2458 return -errno; 2459 return 0; 2460} 2461 2462#define DRM_MAX_FDS 16 2463static struct { 2464 char *BusID; 2465 int fd; 2466 int refcount; 2467} connection[DRM_MAX_FDS]; 2468 2469static int nr_fds = 0; 2470 2471int drmOpenOnce(void *unused, 2472 const char *BusID, 2473 int *newlyopened) 2474{ 2475 int i; 2476 int fd; 2477 2478 for (i = 0; i < nr_fds; i++) 2479 if (strcmp(BusID, connection[i].BusID) == 0) { 2480 connection[i].refcount++; 2481 *newlyopened = 0; 2482 return connection[i].fd; 2483 } 2484 2485 fd = drmOpen(unused, BusID); 2486 if (fd <= 0 || nr_fds == DRM_MAX_FDS) 2487 return fd; 2488 2489 connection[nr_fds].BusID = strdup(BusID); 2490 connection[nr_fds].fd = fd; 2491 connection[nr_fds].refcount = 1; 2492 *newlyopened = 1; 2493 2494 if (0) 2495 fprintf(stderr, "saved connection %d for %s %d\n", 2496 nr_fds, connection[nr_fds].BusID, 2497 strcmp(BusID, connection[nr_fds].BusID)); 2498 2499 nr_fds++; 2500 2501 return fd; 2502} 2503 2504void drmCloseOnce(int fd) 2505{ 2506 int i; 2507 2508 for (i = 0; i < nr_fds; i++) { 2509 if (fd == connection[i].fd) { 2510 if (--connection[i].refcount == 0) { 2511 drmClose(connection[i].fd); 2512 free(connection[i].BusID); 2513 2514 if (i < --nr_fds) 2515 connection[i] = connection[nr_fds]; 2516 2517 return; 2518 } 2519 } 2520 } 2521} 2522 2523int drmSetMaster(int fd) 2524{ 2525 return ioctl(fd, DRM_IOCTL_SET_MASTER, 0); 2526} 2527 2528int drmDropMaster(int fd) 2529{ 2530 return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); 2531} 2532 2533char *drmGetDeviceNameFromFd(int fd) 2534{ 2535 char name[128]; 2536 struct stat sbuf; 2537 dev_t d; 2538 int i; 2539 2540 /* The whole drmOpen thing is a fiasco and we need to find a way 2541 * back to just using open(2). For now, however, lets just make 2542 * things worse with even more ad hoc directory walking code to 2543 * discover the device file name. */ 2544 2545 fstat(fd, &sbuf); 2546 d = sbuf.st_rdev; 2547 2548 for (i = 0; i < DRM_MAX_MINOR; i++) { 2549 snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i); 2550 if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) 2551 break; 2552 } 2553 if (i == DRM_MAX_MINOR) 2554 return NULL; 2555 2556 return strdup(name); 2557} 2558 2559int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) 2560{ 2561 struct drm_prime_handle args; 2562 int ret; 2563 2564 args.handle = handle; 2565 args.flags = flags; 2566 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); 2567 if (ret) 2568 return ret; 2569 2570 *prime_fd = args.fd; 2571 return 0; 2572} 2573 2574int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) 2575{ 2576 struct drm_prime_handle args; 2577 int ret; 2578 2579 args.fd = prime_fd; 2580 args.flags = 0; 2581 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args); 2582 if (ret) 2583 return ret; 2584 2585 *handle = args.handle; 2586 return 0; 2587} 2588 2589