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