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
65 extern int xf86InstallSIGIOHandler(int fd
, void (*f
)(int, void *), void *);
66 extern int xf86RemoveSIGIOHandler(int fd
);
68 # include <X11/Xlibint.h>
69 # define _DRM_MALLOC Xmalloc
70 # define _DRM_FREE Xfree
75 /* No longer needed with CVS kernel modules on alpha
76 #if defined(__alpha__) && defined(__linux__)
77 extern unsigned long _bus_base(void);
78 #define BUS_BASE _bus_base()
82 /* Not all systems have MAP_FAILED defined */
84 #define MAP_FAILED ((void *)-1)
102 #define DRM_MAJOR 226 /* Linux */
105 #ifndef DRM_MAX_MINOR
106 #define DRM_MAX_MINOR 16
110 #include <sys/sysmacros.h> /* for makedev() */
114 /* This definition needs to be changed on
115 some systems if dev_t is a structure.
116 If there is a header file we can get it
117 from, there would be best. */
118 #define makedev(x,y) ((dev_t)(((x) << 8) | (y)))
121 #define DRM_MSG_VERBOSITY 3
124 * Output a message to stderr.
126 * \param format printf() like format string.
129 * This function is a wrapper around vfprintf().
132 drmMsg(const char *format
, ...)
136 #ifndef XFree86Server
138 if ((env
= getenv("LIBGL_DEBUG")) && strstr(env
, "verbose"))
141 va_start(ap
, format
);
143 xf86VDrvMsgVerb(-1, X_NONE
, DRM_MSG_VERBOSITY
, format
, ap
);
145 vfprintf(stderr
, format
, ap
);
151 static void *drmHashTable
= NULL
; /* Context switch callbacks */
153 typedef struct drmHashEntry
{
155 void (*f
)(int, void *, void *);
159 void *drmMalloc(int size
)
162 if ((pt
= _DRM_MALLOC(size
))) memset(pt
, 0, size
);
166 void drmFree(void *pt
)
168 if (pt
) _DRM_FREE(pt
);
171 /* drmStrdup can't use strdup(3), since it doesn't call _DRM_MALLOC... */
172 static char *drmStrdup(const char *s
)
177 retval
= _DRM_MALLOC(strlen(s
)+1);
184 static unsigned long drmGetKeyFromFd(int fd
)
193 static drmHashEntry
*drmGetEntry(int fd
)
195 unsigned long key
= drmGetKeyFromFd(fd
);
199 if (!drmHashTable
) drmHashTable
= drmHashCreate();
201 if (drmHashLookup(drmHashTable
, key
, &value
)) {
202 entry
= drmMalloc(sizeof(*entry
));
205 entry
->tagTable
= drmHashCreate();
206 drmHashInsert(drmHashTable
, key
, entry
);
214 * Compare two busid strings
219 * \return 1 if matched.
222 * This function compares two bus ID strings. It understands the older
223 * PCI:b:d:f format and the newer pci:oooo:bb:dd.f format. In the format, o is
224 * domain, b is bus, d is device, f is function.
226 static int drmMatchBusID(const char *id1
, const char *id2
)
228 /* First, check if the IDs are exactly the same */
229 if (strcasecmp(id1
, id2
) == 0)
232 /* Try to match old/new-style PCI bus IDs. */
233 if (strncasecmp(id1
, "pci", 3) == 0) {
238 ret
= sscanf(id1
, "pci:%04x:%02x:%02x.%d", &o1
, &b1
, &d1
, &f1
);
241 ret
= sscanf(id1
, "PCI:%d:%d:%d", &b1
, &d1
, &f1
);
246 ret
= sscanf(id2
, "pci:%04x:%02x:%02x.%d", &o2
, &b2
, &d2
, &f2
);
249 ret
= sscanf(id2
, "PCI:%d:%d:%d", &b2
, &d2
, &f2
);
254 if ((o1
!= o2
) || (b1
!= b2
) || (d1
!= d2
) || (f1
!= f2
))
263 * Open the DRM device, creating it if necessary.
265 * \param dev major and minor numbers of the device.
266 * \param minor minor number of the device.
268 * \return a file descriptor on success, or a negative value on error.
271 * Assembles the device name from \p minor and opens it, creating the device
272 * special file node with the major and minor numbers specified by \p dev and
273 * parent directory if necessary and was called by root.
275 static int drmOpenDevice(long dev
, int minor
)
280 mode_t devmode
= DRM_DEV_MODE
;
281 int isroot
= !geteuid();
282 #if defined(XFree86Server)
283 uid_t user
= DRM_DEV_UID
;
284 gid_t group
= DRM_DEV_GID
;
287 sprintf(buf
, DRM_DEV_NAME
, DRM_DIR_NAME
, minor
);
288 drmMsg("drmOpenDevice: node name is %s\n", buf
);
290 #if defined(XFree86Server)
291 devmode
= xf86ConfigDRI
.mode
? xf86ConfigDRI
.mode
: DRM_DEV_MODE
;
292 devmode
&= ~(S_IXUSR
|S_IXGRP
|S_IXOTH
);
293 group
= (xf86ConfigDRI
.group
>= 0) ? xf86ConfigDRI
.group
: DRM_DEV_GID
;
296 if (stat(DRM_DIR_NAME
, &st
)) {
297 if (!isroot
) return DRM_ERR_NOT_ROOT
;
298 mkdir(DRM_DIR_NAME
, DRM_DEV_DIRMODE
);
299 chown(DRM_DIR_NAME
, 0, 0); /* root:root */
300 chmod(DRM_DIR_NAME
, DRM_DEV_DIRMODE
);
303 /* Check if the device node exists and create it if necessary. */
304 if (stat(buf
, &st
)) {
305 if (!isroot
) return DRM_ERR_NOT_ROOT
;
307 mknod(buf
, S_IFCHR
| devmode
, dev
);
309 #if defined(XFree86Server)
310 chown(buf
, user
, group
);
314 fd
= open(buf
, O_RDWR
, 0);
315 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
316 fd
, fd
< 0 ? strerror(errno
) : "OK");
317 if (fd
>= 0) return fd
;
319 /* Check if the device node is not what we expect it to be, and recreate it
320 * and try again if so.
322 if (st
.st_rdev
!= dev
) {
323 if (!isroot
) return DRM_ERR_NOT_ROOT
;
325 mknod(buf
, S_IFCHR
| devmode
, dev
);
326 #if defined(XFree86Server)
327 chown(buf
, user
, group
);
331 fd
= open(buf
, O_RDWR
, 0);
332 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
333 fd
, fd
< 0 ? strerror(errno
) : "OK");
334 if (fd
>= 0) return fd
;
336 drmMsg("drmOpenDevice: Open failed\n");
343 * Open the DRM device
345 * \param minor device minor number.
346 * \param create allow to create the device if set.
348 * \return a file descriptor on success, or a negative value on error.
351 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
352 * name from \p minor and opens it.
354 static int drmOpenMinor(int minor
, int create
)
359 if (create
) return drmOpenDevice(makedev(DRM_MAJOR
, minor
), minor
);
361 sprintf(buf
, DRM_DEV_NAME
, DRM_DIR_NAME
, minor
);
362 if ((fd
= open(buf
, O_RDWR
, 0)) >= 0) return fd
;
368 * Determine whether the DRM kernel driver has been loaded.
370 * \return 1 if the DRM driver is loaded, 0 otherwise.
373 * Determine the presence of the kernel driver by attempting to open the 0
374 * minor and get version information. For backward compatibility with older
375 * Linux implementations, /proc/dri is also checked.
377 int drmAvailable(void)
379 drmVersionPtr version
;
383 if ((fd
= drmOpenMinor(0, 1)) < 0) {
385 /* Try proc for backward Linux compatibility */
386 if (!access("/proc/dri/0", R_OK
)) return 1;
391 if ((version
= drmGetVersion(fd
))) {
393 drmFreeVersion(version
);
402 * Open the device by bus ID.
404 * \param busid bus ID.
406 * \return a file descriptor on success, or a negative value on error.
409 * This function attempts to open every possible minor (up to DRM_MAX_MINOR),
410 * comparing the device bus ID with the one supplied.
412 * \sa drmOpenMinor() and drmGetBusid().
414 static int drmOpenByBusid(const char *busid
)
421 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid
);
422 for (i
= 0; i
< DRM_MAX_MINOR
; i
++) {
423 fd
= drmOpenMinor(i
, 1);
424 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd
);
428 sv
.drm_dd_major
= -1; /* Don't care */
429 drmSetInterfaceVersion(fd
, &sv
);
430 buf
= drmGetBusid(fd
);
431 drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf
);
432 if (buf
&& drmMatchBusID(buf
, busid
)) {
436 if (buf
) drmFreeBusid(buf
);
445 * Open the device by name.
447 * \param name driver name.
449 * \return a file descriptor on success, or a negative value on error.
452 * This function opens the first minor number that matches the driver name and
453 * isn't already in use. If it's in use it then it will already have a bus ID
456 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
458 static int drmOpenByName(const char *name
)
462 drmVersionPtr version
;
465 if (!drmAvailable()) {
466 #if !defined(XFree86Server)
469 /* try to load the kernel module now */
470 if (!xf86LoadKernelModule(name
)) {
471 ErrorF("[drm] failed to load kernel module \"%s\"\n",
479 * Open the first minor number that matches the driver name and isn't
480 * already in use. If it's in use it will have a busid assigned already.
482 for (i
= 0; i
< DRM_MAX_MINOR
; i
++) {
483 if ((fd
= drmOpenMinor(i
, 1)) >= 0) {
484 if ((version
= drmGetVersion(fd
))) {
485 if (!strcmp(version
->name
, name
)) {
486 drmFreeVersion(version
);
487 id
= drmGetBusid(fd
);
488 drmMsg("drmGetBusid returned '%s'\n", id
? id
: "NULL");
498 drmFreeVersion(version
);
506 /* Backward-compatibility /proc support */
507 for (i
= 0; i
< 8; i
++) {
508 char proc_name
[64], buf
[512];
509 char *driver
, *pt
, *devstring
;
512 sprintf(proc_name
, "/proc/dri/%d/name", i
);
513 if ((fd
= open(proc_name
, 0, 0)) >= 0) {
514 retcode
= read(fd
, buf
, sizeof(buf
)-1);
517 buf
[retcode
-1] = '\0';
518 for (driver
= pt
= buf
; *pt
&& *pt
!= ' '; ++pt
)
520 if (*pt
) { /* Device is next */
522 if (!strcmp(driver
, name
)) { /* Match */
523 for (devstring
= ++pt
; *pt
&& *pt
!= ' '; ++pt
)
525 if (*pt
) { /* Found busid */
526 return drmOpenByBusid(++pt
);
527 } else { /* No busid */
528 return drmOpenDevice(strtol(devstring
, NULL
, 0),i
);
542 * Open the DRM device.
544 * Looks up the specified name and bus ID, and opens the device found. The
545 * entry in /dev/dri is created if necessary and if called by root.
547 * \param name driver name. Not referenced if bus ID is supplied.
548 * \param busid bus ID. Zero if not known.
550 * \return a file descriptor on success, or a negative value on error.
553 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
556 int drmOpen(const char *name
, const char *busid
)
559 if (!drmAvailable() && name
!= NULL
) {
560 /* try to load the kernel */
561 if (!xf86LoadKernelModule(name
)) {
562 ErrorF("[drm] failed to load kernel module \"%s\"\n",
572 fd
= drmOpenByBusid(busid
);
577 return drmOpenByName(name
);
583 * Free the version information returned by drmGetVersion().
585 * \param v pointer to the version information.
588 * It frees the memory pointed by \p %v as well as all the non-null strings
591 void drmFreeVersion(drmVersionPtr v
)
594 if (v
->name
) drmFree(v
->name
);
595 if (v
->date
) drmFree(v
->date
);
596 if (v
->desc
) drmFree(v
->desc
);
602 * Free the non-public version information returned by the kernel.
604 * \param v pointer to the version information.
607 * Used by drmGetVersion() to free the memory pointed by \p %v as well as all
608 * the non-null strings pointers in it.
610 static void drmFreeKernelVersion(drm_version_t
*v
)
613 if (v
->name
) drmFree(v
->name
);
614 if (v
->date
) drmFree(v
->date
);
615 if (v
->desc
) drmFree(v
->desc
);
621 * Copy version information.
623 * \param d destination pointer.
624 * \param s source pointer.
627 * Used by drmGetVersion() to translate the information returned by the ioctl
628 * interface in a private structure into the public structure counterpart.
630 static void drmCopyVersion(drmVersionPtr d
, const drm_version_t
*s
)
632 d
->version_major
= s
->version_major
;
633 d
->version_minor
= s
->version_minor
;
634 d
->version_patchlevel
= s
->version_patchlevel
;
635 d
->name_len
= s
->name_len
;
636 d
->name
= drmStrdup(s
->name
);
637 d
->date_len
= s
->date_len
;
638 d
->date
= drmStrdup(s
->date
);
639 d
->desc_len
= s
->desc_len
;
640 d
->desc
= drmStrdup(s
->desc
);
645 * Query the driver version information.
647 * \param fd file descriptor.
649 * \return pointer to a drmVersion structure which should be freed with
652 * \note Similar information is available via /proc/dri.
655 * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
656 * first with zeros to get the string lengths, and then the actually strings.
657 * It also null-terminates them since they might not be already.
659 drmVersionPtr
drmGetVersion(int fd
)
661 drmVersionPtr retval
;
662 drm_version_t
*version
= drmMalloc(sizeof(*version
));
664 /* First, get the lengths */
665 version
->name_len
= 0;
666 version
->name
= NULL
;
667 version
->date_len
= 0;
668 version
->date
= NULL
;
669 version
->desc_len
= 0;
670 version
->desc
= NULL
;
672 if (ioctl(fd
, DRM_IOCTL_VERSION
, version
)) {
673 drmFreeKernelVersion(version
);
677 /* Now, allocate space and get the data */
678 if (version
->name_len
)
679 version
->name
= drmMalloc(version
->name_len
+ 1);
680 if (version
->date_len
)
681 version
->date
= drmMalloc(version
->date_len
+ 1);
682 if (version
->desc_len
)
683 version
->desc
= drmMalloc(version
->desc_len
+ 1);
685 if (ioctl(fd
, DRM_IOCTL_VERSION
, version
)) {
686 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno
));
687 drmFreeKernelVersion(version
);
691 /* The results might not be null-terminated
692 strings, so terminate them. */
694 if (version
->name_len
) version
->name
[version
->name_len
] = '\0';
695 if (version
->date_len
) version
->date
[version
->date_len
] = '\0';
696 if (version
->desc_len
) version
->desc
[version
->desc_len
] = '\0';
698 /* Now, copy it all back into the
699 client-visible data structure... */
700 retval
= drmMalloc(sizeof(*retval
));
701 drmCopyVersion(retval
, version
);
702 drmFreeKernelVersion(version
);
708 * Get version information for the DRM user space library.
710 * This version number is driver independent.
712 * \param fd file descriptor.
714 * \return version information.
717 * This function allocates and fills a drm_version structure with a hard coded
720 drmVersionPtr
drmGetLibVersion(int fd
)
722 drm_version_t
*version
= drmMalloc(sizeof(*version
));
725 * revision 1.0.x = original DRM interface with no drmGetLibVersion
726 * entry point and many drm<Device> extensions
727 * revision 1.1.x = added drmCommand entry points for device extensions
728 * added drmGetLibVersion to identify libdrm.a version
729 * revision 1.2.x = added drmSetInterfaceVersion
730 * modified drmOpen to handle both busid and name
732 version
->version_major
= 1;
733 version
->version_minor
= 2;
734 version
->version_patchlevel
= 0;
736 return (drmVersionPtr
)version
;
741 * Free the bus ID information.
743 * \param busid bus ID information string as given by drmGetBusid().
746 * This function is just frees the memory pointed by \p busid.
748 void drmFreeBusid(const char *busid
)
750 drmFree((void *)busid
);
755 * Get the bus ID of the device.
757 * \param fd file descriptor.
759 * \return bus ID string.
762 * This function gets the bus ID via successive DRM_IOCTL_GET_UNIQUE ioctls to
763 * get the string length and data, passing the arguments in a drm_unique
766 char *drmGetBusid(int fd
)
773 if (ioctl(fd
, DRM_IOCTL_GET_UNIQUE
, &u
)) return NULL
;
774 u
.unique
= drmMalloc(u
.unique_len
+ 1);
775 if (ioctl(fd
, DRM_IOCTL_GET_UNIQUE
, &u
)) return NULL
;
776 u
.unique
[u
.unique_len
] = '\0';
783 * Set the bus ID of the device.
785 * \param fd file descriptor.
786 * \param busid bus ID string.
788 * \return zero on success, negative on failure.
791 * This function is a wrapper around the DRM_IOCTL_SET_UNIQUE ioctl, passing
792 * the arguments in a drm_unique structure.
794 int drmSetBusid(int fd
, const char *busid
)
798 u
.unique
= (char *)busid
;
799 u
.unique_len
= strlen(busid
);
801 if (ioctl(fd
, DRM_IOCTL_SET_UNIQUE
, &u
)) {
807 int drmGetMagic(int fd
, drm_magic_t
* magic
)
812 if (ioctl(fd
, DRM_IOCTL_GET_MAGIC
, &auth
)) return -errno
;
817 int drmAuthMagic(int fd
, drm_magic_t magic
)
822 if (ioctl(fd
, DRM_IOCTL_AUTH_MAGIC
, &auth
)) return -errno
;
827 * Specifies a range of memory that is available for mapping by a
830 * \param fd file descriptor.
831 * \param offset usually the physical address. The actual meaning depends of
832 * the \p type parameter. See below.
833 * \param size of the memory in bytes.
834 * \param type type of the memory to be mapped.
835 * \param flags combination of several flags to modify the function actions.
836 * \param handle will be set to a value that may be used as the offset
837 * parameter for mmap().
839 * \return zero on success or a negative value on error.
841 * \par Mapping the frame buffer
842 * For the frame buffer
843 * - \p offset will be the physical address of the start of the frame buffer,
844 * - \p size will be the size of the frame buffer in bytes, and
845 * - \p type will be DRM_FRAME_BUFFER.
848 * The area mapped will be uncached. If MTRR support is available in the
849 * kernel, the frame buffer area will be set to write combining.
851 * \par Mapping the MMIO register area
852 * For the MMIO register area,
853 * - \p offset will be the physical address of the start of the register area,
854 * - \p size will be the size of the register area bytes, and
855 * - \p type will be DRM_REGISTERS.
857 * The area mapped will be uncached.
859 * \par Mapping the SAREA
861 * - \p offset will be ignored and should be set to zero,
862 * - \p size will be the desired size of the SAREA in bytes,
863 * - \p type will be DRM_SHM.
866 * A shared memory area of the requested size will be created and locked in
867 * kernel memory. This area may be mapped into client-space by using the handle
870 * \note May only be called by root.
873 * This function is a wrapper around the DRM_IOCTL_ADD_MAP ioctl, passing
874 * the arguments in a drm_map structure.
876 int drmAddMap(int fd
,
881 drm_handle_t
* handle
)
886 /* No longer needed with CVS kernel modules on alpha
889 map.offset += BUS_BASE;
896 if (ioctl(fd
, DRM_IOCTL_ADD_MAP
, &map
)) return -errno
;
897 if (handle
) *handle
= (drm_handle_t
)map
.handle
;
901 int drmRmMap(int fd
, drm_handle_t handle
)
905 map
.handle
= (void *)handle
;
907 if(ioctl(fd
, DRM_IOCTL_RM_MAP
, &map
)) return -errno
;
912 * Make buffers available for DMA transfers.
914 * \param fd file descriptor.
915 * \param count number of buffers.
916 * \param size size of each buffer.
917 * \param flags buffer allocation flags.
918 * \param agp_offset offset in the AGP aperture
920 * \return number of buffers allocated, negative on error.
923 * This function is a wrapper around DRM_IOCTL_ADD_BUFS ioctl.
927 int drmAddBufs(int fd
, int count
, int size
, drmBufDescFlags flags
,
930 drm_buf_desc_t request
;
932 request
.count
= count
;
934 request
.low_mark
= 0;
935 request
.high_mark
= 0;
936 request
.flags
= flags
;
937 request
.agp_start
= agp_offset
;
939 if (ioctl(fd
, DRM_IOCTL_ADD_BUFS
, &request
)) return -errno
;
940 return request
.count
;
943 int drmMarkBufs(int fd
, double low
, double high
)
951 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) return -EINVAL
;
953 if (!info
.count
) return -EINVAL
;
955 if (!(info
.list
= drmMalloc(info
.count
* sizeof(*info
.list
))))
958 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) {
964 for (i
= 0; i
< info
.count
; i
++) {
965 info
.list
[i
].low_mark
= low
* info
.list
[i
].count
;
966 info
.list
[i
].high_mark
= high
* info
.list
[i
].count
;
967 if (ioctl(fd
, DRM_IOCTL_MARK_BUFS
, &info
.list
[i
])) {
981 * \param fd file descriptor.
982 * \param count number of buffers to free.
983 * \param list list of buffers to be freed.
985 * \return zero on success, or a negative value on failure.
987 * \note This function is primarily used for debugging.
990 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
991 * the arguments in a drm_buf_free structure.
993 int drmFreeBufs(int fd
, int count
, int *list
)
995 drm_buf_free_t request
;
997 request
.count
= count
;
999 if (ioctl(fd
, DRM_IOCTL_FREE_BUFS
, &request
)) return -errno
;
1007 * \param fd file descriptor.
1010 * This function closes the file descriptor.
1012 int drmClose(int fd
)
1014 unsigned long key
= drmGetKeyFromFd(fd
);
1015 drmHashEntry
*entry
= drmGetEntry(fd
);
1017 drmHashDestroy(entry
->tagTable
);
1020 entry
->tagTable
= NULL
;
1022 drmHashDelete(drmHashTable
, key
);
1030 * Map a region of memory.
1032 * \param fd file descriptor.
1033 * \param handle handle returned by drmAddMap().
1034 * \param size size in bytes. Must match the size used by drmAddMap().
1035 * \param address will contain the user-space virtual address where the mapping
1038 * \return zero on success, or a negative value on failure.
1041 * This function is a wrapper for mmap().
1044 drm_handle_t handle
,
1046 drmAddressPtr address
)
1048 static unsigned long pagesize_mask
= 0;
1050 if (fd
< 0) return -EINVAL
;
1053 pagesize_mask
= getpagesize() - 1;
1055 size
= (size
+ pagesize_mask
) & ~pagesize_mask
;
1057 *address
= mmap(0, size
, PROT_READ
|PROT_WRITE
, MAP_SHARED
, fd
, handle
);
1058 if (*address
== MAP_FAILED
) return -errno
;
1064 * Unmap mappings obtained with drmMap().
1066 * \param address address as given by drmMap().
1067 * \param size size in bytes. Must match the size used by drmMap().
1069 * \return zero on success, or a negative value on failure.
1072 * This function is a wrapper for unmap().
1074 int drmUnmap(drmAddress address
, drmSize size
)
1076 return munmap(address
, size
);
1079 drmBufInfoPtr
drmGetBufInfo(int fd
)
1081 drm_buf_info_t info
;
1082 drmBufInfoPtr retval
;
1088 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) return NULL
;
1091 if (!(info
.list
= drmMalloc(info
.count
* sizeof(*info
.list
))))
1094 if (ioctl(fd
, DRM_IOCTL_INFO_BUFS
, &info
)) {
1098 /* Now, copy it all back into the
1099 client-visible data structure... */
1100 retval
= drmMalloc(sizeof(*retval
));
1101 retval
->count
= info
.count
;
1102 retval
->list
= drmMalloc(info
.count
* sizeof(*retval
->list
));
1103 for (i
= 0; i
< info
.count
; i
++) {
1104 retval
->list
[i
].count
= info
.list
[i
].count
;
1105 retval
->list
[i
].size
= info
.list
[i
].size
;
1106 retval
->list
[i
].low_mark
= info
.list
[i
].low_mark
;
1107 retval
->list
[i
].high_mark
= info
.list
[i
].high_mark
;
1116 * Map all DMA buffers into client-virtual space.
1118 * \param fd file descriptor.
1120 * \return a pointer to a ::drmBufMap structure.
1122 * \note The client may not use these buffers until obtaining buffer indices
1126 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1127 * information about the buffers in a drm_buf_map structure into the
1128 * client-visible data structures.
1130 drmBufMapPtr
drmMapBufs(int fd
)
1133 drmBufMapPtr retval
;
1138 bufs
.virtual = NULL
;
1139 if (ioctl(fd
, DRM_IOCTL_MAP_BUFS
, &bufs
)) return NULL
;
1141 if (!bufs
.count
) return NULL
;
1143 if (!(bufs
.list
= drmMalloc(bufs
.count
* sizeof(*bufs
.list
))))
1146 if (ioctl(fd
, DRM_IOCTL_MAP_BUFS
, &bufs
)) {
1150 /* Now, copy it all back into the
1151 client-visible data structure... */
1152 retval
= drmMalloc(sizeof(*retval
));
1153 retval
->count
= bufs
.count
;
1154 retval
->list
= drmMalloc(bufs
.count
* sizeof(*retval
->list
));
1155 for (i
= 0; i
< bufs
.count
; i
++) {
1156 retval
->list
[i
].idx
= bufs
.list
[i
].idx
;
1157 retval
->list
[i
].total
= bufs
.list
[i
].total
;
1158 retval
->list
[i
].used
= 0;
1159 retval
->list
[i
].address
= bufs
.list
[i
].address
;
1169 * Unmap buffers allocated with drmMapBufs().
1171 * \return zero on success, or negative value on failure.
1174 * Calls munmap() for every buffer stored in \p bufs and frees the
1175 * memory allocated by drmMapBufs().
1177 int drmUnmapBufs(drmBufMapPtr bufs
)
1181 for (i
= 0; i
< bufs
->count
; i
++) {
1182 munmap(bufs
->list
[i
].address
, bufs
->list
[i
].total
);
1185 drmFree(bufs
->list
);
1192 #define DRM_DMA_RETRY 16
1195 * Reserve DMA buffers.
1197 * \param fd file descriptor.
1200 * \return zero on success, or a negative value on failure.
1203 * Assemble the arguments into a drm_dma structure and keeps issuing the
1204 * DRM_IOCTL_DMA ioctl until success or until maximum number of retries.
1206 int drmDMA(int fd
, drmDMAReqPtr request
)
1211 /* Copy to hidden structure */
1212 dma
.context
= request
->context
;
1213 dma
.send_count
= request
->send_count
;
1214 dma
.send_indices
= request
->send_list
;
1215 dma
.send_sizes
= request
->send_sizes
;
1216 dma
.flags
= request
->flags
;
1217 dma
.request_count
= request
->request_count
;
1218 dma
.request_size
= request
->request_size
;
1219 dma
.request_indices
= request
->request_list
;
1220 dma
.request_sizes
= request
->request_sizes
;
1221 dma
.granted_count
= 0;
1224 ret
= ioctl( fd
, DRM_IOCTL_DMA
, &dma
);
1225 } while ( ret
&& errno
== EAGAIN
&& i
++ < DRM_DMA_RETRY
);
1228 request
->granted_count
= dma
.granted_count
;
1237 * Obtain heavyweight hardware lock.
1239 * \param fd file descriptor.
1240 * \param context context.
1241 * \param flags flags that determine the sate of the hardware when the function
1244 * \return always zero.
1247 * This function translates the arguments into a drm_lock structure and issue
1248 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
1250 int drmGetLock(int fd
, drm_context_t context
, drmLockFlags flags
)
1254 lock
.context
= context
;
1256 if (flags
& DRM_LOCK_READY
) lock
.flags
|= _DRM_LOCK_READY
;
1257 if (flags
& DRM_LOCK_QUIESCENT
) lock
.flags
|= _DRM_LOCK_QUIESCENT
;
1258 if (flags
& DRM_LOCK_FLUSH
) lock
.flags
|= _DRM_LOCK_FLUSH
;
1259 if (flags
& DRM_LOCK_FLUSH_ALL
) lock
.flags
|= _DRM_LOCK_FLUSH_ALL
;
1260 if (flags
& DRM_HALT_ALL_QUEUES
) lock
.flags
|= _DRM_HALT_ALL_QUEUES
;
1261 if (flags
& DRM_HALT_CUR_QUEUES
) lock
.flags
|= _DRM_HALT_CUR_QUEUES
;
1263 while (ioctl(fd
, DRM_IOCTL_LOCK
, &lock
))
1269 * Release the hardware lock.
1271 * \param fd file descriptor.
1272 * \param context context.
1274 * \return zero on success, or a negative value on failure.
1277 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1278 * argument in a drm_lock structure.
1280 int drmUnlock(int fd
, drm_context_t context
)
1284 lock
.context
= context
;
1286 return ioctl(fd
, DRM_IOCTL_UNLOCK
, &lock
);
1289 drm_context_t
* drmGetReservedContextList(int fd
, int *count
)
1293 drm_context_t
* retval
;
1297 res
.contexts
= NULL
;
1298 if (ioctl(fd
, DRM_IOCTL_RES_CTX
, &res
)) return NULL
;
1300 if (!res
.count
) return NULL
;
1302 if (!(list
= drmMalloc(res
.count
* sizeof(*list
)))) return NULL
;
1303 if (!(retval
= drmMalloc(res
.count
* sizeof(*retval
)))) {
1308 res
.contexts
= list
;
1309 if (ioctl(fd
, DRM_IOCTL_RES_CTX
, &res
)) return NULL
;
1311 for (i
= 0; i
< res
.count
; i
++) retval
[i
] = list
[i
].handle
;
1318 void drmFreeReservedContextList(drm_context_t
* pt
)
1326 * Used by the X server during GLXContext initialization. This causes
1327 * per-context kernel-level resources to be allocated.
1329 * \param fd file descriptor.
1330 * \param handle is set on success. To be used by the client when requesting DMA
1331 * dispatch with drmDMA().
1333 * \return zero on success, or a negative value on failure.
1335 * \note May only be called by root.
1338 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1339 * argument in a drm_ctx structure.
1341 int drmCreateContext(int fd
, drm_context_t
* handle
)
1345 ctx
.flags
= 0; /* Modified with functions below */
1346 if (ioctl(fd
, DRM_IOCTL_ADD_CTX
, &ctx
)) return -errno
;
1347 *handle
= ctx
.handle
;
1351 int drmSwitchToContext(int fd
, drm_context_t context
)
1355 ctx
.handle
= context
;
1356 if (ioctl(fd
, DRM_IOCTL_SWITCH_CTX
, &ctx
)) return -errno
;
1360 int drmSetContextFlags(int fd
, drm_context_t context
, drm_context_tFlags flags
)
1364 /* Context preserving means that no context
1365 switched are done between DMA buffers
1366 from one context and the next. This is
1367 suitable for use in the X server (which
1368 promises to maintain hardware context,
1369 or in the client-side library when
1370 buffers are swapped on behalf of two
1372 ctx
.handle
= context
;
1374 if (flags
& DRM_CONTEXT_PRESERVED
) ctx
.flags
|= _DRM_CONTEXT_PRESERVED
;
1375 if (flags
& DRM_CONTEXT_2DONLY
) ctx
.flags
|= _DRM_CONTEXT_2DONLY
;
1376 if (ioctl(fd
, DRM_IOCTL_MOD_CTX
, &ctx
)) return -errno
;
1380 int drmGetContextFlags(int fd
, drm_context_t context
, drm_context_tFlagsPtr flags
)
1384 ctx
.handle
= context
;
1385 if (ioctl(fd
, DRM_IOCTL_GET_CTX
, &ctx
)) return -errno
;
1387 if (ctx
.flags
& _DRM_CONTEXT_PRESERVED
) *flags
|= DRM_CONTEXT_PRESERVED
;
1388 if (ctx
.flags
& _DRM_CONTEXT_2DONLY
) *flags
|= DRM_CONTEXT_2DONLY
;
1395 * Free any kernel-level resources allocated with drmCreateContext() associated
1398 * \param fd file descriptor.
1399 * \param handle handle given by drmCreateContext().
1401 * \return zero on success, or a negative value on failure.
1403 * \note May only be called by root.
1406 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1407 * argument in a drm_ctx structure.
1409 int drmDestroyContext(int fd
, drm_context_t handle
)
1412 ctx
.handle
= handle
;
1413 if (ioctl(fd
, DRM_IOCTL_RM_CTX
, &ctx
)) return -errno
;
1417 int drmCreateDrawable(int fd
, drm_drawable_t
* handle
)
1420 if (ioctl(fd
, DRM_IOCTL_ADD_DRAW
, &draw
)) return -errno
;
1421 *handle
= draw
.handle
;
1425 int drmDestroyDrawable(int fd
, drm_drawable_t handle
)
1428 draw
.handle
= handle
;
1429 if (ioctl(fd
, DRM_IOCTL_RM_DRAW
, &draw
)) return -errno
;
1434 * Acquire the AGP device.
1436 * Must be called before any of the other AGP related calls.
1438 * \param fd file descriptor.
1440 * \return zero on success, or a negative value on failure.
1443 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1445 int drmAgpAcquire(int fd
)
1447 if (ioctl(fd
, DRM_IOCTL_AGP_ACQUIRE
, NULL
)) return -errno
;
1453 * Release the AGP device.
1455 * \param fd file descriptor.
1457 * \return zero on success, or a negative value on failure.
1460 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1462 int drmAgpRelease(int fd
)
1464 if (ioctl(fd
, DRM_IOCTL_AGP_RELEASE
, NULL
)) return -errno
;
1472 * \param fd file descriptor.
1473 * \param mode AGP mode.
1475 * \return zero on success, or a negative value on failure.
1478 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1479 * argument in a drm_agp_mode structure.
1481 int drmAgpEnable(int fd
, unsigned long mode
)
1486 if (ioctl(fd
, DRM_IOCTL_AGP_ENABLE
, &m
)) return -errno
;
1492 * Allocate a chunk of AGP memory.
1494 * \param fd file descriptor.
1495 * \param size requested memory size in bytes. Will be rounded to page boundary.
1496 * \param type type of memory to allocate.
1497 * \param address if not zero, will be set to the physical address of the
1499 * \param handle on success will be set to a handle of the allocated memory.
1501 * \return zero on success, or a negative value on failure.
1504 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1505 * arguments in a drm_agp_buffer structure.
1507 int drmAgpAlloc(int fd
, unsigned long size
, unsigned long type
,
1508 unsigned long *address
, unsigned long *handle
)
1512 *handle
= DRM_AGP_NO_HANDLE
;
1516 if (ioctl(fd
, DRM_IOCTL_AGP_ALLOC
, &b
)) return -errno
;
1517 if (address
!= 0UL) *address
= b
.physical
;
1524 * Free a chunk of AGP memory.
1526 * \param fd file descriptor.
1527 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1529 * \return zero on success, or a negative value on failure.
1532 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1533 * argument in a drm_agp_buffer structure.
1535 int drmAgpFree(int fd
, unsigned long handle
)
1541 if (ioctl(fd
, DRM_IOCTL_AGP_FREE
, &b
)) return -errno
;
1547 * Bind a chunk of AGP memory.
1549 * \param fd file descriptor.
1550 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1551 * \param offset offset in bytes. It will round to page boundary.
1553 * \return zero on success, or a negative value on failure.
1556 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1557 * argument in a drm_agp_binding structure.
1559 int drmAgpBind(int fd
, unsigned long handle
, unsigned long offset
)
1561 drm_agp_binding_t b
;
1565 if (ioctl(fd
, DRM_IOCTL_AGP_BIND
, &b
)) return -errno
;
1571 * Unbind a chunk of AGP memory.
1573 * \param fd file descriptor.
1574 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1576 * \return zero on success, or a negative value on failure.
1579 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1580 * the argument in a drm_agp_binding structure.
1582 int drmAgpUnbind(int fd
, unsigned long handle
)
1584 drm_agp_binding_t b
;
1588 if (ioctl(fd
, DRM_IOCTL_AGP_UNBIND
, &b
)) return -errno
;
1594 * Get AGP driver major version number.
1596 * \param fd file descriptor.
1598 * \return major version number on success, or a negative value on failure..
1601 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1602 * necessary information in a drm_agp_info structure.
1604 int drmAgpVersionMajor(int fd
)
1608 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return -errno
;
1609 return i
.agp_version_major
;
1614 * Get AGP driver minor version number.
1616 * \param fd file descriptor.
1618 * \return minor version number on success, or a negative value on failure.
1621 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1622 * necessary information in a drm_agp_info structure.
1624 int drmAgpVersionMinor(int fd
)
1628 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return -errno
;
1629 return i
.agp_version_minor
;
1636 * \param fd file descriptor.
1638 * \return mode on success, or zero on failure.
1641 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1642 * necessary information in a drm_agp_info structure.
1644 unsigned long drmAgpGetMode(int fd
)
1648 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1654 * Get AGP aperture base.
1656 * \param fd file descriptor.
1658 * \return aperture base on success, zero on failure.
1661 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1662 * necessary information in a drm_agp_info structure.
1664 unsigned long drmAgpBase(int fd
)
1668 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1669 return i
.aperture_base
;
1674 * Get AGP aperture size.
1676 * \param fd file descriptor.
1678 * \return aperture size on success, zero on failure.
1681 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1682 * necessary information in a drm_agp_info structure.
1684 unsigned long drmAgpSize(int fd
)
1688 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1689 return i
.aperture_size
;
1694 * Get used AGP memory.
1696 * \param fd file descriptor.
1698 * \return memory used on success, or zero on failure.
1701 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1702 * necessary information in a drm_agp_info structure.
1704 unsigned long drmAgpMemoryUsed(int fd
)
1708 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1709 return i
.memory_used
;
1714 * Get available AGP memory.
1716 * \param fd file descriptor.
1718 * \return memory available on success, or zero on failure.
1721 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1722 * necessary information in a drm_agp_info structure.
1724 unsigned long drmAgpMemoryAvail(int fd
)
1728 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1729 return i
.memory_allowed
;
1734 * Get hardware vendor ID.
1736 * \param fd file descriptor.
1738 * \return vendor ID on success, or zero on failure.
1741 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1742 * necessary information in a drm_agp_info structure.
1744 unsigned int drmAgpVendorId(int fd
)
1748 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1754 * Get hardware device ID.
1756 * \param fd file descriptor.
1758 * \return zero on success, or zero on failure.
1761 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1762 * necessary information in a drm_agp_info structure.
1764 unsigned int drmAgpDeviceId(int fd
)
1768 if (ioctl(fd
, DRM_IOCTL_AGP_INFO
, &i
)) return 0;
1772 int drmScatterGatherAlloc(int fd
, unsigned long size
, unsigned long *handle
)
1774 drm_scatter_gather_t sg
;
1779 if (ioctl(fd
, DRM_IOCTL_SG_ALLOC
, &sg
)) return -errno
;
1780 *handle
= sg
.handle
;
1784 int drmScatterGatherFree(int fd
, unsigned long handle
)
1786 drm_scatter_gather_t sg
;
1790 if (ioctl(fd
, DRM_IOCTL_SG_FREE
, &sg
)) return -errno
;
1797 * \param fd file descriptor.
1798 * \param vbl pointer to a drmVBlank structure.
1800 * \return zero on success, or a negative value on failure.
1803 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
1805 int drmWaitVBlank(int fd
, drmVBlankPtr vbl
)
1810 ret
= ioctl(fd
, DRM_IOCTL_WAIT_VBLANK
, vbl
);
1811 vbl
->request
.type
&= ~DRM_VBLANK_RELATIVE
;
1812 } while (ret
&& errno
== EINTR
);
1817 int drmError(int err
, const char *label
)
1820 case DRM_ERR_NO_DEVICE
: fprintf(stderr
, "%s: no device\n", label
); break;
1821 case DRM_ERR_NO_ACCESS
: fprintf(stderr
, "%s: no access\n", label
); break;
1822 case DRM_ERR_NOT_ROOT
: fprintf(stderr
, "%s: not root\n", label
); break;
1823 case DRM_ERR_INVALID
: fprintf(stderr
, "%s: invalid args\n", label
);break;
1825 if (err
< 0) err
= -err
;
1826 fprintf( stderr
, "%s: error %d (%s)\n", label
, err
, strerror(err
) );
1834 * Install IRQ handler.
1836 * \param fd file descriptor.
1837 * \param irq IRQ number.
1839 * \return zero on success, or a negative value on failure.
1842 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1843 * argument in a drm_control structure.
1845 int drmCtlInstHandler(int fd
, int irq
)
1849 ctl
.func
= DRM_INST_HANDLER
;
1851 if (ioctl(fd
, DRM_IOCTL_CONTROL
, &ctl
)) return -errno
;
1857 * Uninstall IRQ handler.
1859 * \param fd file descriptor.
1861 * \return zero on success, or a negative value on failure.
1864 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
1865 * argument in a drm_control structure.
1867 int drmCtlUninstHandler(int fd
)
1871 ctl
.func
= DRM_UNINST_HANDLER
;
1873 if (ioctl(fd
, DRM_IOCTL_CONTROL
, &ctl
)) return -errno
;
1877 int drmFinish(int fd
, int context
, drmLockFlags flags
)
1881 lock
.context
= context
;
1883 if (flags
& DRM_LOCK_READY
) lock
.flags
|= _DRM_LOCK_READY
;
1884 if (flags
& DRM_LOCK_QUIESCENT
) lock
.flags
|= _DRM_LOCK_QUIESCENT
;
1885 if (flags
& DRM_LOCK_FLUSH
) lock
.flags
|= _DRM_LOCK_FLUSH
;
1886 if (flags
& DRM_LOCK_FLUSH_ALL
) lock
.flags
|= _DRM_LOCK_FLUSH_ALL
;
1887 if (flags
& DRM_HALT_ALL_QUEUES
) lock
.flags
|= _DRM_HALT_ALL_QUEUES
;
1888 if (flags
& DRM_HALT_CUR_QUEUES
) lock
.flags
|= _DRM_HALT_CUR_QUEUES
;
1889 if (ioctl(fd
, DRM_IOCTL_FINISH
, &lock
)) return -errno
;
1894 * Get IRQ from bus ID.
1896 * \param fd file descriptor.
1897 * \param busnum bus number.
1898 * \param devnum device number.
1899 * \param funcnum function number.
1901 * \return IRQ number on success, or a negative value on failure.
1904 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
1905 * arguments in a drm_irq_busid structure.
1907 int drmGetInterruptFromBusID(int fd
, int busnum
, int devnum
, int funcnum
)
1913 p
.funcnum
= funcnum
;
1914 if (ioctl(fd
, DRM_IOCTL_IRQ_BUSID
, &p
)) return -errno
;
1918 int drmAddContextTag(int fd
, drm_context_t context
, void *tag
)
1920 drmHashEntry
*entry
= drmGetEntry(fd
);
1922 if (drmHashInsert(entry
->tagTable
, context
, tag
)) {
1923 drmHashDelete(entry
->tagTable
, context
);
1924 drmHashInsert(entry
->tagTable
, context
, tag
);
1929 int drmDelContextTag(int fd
, drm_context_t context
)
1931 drmHashEntry
*entry
= drmGetEntry(fd
);
1933 return drmHashDelete(entry
->tagTable
, context
);
1936 void *drmGetContextTag(int fd
, drm_context_t context
)
1938 drmHashEntry
*entry
= drmGetEntry(fd
);
1941 if (drmHashLookup(entry
->tagTable
, context
, &value
)) return NULL
;
1946 int drmAddContextPrivateMapping(int fd
, drm_context_t ctx_id
, drm_handle_t handle
)
1948 drm_ctx_priv_map_t map
;
1950 map
.ctx_id
= ctx_id
;
1951 map
.handle
= (void *)handle
;
1953 if (ioctl(fd
, DRM_IOCTL_SET_SAREA_CTX
, &map
)) return -errno
;
1957 int drmGetContextPrivateMapping(int fd
, drm_context_t ctx_id
, drm_handle_t
* handle
)
1959 drm_ctx_priv_map_t map
;
1961 map
.ctx_id
= ctx_id
;
1963 if (ioctl(fd
, DRM_IOCTL_GET_SAREA_CTX
, &map
)) return -errno
;
1964 if (handle
) *handle
= (drm_handle_t
)map
.handle
;
1969 int drmGetMap(int fd
, int idx
, drm_handle_t
*offset
, drmSize
*size
,
1970 drmMapType
*type
, drmMapFlags
*flags
, drm_handle_t
*handle
,
1976 if (ioctl(fd
, DRM_IOCTL_GET_MAP
, &map
)) return -errno
;
1977 *offset
= map
.offset
;
1981 *handle
= (unsigned long)map
.handle
;
1986 int drmGetClient(int fd
, int idx
, int *auth
, int *pid
, int *uid
,
1987 unsigned long *magic
, unsigned long *iocs
)
1989 drm_client_t client
;
1992 if (ioctl(fd
, DRM_IOCTL_GET_CLIENT
, &client
)) return -errno
;
1993 *auth
= client
.auth
;
1996 *magic
= client
.magic
;
1997 *iocs
= client
.iocs
;
2001 int drmGetStats(int fd
, drmStatsT
*stats
)
2006 if (ioctl(fd
, DRM_IOCTL_GET_STATS
, &s
)) return -errno
;
2009 memset(stats
, 0, sizeof(*stats
));
2010 if (s
.count
> sizeof(stats
->data
)/sizeof(stats
->data
[0]))
2014 stats->data[i].long_format = "%-20.20s"; \
2015 stats->data[i].rate_format = "%8.8s"; \
2016 stats->data[i].isvalue = 1; \
2017 stats->data[i].verbose = 0
2020 stats->data[i].long_format = "%-20.20s"; \
2021 stats->data[i].rate_format = "%5.5s"; \
2022 stats->data[i].isvalue = 0; \
2023 stats->data[i].mult_names = "kgm"; \
2024 stats->data[i].mult = 1000; \
2025 stats->data[i].verbose = 0
2028 stats->data[i].long_format = "%-20.20s"; \
2029 stats->data[i].rate_format = "%5.5s"; \
2030 stats->data[i].isvalue = 0; \
2031 stats->data[i].mult_names = "KGM"; \
2032 stats->data[i].mult = 1024; \
2033 stats->data[i].verbose = 0
2036 stats
->count
= s
.count
;
2037 for (i
= 0; i
< s
.count
; i
++) {
2038 stats
->data
[i
].value
= s
.data
[i
].value
;
2039 switch (s
.data
[i
].type
) {
2040 case _DRM_STAT_LOCK
:
2041 stats
->data
[i
].long_name
= "Lock";
2042 stats
->data
[i
].rate_name
= "Lock";
2045 case _DRM_STAT_OPENS
:
2046 stats
->data
[i
].long_name
= "Opens";
2047 stats
->data
[i
].rate_name
= "O";
2049 stats
->data
[i
].verbose
= 1;
2051 case _DRM_STAT_CLOSES
:
2052 stats
->data
[i
].long_name
= "Closes";
2053 stats
->data
[i
].rate_name
= "Lock";
2055 stats
->data
[i
].verbose
= 1;
2057 case _DRM_STAT_IOCTLS
:
2058 stats
->data
[i
].long_name
= "Ioctls";
2059 stats
->data
[i
].rate_name
= "Ioc/s";
2062 case _DRM_STAT_LOCKS
:
2063 stats
->data
[i
].long_name
= "Locks";
2064 stats
->data
[i
].rate_name
= "Lck/s";
2067 case _DRM_STAT_UNLOCKS
:
2068 stats
->data
[i
].long_name
= "Unlocks";
2069 stats
->data
[i
].rate_name
= "Unl/s";
2073 stats
->data
[i
].long_name
= "IRQs";
2074 stats
->data
[i
].rate_name
= "IRQ/s";
2077 case _DRM_STAT_PRIMARY
:
2078 stats
->data
[i
].long_name
= "Primary Bytes";
2079 stats
->data
[i
].rate_name
= "PB/s";
2082 case _DRM_STAT_SECONDARY
:
2083 stats
->data
[i
].long_name
= "Secondary Bytes";
2084 stats
->data
[i
].rate_name
= "SB/s";
2088 stats
->data
[i
].long_name
= "DMA";
2089 stats
->data
[i
].rate_name
= "DMA/s";
2092 case _DRM_STAT_SPECIAL
:
2093 stats
->data
[i
].long_name
= "Special DMA";
2094 stats
->data
[i
].rate_name
= "dma/s";
2097 case _DRM_STAT_MISSED
:
2098 stats
->data
[i
].long_name
= "Miss";
2099 stats
->data
[i
].rate_name
= "Ms/s";
2102 case _DRM_STAT_VALUE
:
2103 stats
->data
[i
].long_name
= "Value";
2104 stats
->data
[i
].rate_name
= "Value";
2107 case _DRM_STAT_BYTE
:
2108 stats
->data
[i
].long_name
= "Bytes";
2109 stats
->data
[i
].rate_name
= "B/s";
2112 case _DRM_STAT_COUNT
:
2114 stats
->data
[i
].long_name
= "Count";
2115 stats
->data
[i
].rate_name
= "Cnt/s";
2124 * Issue a set-version ioctl.
2126 * \param fd file descriptor.
2127 * \param drmCommandIndex command index
2128 * \param data source pointer of the data to be read and written.
2129 * \param size size of the data to be read and written.
2131 * \return zero on success, or a negative value on failure.
2134 * It issues a read-write ioctl given by
2135 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2137 int drmSetInterfaceVersion(int fd
, drmSetVersion
*version
)
2140 drm_set_version_t sv
;
2142 sv
.drm_di_major
= version
->drm_di_major
;
2143 sv
.drm_di_minor
= version
->drm_di_minor
;
2144 sv
.drm_dd_major
= version
->drm_dd_major
;
2145 sv
.drm_dd_minor
= version
->drm_dd_minor
;
2147 if (ioctl(fd
, DRM_IOCTL_SET_VERSION
, &sv
)) {
2151 version
->drm_di_major
= sv
.drm_di_major
;
2152 version
->drm_di_minor
= sv
.drm_di_minor
;
2153 version
->drm_dd_major
= sv
.drm_dd_major
;
2154 version
->drm_dd_minor
= sv
.drm_dd_minor
;
2160 * Send a device-specific command.
2162 * \param fd file descriptor.
2163 * \param drmCommandIndex command index
2165 * \return zero on success, or a negative value on failure.
2168 * It issues a ioctl given by
2169 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2171 int drmCommandNone(int fd
, unsigned long drmCommandIndex
)
2173 void *data
= NULL
; /* dummy */
2174 unsigned long request
;
2176 request
= DRM_IO( DRM_COMMAND_BASE
+ drmCommandIndex
);
2178 if (ioctl(fd
, request
, data
)) {
2186 * Send a device-specific read command.
2188 * \param fd file descriptor.
2189 * \param drmCommandIndex command index
2190 * \param data destination pointer of the data to be read.
2191 * \param size size of the data to be read.
2193 * \return zero on success, or a negative value on failure.
2196 * It issues a read ioctl given by
2197 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2199 int drmCommandRead(int fd
, unsigned long drmCommandIndex
,
2200 void *data
, unsigned long size
)
2202 unsigned long request
;
2204 request
= DRM_IOC( DRM_IOC_READ
, DRM_IOCTL_BASE
,
2205 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2207 if (ioctl(fd
, request
, data
)) {
2215 * Send a device-specific write command.
2217 * \param fd file descriptor.
2218 * \param drmCommandIndex command index
2219 * \param data source pointer of the data to be written.
2220 * \param size size of the data to be written.
2222 * \return zero on success, or a negative value on failure.
2225 * It issues a write ioctl given by
2226 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2228 int drmCommandWrite(int fd
, unsigned long drmCommandIndex
,
2229 void *data
, unsigned long size
)
2231 unsigned long request
;
2233 request
= DRM_IOC( DRM_IOC_WRITE
, DRM_IOCTL_BASE
,
2234 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2236 if (ioctl(fd
, request
, data
)) {
2244 * Send a device-specific read-write command.
2246 * \param fd file descriptor.
2247 * \param drmCommandIndex command index
2248 * \param data source pointer of the data to be read and written.
2249 * \param size size of the data to be read and written.
2251 * \return zero on success, or a negative value on failure.
2254 * It issues a read-write ioctl given by
2255 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2257 int drmCommandWriteRead(int fd
, unsigned long drmCommandIndex
,
2258 void *data
, unsigned long size
)
2260 unsigned long request
;
2262 request
= DRM_IOC( DRM_IOC_READ
|DRM_IOC_WRITE
, DRM_IOCTL_BASE
,
2263 DRM_COMMAND_BASE
+ drmCommandIndex
, size
);
2265 if (ioctl(fd
, request
, data
)) {
2271 #if defined(XFree86Server) || defined(DRM_USE_MALLOC)
2272 static void drmSIGIOHandler(int interrupt
, void *closure
)
2278 typedef void (*_drmCallback
)(int, void *, void *);
2285 drmHashEntry
*entry
;
2287 if (!drmHashTable
) return;
2288 if (drmHashFirst(drmHashTable
, &key
, &value
)) {
2292 fprintf(stderr
, "Trying %d\n", entry
->fd
);
2294 if ((count
= read(entry
->fd
, buf
, sizeof(buf
))) > 0) {
2297 fprintf(stderr
, "Got %s\n", buf
);
2300 for (pt
= buf
; *pt
!= ' '; ++pt
); /* Find first space */
2302 old
= strtol(pt
, &pt
, 0);
2303 new = strtol(pt
, NULL
, 0);
2304 oldctx
= drmGetContextTag(entry
->fd
, old
);
2305 newctx
= drmGetContextTag(entry
->fd
, new);
2307 fprintf(stderr
, "%d %d %p %p\n", old
, new, oldctx
, newctx
);
2309 ((_drmCallback
)entry
->f
)(entry
->fd
, oldctx
, newctx
);
2311 ioctl(entry
->fd
, DRM_IOCTL_NEW_CTX
, &ctx
);
2313 } while (drmHashNext(drmHashTable
, &key
, &value
));
2317 int drmInstallSIGIOHandler(int fd
, void (*f
)(int, void *, void *))
2319 drmHashEntry
*entry
;
2321 entry
= drmGetEntry(fd
);
2324 return xf86InstallSIGIOHandler(fd
, drmSIGIOHandler
, 0);
2327 int drmRemoveSIGIOHandler(int fd
)
2329 drmHashEntry
*entry
= drmGetEntry(fd
);
2333 return xf86RemoveSIGIOHandler(fd
);