3 * User-level interface to DRM device
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Kevin E. Martin <martin@valinux.com>
10 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
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:
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
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.
47 #include <sys/types.h>
49 #define stat_t struct stat
50 #include <sys/ioctl.h>
55 /* Not all systems have MAP_FAILED defined */
57 #define MAP_FAILED ((void *)-1)
62 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
75 #define DRM_MAJOR 226 /* Linux */
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.
83 #define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
86 #define DRM_MSG_VERBOSITY 3
88 #define DRM_NODE_CONTROL 0
89 #define DRM_NODE_RENDER 1
91 static drmServerInfoPtr drm_server_info;
93 void drmSetServerInfo(drmServerInfoPtr info)
95 drm_server_info = info;
99 * Output a message to stderr.
101 * \param format printf() like format string.
104 * This function is a wrapper around vfprintf().
107 static int drmDebugPrint(const char *format, va_list ap)
109 return vfprintf(stderr, format, ap);
112 static int (*drm_debug_print)(const char *format, va_list ap) = drmDebugPrint;
115 drmMsg(const char *format, ...)
119 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || drm_server_info)
121 va_start(ap, format);
122 if (drm_server_info) {
123 drm_server_info->debug_print(format,ap);
125 drm_debug_print(format, ap);
132 drmSetDebugMsgFunction(int (*debug_msg_ptr)(const char *format, va_list ap))
134 drm_debug_print = debug_msg_ptr;
137 static void *drmHashTable = NULL; /* Context switch callbacks */
139 void *drmGetHashTable(void)
144 void *drmMalloc(int size)
147 if ((pt = malloc(size)))
152 void drmFree(void *pt)
158 /* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
159 static char *drmStrdup(const char *s)
166 retval = malloc(strlen(s)+1);
176 * Call ioctl, restarting if it is interupted
179 drmIoctl(int fd, unsigned long request, void *arg)
184 ret = ioctl(fd, request, arg);
185 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
189 static unsigned long drmGetKeyFromFd(int fd)
198 drmHashEntry *drmGetEntry(int fd)
200 unsigned long key = drmGetKeyFromFd(fd);
205 drmHashTable = drmHashCreate();
207 if (drmHashLookup(drmHashTable, key, &value)) {
208 entry = drmMalloc(sizeof(*entry));
211 entry->tagTable = drmHashCreate();
212 drmHashInsert(drmHashTable, key, entry);
220 * Compare two busid strings
225 * \return 1 if matched.
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.
232 static int drmMatchBusID(const char *id1, const char *id2)
234 /* First, check if the IDs are exactly the same */
235 if (strcasecmp(id1, id2) == 0)
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;
244 ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
247 ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
252 ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
255 ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
260 if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
269 * Handles error checking for chown call.
271 * \param path to file.
272 * \param id of the new owner.
273 * \param id of the new group.
275 * \return zero if success or -1 if failure.
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
282 static int chown_check_return(const char *path, uid_t owner, gid_t group)
287 rv = chown(path, owner, group);
288 } while (rv != 0 && errno == EINTR);
293 drmMsg("Failed to change owner or group for file %s! %d: %s\n",
294 path, errno, strerror(errno));
299 * Open the DRM device, creating it if necessary.
301 * \param dev major and minor numbers of the device.
302 * \param minor minor number of the device.
304 * \return a file descriptor on success, or a negative value on error.
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.
311 static int drmOpenDevice(long dev, int minor, int type)
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;
321 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
322 drmMsg("drmOpenDevice: node name is %s\n", buf);
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;
332 if (stat(DRM_DIR_NAME, &st)) {
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);
340 /* Check if the device node exists and create it if necessary. */
341 if (stat(buf, &st)) {
343 return DRM_ERR_NOT_ROOT;
345 mknod(buf, S_IFCHR | devmode, dev);
348 if (drm_server_info) {
349 chown_check_return(buf, user, group);
353 /* if we modprobed then wait for udev */
357 if (stat(DRM_DIR_NAME, &st)) {
361 if (udev_count == 50)
366 if (stat(buf, &st)) {
370 if (udev_count == 50)
377 fd = open(buf, O_RDWR, 0);
378 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
379 fd, fd < 0 ? strerror(errno) : "OK");
383 /* Check if the device node is not what we expect it to be, and recreate it
384 * and try again if so.
386 if (st.st_rdev != dev) {
388 return DRM_ERR_NOT_ROOT;
390 mknod(buf, S_IFCHR | devmode, dev);
391 if (drm_server_info) {
392 chown_check_return(buf, user, group);
396 fd = open(buf, O_RDWR, 0);
397 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
398 fd, fd < 0 ? strerror(errno) : "OK");
402 drmMsg("drmOpenDevice: Open failed\n");
409 * Open the DRM device
411 * \param minor device minor number.
412 * \param create allow to create the device if set.
414 * \return a file descriptor on success, or a negative value on error.
417 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
418 * name from \p minor and opens it.
420 static int drmOpenMinor(int minor, int create, int type)
426 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
428 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
429 if ((fd = open(buf, O_RDWR, 0)) >= 0)
436 * Determine whether the DRM kernel driver has been loaded.
438 * \return 1 if the DRM driver is loaded, 0 otherwise.
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.
445 int drmAvailable(void)
447 drmVersionPtr version;
451 if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
453 /* Try proc for backward Linux compatibility */
454 if (!access("/proc/dri/0", R_OK))
460 if ((version = drmGetVersion(fd))) {
462 drmFreeVersion(version);
471 * Open the device by bus ID.
473 * \param busid bus ID.
475 * \return a file descriptor on success, or a negative value on error.
478 * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
479 * comparing the device bus ID with the one supplied.
481 * \sa drmOpenMinor() and drmGetBusid().
483 static int drmOpenByBusid(const char *busid)
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);
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)) {
516 * Open the device by name.
518 * \param name driver name.
520 * \return a file descriptor on success, or a negative value on error.
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
527 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
529 static int drmOpenByName(const char *name)
533 drmVersionPtr version;
536 if (!drmAvailable()) {
537 if (!drm_server_info) {
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);
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.
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");
568 drmFreeVersion(version);
576 /* Backward-compatibility /proc support */
577 for (i = 0; i < 8; i++) {
578 char proc_name[64], buf[512];
579 char *driver, *pt, *devstring;
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);
587 buf[retcode-1] = '\0';
588 for (driver = pt = buf; *pt && *pt != ' '; ++pt)
590 if (*pt) { /* Device is next */
592 if (!strcmp(driver, name)) { /* Match */
593 for (devstring = ++pt; *pt && *pt != ' '; ++pt)
595 if (*pt) { /* Found busid */
596 return drmOpenByBusid(++pt);
597 } else { /* No busid */
598 return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
612 * Open the DRM device.
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.
617 * \param name driver name. Not referenced if bus ID is supplied.
618 * \param busid bus ID. Zero if not known.
620 * \return a file descriptor on success, or a negative value on error.
623 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
626 int drmOpen(const char *name, const char *busid)
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);
637 int fd = drmOpenByBusid(busid);
643 return drmOpenByName(name);
648 int drmOpenControl(int minor)
650 return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
654 * Free the version information returned by drmGetVersion().
656 * \param v pointer to the version information.
659 * It frees the memory pointed by \p %v as well as all the non-null strings
662 void drmFreeVersion(drmVersionPtr v)
674 * Free the non-public version information returned by the kernel.
676 * \param v pointer to the version information.
679 * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
680 * the non-null strings pointers in it.
682 static void drmFreeKernelVersion(drm_version_t *v)
694 * Copy version information.
696 * \param d destination pointer.
697 * \param s source pointer.
700 * Used by drmGetVersion() to translate the information returned by the ioctl
701 * interface in a private structure into the public structure counterpart.
703 static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
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);
718 * Query the driver version information.
720 * \param fd file descriptor.
722 * \return pointer to a drmVersion structure which should be freed with
725 * \note Similar information is available via /proc/dri.
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.
732 drmVersionPtr drmGetVersion(int fd)
734 drmVersionPtr retval;
735 drm_version_t *version = drmMalloc(sizeof(*version));
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;
744 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
745 drmFreeKernelVersion(version);
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);
756 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
757 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
758 drmFreeKernelVersion(version);
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';
767 retval = drmMalloc(sizeof(*retval));
768 drmCopyVersion(retval, version);
769 drmFreeKernelVersion(version);
775 * Get version information for the DRM user space library.
777 * This version number is driver independent.
779 * \param fd file descriptor.
781 * \return version information.
784 * This function allocates and fills a drm_version structure with a hard coded
787 drmVersionPtr drmGetLibVersion(int fd)
789 drm_version_t *version = drmMalloc(sizeof(*version));
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
801 version->version_major = 1;
802 version->version_minor = 3;
803 version->version_patchlevel = 0;
805 return (drmVersionPtr)version;
810 * Free the bus ID information.
812 * \param busid bus ID information string as given by drmGetBusid().
815 * This function is just frees the memory pointed by \p busid.
817 void drmFreeBusid(const char *busid)
819 drmFree((void *)busid);
824 * Get the bus ID of the device.
826 * \param fd file descriptor.
828 * \return bus ID string.
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
835 char *drmGetBusid(int fd)
842 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
844 u.unique = drmMalloc(u.unique_len + 1);
845 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
847 u.unique[u.unique_len] = '\0';
854 * Set the bus ID of the device.
856 * \param fd file descriptor.
857 * \param busid bus ID string.
859 * \return zero on success, negative on failure.
862 * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
863 * the arguments in a drm_unique structure.
865 int drmSetBusid(int fd, const char *busid)
869 u.unique = (char *)busid;
870 u.unique_len = strlen(busid);
872 if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
878 int drmGetMagic(int fd, drm_magic_t * magic)
883 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
889 int drmAuthMagic(int fd, drm_magic_t magic)
894 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
900 * Specifies a range of memory that is available for mapping by a
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().
912 * \return zero on success or a negative value on error.
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.
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.
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.
930 * The area mapped will be uncached.
932 * \par Mapping 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.
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
943 * \note May only be called by root.
946 * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
947 * the arguments in a drm_map structure.
949 int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
950 drmMapFlags flags, drm_handle_t *handle)
959 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
962 *handle = (drm_handle_t)map.handle;
966 int drmRmMap(int fd, drm_handle_t handle)
970 map.handle = (void *)handle;
972 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
978 * Make buffers available for DMA transfers.
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
986 * \return number of buffers allocated, negative on error.
989 * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
993 int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
996 drm_buf_desc_t request;
998 request.count = count;
1000 request.low_mark = 0;
1001 request.high_mark = 0;
1002 request.flags = flags;
1003 request.agp_start = agp_offset;
1005 if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1007 return request.count;
1010 int drmMarkBufs(int fd, double low, double high)
1012 drm_buf_info_t info;
1018 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1024 if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1027 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1028 int retval = -errno;
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;
1050 * \param fd file descriptor.
1051 * \param count number of buffers to free.
1052 * \param list list of buffers to be freed.
1054 * \return zero on success, or a negative value on failure.
1056 * \note This function is primarily used for debugging.
1059 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1060 * the arguments in a drm_buf_free structure.
1062 int drmFreeBufs(int fd, int count, int *list)
1064 drm_buf_free_t request;
1066 request.count = count;
1067 request.list = list;
1068 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1077 * \param fd file descriptor.
1080 * This function closes the file descriptor.
1082 int drmClose(int fd)
1084 unsigned long key = drmGetKeyFromFd(fd);
1085 drmHashEntry *entry = drmGetEntry(fd);
1087 drmHashDestroy(entry->tagTable);
1090 entry->tagTable = NULL;
1092 drmHashDelete(drmHashTable, key);
1100 * Map a region of memory.
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
1108 * \return zero on success, or a negative value on failure.
1111 * This function is a wrapper for mmap().
1113 int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1115 static unsigned long pagesize_mask = 0;
1121 pagesize_mask = getpagesize() - 1;
1123 size = (size + pagesize_mask) & ~pagesize_mask;
1125 *address = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1126 if (*address == MAP_FAILED)
1133 * Unmap mappings obtained with drmMap().
1135 * \param address address as given by drmMap().
1136 * \param size size in bytes. Must match the size used by drmMap().
1138 * \return zero on success, or a negative value on failure.
1141 * This function is a wrapper for munmap().
1143 int drmUnmap(drmAddress address, drmSize size)
1145 return munmap(address, size);
1148 drmBufInfoPtr drmGetBufInfo(int fd)
1150 drm_buf_info_t info;
1151 drmBufInfoPtr retval;
1157 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1161 if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1164 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
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;
1185 * Map all DMA buffers into client-virtual space.
1187 * \param fd file descriptor.
1189 * \return a pointer to a ::drmBufMap structure.
1191 * \note The client may not use these buffers until obtaining buffer indices
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.
1199 drmBufMapPtr drmMapBufs(int fd)
1202 drmBufMapPtr retval;
1207 bufs.virtual = NULL;
1208 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1214 if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1217 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
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;
1239 * Unmap buffers allocated with drmMapBufs().
1241 * \return zero on success, or negative value on failure.
1244 * Calls munmap() for every buffer stored in \p bufs and frees the
1245 * memory allocated by drmMapBufs().
1247 int drmUnmapBufs(drmBufMapPtr bufs)
1251 for (i = 0; i < bufs->count; i++) {
1252 munmap(bufs->list[i].address, bufs->list[i].total);
1255 drmFree(bufs->list);
1262 #define DRM_DMA_RETRY 16
1265 * Reserve DMA buffers.
1267 * \param fd file descriptor.
1270 * \return zero on success, or a negative value on failure.
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.
1276 int drmDMA(int fd, drmDMAReqPtr request)
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;
1293 ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1294 } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1297 request->granted_count = dma.granted_count;
1306 * Obtain heavyweight hardware lock.
1308 * \param fd file descriptor.
1309 * \param context context.
1310 * \param flags flags that determine the sate of the hardware when the function
1313 * \return always zero.
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.
1319 int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1323 lock.context = context;
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;
1332 while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1338 * Release the hardware lock.
1340 * \param fd file descriptor.
1341 * \param context context.
1343 * \return zero on success, or a negative value on failure.
1346 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1347 * argument in a drm_lock structure.
1349 int drmUnlock(int fd, drm_context_t context)
1353 lock.context = context;
1355 return drmIoctl(fd, DRM_IOCTL_UNLOCK, &lock);
1358 drm_context_t *drmGetReservedContextList(int fd, int *count)
1362 drm_context_t * retval;
1366 res.contexts = NULL;
1367 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1373 if (!(list = drmMalloc(res.count * sizeof(*list))))
1375 if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1380 res.contexts = list;
1381 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1384 for (i = 0; i < res.count; i++)
1385 retval[i] = list[i].handle;
1392 void drmFreeReservedContextList(drm_context_t *pt)
1400 * Used by the X server during GLXContext initialization. This causes
1401 * per-context kernel-level resources to be allocated.
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().
1407 * \return zero on success, or a negative value on failure.
1409 * \note May only be called by root.
1412 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1413 * argument in a drm_ctx structure.
1415 int drmCreateContext(int fd, drm_context_t *handle)
1419 ctx.flags = 0; /* Modified with functions below */
1420 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1422 *handle = ctx.handle;
1426 int drmSwitchToContext(int fd, drm_context_t context)
1430 ctx.handle = context;
1431 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1436 int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
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.
1446 ctx.handle = context;
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))
1457 int drmGetContextFlags(int fd, drm_context_t context,
1458 drm_context_tFlagsPtr flags)
1462 ctx.handle = context;
1463 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1466 if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1467 *flags |= DRM_CONTEXT_PRESERVED;
1468 if (ctx.flags & _DRM_CONTEXT_2DONLY)
1469 *flags |= DRM_CONTEXT_2DONLY;
1476 * Free any kernel-level resources allocated with drmCreateContext() associated
1479 * \param fd file descriptor.
1480 * \param handle handle given by drmCreateContext().
1482 * \return zero on success, or a negative value on failure.
1484 * \note May only be called by root.
1487 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1488 * argument in a drm_ctx structure.
1490 int drmDestroyContext(int fd, drm_context_t handle)
1493 ctx.handle = handle;
1494 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1499 int drmCreateDrawable(int fd, drm_drawable_t *handle)
1502 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1504 *handle = draw.handle;
1508 int drmDestroyDrawable(int fd, drm_drawable_t handle)
1511 draw.handle = handle;
1512 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1517 int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1518 drm_drawable_info_type_t type, unsigned int num,
1521 drm_update_draw_t update;
1523 update.handle = handle;
1526 update.data = (unsigned long long)(unsigned long)data;
1528 if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1535 * Acquire the AGP device.
1537 * Must be called before any of the other AGP related calls.
1539 * \param fd file descriptor.
1541 * \return zero on success, or a negative value on failure.
1544 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1546 int drmAgpAcquire(int fd)
1548 if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1555 * Release the AGP device.
1557 * \param fd file descriptor.
1559 * \return zero on success, or a negative value on failure.
1562 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1564 int drmAgpRelease(int fd)
1566 if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1575 * \param fd file descriptor.
1576 * \param mode AGP mode.
1578 * \return zero on success, or a negative value on failure.
1581 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1582 * argument in a drm_agp_mode structure.
1584 int drmAgpEnable(int fd, unsigned long mode)
1589 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1596 * Allocate a chunk of AGP memory.
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
1603 * \param handle on success will be set to a handle of the allocated memory.
1605 * \return zero on success, or a negative value on failure.
1608 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1609 * arguments in a drm_agp_buffer structure.
1611 int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1612 unsigned long *address, drm_handle_t *handle)
1616 *handle = DRM_AGP_NO_HANDLE;
1620 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1623 *address = b.physical;
1630 * Free a chunk of AGP memory.
1632 * \param fd file descriptor.
1633 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1635 * \return zero on success, or a negative value on failure.
1638 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1639 * argument in a drm_agp_buffer structure.
1641 int drmAgpFree(int fd, drm_handle_t handle)
1647 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1654 * Bind a chunk of AGP memory.
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.
1660 * \return zero on success, or a negative value on failure.
1663 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1664 * argument in a drm_agp_binding structure.
1666 int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1668 drm_agp_binding_t b;
1672 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1679 * Unbind a chunk of AGP memory.
1681 * \param fd file descriptor.
1682 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1684 * \return zero on success, or a negative value on failure.
1687 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1688 * the argument in a drm_agp_binding structure.
1690 int drmAgpUnbind(int fd, drm_handle_t handle)
1692 drm_agp_binding_t b;
1696 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1703 * Get AGP driver major version number.
1705 * \param fd file descriptor.
1707 * \return major version number on success, or a negative value on failure..
1710 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1711 * necessary information in a drm_agp_info structure.
1713 int drmAgpVersionMajor(int fd)
1717 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1719 return i.agp_version_major;
1724 * Get AGP driver minor version number.
1726 * \param fd file descriptor.
1728 * \return minor version number on success, or a negative value on failure.
1731 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1732 * necessary information in a drm_agp_info structure.
1734 int drmAgpVersionMinor(int fd)
1738 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1740 return i.agp_version_minor;
1747 * \param fd file descriptor.
1749 * \return mode on success, or zero on failure.
1752 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1753 * necessary information in a drm_agp_info structure.
1755 unsigned long drmAgpGetMode(int fd)
1759 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1766 * Get AGP aperture base.
1768 * \param fd file descriptor.
1770 * \return aperture base on success, zero on failure.
1773 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1774 * necessary information in a drm_agp_info structure.
1776 unsigned long drmAgpBase(int fd)
1780 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1782 return i.aperture_base;
1787 * Get AGP aperture size.
1789 * \param fd file descriptor.
1791 * \return aperture size on success, zero on failure.
1794 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1795 * necessary information in a drm_agp_info structure.
1797 unsigned long drmAgpSize(int fd)
1801 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1803 return i.aperture_size;
1808 * Get used AGP memory.
1810 * \param fd file descriptor.
1812 * \return memory used on success, or zero on failure.
1815 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1816 * necessary information in a drm_agp_info structure.
1818 unsigned long drmAgpMemoryUsed(int fd)
1822 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1824 return i.memory_used;
1829 * Get available AGP memory.
1831 * \param fd file descriptor.
1833 * \return memory available on success, or zero on failure.
1836 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1837 * necessary information in a drm_agp_info structure.
1839 unsigned long drmAgpMemoryAvail(int fd)
1843 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1845 return i.memory_allowed;
1850 * Get hardware vendor ID.
1852 * \param fd file descriptor.
1854 * \return vendor ID on success, or zero on failure.
1857 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1858 * necessary information in a drm_agp_info structure.
1860 unsigned int drmAgpVendorId(int fd)
1864 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1871 * Get hardware device ID.
1873 * \param fd file descriptor.
1875 * \return zero on success, or zero on failure.
1878 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1879 * necessary information in a drm_agp_info structure.
1881 unsigned int drmAgpDeviceId(int fd)
1885 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1890 int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
1892 drm_scatter_gather_t sg;
1897 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
1899 *handle = sg.handle;
1903 int drmScatterGatherFree(int fd, drm_handle_t handle)
1905 drm_scatter_gather_t sg;
1909 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
1917 * \param fd file descriptor.
1918 * \param vbl pointer to a drmVBlank structure.
1920 * \return zero on success, or a negative value on failure.
1923 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
1925 int drmWaitVBlank(int fd, drmVBlankPtr vbl)
1927 struct timespec timeout, cur;
1930 ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
1932 fprintf(stderr, "clock_gettime failed: %s\n", strerror(ret));
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 >=
1951 } while (ret && errno == EINTR);
1957 int drmError(int err, const char *label)
1960 case DRM_ERR_NO_DEVICE:
1961 fprintf(stderr, "%s: no device\n", label);
1963 case DRM_ERR_NO_ACCESS:
1964 fprintf(stderr, "%s: no access\n", label);
1966 case DRM_ERR_NOT_ROOT:
1967 fprintf(stderr, "%s: not root\n", label);
1969 case DRM_ERR_INVALID:
1970 fprintf(stderr, "%s: invalid args\n", label);
1975 fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
1983 * Install IRQ handler.
1985 * \param fd file descriptor.
1986 * \param irq IRQ number.
1988 * \return zero on success, or a negative value on failure.
1991 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1992 * argument in a drm_control structure.
1994 int drmCtlInstHandler(int fd, int irq)
1998 ctl.func = DRM_INST_HANDLER;
2000 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2007 * Uninstall IRQ handler.
2009 * \param fd file descriptor.
2011 * \return zero on success, or a negative value on failure.
2014 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2015 * argument in a drm_control structure.
2017 int drmCtlUninstHandler(int fd)
2021 ctl.func = DRM_UNINST_HANDLER;
2023 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2028 int drmFinish(int fd, int context, drmLockFlags flags)
2032 lock.context = context;
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))
2046 * Get IRQ from bus ID.
2048 * \param fd file descriptor.
2049 * \param busnum bus number.
2050 * \param devnum device number.
2051 * \param funcnum function number.
2053 * \return IRQ number on success, or a negative value on failure.
2056 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2057 * arguments in a drm_irq_busid structure.
2059 int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2065 p.funcnum = funcnum;
2066 if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2071 int drmAddContextTag(int fd, drm_context_t context, void *tag)
2073 drmHashEntry *entry = drmGetEntry(fd);
2075 if (drmHashInsert(entry->tagTable, context, tag)) {
2076 drmHashDelete(entry->tagTable, context);
2077 drmHashInsert(entry->tagTable, context, tag);
2082 int drmDelContextTag(int fd, drm_context_t context)
2084 drmHashEntry *entry = drmGetEntry(fd);
2086 return drmHashDelete(entry->tagTable, context);
2089 void *drmGetContextTag(int fd, drm_context_t context)
2091 drmHashEntry *entry = drmGetEntry(fd);
2094 if (drmHashLookup(entry->tagTable, context, &value))
2100 int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
2101 drm_handle_t handle)
2103 drm_ctx_priv_map_t map;
2105 map.ctx_id = ctx_id;
2106 map.handle = (void *)handle;
2108 if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2113 int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
2114 drm_handle_t *handle)
2116 drm_ctx_priv_map_t map;
2118 map.ctx_id = ctx_id;
2120 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2123 *handle = (drm_handle_t)map.handle;
2128 int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2129 drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
2135 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2137 *offset = map.offset;
2141 *handle = (unsigned long)map.handle;
2146 int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2147 unsigned long *magic, unsigned long *iocs)
2149 drm_client_t client;
2152 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2154 *auth = client.auth;
2157 *magic = client.magic;
2158 *iocs = client.iocs;
2162 int drmGetStats(int fd, drmStatsT *stats)
2167 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2171 memset(stats, 0, sizeof(*stats));
2172 if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
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
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
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
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";
2207 case _DRM_STAT_OPENS:
2208 stats->data[i].long_name = "Opens";
2209 stats->data[i].rate_name = "O";
2211 stats->data[i].verbose = 1;
2213 case _DRM_STAT_CLOSES:
2214 stats->data[i].long_name = "Closes";
2215 stats->data[i].rate_name = "Lock";
2217 stats->data[i].verbose = 1;
2219 case _DRM_STAT_IOCTLS:
2220 stats->data[i].long_name = "Ioctls";
2221 stats->data[i].rate_name = "Ioc/s";
2224 case _DRM_STAT_LOCKS:
2225 stats->data[i].long_name = "Locks";
2226 stats->data[i].rate_name = "Lck/s";
2229 case _DRM_STAT_UNLOCKS:
2230 stats->data[i].long_name = "Unlocks";
2231 stats->data[i].rate_name = "Unl/s";
2235 stats->data[i].long_name = "IRQs";
2236 stats->data[i].rate_name = "IRQ/s";
2239 case _DRM_STAT_PRIMARY:
2240 stats->data[i].long_name = "Primary Bytes";
2241 stats->data[i].rate_name = "PB/s";
2244 case _DRM_STAT_SECONDARY:
2245 stats->data[i].long_name = "Secondary Bytes";
2246 stats->data[i].rate_name = "SB/s";
2250 stats->data[i].long_name = "DMA";
2251 stats->data[i].rate_name = "DMA/s";
2254 case _DRM_STAT_SPECIAL:
2255 stats->data[i].long_name = "Special DMA";
2256 stats->data[i].rate_name = "dma/s";
2259 case _DRM_STAT_MISSED:
2260 stats->data[i].long_name = "Miss";
2261 stats->data[i].rate_name = "Ms/s";
2264 case _DRM_STAT_VALUE:
2265 stats->data[i].long_name = "Value";
2266 stats->data[i].rate_name = "Value";
2269 case _DRM_STAT_BYTE:
2270 stats->data[i].long_name = "Bytes";
2271 stats->data[i].rate_name = "B/s";
2274 case _DRM_STAT_COUNT:
2276 stats->data[i].long_name = "Count";
2277 stats->data[i].rate_name = "Cnt/s";
2286 * Issue a set-version ioctl.
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.
2293 * \return zero on success, or a negative value on failure.
2296 * It issues a read-write ioctl given by
2297 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2299 int drmSetInterfaceVersion(int fd, drmSetVersion *version)
2302 drm_set_version_t sv;
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;
2309 if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
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;
2322 * Send a device-specific command.
2324 * \param fd file descriptor.
2325 * \param drmCommandIndex command index
2327 * \return zero on success, or a negative value on failure.
2330 * It issues a ioctl given by
2331 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2333 int drmCommandNone(int fd, unsigned long drmCommandIndex)
2335 void *data = NULL; /* dummy */
2336 unsigned long request;
2338 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
2340 if (drmIoctl(fd, request, data)) {
2348 * Send a device-specific read command.
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.
2355 * \return zero on success, or a negative value on failure.
2358 * It issues a read ioctl given by
2359 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2361 int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
2364 unsigned long request;
2366 request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
2367 DRM_COMMAND_BASE + drmCommandIndex, size);
2369 if (drmIoctl(fd, request, data)) {
2377 * Send a device-specific write command.
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.
2384 * \return zero on success, or a negative value on failure.
2387 * It issues a write ioctl given by
2388 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2390 int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
2393 unsigned long request;
2395 request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
2396 DRM_COMMAND_BASE + drmCommandIndex, size);
2398 if (drmIoctl(fd, request, data)) {
2406 * Send a device-specific read-write command.
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.
2413 * \return zero on success, or a negative value on failure.
2416 * It issues a read-write ioctl given by
2417 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2419 int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
2422 unsigned long request;
2424 request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
2425 DRM_COMMAND_BASE + drmCommandIndex, size);
2427 if (drmIoctl(fd, request, data))
2432 #define DRM_MAX_FDS 16
2437 } connection[DRM_MAX_FDS];
2439 static int nr_fds = 0;
2441 int drmOpenOnce(void *unused,
2448 for (i = 0; i < nr_fds; i++)
2449 if (strcmp(BusID, connection[i].BusID) == 0) {
2450 connection[i].refcount++;
2452 return connection[i].fd;
2455 fd = drmOpen(unused, BusID);
2456 if (fd <= 0 || nr_fds == DRM_MAX_FDS)
2459 connection[nr_fds].BusID = strdup(BusID);
2460 connection[nr_fds].fd = fd;
2461 connection[nr_fds].refcount = 1;
2465 fprintf(stderr, "saved connection %d for %s %d\n",
2466 nr_fds, connection[nr_fds].BusID,
2467 strcmp(BusID, connection[nr_fds].BusID));
2474 void drmCloseOnce(int fd)
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);
2485 connection[i] = connection[nr_fds];
2493 int drmSetMaster(int fd)
2495 return ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
2498 int drmDropMaster(int fd)
2500 return ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2503 char *drmGetDeviceNameFromFd(int fd)
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. */
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)
2523 if (i == DRM_MAX_MINOR)
2526 return drmStrdup(name);