summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stone <daniel@fooishbar.org>2006-11-02 03:15:25 +0200
committerDaniel Stone <daniels@endtroducing.fooishbar.org>2006-11-02 03:15:25 +0200
commitbe291a6d9764cf29a7d9a8114d47d9f41ce856e9 (patch)
tree0c6f93a1ec3a89441cfde49c71459baaeb07ed31
parenta2d6242106bb3a440faa9cad157e0120dbfa7b6e (diff)
parent6fdfd9dad91d7b7aa292f8c4d268dd27c34de8d3 (diff)
Merge branch 'master' of git+ssh://git.freedesktop.org/git/xorg/xserver into input-hotplug
-rw-r--r--GL/mesa/main/Makefile.am1
-rw-r--r--configure.ac19
-rw-r--r--fb/fbpict.c15
-rw-r--r--fb/fbpict.h47
-rw-r--r--hw/xfree86/Makefile.am11
-rw-r--r--hw/xfree86/os-support/drm/xf86drm.c955
-rw-r--r--hw/xfree86/os-support/xf86drm.h1
-rw-r--r--hw/xfree86/os-support/xf86mm.h210
-rw-r--r--include/libdrm-config.h.in10
-rw-r--r--os/utils.c2
10 files changed, 1241 insertions, 30 deletions
diff --git a/GL/mesa/main/Makefile.am b/GL/mesa/main/Makefile.am
index 4d5b0cd4a..64b383dc9 100644
--- a/GL/mesa/main/Makefile.am
+++ b/GL/mesa/main/Makefile.am
@@ -60,6 +60,7 @@ nodist_libmain_la_SOURCES = accum.c \
light.c \
lines.c \
matrix.c \
+ mipmap.c \
mm.c \
occlude.c \
pixel.c \
diff --git a/configure.ac b/configure.ac
index 8935aa088..9322a2deb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,7 +49,8 @@ dnl xwin-config.h covers the XWin DDX.
AC_CONFIG_HEADERS(include/xwin-config.h)
dnl kdrive-config.h covers the kdrive DDX
AC_CONFIG_HEADERS(include/kdrive-config.h)
-
+dnl libdrm now needs 64-bit file offsets
+AC_CONFIG_HEADERS(include/libdrm-config.h)
AC_PROG_CC
AM_PROG_AS
@@ -62,6 +63,7 @@ AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
AC_PROG_LEX
AC_PROG_YACC
+AC_SYS_LARGEFILE
XORG_PROG_RAWCPP
AC_HEADER_DIRENT
@@ -889,7 +891,7 @@ PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS])
PKG_CHECK_MODULES([XSERVERLIBS], [$REQUIRED_LIBS])
XSERVER_CFLAGS="${XSERVERCFLAGS_CFLAGS}"
-XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} -lm"
+XSERVER_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS}"
AC_SUBST([SYS_LIBS])
# The Xorg binary needs to export symbols so that they can be used from modules
@@ -923,9 +925,9 @@ AC_MSG_CHECKING([for a useful monotonic clock ...])
if ! test "x$have_clock_gettime" = xno; then
if ! test "x$have_clock_gettime" = xyes; then
- LIBS="$have_clock_gettime"
+ CLOCK_LIBS="$have_clock_gettime"
else
- LIBS=""
+ CLOCK_LIBS=""
fi
AC_RUN_IFELSE([
@@ -950,7 +952,8 @@ AC_MSG_RESULT([$MONOTONIC_CLOCK])
if test "x$MONOTONIC_CLOCK" = xyes; then
AC_DEFINE(MONOTONIC_CLOCK, 1, [Have monotonic clock from clock_gettime()])
- XSERVER_LIBS="$XSERVER_LIBS $LIBS"
+ XSERVER_LIBS="$XSERVER_LIBS $CLOCK_LIBS"
+ LIBS="$LIBS $CLOCK_LIBS"
fi
dnl Imake defines SVR4 on SVR4 systems, and many files check for it, so
@@ -1028,7 +1031,7 @@ AC_MSG_RESULT([$XVFB])
AM_CONDITIONAL(XVFB, [test "x$XVFB" = xyes])
if test "x$XVFB" = xyes; then
- XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
+ XVFB_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XVFB_LIBS])
fi
@@ -1044,7 +1047,7 @@ AC_MSG_RESULT([$XNEST])
AM_CONDITIONAL(XNEST, [test "x$XNEST" = xyes])
if test "x$XNEST" = xyes; then
- XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB"
+ XNEST_LIBS="$XSERVER_LIBS $FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $CONFIG_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XNEST_LIBS])
fi
@@ -1394,7 +1397,7 @@ AC_MSG_RESULT([$XPRINT])
if test "x$XPRINT" = xyes; then
PKG_CHECK_MODULES([XPRINT], [printproto x11 xfont $XDMCP_MODULES xau])
XPRINT_EXTENSIONS="$XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $RENDER_LIB $COMPOSITE_LIB $RANDR_LIB $XI_LIB $FIXES_LIB $DAMAGE_LIB $XI_LIB $GLX_LIBS"
- XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB"
+ XPRINT_LIBS="$XPRINT_LIBS $DIX_LIB $CONFIG_LIB $XKB_LIB $XKB_STUB_LIB $XPRINT_EXTENSIONS $MI_LIB $MIEXT_DAMAGE_LIB $CWRAP_LIB $OS_LIB $LIBS"
AC_SUBST([XPRINT_CFLAGS])
AC_SUBST([XPRINT_LIBS])
diff --git a/fb/fbpict.c b/fb/fbpict.c
index d839994ae..28503c0cf 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -930,9 +930,8 @@ fbComposite (CARD8 op,
case PictOpOver:
if (pMask)
{
- if (srcRepeat &&
- pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1)
+ if (fbCanGetSolid(pSrc) &&
+ !maskRepeat)
{
srcRepeat = FALSE;
if (PICT_FORMAT_COLOR(pSrc->format)) {
@@ -1044,7 +1043,7 @@ fbComposite (CARD8 op,
{
if (pSrc->pDrawable == pMask->pDrawable &&
xSrc == xMask && ySrc == yMask &&
- !pMask->componentAlpha)
+ !pMask->componentAlpha && !maskRepeat)
{
/* source == mask: non-premultiplied data */
switch (pSrc->format) {
@@ -1108,9 +1107,7 @@ fbComposite (CARD8 op,
else
{
/* non-repeating source, repeating mask => translucent window */
- if (maskRepeat &&
- pMask->pDrawable->width == 1 &&
- pMask->pDrawable->height == 1)
+ if (fbCanGetSolid(pMask))
{
if (pSrc->format == PICT_x8r8g8b8 &&
pDst->format == PICT_x8r8g8b8 &&
@@ -1127,9 +1124,7 @@ fbComposite (CARD8 op,
}
else /* no mask */
{
- if (srcRepeat &&
- pSrc->pDrawable->width == 1 &&
- pSrc->pDrawable->height == 1)
+ if (fbCanGetSolid(pSrc))
{
/* no mask and repeating source */
switch (pSrc->format) {
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 19d555781..5cdde9ef5 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -30,6 +30,13 @@
#include "renderedge.h"
+
+#if defined(__GNUC__)
+#define INLINE __inline__
+#else
+#define INLINE
+#endif
+
#define FbIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
#define FbIntDiv(a,b) (((CARD16) (a) * 255) / (b))
@@ -67,6 +74,40 @@
#define Green(x) (((x) >> 8) & 0xff)
#define Blue(x) ((x) & 0xff)
+/**
+ * Returns TRUE if the fbComposeGetSolid can be used to get a single solid
+ * color representing every source sampling location of the picture.
+ */
+static INLINE Bool
+fbCanGetSolid(PicturePtr pict)
+{
+ if (pict->pDrawable == NULL ||
+ pict->pDrawable->width != 1 ||
+ pict->pDrawable->height != 1)
+ {
+ return FALSE;
+ }
+ if (pict->repeat != RepeatNormal)
+ return FALSE;
+
+ switch (pict->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+#define fbCanGetSolid(pict) \
+(pict->pDrawable != NULL && pict->pDrawable->width == 1 && pict->pDrawable->height == 1)
+
#define fbComposeGetSolid(pict, bits, fmt) { \
FbBits *__bits__; \
FbStride __stride__; \
@@ -322,12 +363,6 @@
#define FASTCALL
#endif
-#if defined(__GNUC__)
-#define INLINE __inline__
-#else
-#define INLINE
-#endif
-
typedef struct _FbComposeData {
CARD8 op;
PicturePtr src;
diff --git a/hw/xfree86/Makefile.am b/hw/xfree86/Makefile.am
index 79d2ec5c0..72befea19 100644
--- a/hw/xfree86/Makefile.am
+++ b/hw/xfree86/Makefile.am
@@ -58,12 +58,15 @@ Xorg_LDADD = $(XORG_LIBS) \
Xorg_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
+BUILT_SOURCES = xorg.conf.example
+CLEAN = xorg.conf.example xorg.conf.example.pre
+EXTRA_DIST = xorgconf.cpp
if SOLARIS_ASM_INLINE
# Needs to be built before any files are compiled when using Sun compilers
# so in*/out* inline definitions are properly processed.
-BUILT_SOURCES = os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il
+BUILT_SOURCES += os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il
os-support/solaris/solaris-$(SOLARIS_INOUT_ARCH).il:
cd os-support/solaris ; make solaris-$(SOLARIS_INOUT_ARCH).il
@@ -84,10 +87,6 @@ endif
optionsdir = $(libdir)/X11
dist_options_DATA = Options
-BUILT_SOURCES = xorg.conf.example
-CLEAN = xorg.conf.example xorg.conf.example.pre
-EXTRA_DIST = xorgconf.cpp
-
CPP_FILES_FLAGS = \
-DRGBPATH=\"$(RGB_DB)\" \
-DLOCALFONTPATH="\"$(BASE_FONT_PATH)/local\"" \
@@ -103,4 +102,4 @@ relink:
rm -f Xorg && $(MAKE) Xorg
xorg.conf.example.pre: xorgconf.cpp
- cp $< $@
+ cp $(srcdir)/xorgconf.cpp $@
diff --git a/hw/xfree86/os-support/drm/xf86drm.c b/hw/xfree86/os-support/drm/xf86drm.c
index 214e58ba7..e990e286b 100644
--- a/hw/xfree86/os-support/drm/xf86drm.c
+++ b/hw/xfree86/os-support/drm/xf86drm.c
@@ -33,6 +33,7 @@
#ifdef HAVE_XORG_CONFIG_H
+#include <libdrm-config.h>
#include <xorg-config.h>
#endif
@@ -2305,3 +2306,957 @@ int drmRemoveSIGIOHandler(int fd)
return xf86RemoveSIGIOHandler(fd);
}
+
+/*
+ * Valid flags are
+ * DRM_FENCE_FLAG_EMIT
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+int drmFenceCreate(int fd, unsigned flags, int class,unsigned type,
+ drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.type = type;
+ arg.class = class;
+ arg.op = drm_fence_create;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->handle = arg.handle;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->flags = arg.flags;
+ fence->signaled = 0;
+ return 0;
+}
+
+/*
+ * Valid flags are
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+int drmFenceBuffers(int fd, unsigned flags, drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.flags = flags;
+ arg.op = drm_fence_buffers;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->handle = arg.handle;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->flags = arg.flags;
+ fence->signaled = 0;
+ return 0;
+}
+
+int drmFenceDestroy(int fd, const drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = fence->handle;
+ arg.op = drm_fence_destroy;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ return 0;
+}
+
+int drmFenceReference(int fd, unsigned handle, drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = handle;
+ arg.op = drm_fence_reference;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->handle = arg.handle;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->flags = arg.flags;
+ fence->signaled = arg.signaled;
+ return 0;
+}
+
+int drmFenceUnreference(int fd, const drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = fence->handle;
+ arg.op = drm_fence_unreference;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ return 0;
+}
+
+int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = fence->handle;
+ arg.type = flush_type;
+ arg.op = drm_fence_flush;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->signaled = arg.signaled;
+ return 0;
+}
+
+int drmFenceUpdate(int fd, drmFence *fence)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = fence->handle;
+ arg.op = drm_fence_signaled;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->signaled = arg.signaled;
+ return 0;
+}
+
+int drmFenceSignaled(int fd, drmFence *fence, unsigned fenceType,
+ int *signaled)
+{
+ int
+ ret;
+
+ if ((fence->flags & DRM_FENCE_FLAG_SHAREABLE) ||
+ ((fenceType & fence->signaled) != fenceType)) {
+
+ ret = drmFenceFlush(fd, fence, fenceType);
+ if (ret)
+ return ret;
+ }
+
+ *signaled = ((fenceType & fence->signaled) == fenceType);
+
+ return 0;
+}
+
+/*
+ * Valid flags are
+ * DRM_FENCE_FLAG_SHAREABLE
+ * DRM_FENCE_MASK_DRIVER
+ */
+
+
+int drmFenceEmit(int fd, unsigned flags, drmFence *fence, unsigned emit_type)
+{
+ drm_fence_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.flags = flags;
+ arg.handle = fence->handle;
+ arg.type = emit_type;
+ arg.op = drm_fence_emit;
+ if (ioctl(fd, DRM_IOCTL_FENCE, &arg))
+ return -errno;
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->signaled = arg.signaled;
+ return 0;
+}
+
+/*
+ * Valid flags are
+ * DRM_FENCE_FLAG_WAIT_LAZY
+ * DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS
+ */
+
+int drmFenceWait(int fd, unsigned flags, drmFence *fence, unsigned flush_type)
+{
+ drm_fence_arg_t arg;
+ int ret;
+
+ if (flush_type == 0) {
+ flush_type = fence->type;
+ }
+
+ if (!(fence->flags & DRM_FENCE_FLAG_SHAREABLE)) {
+ if ((flush_type & fence->signaled) == flush_type) {
+ return 0;
+ }
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = fence->handle;
+ arg.type = flush_type;
+ arg.flags = flags;
+ arg.op = drm_fence_wait;
+ do {
+ ret = ioctl(fd, DRM_IOCTL_FENCE, &arg);
+ } while (ret != 0 && errno == EAGAIN);
+
+ if (ret)
+ return -errno;
+
+ fence->class = arg.class;
+ fence->type = arg.type;
+ fence->signaled = arg.signaled;
+ return 0;
+}
+
+static int drmAdjustListNodes(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+ int ret = 0;
+
+ while(list->numCurrent < list->numTarget) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ ret = -ENOMEM;
+ break;
+ }
+ list->numCurrent++;
+ DRMLISTADD(&node->head, &list->free);
+ }
+
+ while(list->numCurrent > list->numTarget) {
+ l = list->free.next;
+ if (l == &list->free)
+ break;
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ list->numCurrent--;
+ }
+ return ret;
+}
+
+void drmBOFreeList(drmBOList *list)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->list.next;
+ while(l != &list->list) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->free.next;
+ list->numCurrent--;
+ list->numOnList--;
+ }
+
+ l = list->free.next;
+ while(l != &list->free) {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ free(node);
+ l = list->free.next;
+ list->numCurrent--;
+ }
+}
+
+int drmBOResetList(drmBOList *list) {
+
+ drmMMListHead *l;
+ int ret;
+
+ ret = drmAdjustListNodes(list);
+ if (ret)
+ return ret;
+
+ l = list->list.next;
+ while(l != &list->list) {
+ DRMLISTDEL(l);
+ DRMLISTADD(l, &list->free);
+ list->numOnList--;
+ l = list->list.next;
+ }
+ return drmAdjustListNodes(list);
+}
+
+static drmBONode *drmAddListItem(drmBOList *list, drmBO *item,
+ unsigned long arg0,
+ unsigned long arg1)
+{
+ drmBONode *node;
+ drmMMListHead *l;
+
+ l = list->free.next;
+ if (l == &list->free) {
+ node = (drmBONode *) malloc(sizeof(*node));
+ if (!node) {
+ return NULL;
+ }
+ list->numCurrent++;
+ } else {
+ DRMLISTDEL(l);
+ node = DRMLISTENTRY(drmBONode, l, head);
+ }
+ node->buf = item;
+ node->arg0 = arg0;
+ node->arg1 = arg1;
+ DRMLISTADD(&node->head, &list->list);
+ list->numOnList++;
+ return node;
+}
+
+void *drmBOListIterator(drmBOList *list)
+{
+ void *ret = list->list.next;
+
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+void *drmBOListNext(drmBOList *list, void *iterator)
+{
+ void *ret;
+
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ ret = l->next;
+ if (ret == &list->list)
+ return NULL;
+ return ret;
+}
+
+drmBO *drmBOListBuf(void *iterator)
+{
+ drmBONode *node;
+ drmMMListHead *l = (drmMMListHead *) iterator;
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ return node->buf;
+}
+
+
+int drmBOCreateList(int numTarget, drmBOList *list)
+{
+ DRMINITLISTHEAD(&list->list);
+ DRMINITLISTHEAD(&list->free);
+ list->numTarget = numTarget;
+ list->numCurrent = 0;
+ list->numOnList = 0;
+ return drmAdjustListNodes(list);
+}
+
+static void drmBOCopyReply(const drm_bo_arg_reply_t *rep,
+ drmBO *buf)
+{
+ buf->handle = rep->handle;
+ buf->flags = rep->flags;
+ buf->size = rep->size;
+ buf->offset = rep->offset;
+ buf->mapHandle = rep->arg_handle;
+ buf->mask = rep->mask;
+ buf->start = rep->buffer_start;
+ buf->fenceFlags = rep->fence_flags;
+ buf->replyFlags = rep->rep_flags;
+ buf->pageAlignment = rep->page_alignment;
+}
+
+
+
+int drmBOCreate(int fd, unsigned long start, unsigned long size,
+ unsigned pageAlignment, void *user_buffer, drm_bo_type_t type,
+ unsigned mask,
+ unsigned hint, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret;
+
+ memset(buf, 0, sizeof(*buf));
+ memset(&arg, 0, sizeof(arg));
+ req->mask = mask;
+ req->hint = hint;
+ req->size = size;
+ req->type = type;
+ req->page_alignment = pageAlignment;
+
+ buf->virtual = NULL;
+
+ switch(type) {
+ case drm_bo_type_dc:
+ req->buffer_start = start;
+ break;
+ case drm_bo_type_user:
+ req->buffer_start = (unsigned long) user_buffer;
+ buf->virtual = user_buffer;
+ break;
+ case drm_bo_type_fake:
+ req->buffer_start = start;
+ break;
+ default:
+ return -EINVAL;
+ }
+ req->op = drm_bo_create;
+
+ do {
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret != 0 && errno == EAGAIN);
+
+ if (ret)
+ return -errno;
+ if (!arg.handled) {
+ return -EFAULT;
+ }
+ if (rep->ret) {
+ fprintf(stderr, "Error %d\n", rep->ret);
+ return rep->ret;
+ }
+
+ drmBOCopyReply(rep, buf);
+ buf->mapVirtual = NULL;
+ buf->mapCount = 0;
+
+ return 0;
+}
+
+int drmBODestroy(int fd, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+
+ if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
+ (void) drmUnmap(buf->mapVirtual, buf->start + buf->size);
+ buf->mapVirtual = NULL;
+ buf->virtual = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->op = drm_bo_destroy;
+
+ if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ return -errno;
+ if (!arg.handled) {
+ return -EFAULT;
+ }
+ if (rep->ret) {
+ return rep->ret;
+ }
+
+ buf->handle = 0;
+ return 0;
+}
+
+int drmBOReference(int fd, unsigned handle, drmBO *buf)
+{
+
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = handle;
+ req->op = drm_bo_reference;
+
+ if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ return -errno;
+ if (!arg.handled) {
+ return -EFAULT;
+ }
+ if (rep->ret) {
+ return rep->ret;
+ }
+
+ drmBOCopyReply(rep, buf);
+ buf->type = drm_bo_type_dc;
+ buf->mapVirtual = NULL;
+ buf->mapCount = 0;
+ buf->virtual = NULL;
+
+ return 0;
+}
+
+int drmBOUnReference(int fd, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+
+
+ if (buf->mapVirtual && (buf->type != drm_bo_type_fake)) {
+ (void) munmap(buf->mapVirtual, buf->start + buf->size);
+ buf->mapVirtual = NULL;
+ buf->virtual = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->op = drm_bo_unreference;
+
+ if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg))
+ return -errno;
+ if (!arg.handled) {
+ return -EFAULT;
+ }
+ if (rep->ret) {
+ return rep->ret;
+ }
+
+ buf->handle = 0;
+ return 0;
+}
+
+/*
+ * Flags can be DRM_BO_FLAG_READ, DRM_BO_FLAG_WRITE or'ed together
+ * Hint currently be DRM_BO_HINT_DONT_BLOCK, which makes the
+ * call return an -EBUSY if it can' immediately honor the mapping request.
+ */
+
+int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
+ void **address)
+{
+
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret = 0;
+
+ /*
+ * Make sure we have a virtual address of the buffer.
+ */
+
+ if (!buf->virtual && buf->type != drm_bo_type_fake) {
+ drmAddress virtual;
+ virtual = mmap(0, buf->size + buf->start,
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ fd, buf->mapHandle);
+ if (virtual == MAP_FAILED) {
+ ret = -errno;
+ }
+ if (ret)
+ return ret;
+ buf->mapVirtual = virtual;
+ buf->virtual = ((char *) virtual) + buf->start;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->mask = mapFlags;
+ req->hint = mapHint;
+ req->op = drm_bo_map;
+
+ /*
+ * May hang if the buffer object is busy.
+ * This IOCTL synchronizes the buffer.
+ */
+
+ do {
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret != 0 && errno == EAGAIN);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ drmBOCopyReply(rep, buf);
+ buf->mapFlags = mapFlags;
+ ++buf->mapCount;
+ *address = buf->virtual;
+
+ return 0;
+}
+
+int drmBOUnmap(int fd, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->op = drm_bo_unmap;
+
+ if (ioctl(fd, DRM_IOCTL_BUFOBJ, &arg)) {
+ return -errno;
+ }
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ return 0;
+}
+
+int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
+ unsigned hint)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret = 0;
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->mask = flags;
+ req->hint = hint;
+ req->arg_handle = mask; /* Encode mask in the arg_handle field :/ */
+ req->op = drm_bo_validate;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret && errno == EAGAIN);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+
+ drmBOCopyReply(rep, buf);
+ return 0;
+}
+
+
+int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret = 0;
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->mask = flags;
+ req->arg_handle = fenceHandle;
+ req->op = drm_bo_validate;
+
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ return 0;
+}
+
+int drmBOInfo(int fd, drmBO *buf)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret = 0;
+
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->op = drm_bo_info;
+
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ drmBOCopyReply(rep, buf);
+ return 0;
+}
+
+int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint)
+{
+ drm_bo_arg_t arg;
+ drm_bo_arg_request_t *req = &arg.d.req;
+ drm_bo_arg_reply_t *rep = &arg.d.rep;
+ int ret = 0;
+
+ if ((buf->flags & DRM_BO_FLAG_SHAREABLE) ||
+ (buf->replyFlags & DRM_BO_REP_BUSY)) {
+ memset(&arg, 0, sizeof(arg));
+ req->handle = buf->handle;
+ req->op = drm_bo_wait_idle;
+ req->hint = hint;
+
+ do {
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, &arg);
+ } while (ret && errno == EAGAIN);
+
+ if (ret)
+ return ret;
+ if (!arg.handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ drmBOCopyReply(rep, buf);
+ }
+ return 0;
+}
+
+int drmBOBusy(int fd, drmBO *buf, int *busy)
+{
+ if (!(buf->flags & DRM_BO_FLAG_SHAREABLE) &&
+ !(buf->replyFlags & DRM_BO_REP_BUSY)) {
+ *busy = 0;
+ return 0;
+ } else {
+ int ret = drmBOInfo(fd, buf);
+ if (ret)
+ return ret;
+ *busy = (buf->replyFlags & DRM_BO_REP_BUSY);
+ return 0;
+ }
+}
+
+
+int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
+ unsigned mask,
+ int *newItem)
+{
+ drmBONode *node, *cur;
+ drmMMListHead *l;
+
+ *newItem = 0;
+ cur = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ if (node->buf == buf) {
+ cur = node;
+ break;
+ }
+ }
+ if (!cur) {
+ cur = drmAddListItem(list, buf, flags, mask);
+ if (!cur) {
+ drmMsg("Out of memory creating validate list node.\n");
+ return -ENOMEM;
+ }
+ *newItem = 1;
+ cur->arg0 = flags;
+ cur->arg1 = mask;
+ } else {
+ unsigned memMask = (cur->arg1 | mask) & DRM_BO_MASK_MEM;
+ unsigned memFlags = cur->arg0 & flags & memMask;
+
+ if (!memFlags) {
+ drmMsg("Incompatible memory location requests "
+ "on validate list.\n");
+ drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
+ cur->arg0, cur->arg1);
+ drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
+ flags, mask);
+ return -EINVAL;
+ }
+ if (mask & cur->arg1 & ~DRM_BO_MASK_MEM & (cur->arg0 ^ flags)) {
+ drmMsg("Incompatible buffer flag requests "
+ "on validate list.\n");
+ drmMsg("Previous flag: 0x%08lx, mask: 0x%08lx\n",
+ cur->arg0, cur->arg1);
+ drmMsg("Current flag: 0x%08lx, mask: 0x%08lx\n",
+ flags, mask);
+ return -EINVAL;
+ }
+ cur->arg1 |= mask;
+ cur->arg0 = memFlags | ((cur->arg0 | flags) &
+ cur->arg1 & ~DRM_BO_MASK_MEM);
+ }
+ return 0;
+}
+
+
+int drmBOValidateList(int fd, drmBOList *list)
+{
+
+ drmBONode *node;
+ drmMMListHead *l;
+ drm_bo_arg_t *arg, *first;
+ drm_bo_arg_request_t *req;
+ drm_bo_arg_reply_t *rep;
+ drm_u64_t *prevNext = NULL;
+ drmBO *buf;
+ int ret;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ memset(arg, 0, sizeof(*arg));
+ prevNext = &arg->next;
+ req->handle = node->buf->handle;
+ req->op = drm_bo_validate;
+ req->mask = node->arg0;
+ req->hint = 0;
+ req->arg_handle = node->arg1;
+ }
+
+ if (!first)
+ return 0;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
+ } while (ret && errno == EAGAIN);
+
+
+ if (ret)
+ return -errno;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+ arg = &node->bo_arg;
+ rep = &arg->d.rep;
+
+ if (!arg->handled) {
+ drmMsg("Unhandled request\n");
+ return -EFAULT;
+ }
+ if (rep->ret)
+ return rep->ret;
+
+ buf = node->buf;
+ drmBOCopyReply(rep, buf);
+ }
+
+ return 0;
+}
+
+
+int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle)
+{
+
+ drmBONode *node;
+ drmMMListHead *l;
+ drm_bo_arg_t *arg, *first;
+ drm_bo_arg_request_t *req;
+ drm_bo_arg_reply_t *rep;
+ drm_u64_t *prevNext = NULL;
+ int ret;
+
+ first = NULL;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ req = &arg->d.req;
+
+ if (!first)
+ first = arg;
+
+ if (prevNext)
+ *prevNext = (unsigned long) arg;
+
+ memset(arg, 0, sizeof(*arg));
+ prevNext = &arg->next;
+ req->handle = node->buf->handle;
+ req->op = drm_bo_fence;
+ req->mask = node->arg0;
+ req->arg_handle = fenceHandle;
+ }
+
+ if (!first)
+ return 0;
+
+ ret = ioctl(fd, DRM_IOCTL_BUFOBJ, first);
+
+ if (ret)
+ return -errno;
+
+ for (l = list->list.next; l != &list->list; l = l->next) {
+ node = DRMLISTENTRY(drmBONode, l, head);
+
+ arg = &node->bo_arg;
+ rep = &arg->d.rep;
+
+ if (!arg->handled)
+ return -EFAULT;
+ if (rep->ret)
+ return rep->ret;
+ drmBOCopyReply(rep, node->buf);
+ }
+
+ return 0;
+}
+
+int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
+ unsigned memType)
+{
+ drm_mm_init_arg_t arg;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.req.op = mm_init;
+ arg.req.p_offset = pOffset;
+ arg.req.p_size = pSize;
+ arg.req.mem_type = memType;
+
+ if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
+ return -errno;
+
+ return 0;
+}
+
+int drmMMTakedown(int fd, unsigned memType)
+{
+ drm_mm_init_arg_t arg;
+
+
+ memset(&arg, 0, sizeof(arg));
+ arg.req.op = mm_takedown;
+ arg.req.mem_type = memType;
+
+ if (ioctl(fd, DRM_IOCTL_MM_INIT, &arg))
+ return -errno;
+
+ return 0;
+}
+
+int drmMMLock(int fd, unsigned memType)
+{
+ drm_mm_init_arg_t arg;
+ int ret;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.req.op = mm_lock;
+ arg.req.mem_type = memType;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+ } while (ret && errno == EAGAIN);
+
+ return ret;
+}
+
+int drmMMUnlock(int fd, unsigned memType)
+{
+ drm_mm_init_arg_t arg;
+ int ret;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.req.op = mm_unlock;
+ arg.req.mem_type = memType;
+
+ do{
+ ret = ioctl(fd, DRM_IOCTL_MM_INIT, &arg);
+ } while (ret && errno == EAGAIN);
+
+ return ret;
+}
diff --git a/hw/xfree86/os-support/xf86drm.h b/hw/xfree86/os-support/xf86drm.h
index 107670672..18e4564d1 100644
--- a/hw/xfree86/os-support/xf86drm.h
+++ b/hw/xfree86/os-support/xf86drm.h
@@ -36,6 +36,7 @@
#define _XF86DRM_H_
#include <drm.h>
+#include <xf86mm.h>
/* Defaults, if nothing set in xf86config */
#define DRM_DEV_UID 0
diff --git a/hw/xfree86/os-support/xf86mm.h b/hw/xfree86/os-support/xf86mm.h
new file mode 100644
index 000000000..e1a4e3ed9
--- /dev/null
+++ b/hw/xfree86/os-support/xf86mm.h
@@ -0,0 +1,210 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ *
+ **************************************************************************/
+
+#ifndef _XF86MM_H_
+#define _XF86MM_H_
+#include <stddef.h>
+#include "drm.h"
+
+/*
+ * Note on multithreaded applications using this interface.
+ * Libdrm is not threadsafe, so common buffer, TTM, and fence objects need to
+ * be protected using an external mutex.
+ *
+ * Note: Don't protect the following functions, as it may lead to deadlocks:
+ * drmBOUnmap(), drmFenceBuffers().
+ * The kernel is synchronizing and refcounting buffer maps.
+ * User space only needs to refcount object usage within the same application.
+ */
+
+
+/*
+ * List macros heavily inspired by the Linux kernel
+ * list handling. No list looping yet.
+ */
+
+typedef struct _drmMMListHead
+{
+ struct _drmMMListHead *prev;
+ struct _drmMMListHead *next;
+} drmMMListHead;
+
+#define DRMINITLISTHEAD(__item) \
+ do{ \
+ (__item)->prev = (__item); \
+ (__item)->next = (__item); \
+ } while (0)
+
+#define DRMLISTADD(__item, __list) \
+ do { \
+ (__item)->prev = (__list); \
+ (__item)->next = (__list)->next; \
+ (__list)->next->prev = (__item); \
+ (__list)->next = (__item); \
+ } while (0)
+
+#define DRMLISTADDTAIL(__item, __list) \
+ do { \
+ (__item)->next = (__list); \
+ (__item)->prev = (__list)->prev; \
+ (__list)->prev->next = (__item); \
+ (__list)->prev = (__item); \
+ } while(0)
+
+#define DRMLISTDEL(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ } while(0)
+
+#define DRMLISTDELINIT(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ (__item)->next = (__item); \
+ (__item)->prev = (__item); \
+ } while(0)
+
+#define DRMLISTENTRY(__type, __item, __field) \
+ ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
+
+typedef struct _drmFence{
+ unsigned handle;
+ int class;
+ unsigned type;
+ unsigned flags;
+ unsigned signaled;
+ unsigned pad[4]; /* for future expansion */
+} drmFence;
+
+typedef struct _drmBO{
+ drm_bo_type_t type;
+ unsigned handle;
+ drm_u64_t mapHandle;
+ unsigned flags;
+ unsigned mask;
+ unsigned mapFlags;
+ unsigned long size;
+ unsigned long offset;
+ unsigned long start;
+ unsigned replyFlags;
+ unsigned fenceFlags;
+ unsigned pageAlignment;
+ void *virtual;
+ void *mapVirtual;
+ int mapCount;
+ unsigned pad[8]; /* for future expansion */
+} drmBO;
+
+
+typedef struct _drmBONode {
+ drmMMListHead head;
+ drmBO *buf;
+ drm_bo_arg_t bo_arg;
+ unsigned long arg0;
+ unsigned long arg1;
+} drmBONode;
+
+typedef struct _drmBOList {
+ unsigned numTarget;
+ unsigned numCurrent;
+ unsigned numOnList;
+ drmMMListHead list;
+ drmMMListHead free;
+} drmBOList;
+
+/* Fencing */
+
+extern int drmFenceCreate(int fd, unsigned flags, int class,
+ unsigned type,
+ drmFence *fence);
+extern int drmFenceDestroy(int fd, const drmFence *fence);
+extern int drmFenceReference(int fd, unsigned handle, drmFence *fence);
+extern int drmFenceUnreference(int fd, const drmFence *fence);
+extern int drmFenceFlush(int fd, drmFence *fence, unsigned flush_type);
+extern int drmFenceSignaled(int fd, drmFence *fence,
+ unsigned fenceType, int *signaled);
+extern int drmFenceWait(int fd, unsigned flags, drmFence *fence,
+ unsigned flush_type);
+extern int drmFenceEmit(int fd, unsigned flags, drmFence *fence,
+ unsigned emit_type);
+extern int drmFenceBuffers(int fd, unsigned flags, drmFence *fence);
+extern int drmFenceUpdate(int fd, drmFence *fence);
+
+
+/*
+ * Buffer object list functions.
+ */
+
+extern void drmBOFreeList(drmBOList *list);
+extern int drmBOResetList(drmBOList *list);
+extern void *drmBOListIterator(drmBOList *list);
+extern void *drmBOListNext(drmBOList *list, void *iterator);
+extern drmBO *drmBOListBuf(void *iterator);
+extern int drmBOCreateList(int numTarget, drmBOList *list);
+
+/*
+ * Buffer object functions.
+ */
+
+extern int drmBOCreate(int fd, unsigned long start, unsigned long size,
+ unsigned pageAlignment,void *user_buffer,
+ drm_bo_type_t type, unsigned mask,
+ unsigned hint, drmBO *buf);
+extern int drmBODestroy(int fd, drmBO *buf);
+extern int drmBOReference(int fd, unsigned handle, drmBO *buf);
+extern int drmBOUnReference(int fd, drmBO *buf);
+extern int drmBOMap(int fd, drmBO *buf, unsigned mapFlags, unsigned mapHint,
+ void **address);
+extern int drmBOUnmap(int fd, drmBO *buf);
+extern int drmBOValidate(int fd, drmBO *buf, unsigned flags, unsigned mask,
+ unsigned hint);
+extern int drmBOFence(int fd, drmBO *buf, unsigned flags, unsigned fenceHandle);
+extern int drmBOInfo(int fd, drmBO *buf);
+extern int drmBOBusy(int fd, drmBO *buf, int *busy);
+
+
+extern int drmAddValidateItem(drmBOList *list, drmBO *buf, unsigned flags,
+ unsigned mask,
+ int *newItem);
+extern int drmBOValidateList(int fd, drmBOList *list);
+extern int drmBOFenceList(int fd, drmBOList *list, unsigned fenceHandle);
+extern int drmBOWaitIdle(int fd, drmBO *buf, unsigned hint);
+
+/*
+ * Initialization functions.
+ */
+
+extern int drmMMInit(int fd, unsigned long pOffset, unsigned long pSize,
+ unsigned memType);
+extern int drmMMTakedown(int fd, unsigned memType);
+extern int drmMMLock(int fd, unsigned memType);
+extern int drmMMUnlock(int fd, unsigned memType);
+
+
+#endif
diff --git a/include/libdrm-config.h.in b/include/libdrm-config.h.in
new file mode 100644
index 000000000..286004b96
--- /dev/null
+++ b/include/libdrm-config.h.in
@@ -0,0 +1,10 @@
+/*
+ * libdrm-config.h.in: not at all generated.
+ */
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
diff --git a/os/utils.c b/os/utils.c
index c7a8964ef..65e131166 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -58,6 +58,8 @@ OR PERFORMANCE OF THIS SOFTWARE.
#ifdef _POSIX_C_SOURCE
#define _SAVED_POSIX_C_SOURCE _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
+#else if defined(sun) /* Needed to tell Solaris headers not to restrict to */
+#define __EXTENSIONS__ /* only the functions defined in POSIX 199309. */
#endif
#define _POSIX_C_SOURCE 199309L
#include <time.h>