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.
34 /* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drm.c,v 1.36 2003/08/24 17:35:35 tsi Exp $ */
38 # include "xf86_OSproc.h"
40 # include "xf86_ansic.h"
41 # define _DRM_MALLOC xalloc
42 # define _DRM_FREE xfree
43 # ifndef XFree86LOADER
44 # include <sys/mman.h>
55 # include <sys/types.h>
56 # include <sys/stat.h>
57 # define stat_t struct stat
58 # include <sys/ioctl.h>
59 # include <sys/mman.h>
60 # include <sys/time.h>
62 # ifdef DRM_USE_MALLOC
63 # define _DRM_MALLOC malloc
64 # define _DRM_FREE free
66 # include <X11/Xlibint.h>
67 # define _DRM_MALLOC Xmalloc
68 # define _DRM_FREE Xfree
73 /* No longer needed with CVS kernel modules on alpha
74 #if defined(__alpha__) && defined(__linux__)
75 extern unsigned long _bus_base(void);
76 #define BUS_BASE _bus_base()
80 /* Not all systems have MAP_FAILED defined */
82 #define MAP_FAILED ((void *)-1)
100 #define DRM_MAJOR 226 /* Linux */
103 #ifndef DRM_MAX_MINOR
104 #define DRM_MAX_MINOR 16
108 #include <sys/sysmacros.h> /* for makedev() */
112 /* This definition needs to be changed on
113 some systems if dev_t is a structure.
114 If there is a header file we can get it
115 from, there would be best. */
116 #define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
119 #define DRM_MSG_VERBOSITY 3
122 * Output a message to stderr.
124 * \param format printf() like format string.
127 * This function is a wrapper around vfprintf().
130 drmMsg(const char *format
, ...)
134 #ifndef XFree86Server
136 if ((env
= getenv("LIBGL_DEBUG")) && strstr(env
, "verbose"))
139 va_start(ap
, format
);
141 xf86VDrvMsgVerb(-1, X_NONE
, DRM_MSG_VERBOSITY
, format
, ap
);
143 vfprintf(stderr
, format
, ap
);
149 static void *drmHashTable
= NULL
; /* Context switch callbacks */
151 typedef struct drmHashEntry
{
153 void (*f
)(int, void *, void *);
157 void *drmMalloc(int size
)
160 if ((pt
= _DRM_MALLOC(size
))) memset(pt
, 0, size
);
164 void drmFree(void *pt
)
166 if (pt
) _DRM_FREE(pt
);
169 /* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
170 static char *drmStrdup(const char *s
)
175 retval
= _DRM_MALLOC(strlen(s
)+1);
182 static unsigned long drmGetKeyFromFd(int fd
)
191 static drmHashEntry
*drmGetEntry(int fd
)
193 unsigned long key
= drmGetKeyFromFd(fd
);
197 if (!drmHashTable
) drmHashTable
= drmHashCreate();
199 if (drmHashLookup(drmHashTable
, key
, &value
)) {
200 entry
= drmMalloc(sizeof(*entry
));
203 entry
->tagTable
= drmHashCreate();
204 drmHashInsert(drmHashTable
, key
, entry
);
212 * Compare two busid strings
217 * \return 1 if matched.
220 * This function compares two bus ID strings. It understands the older
221 * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is
222 * domain, b is bus, d is device, f is function.
224 static int drmMatchBusID(const char *id1
, const char *id2
)
226 /* First, check if the IDs are exactly the same */
227 if (strcasecmp(id1
, id2
) == 0)
230 /* Try to match old/new-style PCI bus IDs. */
231 if (strncasecmp(id1
, "pci", 3) == 0) {
236 ret
= sscanf(id1
, "pci:%04x:%02x:%02x.%d", &o1
, &b1
, &d1
, &f1
);
239 ret
= sscanf(id1
, "PCI:%d:%d:%d", &b1
, &d1
, &f1
);
244 ret
= sscanf(id2
, "pci:%04x:%02x:%02x.%d", &o2
, &b2
, &d2
, &f2
);
247 ret
= sscanf(id2
, "PCI:%d:%d:%d", &b2
, &d2
, &f2
);
252 if ((o1
!= o2
) || (b1
!= b2
) || (d1
!= d2
) || (f1
!= f2
))
261 * Open the DRM device, creating it if necessary.
263 * \param dev major and minor numbers of the device.
264 * \param minor minor number of the device.
266 * \return a file descriptor on success, or a negative value on error.
269 * Assembles the device name from \p minor and opens it, creating the device
270 * special file node with the major and minor numbers specified by \p dev and
271 * parent directory if necessary and was called by root.
273 static int drmOpenDevice(long dev
, int minor
)
278 mode_t devmode
= DRM_DEV_MODE
;
279 int isroot
= !geteuid();
280 #if defined(XFree86Server)
281 uid_t user
= DRM_DEV_UID
;
282 gid_t group
= DRM_DEV_GID
;
285 sprintf(buf
, DRM_DEV_NAME
, DRM_DIR_NAME
, minor
);
286 drmMsg("drmOpenDevice: node name is %s\n", buf
);
288 #if defined(XFree86Server)
289 devmode
= xf86ConfigDRI
.mode
? xf86ConfigDRI
.mode
: DRM_DEV_MODE
;
290 devmode
&= ~(S_IXUSR
|S_IXGRP
|S_IXOTH
);
291 group
= (xf86ConfigDRI
.group
>= 0) ? xf86ConfigDRI
.group
: DRM_DEV_GID
;
294 if (stat(DRM_DIR_NAME
, &st
)) {
295 if (!isroot
) return DRM_ERR_NOT_ROOT
;
296 mkdir(DRM_DIR_NAME
, DRM_DEV_DIRMODE
);
297 chown(DRM_DIR_NAME
, 0, 0); /* root:root */
298 chmod(DRM_DIR_NAME
, DRM_DEV_DIRMODE
);
301 /* Check if the device node exists and create it if necessary. */
302 if (stat(buf
, &st
)) {
303 if (!isroot
) return DRM_ERR_NOT_ROOT
;
305 mknod(buf
, S_IFCHR
| devmode
, dev
);
307 #if defined(XFree86Server)
308 chown(buf
, user
, group
);
312 fd
= open(buf
, O_RDWR
, 0);
313 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
314 fd
, fd
< 0 ? strerror(errno
) : "OK");
315 if (fd
>= 0) return fd
;
317 /* Check if the device node is not what we expect it to be, and recreate it
318 * and try again if so.
320 if (st
.st_rdev
!= dev
) {
321 if (!isroot
) return DRM_ERR_NOT_ROOT
;
323 mknod(buf
, S_IFCHR
| devmode
, dev
);
324 #if defined(XFree86Server)
325 chown(buf
, user
, group
);
329 fd
= open(buf
, O_RDWR
, 0);
330 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
331 fd
, fd
< 0 ? strerror(errno
) : "OK");
332 if (fd
>= 0) return fd
;
334 drmMsg("drmOpenDevice: Open failed\n");
341 * Open the DRM device
343 * \param minor device minor number.
344 * \param create allow to create the device if set.
346 * \return a file descriptor on success, or a negative value on error.
349 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
350 * name from \p minor and opens it.
352 static int drmOpenMinor(int minor
, int create
)
357 if (create
) return drmOpenDevice(makedev(DRM_MAJOR
, minor
), minor
);
359 sprintf(buf
, DRM_DEV_NAME
, DRM_DIR_NAME
, minor
);
360 if ((fd
= open(buf
, O_RDWR
, 0)) >= 0) return fd
;
366 * Determine whether the DRM kernel driver has been loaded.
368 * \return 1 if the DRM driver is loaded, 0 otherwise.
371 * Determine the presence of the kernel driver by attempting to open the 0
372 * minor and get version information. For backward compatibility with older
373 * Linux implementations, /proc/dri is also checked.
375 int drmAvailable(void)
377 drmVersionPtr version
;
381 if ((fd
= drmOpenMinor(0, 1)) < 0) {
383 /* Try proc for backward Linux compatibility */
384 if (!access("/proc/dri/0", R_OK
)) return 1;
389 if ((version
= drmGetVersion(fd
))) {
391 drmFreeVersion(version
);
400 * Open the device by bus ID.
402 * \param busid bus ID.
404 * \return a file descriptor on success, or a negative value on error.
407 * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
408 * comparing the device bus ID with the one supplied.
410 * \sa drmOpenMinor() and drmGetBusid().
412 static int drmOpenByBusid(const char *busid
)
419 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid
);
420 for (i
= 0; i
< DRM_MAX_MINOR
; i
++) {
421 fd
= drmOpenMinor(i
, 1);
422 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd
);
426 sv
.drm_dd_major
= -1; /* Don't care */
427 drmSetInterfaceVersion(fd
, &sv
);
428 buf
= drmGetBusid(fd
);
429 drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf
);
430 if (buf
&& drmMatchBusID(buf
, busid
)) {
434 if (buf
) drmFreeBusid(buf
);
443 * Open the device by name.
445 * \param name driver name.
447 * \return a file descriptor on success, or a negative value on error.
450 * This function opens the first minor number that matches the driver name and
451 * isn't already in use. If it's in use it then it will already have a bus ID
454 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
456 static int drmOpenByName(const char *name
)
460 drmVersionPtr version
;
463 if (!drmAvailable()) {
464 #if !defined(XFree86Server)
467 /* try to load the kernel module now */
468 if (!xf86LoadKernelModule(name
)) {
469 ErrorF("[drm] failed to load kernel module \"%s\"\n",
477 * Open the first minor number that matches the driver name and isn't
478 * already in use. If it's in use it will have a busid assigned already.
480 for (i
= 0; i
< DRM_MAX_MINOR
; i
++) {
481 if ((fd
= drmOpenMinor(i
, 1)) >= 0) {
482 if ((version
= drmGetVersion(fd
))) {
483 if (!strcmp(version
->name
, name
)) {
484 drmFreeVersion(version
);
485 id
= drmGetBusid(fd
);
486 drmMsg("drmGetBusid returned '%s'\n", id
? id
: "NULL");
496 drmFreeVersion(version
);
504 /* Backward-compatibility /proc support */
505 for (i
= 0; i
< 8; i
++) {
506 char proc_name
[64], buf
[512];
507 char *driver
, *pt
, *devstring
;
510 sprintf(proc_name
, "/proc/dri/%d/name", i
);
511 if ((fd
= open(proc_name
, 0, 0)) >= 0) {
512 retcode
= read(fd
, buf
, sizeof(buf
)-1);
515 buf
[retcode
-1] = '\0';
516 for (driver
= pt
= buf
; *pt
&& *pt
!= ' '; ++pt
)
518 if (*pt
) { /* Device is next */
520 if (!strcmp(driver
, name
)) { /* Match */
521 for (devstring
= ++pt
; *pt
&& *pt
!= ' '; ++pt
)
523 if (*pt
) { /* Found busid */
524 return drmOpenByBusid(++pt
);
525 } else { /* No busid */
526 return drmOpenDevice(strtol(devstring
, NULL
, 0),i
);
540 * Open the DRM device.
542 * Looks up the specified name and bus ID, and opens the device found. The
543 * entry in /dev/dri is created if necessary and if called by root.
545 * \param name driver name. Not referenced if bus ID is supplied.
546 * \param busid bus ID. Zero if not known.
548 * \return a file descriptor on success, or a negative value on error.
551 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
554 int drmOpen(const char *name
, const char *busid
)
557 if (!drmAvailable() && name
!= NULL
) {
558 /* try to load the kernel */
559 if (!xf86LoadKernelModule(name
)) {
560 ErrorF("[drm] failed to load kernel module \"%s\"\n",
570 fd
= drmOpenByBusid(busid
);
575 return drmOpenByName(name
);
581 * Free the version information returned by drmGetVersion().
583 * \param v pointer to the version information.
586 * It frees the memory pointed by \p %v as well as all the non-null strings
589 void drmFreeVersion(drmVersionPtr v
)
592 if (v
->name
) drmFree(v
->name
);
593 if (v
->date
) drmFree(v
->date
);
594 if (v
->desc
) drmFree(v
->desc
);
600 * Free the non-public version information returned by the kernel.
602 * \param v pointer to the version information.
605 * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
606 * the non-null strings pointers in it.
608 static void drmFreeKernelVersion(drm_version_t
*v
)
611 if (v
->name
) drmFree(v
->name
);
612 if (v
->date
) drmFree(v
->date
);
613 if (v
->desc
) drmFree(v
->desc
);
619 * Copy version information.
621 * \param d destination pointer.
622 * \param s source pointer.
625 * Used by drmGetVersion() to translate the information returned by the ioctl
626 * interface in a private structure into the public structure counterpart.
628 static void drmCopyVersion(drmVersionPtr d
, const drm_version_t
*s
)
630 d
->version_major
= s
->version_major
;
631 d
->version_minor
= s
->version_minor
;
632 d
->version_patchlevel
= s
->version_patchlevel
;
633 d
->name_len
= s
->name_len
;
634 d
->name
= drmStrdup(s
->name
);
635 d
->date_len
= s
->date_len
;
636 d
->date
= drmStrdup(s
->date
);
637 d
->desc_len
= s
->desc_len
;
638 d
->desc
= drmStrdup(s
->desc
);
643 * Query the driver version information.
645 * \param fd file descriptor.
647 * \return pointer to a drmVersion structure which should be freed with
650 * \note Similar information is available via /proc/dri.
653 * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
654 * first with zeros to get the string lengths, and then the actually strings.
655 * It also null-terminates them since they might not be already.
657 drmVersionPtr
drmGetVersion(int fd
)
659 drmVersionPtr retval
;
660 drm_version_t
*version
= drmMalloc(sizeof(*version
));
662 /* First, get the lengths */
663 version
->name_len
= 0;
664 version
->name
= NULL
;
665 version
->date_len
= 0;
666 version
->date
= NULL
;
667 version
->desc_len
= 0;
668 version
->desc
= NULL
;
670 if (ioctl(fd
, DRM_IOCTL_VERSION
, version
)) {
671 drmFreeKernelVersion(version
);
675 /* Now, allocate space and get the data */
676 if (version
->name_len
)
677 version
->name
= drmMalloc(version
->name_len
+ 1);
678 if (version
->date_len
)
679 version
->date
= drmMalloc(version
->date_len
+ 1);
680 if (version
->desc_len
)
681 version
->desc
= drmMalloc(version
->desc_len
+ 1);
683 if (ioctl(fd
, DRM_IOCTL_VERSION
, version
)) {
684 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno
));
685 drmFreeKernelVersion(version
);
689 /* The results might not be null-terminated
690 strings, so terminate them. */
692 if (version
->name_len
) version
->name
[version
->name_len
] = '\0';
693 if (version
->date_len
) version
->date
[version
->date_len
] = '\0';
694 if (version
->desc_len
) version
->desc
[version
->desc_len
] = '\0';
696 /* Now, copy it all back into the
697 client-visible data structure... */
698 retval
= drmMalloc(sizeof(*retval
));
699 drmCopyVersion(retval
, version
);
700 drmFreeKernelVersion(version
);
706 * Get version information for the DRM user space library.
708 * This version number is driver independent.
710 * \param fd file descriptor.
712 * \return version information.
715 * This function allocates and fills a drm_version structure with a hard coded
718 drmVersionPtr
drmGetLibVersion(int fd
)
720 drm_version_t
*version
= drmMalloc(sizeof(*version
));
723 * revision 1.0.x = original DRM interface with no drmGetLibVersion
724 * entry point and many drm<Device> extensions
725 * revision 1.1.x = added drmCommand entry points for device extensions
726 * added drmGetLibVersion to identify libdrm.a version
727 * revision 1.2.x = added drmSetInterfaceVersion
728 * modified drmOpen to handle both busid and name
730 version
->version_major
= 1;
731 version
->version_minor
= 2;
732 version
->version_patchlevel
= 0;
734 return (drmVersionPtr
)version
;
739 * Free the bus ID information.
741 * \param busid bus ID information string as given by drmGetBusid().
744 * This function is just frees the memory pointed by \p busid.
746 void drmFreeBusid(const char *busid
)
748 drmFree((void *)busid
);
753 * Get the bus ID of the device.
755 * \param fd file descriptor.
757 * \return bus ID string.
760 * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
761 * get the string length and data, passing the arguments in a drm_unique
764 char *drmGetBusid(int fd
)
771 if (ioctl(fd
, DRM_IOCTL_GET_UNIQUE
, &u
)) return NULL
;
772 u
.unique
= drmMalloc(u
.unique_len
+ 1);
773 if (ioctl(fd
, DRM_IOCTL_GET_UNIQUE
, &u
)) return NULL
;
774 u
.unique
[u
.unique_len
] = '\0';
781 * Set the bus ID of the device.
783 * \param fd file descriptor.
784 * \param busid bus ID string.
786 * \return zero on success, negative on failure.
789 * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
790 * the arguments in a drm_unique structure.
792 int drmSetBusid(int fd
, const char *busid
)
796 u
.unique
= (char *)busid
;
797 u
.unique_len
= strlen(busid
);
799 if (ioctl(fd
, DRM_IOCTL_SET_UNIQUE
, &u
)) {
805 int drmGetMagic(int fd
, drm_magic_t
* magic
)
810 if (ioctl(fd
, DRM_IOCTL_GET_MAGIC
, &auth
)) return -errno
;
815 int drmAuthMagic(int fd
, drm_magic_t magic
)
820 if (ioctl(fd
, DRM_IOCTL_AUTH_MAGIC
, &auth
)) return -errno
;
825 * Specifies a range of memory that is available for mapping by a
828 * \param fd file descriptor.
829 * \param offset usually the physical address. The actual meaning depends of
830 * the \p type parameter. See below.
831 * \param size of the memory in bytes.
832 * \param type type of the memory to be mapped.
833 * \param flags combination of several flags to modify the function actions.
834 * \param handle will be set to a value that may be used as the offset
835 * parameter for mmap().
837 * \return zero on success or a negative value on error.
839 * \par Mapping the frame buffer
840 * For the frame buffer
841 * - \p offset will be the physical address of the start of the frame buffer,
842 * - \p size will be the size of the frame buffer in bytes, and
843 * - \p type will be DRM_FRAME_BUFFER.
846 * The area mapped will be uncached. If MTRR support is available in the
847 * kernel, the frame buffer area will be set to write combining.
849 * \par Mapping the MMIO register area
850 * For the MMIO register area,
851 * - \p offset will be the physical address of the start of the register area,
852 * - \p size will be the size of the register area bytes, and
853 * - \p type will be DRM_REGISTERS.
855 * The area mapped will be uncached.
857 * \par Mapping the SAREA
859 * - \p offset will be ignored and should be set to zero,
860 * - \p size will be the desired size of the SAREA in bytes,
861 * - \p type will be DRM_SHM.
864 * A shared memory area of the requested size will be created and locked in
865 * kernel memory. This area may be mapped into client-space by using the handle
868 * \note May only be called by root.
871 * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
872 * the arguments in a drm_map structure.
874 int drmAddMap(int fd
,
879 drm_handle_t
* handle
)
884 /* No longer needed with CVS kernel modules on alpha
887 map.offset += BUS_BASE;
894 if (ioctl(fd
, DRM_IOCTL_ADD_MAP
, &map
)) return -errno
;
895 if (handle
) *handle
= (drm_handle_t
)map
.handle
;
899 int drmRmMap(int fd
, drm_handle_t handle
)
903 map
.handle
= (void *)handle
;
905 if(ioctl(fd
, DRM_IOCTL_RM_MAP
, &map
)) return -errno
;
910 * Make buffers available for DMA transfers.
912 * \param fd file descriptor.
913 * \param count number of buffers.
914 * \param size size of each buffer.
915 * \param flags buffer allocation flags.
916 * \param agp_offset offset in the AGP aperture
918 * \return number of buffers allocated, negative on error.
921 * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
925 int drmAddBufs(int fd
, int count
, int size
, drmBufDescFlags flags
,
928 drm_buf_desc_t request
;
930 request
.count
= count
;
932 request
.low_mark
= 0;
933 request
.high_mark
= 0;
934 request
.flags
= flags
;
935 request
.agp_start
= agp_offset
;
937 if (ioctl(fd
, DRM_IOCTL_ADD_BUFS
, &request
)) return -errno
;
938 return request
.count
;
941 int drmMarkBufs(int fd
, double low
, double high
)
949 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) return -EINVAL
;
951 if (!info
.count
) return -EINVAL
;
953 if (!(info
.list
= drmMalloc(info
.count
* sizeof(*info
.list
))))
956 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) {
962 for (i
= 0; i
< info
.count
; i
++) {
963 info
.list
[i
].low_mark
= low
* info
.list
[i
].count
;
964 info
.list
[i
].high_mark
= high
* info
.list
[i
].count
;
965 if (ioctl(fd
, DRM_IOCTL_MARK_BUFS
, &info
.list
[i
])) {
979 * \param fd file descriptor.
980 * \param count number of buffers to free.
981 * \param list list of buffers to be freed.
983 * \return zero on success, or a negative value on failure.
985 * \note This function is primarily used for debugging.
988 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
989 * the arguments in a drm_buf_free structure.
991 int drmFreeBufs(int fd
, int count
, int *list
)
993 drm_buf_free_t request
;
995 request
.count
= count
;
997 if (ioctl(fd
, DRM_IOCTL_FREE_BUFS
, &request
)) return -errno
;
1005 * \param fd file descriptor.
1008 * This function closes the file descriptor.
1010 int drmClose(int fd
)
1012 unsigned long key
= drmGetKeyFromFd(fd
);
1013 drmHashEntry
*entry
= drmGetEntry(fd
);
1015 drmHashDestroy(entry
->tagTable
);
1018 entry
->tagTable
= NULL
;
1020 drmHashDelete(drmHashTable
, key
);
1028 * Map a region of memory.
1030 * \param fd file descriptor.
1031 * \param handle handle returned by drmAddMap().
1032 * \param size size in bytes. Must match the size used by drmAddMap().
1033 * \param address will contain the user-space virtual address where the mapping
1036 * \return zero on success, or a negative value on failure.
1039 * This function is a wrapper for mmap().
1042 drm_handle_t handle
,
1044 drmAddressPtr address
)
1046 static unsigned long pagesize_mask
= 0;
1048 if (fd
< 0) return -EINVAL
;
1051 pagesize_mask
= getpagesize() - 1;
1053 size
= (size
+ pagesize_mask
) & ~pagesize_mask
;
1055 *address
= mmap(0, size
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, handle
);
1056 if (*address
== MAP_FAILED
) return -errno
;
1062 * Unmap mappings obtained with drmMap().
1064 * \param address address as given by drmMap().
1065 * \param size size in bytes. Must match the size used by drmMap().
1067 * \return zero on success, or a negative value on failure.
1070 * This function is a wrapper for unmap().
1072 int drmUnmap(drmAddress address
, drmSize size
)
1074 return munmap(address
, size
);
1077 drmBufInfoPtr
drmGetBufInfo(int fd
)
1079 drm_buf_info_t info
;
1080 drmBufInfoPtr retval
;
1086 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) return NULL
;
1089 if (!(info
.list
= drmMalloc(info
.count
* sizeof(*info
.list
))))
1092 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) {
1096 /* Now, copy it all back into the
1097 client-visible data structure... */
1098 retval
= drmMalloc(sizeof(*retval
));
1099 retval
->count
= info
.count
;
1100 retval
->list
= drmMalloc(info
.count
* sizeof(*retval
->list
));
1101 for (i
= 0; i
< info
.count
; i
++) {
1102 retval
->list
[i
].count
= info
.list
[i
].count
;
1103 retval
->list
[i
].size
= info
.list
[i
].size
;
1104 retval
->list
[i
].low_mark
= info
.list
[i
].low_mark
;
1105 retval
->list
[i
].high_mark
= info
.list
[i
].high_mark
;
1114 * Map all DMA buffers into client-virtual space.
1116 * \param fd file descriptor.
1118 * \return a pointer to a ::drmBufMap structure.
1120 * \note The client may not use these buffers until obtaining buffer indices
1124 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1125 * information about the buffers in a drm_buf_map structure into the
1126 * client-visible data structures.
1128 drmBufMapPtr
drmMapBufs(int fd
)
1131 drmBufMapPtr retval
;
1136 bufs
.virtual = NULL
;
1137 if (ioctl(fd
, DRM_IOCTL_MAP_BUFS
, &bufs
)) return NULL
;
1139 if (!bufs
.count
) return NULL
;
1141 if (!(bufs
.list
= drmMalloc(bufs
.count
* sizeof(*bufs
.list
))))
1144 if (ioctl(fd
, DRM_IOCTL_MAP_BUFS
, &bufs
)) {
1148 /* Now, copy it all back into the
1149 client-visible data structure... */
1150 retval
= drmMalloc(sizeof(*retval
));
1151 retval
->count
= bufs
.count
;
1152 retval
->list
= drmMalloc(bufs
.count
* sizeof(*retval
->list
));
1153 for (i
= 0; i
< bufs
.count
; i
++) {
1154 retval
->list
[i
].idx
= bufs
.list
[i
].idx
;
1155 retval
->list
[i
].total
= bufs
.list
[i
].total
;
1156 retval
->list
[i
].used
= 0;
1157 retval
->list
[i
].address
= bufs
.list
[i
].address
;
1167 * Unmap buffers allocated with drmMapBufs().
1169 * \return zero on success, or negative value on failure.
1172 * Calls munmap() for every buffer stored in \p bufs and frees the
1173 * memory allocated by drmMapBufs().
1175 int drmUnmapBufs(drmBufMapPtr bufs
)
1179 for (i
= 0; i
< bufs
->count
; i
++) {
1180 munmap(bufs
->list
[i
].address
, bufs
->list
[i
].total
);
1183 drmFree(bufs
->list
);
1190 #define DRM_DMA_RETRY 16
1193 * Reserve DMA buffers.
1195 * \param fd file descriptor.
1198 * \return zero on success, or a negative value on failure.
1201 * Assemble the arguments into a drm_dma structure and keeps issuing the
1202 * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1204 int drmDMA(int fd
, drmDMAReqPtr request
)
1209 /* Copy to hidden structure */
1210 dma
.context
= request
->context
;
1211 dma
.send_count
= request
->send_count
;
1212 dma
.send_indices
= request
->send_list
;
1213 dma
.send_sizes
= request
->send_sizes
;
1214 dma
.flags
= request
->flags
;
1215 dma
.request_count
= request
->request_count
;
1216 dma
.request_size
= request
->request_size
;
1217 dma
.request_indices
= request
->request_list
;
1218 dma
.request_sizes
= request
->request_sizes
;
1219 dma
.granted_count
= 0;
1222 ret
= ioctl( fd
, DRM_IOCTL_DMA
, &dma
);
1223 } while ( ret
&& errno
== EAGAIN
&& i
++ < DRM_DMA_RETRY
);
1226 request
->granted_count
= dma
.granted_count
;
1235 * Obtain heavyweight hardware lock.
1237 * \param fd file descriptor.
1238 * \param context context.
1239 * \param flags flags that determine the sate of the hardware when the function
1242 * \return always zero.
1245 * This function translates the arguments into a drm_lock structure and issue
1246 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1248 int drmGetLock(int fd
, drm_context_t context
, drmLockFlags flags
)
1252 lock
.context
= context
;
1254 if (flags
& DRM_LOCK_READY
) lock
.flags
|= _DRM_LOCK_READY
;
1255 if (flags
& DRM_LOCK_QUIESCENT
) lock
.flags
|= _DRM_LOCK_QUIESCENT
;
1256 if (flags
& DRM_LOCK_FLUSH
) lock
.flags
|= _DRM_LOCK_FLUSH
;
1257 if (flags
& DRM_LOCK_FLUSH_ALL
) lock
.flags
|= _DRM_LOCK_FLUSH_ALL
;
1258 if (flags
& DRM_HALT_ALL_QUEUES
) lock
.flags
|= _DRM_HALT_ALL_QUEUES
;
1259 if (flags
& DRM_HALT_CUR_QUEUES
) lock
.flags
|= _DRM_HALT_CUR_QUEUES
;
1261 while (ioctl(fd
, DRM_IOCTL_LOCK
, &lock
))
1267 * Release the hardware lock.
1269 * \param fd file descriptor.
1270 * \param context context.
1272 * \return zero on success, or a negative value on failure.
1275 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1276 * argument in a drm_lock structure.
1278 int drmUnlock(int fd
, drm_context_t context
)
1282 lock
.context
= context
;
1284 return ioctl(fd
, DRM_IOCTL_UNLOCK
, &lock
);
1287 drm_context_t
* drmGetReservedContextList(int fd
, int *count
)
1291 drm_context_t
* retval
;
1295 res
.contexts
= NULL
;
1296 if (ioctl(fd
, DRM_IOCTL_RES_CTX
, &res
)) return NULL
;
1298 if (!res
.count
) return NULL
;
1300 if (!(list
= drmMalloc(res
.count
* sizeof(*list
)))) return NULL
;
1301 if (!(retval
= drmMalloc(res
.count
* sizeof(*retval
)))) {
1306 res
.contexts
= list
;
1307 if (ioctl(fd
, DRM_IOCTL_RES_CTX
, &res
)) return NULL
;
1309 for (i
= 0; i
< res
.count
; i
++) retval
[i
] = list
[i
].handle
;
1316 void drmFreeReservedContextList(drm_context_t
* pt
)
1324 * Used by the X server during GLXContext initialization. This causes
1325 * per-context kernel-level resources to be allocated.
1327 * \param fd file descriptor.
1328 * \param handle is set on success. To be used by the client when requesting DMA
1329 * dispatch with drmDMA().
1331 * \return zero on success, or a negative value on failure.
1333 * \note May only be called by root.
1336 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1337 * argument in a drm_ctx structure.
1339 int drmCreateContext(int fd
, drm_context_t
* handle
)
1343 ctx
.flags
= 0; /* Modified with functions below */
1344 if (ioctl(fd
, DRM_IOCTL_ADD_CTX
, &ctx
)) return -errno
;
1345 *handle
= ctx
.handle
;
1349 int drmSwitchToContext(int fd
, drm_context_t context
)
1353 ctx
.handle
= context
;
1354 if (ioctl(fd
, DRM_IOCTL_SWITCH_CTX
, &ctx
)) return -errno
;
1358 int drmSetContextFlags(int fd
, drm_context_t context
, drm_context_tFlags flags
)
1362 /* Context preserving means that no context
1363 switched are done between DMA buffers
1364 from one context and the next. This is
1365 suitable for use in the X server (which
1366 promises to maintain hardware context,
1367 or in the client-side library when
1368 buffers are swapped on behalf of two
1370 ctx
.handle
= context
;
1372 if (flags
& DRM_CONTEXT_PRESERVED
) ctx
.flags
|= _DRM_CONTEXT_PRESERVED
;
1373 if (flags
& DRM_CONTEXT_2DONLY
) ctx
.flags
|= _DRM_CONTEXT_2DONLY
;
1374 if (ioctl(fd
, DRM_IOCTL_MOD_CTX
, &ctx
)) return -errno
;
1378 int drmGetContextFlags(int fd
, drm_context_t context
, drm_context_tFlagsPtr flags
)
1382 ctx
.handle
= context
;
1383 if (ioctl(fd
, DRM_IOCTL_GET_CTX
, &ctx
)) return -errno
;
1385 if (ctx
.flags
& _DRM_CONTEXT_PRESERVED
) *flags
|= DRM_CONTEXT_PRESERVED
;
1386 if (ctx
.flags
& _DRM_CONTEXT_2DONLY
) *flags
|= DRM_CONTEXT_2DONLY
;
1393 * Free any kernel-level resources allocated with drmCreateContext() associated
1396 * \param fd file descriptor.
1397 * \param handle handle given by drmCreateContext().
1399 * \return zero on success, or a negative value on failure.
1401 * \note May only be called by root.
1404 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1405 * argument in a drm_ctx structure.
1407 int drmDestroyContext(int fd
, drm_context_t handle
)
1410 ctx
.handle
= handle
;
1411 if (ioctl(fd
, DRM_IOCTL_RM_CTX
, &ctx
)) return -errno
;
1415 int drmCreateDrawable(int fd
, drm_drawable_t
* handle
)
1418 if (ioctl(fd
, DRM_IOCTL_ADD_DRAW
, &draw
)) return -errno
;
1419 *handle
= draw
.handle
;
1423 int drmDestroyDrawable(int fd
, drm_drawable_t handle
)
1426 draw
.handle
= handle
;
1427 if (ioctl(fd
, DRM_IOCTL_RM_DRAW
, &draw
)) return -errno
;
1432 * Acquire the AGP device.
1434 * Must be called before any of the other AGP related calls.
1436 * \param fd file descriptor.
1438 * \return zero on success, or a negative value on failure.
1441 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1443 int drmAgpAcquire(int fd
)
1445 if (ioctl(fd
, DRM_IOCTL_AGP_ACQUIRE
, NULL
)) return -errno
;
1451 * Release the AGP device.
1453 * \param fd file descriptor.
1455 * \return zero on success, or a negative value on failure.
1458 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1460 int drmAgpRelease(int fd
)
1462 if (ioctl(fd
, DRM_IOCTL_AGP_RELEASE
, NULL
)) return -errno
;
1470 * \param fd file descriptor.
1471 * \param mode AGP mode.
1473 * \return zero on success, or a negative value on failure.
1476 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1477 * argument in a drm_agp_mode structure.
1479 int drmAgpEnable(int fd
, unsigned long mode
)
1484 if (ioctl(fd
, DRM_IOCTL_AGP_ENABLE
, &m
)) return -errno
;
1490 * Allocate a chunk of AGP memory.
1492 * \param fd file descriptor.
1493 * \param size requested memory size in bytes. Will be rounded to page boundary.
1494 * \param type type of memory to allocate.
1495 * \param address if not zero, will be set to the physical address of the
1497 * \param handle on success will be set to a handle of the allocated memory.
1499 * \return zero on success, or a negative value on failure.
1502 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1503 * arguments in a drm_agp_buffer structure.
1505 int drmAgpAlloc(int fd
, unsigned long size
, unsigned long type
,
1506 unsigned long *address
, unsigned long *handle
)
1510 *handle
= DRM_AGP_NO_HANDLE
;
1514 if (ioctl(fd
, DRM_IOCTL_AGP_ALLOC
, &b
)) return -errno
;
1515 if (address
!= 0UL) *address
= b
.physical
;
1522 * Free a chunk of AGP memory.
1524 * \param fd file descriptor.
1525 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1527 * \return zero on success, or a negative value on failure.
1530 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1531 * argument in a drm_agp_buffer structure.
1533 int drmAgpFree(int fd
, unsigned long handle
)
1539 if (ioctl(fd
, DRM_IOCTL_AGP_FREE
, &b
)) return -errno
;
1545 * Bind a chunk of AGP memory.
1547 * \param fd file descriptor.
1548 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1549 * \param offset offset in bytes. It will round to page boundary.
1551 * \return zero on success, or a negative value on failure.
1554 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1555 * argument in a drm_agp_binding structure.
1557 int drmAgpBind(int fd
, unsigned long handle
, unsigned long offset
)
1559 drm_agp_binding_t b
;
1563 if (ioctl(fd
, DRM_IOCTL_AGP_BIND
, &b
)) return -errno
;
1569 * Unbind a chunk of AGP memory.
1571 * \param fd file descriptor.
1572 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1574 * \return zero on success, or a negative value on failure.
1577 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1578 * the argument in a drm_agp_binding structure.
1580 int drmAgpUnbind(int fd
, unsigned long handle
)
1582 drm_agp_binding_t b
;
1586 if (ioctl(fd
, DRM_IOCTL_AGP_UNBIND
, &b
)) return -errno
;
1592 * Get AGP driver major version number.
1594 * \param fd file descriptor.
1596 * \return major version number on success, or a negative value on failure..
1599 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1600 * necessary information in a drm_agp_info structure.
1602 int drmAgpVersionMajor(int fd
)
1606 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return -errno
;
1607 return i
.agp_version_major
;
1612 * Get AGP driver minor version number.
1614 * \param fd file descriptor.
1616 * \return minor version number on success, or a negative value on failure.
1619 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1620 * necessary information in a drm_agp_info structure.
1622 int drmAgpVersionMinor(int fd
)
1626 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return -errno
;
1627 return i
.agp_version_minor
;
1634 * \param fd file descriptor.
1636 * \return mode on success, or zero on failure.
1639 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1640 * necessary information in a drm_agp_info structure.
1642 unsigned long drmAgpGetMode(int fd
)
1646 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1652 * Get AGP aperture base.
1654 * \param fd file descriptor.
1656 * \return aperture base on success, zero on failure.
1659 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1660 * necessary information in a drm_agp_info structure.
1662 unsigned long drmAgpBase(int fd
)
1666 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1667 return i
.aperture_base
;
1672 * Get AGP aperture size.
1674 * \param fd file descriptor.
1676 * \return aperture size on success, zero on failure.
1679 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1680 * necessary information in a drm_agp_info structure.
1682 unsigned long drmAgpSize(int fd
)
1686 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1687 return i
.aperture_size
;
1692 * Get used AGP memory.
1694 * \param fd file descriptor.
1696 * \return memory used on success, or zero on failure.
1699 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1700 * necessary information in a drm_agp_info structure.
1702 unsigned long drmAgpMemoryUsed(int fd
)
1706 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1707 return i
.memory_used
;
1712 * Get available AGP memory.
1714 * \param fd file descriptor.
1716 * \return memory available on success, or zero on failure.
1719 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1720 * necessary information in a drm_agp_info structure.
1722 unsigned long drmAgpMemoryAvail(int fd
)
1726 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1727 return i
.memory_allowed
;
1732 * Get hardware vendor ID.
1734 * \param fd file descriptor.
1736 * \return vendor ID on success, or zero on failure.
1739 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1740 * necessary information in a drm_agp_info structure.
1742 unsigned int drmAgpVendorId(int fd
)
1746 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1752 * Get hardware device ID.
1754 * \param fd file descriptor.
1756 * \return zero on success, or zero on failure.
1759 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1760 * necessary information in a drm_agp_info structure.
1762 unsigned int drmAgpDeviceId(int fd
)
1766 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1770 int drmScatterGatherAlloc(int fd
, unsigned long size
, unsigned long *handle
)
1772 drm_scatter_gather_t sg
;
1777 if (ioctl(fd
, DRM_IOCTL_SG_ALLOC
, &sg
)) return -errno
;
1778 *handle
= sg
.handle
;
1782 int drmScatterGatherFree(int fd
, unsigned long handle
)
1784 drm_scatter_gather_t sg
;
1788 if (ioctl(fd
, DRM_IOCTL_SG_FREE
, &sg
)) return -errno
;
1795 * \param fd file descriptor.
1796 * \param vbl pointer to a drmVBlank structure.
1798 * \return zero on success, or a negative value on failure.
1801 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
1803 int drmWaitVBlank(int fd
, drmVBlankPtr vbl
)
1808 ret
= ioctl(fd
, DRM_IOCTL_WAIT_VBLANK
, vbl
);
1809 vbl
->request
.type
&= ~DRM_VBLANK_RELATIVE
;
1810 } while (ret
&& errno
== EINTR
);
1815 int drmError(int err
, const char *label
)
1818 case DRM_ERR_NO_DEVICE
: fprintf(stderr
, "%s: no device\n", label
); break;
1819 case DRM_ERR_NO_ACCESS
: fprintf(stderr
, "%s: no access\n", label
); break;
1820 case DRM_ERR_NOT_ROOT
: fprintf(stderr
, "%s: not root\n", label
); break;
1821 case DRM_ERR_INVALID
: fprintf(stderr
, "%s: invalid args\n", label
);break;
1823 if (err
< 0) err
= -err
;
1824 fprintf( stderr
, "%s: error %d (%s)\n", label
, err
, strerror(err
) );
1832 * Install IRQ handler.
1834 * \param fd file descriptor.
1835 * \param irq IRQ number.
1837 * \return zero on success, or a negative value on failure.
1840 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1841 * argument in a drm_control structure.
1843 int drmCtlInstHandler(int fd
, int irq
)
1847 ctl
.func
= DRM_INST_HANDLER
;
1849 if (ioctl(fd
, DRM_IOCTL_CONTROL
, &ctl
)) return -errno
;
1855 * Uninstall IRQ handler.
1857 * \param fd file descriptor.
1859 * \return zero on success, or a negative value on failure.
1862 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1863 * argument in a drm_control structure.
1865 int drmCtlUninstHandler(int fd
)
1869 ctl
.func
= DRM_UNINST_HANDLER
;
1871 if (ioctl(fd
, DRM_IOCTL_CONTROL
, &ctl
)) return -errno
;
1875 int drmFinish(int fd
, int context
, drmLockFlags flags
)
1879 lock
.context
= context
;
1881 if (flags
& DRM_LOCK_READY
) lock
.flags
|= _DRM_LOCK_READY
;
1882 if (flags
& DRM_LOCK_QUIESCENT
) lock
.flags
|= _DRM_LOCK_QUIESCENT
;
1883 if (flags
& DRM_LOCK_FLUSH
) lock
.flags
|= _DRM_LOCK_FLUSH
;
1884 if (flags
& DRM_LOCK_FLUSH_ALL
) lock
.flags
|= _DRM_LOCK_FLUSH_ALL
;
1885 if (flags
& DRM_HALT_ALL_QUEUES
) lock
.flags
|= _DRM_HALT_ALL_QUEUES
;
1886 if (flags
& DRM_HALT_CUR_QUEUES
) lock
.flags
|= _DRM_HALT_CUR_QUEUES
;
1887 if (ioctl(fd
, DRM_IOCTL_FINISH
, &lock
)) return -errno
;
1892 * Get IRQ from bus ID.
1894 * \param fd file descriptor.
1895 * \param busnum bus number.
1896 * \param devnum device number.
1897 * \param funcnum function number.
1899 * \return IRQ number on success, or a negative value on failure.
1902 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
1903 * arguments in a drm_irq_busid structure.
1905 int drmGetInterruptFromBusID(int fd
, int busnum
, int devnum
, int funcnum
)
1911 p
.funcnum
= funcnum
;
1912 if (ioctl(fd
, DRM_IOCTL_IRQ_BUSID
, &p
)) return -errno
;
1916 int drmAddContextTag(int fd
, drm_context_t context
, void *tag
)
1918 drmHashEntry
*entry
= drmGetEntry(fd
);
1920 if (drmHashInsert(entry
->tagTable
, context
, tag
)) {
1921 drmHashDelete(entry
->tagTable
, context
);
1922 drmHashInsert(entry
->tagTable
, context
, tag
);
1927 int drmDelContextTag(int fd
, drm_context_t context
)
1929 drmHashEntry
*entry
= drmGetEntry(fd
);
1931 return drmHashDelete(entry
->tagTable
, context
);
1934 void *drmGetContextTag(int fd
, drm_context_t context
)
1936 drmHashEntry
*entry
= drmGetEntry(fd
);
1939 if (drmHashLookup(entry
->tagTable
, context
, &value
)) return NULL
;
1944 int drmAddContextPrivateMapping(int fd
, drm_context_t ctx_id
, drm_handle_t handle
)
1946 drm_ctx_priv_map_t map
;
1948 map
.ctx_id
= ctx_id
;
1949 map
.handle
= (void *)handle
;
1951 if (ioctl(fd
, DRM_IOCTL_SET_SAREA_CTX
, &map
)) return -errno
;
1955 int drmGetContextPrivateMapping(int fd
, drm_context_t ctx_id
, drm_handle_t
* handle
)
1957 drm_ctx_priv_map_t map
;
1959 map
.ctx_id
= ctx_id
;
1961 if (ioctl(fd
, DRM_IOCTL_GET_SAREA_CTX
, &map
)) return -errno
;
1962 if (handle
) *handle
= (drm_handle_t
)map
.handle
;
1967 int drmGetMap(int fd
, int idx
, drm_handle_t
*offset
, drmSize
*size
,
1968 drmMapType
*type
, drmMapFlags
*flags
, drm_handle_t
*handle
,
1974 if (ioctl(fd
, DRM_IOCTL_GET_MAP
, &map
)) return -errno
;
1975 *offset
= map
.offset
;
1979 *handle
= (unsigned long)map
.handle
;
1984 int drmGetClient(int fd
, int idx
, int *auth
, int *pid
, int *uid
,
1985 unsigned long *magic
, unsigned long *iocs
)
1987 drm_client_t client
;
1990 if (ioctl(fd
, DRM_IOCTL_GET_CLIENT
, &client
)) return -errno
;
1991 *auth
= client
.auth
;
1994 *magic
= client
.magic
;
1995 *iocs
= client
.iocs
;
1999 int drmGetStats(int fd
, drmStatsT
*stats
)
2004 if (ioctl(fd
, DRM_IOCTL_GET_STATS
, &s
)) return -errno
;
2007 memset(stats
, 0, sizeof(*stats
));
2008 if (s
.count
> sizeof(stats
->data
)/sizeof(stats
->data
[0]))
2012 stats->data[i].long_format = "%-20.20s"; \
2013 stats->data[i].rate_format = "%8.8s"; \
2014 stats->data[i].isvalue = 1; \
2015 stats->data[i].verbose = 0
2018 stats->data[i].long_format = "%-20.20s"; \
2019 stats->data[i].rate_format = "%5.5s"; \
2020 stats->data[i].isvalue = 0; \
2021 stats->data[i].mult_names = "kgm"; \
2022 stats->data[i].mult = 1000; \
2023 stats->data[i].verbose = 0
2026 stats->data[i].long_format = "%-20.20s"; \
2027 stats->data[i].rate_format = "%5.5s"; \
2028 stats->data[i].isvalue = 0; \
2029 stats->data[i].mult_names = "KGM"; \
2030 stats->data[i].mult = 1024; \
2031 stats->data[i].verbose = 0
2034 stats
->count
= s
.count
;
2035 for (i
= 0; i
< s
.count
; i
++) {
2036 stats
->data
[i
].value
= s
.data
[i
].value
;
2037 switch (s
.data
[i
].type
) {
2038 case _DRM_STAT_LOCK
:
2039 stats
->data
[i
].long_name
= "Lock";
2040 stats
->data
[i
].rate_name
= "Lock";
2043 case _DRM_STAT_OPENS
:
2044 stats
->data
[i
].long_name
= "Opens";
2045 stats
->data
[i
].rate_name
= "O";
2047 stats
->data
[i
].verbose
= 1;
2049 case _DRM_STAT_CLOSES
:
2050 stats
->data
[i
].long_name
= "Closes";
2051 stats
->data
[i
].rate_name
= "Lock";
2053 stats
->data
[i
].verbose
= 1;
2055 case _DRM_STAT_IOCTLS
:
2056 stats
->data
[i
].long_name
= "Ioctls";
2057 stats
->data
[i
].rate_name
= "Ioc/s";
2060 case _DRM_STAT_LOCKS
:
2061 stats
->data
[i
].long_name
= "Locks";
2062 stats
->data
[i
].rate_name
= "Lck/s";
2065 case _DRM_STAT_UNLOCKS
:
2066 stats
->data
[i
].long_name
= "Unlocks";
2067 stats
->data
[i
].rate_name
= "Unl/s";
2071 stats
->data
[i
].long_name
= "IRQs";
2072 stats
->data
[i
].rate_name
= "IRQ/s";
2075 case _DRM_STAT_PRIMARY
:
2076 stats
->data
[i
].long_name
= "Primary Bytes";
2077 stats
->data
[i
].rate_name
= "PB/s";
2080 case _DRM_STAT_SECONDARY
:
2081 stats
->data
[i
].long_name
= "Secondary Bytes";
2082 stats
->data
[i
].rate_name
= "SB/s";
2086 stats
->data
[i
].long_name
= "DMA";
2087 stats
->data
[i
].rate_name
= "DMA/s";
2090 case _DRM_STAT_SPECIAL
:
2091 stats
->data
[i
].long_name
= "Special DMA";
2092 stats
->data
[i
].rate_name
= "dma/s";
2095 case _DRM_STAT_MISSED
:
2096 stats
->data
[i
].long_name
= "Miss";
2097 stats
->data
[i
].rate_name
= "Ms/s";
2100 case _DRM_STAT_VALUE
:
2101 stats
->data
[i
].long_name
= "Value";
2102 stats
->data
[i
].rate_name
= "Value";
2105 case _DRM_STAT_BYTE
:
2106 stats
->data
[i
].long_name
= "Bytes";
2107 stats
->data
[i
].rate_name
= "B/s";
2110 case _DRM_STAT_COUNT
:
2112 stats
->data
[i
].long_name
= "Count";
2113 stats
->data
[i
].rate_name
= "Cnt/s";
2122 * Issue a set-version ioctl.
2124 * \param fd file descriptor.
2125 * \param drmCommandIndex command index
2126 * \param data source pointer of the data to be read and written.
2127 * \param size size of the data to be read and written.
2129 * \return zero on success, or a negative value on failure.
2132 * It issues a read-write ioctl given by
2133 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2135 int drmSetInterfaceVersion(int fd
, drmSetVersion
*version
)
2138 drm_set_version_t sv
;
2140 sv
.drm_di_major
= version
->drm_di_major
;
2141 sv
.drm_di_minor
= version
->drm_di_minor
;
2142 sv
.drm_dd_major
= version
->drm_dd_major
;
2143 sv
.drm_dd_minor
= version
->drm_dd_minor
;
2145 if (ioctl(fd
, DRM_IOCTL_SET_VERSION
, &sv
)) {
2149 version
->drm_di_major
= sv
.drm_di_major
;
2150 version
->drm_di_minor
= sv
.drm_di_minor
;
2151 version
->drm_dd_major
= sv
.drm_dd_major
;
2152 version
->drm_dd_minor
= sv
.drm_dd_minor
;
2158 * Send a device-specific command.
2160 * \param fd file descriptor.
2161 * \param drmCommandIndex command index
2163 * \return zero on success, or a negative value on failure.
2166 * It issues a ioctl given by
2167 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2169 int drmCommandNone(int fd
, unsigned long drmCommandIndex
)
2171 void *data
= NULL
; /* dummy */
2172 unsigned long request
;
2174 request
= DRM_IO( DRM_COMMAND_BASE
+ drmCommandIndex
);
2176 if (ioctl(fd
, request
, data
)) {
2184 * Send a device-specific read command.
2186 * \param fd file descriptor.
2187 * \param drmCommandIndex command index
2188 * \param data destination pointer of the data to be read.
2189 * \param size size of the data to be read.
2191 * \return zero on success, or a negative value on failure.
2194 * It issues a read ioctl given by
2195 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2197 int drmCommandRead(int fd
, unsigned long drmCommandIndex
,
2198 void *data
, unsigned long size
)
2200 unsigned long request
;
2202 request
= DRM_IOC( DRM_IOC_READ
, DRM_IOCTL_BASE
,
2203 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2205 if (ioctl(fd
, request
, data
)) {
2213 * Send a device-specific write command.
2215 * \param fd file descriptor.
2216 * \param drmCommandIndex command index
2217 * \param data source pointer of the data to be written.
2218 * \param size size of the data to be written.
2220 * \return zero on success, or a negative value on failure.
2223 * It issues a write ioctl given by
2224 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2226 int drmCommandWrite(int fd
, unsigned long drmCommandIndex
,
2227 void *data
, unsigned long size
)
2229 unsigned long request
;
2231 request
= DRM_IOC( DRM_IOC_WRITE
, DRM_IOCTL_BASE
,
2232 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2234 if (ioctl(fd
, request
, data
)) {
2242 * Send a device-specific read-write command.
2244 * \param fd file descriptor.
2245 * \param drmCommandIndex command index
2246 * \param data source pointer of the data to be read and written.
2247 * \param size size of the data to be read and written.
2249 * \return zero on success, or a negative value on failure.
2252 * It issues a read-write ioctl given by
2253 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2255 int drmCommandWriteRead(int fd
, unsigned long drmCommandIndex
,
2256 void *data
, unsigned long size
)
2258 unsigned long request
;
2260 request
= DRM_IOC( DRM_IOC_READ
|DRM_IOC_WRITE
, DRM_IOCTL_BASE
,
2261 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2263 if (ioctl(fd
, request
, data
)) {
2269 #if defined(XFree86Server)
2270 static void drmSIGIOHandler(int interrupt
, void *closure
)
2276 typedef void (*_drmCallback
)(int, void *, void *);
2283 drmHashEntry
*entry
;
2285 if (!drmHashTable
) return;
2286 if (drmHashFirst(drmHashTable
, &key
, &value
)) {
2290 fprintf(stderr
, "Trying %d\n", entry
->fd
);
2292 if ((count
= read(entry
->fd
, buf
, sizeof(buf
))) > 0) {
2295 fprintf(stderr
, "Got %s\n", buf
);
2298 for (pt
= buf
; *pt
!= ' '; ++pt
); /* Find first space */
2300 old
= strtol(pt
, &pt
, 0);
2301 new = strtol(pt
, NULL
, 0);
2302 oldctx
= drmGetContextTag(entry
->fd
, old
);
2303 newctx
= drmGetContextTag(entry
->fd
, new);
2305 fprintf(stderr
, "%d %d %p %p\n", old
, new, oldctx
, newctx
);
2307 ((_drmCallback
)entry
->f
)(entry
->fd
, oldctx
, newctx
);
2309 ioctl(entry
->fd
, DRM_IOCTL_NEW_CTX
, &ctx
);
2311 } while (drmHashNext(drmHashTable
, &key
, &value
));
2315 int drmInstallSIGIOHandler(int fd
, void (*f
)(int, void *, void *))
2317 drmHashEntry
*entry
;
2319 entry
= drmGetEntry(fd
);
2322 return xf86InstallSIGIOHandler(fd
, drmSIGIOHandler
, 0);
2325 int drmRemoveSIGIOHandler(int fd
)
2327 drmHashEntry
*entry
= drmGetEntry(fd
);
2331 return xf86RemoveSIGIOHandler(fd
);