Blob Blame History Raw
From 1dd898dc07dadbb2f115bbb177bb52d05bea2df3 Mon Sep 17 00:00:00 2001
From: Dave Airlie <airlied@redhat.com>
Date: Mon, 3 Aug 2009 14:09:32 +1000
Subject: [PATCH 03/15] X server: VGA arbitration.

This patch adds the VGA arb paths to the X server.

TODO:
test with lots more sigio mouse movement type stuff - RAC used to disable it
---
 configure.ac                           |    1 +
 hw/xfree86/common/Makefile.am          |    6 +-
 hw/xfree86/common/xf86Bus.c            |   15 +
 hw/xfree86/common/xf86DPMS.c           |    4 +-
 hw/xfree86/common/xf86Init.c           |   11 +-
 hw/xfree86/common/xf86PM.c             |    6 +-
 hw/xfree86/common/xf86VGAarbiter.c     | 1151 ++++++++++++++++++++++++++++++++
 hw/xfree86/common/xf86VGAarbiter.h     |   48 ++
 hw/xfree86/common/xf86VGAarbiterPriv.h |  266 ++++++++
 hw/xfree86/common/xf86str.h            |    4 +-
 hw/xfree86/dri/dri.c                   |    7 +
 hw/xfree86/dri2/dri2.c                 |    7 +
 hw/xfree86/int10/generic.c             |    2 +
 hw/xfree86/loader/sdksyms.sh           |    1 +
 include/xorg-config.h.in               |    3 +
 15 files changed, 1522 insertions(+), 10 deletions(-)
 create mode 100644 hw/xfree86/common/xf86VGAarbiter.c
 create mode 100644 hw/xfree86/common/xf86VGAarbiter.h
 create mode 100644 hw/xfree86/common/xf86VGAarbiterPriv.h

diff --git a/configure.ac b/configure.ac
index 1e3438e..a1219d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1388,6 +1388,7 @@ if test "x$XORG" = xyes; then
 	AC_CHECK_FUNCS([pci_system_init_dev_mem])
 	AC_CHECK_FUNCS([pci_device_enable])
 	AC_CHECK_FUNCS([pci_device_is_boot_vga])
+	AC_CHECK_FUNCS([pci_device_vgaarb_init])
 	LIBS=$SAVE_LIBS
 	CFLAGS=$SAVE_CFLAGS
 	XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $DLOPEN_LIBS $GLX_SYS_LIBS"
diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index f3e201b..ad27210 100644
--- a/hw/xfree86/common/Makefile.am
+++ b/hw/xfree86/common/Makefile.am
@@ -35,7 +35,7 @@ AM_LDFLAGS = -r
 libcommon_la_SOURCES = xf86Configure.c xf86ShowOpts.c xf86Bus.c xf86Config.c \
                       xf86Cursor.c $(DGASOURCES) xf86DPMS.c \
                       xf86Events.c xf86Globals.c xf86AutoConfig.c \
-                      xf86Option.c xf86Init.c \
+                      xf86Option.c xf86Init.c xf86VGAarbiter.c \
                       xf86VidMode.c xf86fbman.c xf86cmap.c \
                       xf86Helper.c xf86PM.c xf86Xinput.c xisb.c \
                       xf86Mode.c xorgHelper.c \
@@ -52,7 +52,7 @@ sdk_HEADERS = compiler.h fourcc.h xf86.h xf86Module.h xf86Opt.h \
               xf86PciInfo.h xf86Priv.h xf86Privstr.h \
               xf86cmap.h xf86fbman.h xf86str.h xf86Xinput.h xisb.h \
               $(XVSDKINCS) $(XF86VMODE_SDK) xorgVersion.h \
-              xf86sbusBus.h
+              xf86sbusBus.h xf86VGAarbiter.h
 
 DISTCLEANFILES = xf86Build.h
 CLEANFILES = $(BUILT_SOURCES)
@@ -83,6 +83,8 @@ EXTRA_DIST = \
 	xorgVersion.h \
 	$(MODEDEFSOURCES) \
 	modeline2c.awk \
+	xf86VGAarbiter.h \
+	xf86VGAarbiterPriv.h \
         $(DISTKBDSOURCES)
 
 if LNXACPI
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 01716ed..bf6a6f8 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -48,6 +48,7 @@
 #define XF86_OS_PRIVS
 #define NEED_OS_RAC_PROTOS
 #include "xf86_OSproc.h"
+#include "xf86VGAarbiter.h"
 
 #include "Pci.h"
 
@@ -545,11 +546,25 @@ xf86PostPreInit(void)
 void
 xf86PostScreenInit(void)
 {
+    int i;
+    int vga_count;
     if (doFramebufferMode) {
 	SetSIGIOForState(OPERATING);
 	return;
     }
 
+    /*
+     * we need to wrap the arbiter if we have more than
+     * one VGA card - hotplug cries.
+     */
+#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
+    pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
+    if (vga_count > 1 && xf86Screens) {
+	xf86Msg(X_INFO,"Number of VGA devices: %d: arbiter wrapping enabled\n", vga_count);
+        for (i = 0; i < xf86NumScreens; i++)
+	    xf86VGAarbiterWrapFunctions(xf86Screens[i]->pScreen);
+    }
+#endif
     DebugF("PostScreenInit  generation: %i\n",serverGeneration);
     xf86EnterServerState(OPERATING);
     
diff --git a/hw/xfree86/common/xf86DPMS.c b/hw/xfree86/common/xf86DPMS.c
index f78267d..22174c7 100644
--- a/hw/xfree86/common/xf86DPMS.c
+++ b/hw/xfree86/common/xf86DPMS.c
@@ -42,6 +42,7 @@
 #include <X11/extensions/dpmsconst.h>
 #include "dpmsproc.h"
 #endif
+#include "xf86VGAarbiter.h"
 
 
 #ifdef DPMSExtension
@@ -162,8 +163,9 @@ DPMSSet(ClientPtr client, int level)
     	pScrn = xf86Screens[i];
 	pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
 	if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) { 
-	    xf86EnableAccess(pScrn);
+	    xf86VGAarbiterLock(pScrn);
 	    pScrn->DPMSSet(pScrn, level, 0);
+	    xf86VGAarbiterUnlock(pScrn);
 	}
     }
     return Success;
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index 44eed4d..e84da4e 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -78,6 +78,7 @@
 #include "picturestr.h"
 #endif
 
+#include "xf86VGAarbiter.h"
 #include "globals.h"
 
 #ifdef DPMSExtension
@@ -714,6 +715,8 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
       return;
     }
 
+    xf86VGAarbiterInit();
+
     /*
      * Match up the screens found by the probes against those specified
      * in the config file.  Remove the ones that won't be used.  Sort
@@ -794,10 +797,12 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
      */
 
     for (i = 0; i < xf86NumScreens; i++) {
-	xf86EnableAccess(xf86Screens[i]);
+	xf86VGAarbiterScrnInit(xf86Screens[i]);
+	xf86VGAarbiterLock(xf86Screens[i]);
 	if (xf86Screens[i]->PreInit &&
 	    xf86Screens[i]->PreInit(xf86Screens[i], 0))
 	    xf86Screens[i]->configured = TRUE;
+	xf86VGAarbiterUnlock(xf86Screens[i]);
     }
     for (i = 0; i < xf86NumScreens; i++)
 	if (!xf86Screens[i]->configured)
@@ -1010,7 +1015,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 #endif /* SCO325 */
 
   for (i = 0; i < xf86NumScreens; i++) {
-	xf86EnableAccess(xf86Screens[i]);
+	xf86VGAarbiterLock(xf86Screens[i]);
 	/*
 	 * Almost everything uses these defaults, and many of those that
 	 * don't, will wrap them.
@@ -1025,6 +1030,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 	xf86Screens[i]->DriverFunc = NULL;
 	xf86Screens[i]->pScreen = NULL;
 	scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+	xf86VGAarbiterUnlock(xf86Screens[i]);
       if (scr_index == i) {
 	/*
 	 * Hook in our ScrnInfoRec, and initialise some other pScreen
@@ -1222,7 +1228,6 @@ AbortDDX(void)
 	       * we might not have been wrapped yet. Therefore enable
 	       * screen explicitely.
 	       */
-	      xf86EnableAccess(xf86Screens[i]);
 	      (xf86Screens[i]->LeaveVT)(i, 0);
 	  }
   }
diff --git a/hw/xfree86/common/xf86PM.c b/hw/xfree86/common/xf86PM.c
index f6138c3..fa24813 100644
--- a/hw/xfree86/common/xf86PM.c
+++ b/hw/xfree86/common/xf86PM.c
@@ -100,7 +100,7 @@ resume(pmEvent event, Bool undo)
     xf86AccessEnter();
     xf86EnterServerState(SETUP);
     for (i = 0; i < xf86NumScreens; i++) {
-        xf86EnableAccess(xf86Screens[i]);
+     //   xf86EnableAccess(xf86Screens[i]);
 	if (xf86Screens[i]->PMEvent)
 	    xf86Screens[i]->PMEvent(i,event,undo);
 	else {
@@ -110,7 +110,7 @@ resume(pmEvent event, Bool undo)
     }
     xf86EnterServerState(OPERATING);
     for (i = 0; i < xf86NumScreens; i++) {
-        xf86EnableAccess(xf86Screens[i]);
+        //xf86EnableAccess(xf86Screens[i]);
 	if (xf86Screens[i]->EnableDisableFBAccess)
 	    (*xf86Screens[i]->EnableDisableFBAccess) (i, TRUE);
     }
@@ -165,7 +165,7 @@ DoApmEvent(pmEvent event, Bool undo)
 	    if (xf86Screens[i]->PMEvent) {
 		if (!setup) xf86EnterServerState(SETUP);
 		setup = 1;
-		xf86EnableAccess(xf86Screens[i]);
+//		xf86EnableAccess(xf86Screens[i]);
 		xf86Screens[i]->PMEvent(i,event,undo);
 	    }
 	}
diff --git a/hw/xfree86/common/xf86VGAarbiter.c b/hw/xfree86/common/xf86VGAarbiter.c
new file mode 100644
index 0000000..13802cd
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiter.c
@@ -0,0 +1,1151 @@
+/*
+ * This code was stolen from RAC and adapted to control the legacy vga
+ * interface.
+ *
+ *
+ * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
+ *
+ * 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, sublicense, 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 above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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.
+ *
+ */
+
+#include "xorg-config.h"
+
+#include "xf86VGAarbiter.h"
+#include "xf86VGAarbiterPriv.h"
+#include "xf86Bus.h"
+#include "pciaccess.h"
+
+#ifdef DEBUG
+#error "no, really, you dont want to do this"
+#define DPRINT_S(x,y) ErrorF(x ": %i\n",y);
+#define DPRINT(x) ErrorF(x "\n");
+#else
+#define DPRINT_S(x,y)
+#define DPRINT(x)
+#endif
+
+#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
+
+static GCFuncs VGAarbiterGCFuncs = {
+    VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
+    VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
+    VGAarbiterCopyClip
+};
+
+static GCOps VGAarbiterGCOps = {
+    VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
+    VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
+    VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
+    VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
+    VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
+    VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
+    VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
+    {NULL}      /* devPrivate */
+};
+
+static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
+    VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
+    VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
+    VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
+};
+
+static int VGAarbiterKeyIndex;
+static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
+static int VGAarbiterGCIndex;
+static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
+
+static int vga_no_arb = 0;
+void
+xf86VGAarbiterInit(void)
+{
+    if (pci_device_vgaarb_init() != 0) {
+	vga_no_arb = 1;
+        Error("VGA Arbiter: cannot open vga arbiter fd. Exiting\n");
+    }
+}
+
+void
+xf86VGAarbiterFini(void)
+{
+    pci_device_vgaarb_fini();
+}
+
+void
+xf86VGAarbiterLock(ScrnInfoPtr pScrn)
+{
+    pci_device_vgaarb_set_target(pScrn->vgaDev);
+    pci_device_vgaarb_lock();
+}
+
+void
+xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
+{
+    pci_device_vgaarb_unlock();
+}
+
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
+{
+    int vga_count;
+    int rsrc_decodes;
+    ScrnInfoPtr         pScrn = xf86Screens[pScreen->myNum];
+
+    if (vga_no_arb)
+	return TRUE;
+
+    pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
+    if (vga_count > 1) {
+        if (rsrc_decodes) {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+void
+xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
+{
+    struct pci_device *dev;
+    EntityPtr pEnt;
+
+    if (vga_no_arb)
+	return;
+
+    pEnt = xf86Entities[pScrn->entityList[0]];
+    if (pEnt->bus.type != BUS_PCI)
+	return;
+
+    dev = pEnt->bus.id.pci;
+    pScrn->vgaDev = dev;
+}
+
+void
+xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
+{
+    if (vga_no_arb)
+	return;
+    pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
+}
+
+Bool
+xf86VGAarbiterWrapFunctions(ScreenPtr pScreen)
+{
+    ScrnInfoPtr pScrn;
+    VGAarbiterScreenPtr pScreenPriv;
+    miPointerScreenPtr PointPriv;
+#ifdef RENDER
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    if (vga_no_arb)
+	return FALSE;
+
+    pScrn = xf86Screens[pScreen->myNum];
+    PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+    DPRINT_S("VGAarbiterWrapFunctions",pScreen->myNum);
+
+    if (!dixRequestPrivate(VGAarbiterGCKey, sizeof(VGAarbiterGCRec)))
+    	return FALSE;
+
+    if (!(pScreenPriv = xalloc(sizeof(VGAarbiterScreenRec))))
+    	return FALSE;
+
+    dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
+
+    WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
+    WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
+    WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
+    WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
+    WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
+    WRAP_SCREEN(GetImage, VGAarbiterGetImage);
+    WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
+    WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
+    WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
+    WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
+    WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
+    WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
+    WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
+    WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
+    WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
+    WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
+    WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
+#ifdef RENDER
+    WRAP_PICT(Composite,VGAarbiterComposite);
+    WRAP_PICT(Glyphs,VGAarbiterGlyphs);
+    WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
+#endif
+    WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
+    WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
+    WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
+    WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
+    WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
+    WRAP_SPRITE;
+    return TRUE;
+}
+
+/* Screen funcs */
+static Bool
+VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
+{
+    Bool val;
+    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+    miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, miPointerScreenKey);
+#ifdef RENDER
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    DPRINT_S("VGAarbiterCloseScreen",pScreen->myNum);
+    UNWRAP_SCREEN(CreateGC);
+    UNWRAP_SCREEN(CloseScreen);
+    UNWRAP_SCREEN(GetImage);
+    UNWRAP_SCREEN(GetSpans);
+    UNWRAP_SCREEN(SourceValidate);
+    UNWRAP_SCREEN(CopyWindow);
+    UNWRAP_SCREEN(ClearToBackground);
+    UNWRAP_SCREEN(SaveScreen);
+    UNWRAP_SCREEN(StoreColors);
+    UNWRAP_SCREEN(DisplayCursor);
+    UNWRAP_SCREEN(RealizeCursor);
+    UNWRAP_SCREEN(UnrealizeCursor);
+    UNWRAP_SCREEN(RecolorCursor);
+    UNWRAP_SCREEN(SetCursorPosition);
+#ifdef RENDER
+    UNWRAP_PICT(Composite);
+    UNWRAP_PICT(Glyphs);
+    UNWRAP_PICT(CompositeRects);
+#endif
+    UNWRAP_SCREEN_INFO(AdjustFrame);
+    UNWRAP_SCREEN_INFO(SwitchMode);
+    UNWRAP_SCREEN_INFO(EnterVT);
+    UNWRAP_SCREEN_INFO(LeaveVT);
+    UNWRAP_SCREEN_INFO(FreeScreen);
+    UNWRAP_SPRITE;
+
+    xfree ((pointer) pScreenPriv);
+    xf86VGAarbiterLock(xf86Screens[i]);
+    val = (*pScreen->CloseScreen) (i, pScreen);
+    xf86VGAarbiterUnlock(xf86Screens[i]);
+    return val;
+}
+
+static void
+VGAarbiterBlockHandler(int i,
+                       pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+    ScreenPtr pScreen = screenInfo.screens[i];
+    SCREEN_PROLOG(BlockHandler);
+    VGAGet();
+    pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+    VGAPut();
+    SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
+}
+
+static void
+VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
+{
+    ScreenPtr pScreen = screenInfo.screens[i];
+    SCREEN_PROLOG(WakeupHandler);
+    VGAGet();
+    pScreen->WakeupHandler(i, blockData, result, pReadmask);
+    VGAPut();
+    SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
+}
+
+static void
+VGAarbiterGetImage (
+    DrawablePtr pDrawable,
+    int sx, int sy, int w, int h,
+    unsigned int    format,
+    unsigned long   planemask,
+    char        *pdstLine
+    )
+{
+    ScreenPtr pScreen = pDrawable->pScreen;
+    DPRINT_S("VGAarbiterGetImage",pScreen->myNum);
+    SCREEN_PROLOG(GetImage);
+//    if (xf86Screens[pScreen->myNum]->vtSema) {
+    VGAGet();
+//    }
+    (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+              format, planemask, pdstLine);
+    VGAPut();
+    SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
+}
+
+static void
+VGAarbiterGetSpans (
+    DrawablePtr pDrawable,
+    int     wMax,
+    DDXPointPtr ppt,
+    int     *pwidth,
+    int     nspans,
+    char    *pdstStart
+    )
+{
+    ScreenPtr       pScreen = pDrawable->pScreen;
+
+    DPRINT_S("VGAarbiterGetSpans",pScreen->myNum);
+    SCREEN_PROLOG (GetSpans);
+    VGAGet();
+    (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+    VGAPut();
+    SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
+}
+
+static void
+VGAarbiterSourceValidate (
+    DrawablePtr pDrawable,
+    int x, int y, int width, int height )
+{
+    ScreenPtr   pScreen = pDrawable->pScreen;
+    DPRINT_S("VGAarbiterSourceValidate",pScreen->myNum);
+    SCREEN_PROLOG (SourceValidate);
+    VGAGet();
+    if (pScreen->SourceValidate)
+    (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+    VGAPut();
+    SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
+}
+
+static void
+VGAarbiterCopyWindow(
+    WindowPtr pWin,
+    DDXPointRec ptOldOrg,
+    RegionPtr prgnSrc )
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DPRINT_S("VGAarbiterCopyWindow",pScreen->myNum);
+    SCREEN_PROLOG (CopyWindow);
+    VGAGet();
+    (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+    VGAPut();
+    SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
+}
+
+static void
+VGAarbiterClearToBackground (
+    WindowPtr pWin,
+    int x, int y,
+    int w, int h,
+    Bool generateExposures )
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+
+    DPRINT_S("VGAarbiterClearToBackground",pScreen->myNum);
+    SCREEN_PROLOG ( ClearToBackground);
+    VGAGet();
+    (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+    VGAPut();
+    SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
+}
+
+static PixmapPtr
+VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
+{
+    PixmapPtr pPix;
+
+    DPRINT_S("VGAarbiterCreatePixmap",pScreen->myNum);
+    SCREEN_PROLOG ( CreatePixmap);
+    VGAGet();
+    pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
+    VGAPut();
+    SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
+
+    return pPix;
+}
+
+static Bool
+VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+    Bool val;
+
+    DPRINT_S("VGAarbiterSaveScreen",pScreen->myNum);
+    SCREEN_PROLOG (SaveScreen);
+    VGAGet();
+    val = (*pScreen->SaveScreen) (pScreen, unblank);
+    VGAPut();
+    SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
+
+    return val;
+}
+
+static void
+VGAarbiterStoreColors (
+    ColormapPtr        pmap,
+    int                ndef,
+    xColorItem         *pdefs)
+{
+    ScreenPtr pScreen = pmap->pScreen;
+
+    DPRINT_S("VGAarbiterStoreColors",pScreen->myNum);
+    SCREEN_PROLOG (StoreColors);
+    VGAGet();
+    (*pScreen->StoreColors) (pmap,ndef,pdefs);
+    VGAPut();
+    SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
+}
+
+static void
+VGAarbiterRecolorCursor (
+    DeviceIntPtr pDev,
+    ScreenPtr pScreen,
+    CursorPtr pCurs,
+    Bool displayed
+    )
+{
+    DPRINT_S("VGAarbiterRecolorCursor",pScreen->myNum);
+    SCREEN_PROLOG (RecolorCursor);
+    VGAGet();
+    (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
+    VGAPut();
+    SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
+}
+
+static Bool
+VGAarbiterRealizeCursor (
+    DeviceIntPtr pDev,
+    ScreenPtr   pScreen,
+    CursorPtr   pCursor
+    )
+{
+    Bool val;
+
+    DPRINT_S("VGAarbiterRealizeCursor",pScreen->myNum);
+    SCREEN_PROLOG (RealizeCursor);
+    VGAGet();
+    val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
+    VGAPut();
+    SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
+    return val;
+}
+
+static Bool
+VGAarbiterUnrealizeCursor (
+    DeviceIntPtr pDev,
+    ScreenPtr   pScreen,
+    CursorPtr   pCursor
+    )
+{
+    Bool val;
+
+    DPRINT_S("VGAarbiterUnrealizeCursor",pScreen->myNum);
+    SCREEN_PROLOG (UnrealizeCursor);
+    VGAGet();
+    val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
+    VGAPut();
+    SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
+    return val;
+}
+
+static Bool
+VGAarbiterDisplayCursor (
+    DeviceIntPtr pDev,
+    ScreenPtr   pScreen,
+    CursorPtr   pCursor
+    )
+{
+    Bool val;
+
+    DPRINT_S("VGAarbiterDisplayCursor",pScreen->myNum);
+    SCREEN_PROLOG (DisplayCursor);
+    VGAGet();
+    val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
+    VGAPut();
+    SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
+    return val;
+}
+
+static Bool
+VGAarbiterSetCursorPosition (
+    DeviceIntPtr pDev,
+    ScreenPtr   pScreen,
+    int x, int y,
+    Bool generateEvent)
+{
+    Bool val;
+
+    DPRINT_S("VGAarbiterSetCursorPosition",pScreen->myNum);
+    SCREEN_PROLOG (SetCursorPosition);
+    VGAGet();
+    val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
+    VGAPut();
+    SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
+    return val;
+}
+
+static void
+VGAarbiterAdjustFrame(int index, int x, int y, int flags)
+{
+    ScreenPtr pScreen = screenInfo.screens[index];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+
+    DPRINT_S("VGAarbiterAdjustFrame",index);
+    VGAGet();
+    (*pScreenPriv->AdjustFrame)(index, x, y, flags);
+    VGAPut();
+}
+
+static Bool
+VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+    Bool val;
+    ScreenPtr pScreen = screenInfo.screens[index];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+
+    DPRINT_S("VGAarbiterSwitchMode",index);
+    VGAGet();
+    val = (*pScreenPriv->SwitchMode)(index, mode, flags);
+    VGAPut();
+    return val;
+}
+
+static Bool
+VGAarbiterEnterVT(int index, int flags)
+{
+    Bool val;
+    ScreenPtr pScreen = screenInfo.screens[index];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+
+    DPRINT_S("VGAarbiterEnterVT",index);
+    VGAGet();
+    val = (*pScreenPriv->EnterVT)(index, flags);
+    VGAPut();
+    return val;
+}
+
+static void
+VGAarbiterLeaveVT(int index, int flags)
+{
+    ScreenPtr pScreen = screenInfo.screens[index];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+
+    DPRINT_S("VGAarbiterLeaveVT",index);
+
+    VGAGet();
+    (*pScreenPriv->LeaveVT)(index, flags);
+    VGAPut();
+}
+
+static void
+VGAarbiterFreeScreen(int index, int flags)
+{
+    ScreenPtr pScreen = screenInfo.screens[index];
+    VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+        &pScreen->devPrivates, VGAarbiterScreenKey);
+
+    DPRINT_S("VGAarbiterFreeScreen",index);
+
+    VGAGet();
+    (*pScreenPriv->FreeScreen)(index, flags);
+    VGAPut();
+}
+
+static Bool
+VGAarbiterCreateGC(GCPtr pGC)
+{
+    ScreenPtr    pScreen = pGC->pScreen;
+    VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
+    Bool         ret;
+
+    DPRINT_S("VGAarbiterCreateGC",pScreen->myNum);
+    SCREEN_PROLOG(CreateGC);
+    VGAGet();
+    ret = (*pScreen->CreateGC)(pGC);
+    VGAPut();
+    GC_WRAP(pGC);
+    SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
+
+    return ret;
+}
+
+/* GC funcs */
+static void
+VGAarbiterValidateGC(
+   GCPtr         pGC,
+   unsigned long changes,
+   DrawablePtr   pDraw )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterValidateGC");
+    (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+    GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterDestroyGC(GCPtr pGC)
+{
+    GC_UNWRAP (pGC);
+    DPRINT("VGAarbiterDestroyGC");
+    (*pGC->funcs->DestroyGC)(pGC);
+    GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterChangeGC (
+    GCPtr       pGC,
+    unsigned long   mask)
+{
+    GC_UNWRAP (pGC);
+    DPRINT("VGAarbiterChangeGC");
+    (*pGC->funcs->ChangeGC) (pGC, mask);
+    GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyGC (
+    GCPtr       pGCSrc,
+    unsigned long   mask,
+    GCPtr       pGCDst)
+{
+    GC_UNWRAP (pGCDst);
+    DPRINT("VGAarbiterCopyGC");
+    (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+    GC_WRAP (pGCDst);
+}
+
+static void
+VGAarbiterChangeClip (
+    GCPtr   pGC,
+    int     type,
+    pointer pvalue,
+    int     nrects )
+{
+    GC_UNWRAP (pGC);
+    DPRINT("VGAarbiterChangeClip");
+    (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+    GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+    GC_UNWRAP (pgcDst);
+    DPRINT("VGAarbiterCopyClip");
+    (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+    GC_WRAP (pgcDst);
+}
+
+static void
+VGAarbiterDestroyClip(GCPtr pGC)
+{
+    GC_UNWRAP (pGC);
+    DPRINT("VGAarbiterDestroyClip");
+    (* pGC->funcs->DestroyClip)(pGC);
+    GC_WRAP (pGC);
+}
+
+/* GC Ops */
+static void
+VGAarbiterFillSpans(
+    DrawablePtr pDraw,
+    GC      *pGC,
+    int     nInit,
+    DDXPointPtr pptInit,
+    int *pwidthInit,
+    int fSorted )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterFillSpans");
+    VGAGet_GC();
+    (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterSetSpans(
+    DrawablePtr     pDraw,
+    GCPtr       pGC,
+    char        *pcharsrc,
+    register DDXPointPtr ppt,
+    int         *pwidth,
+    int         nspans,
+    int         fSorted )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterSetSpans");
+    VGAGet_GC();
+    (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPutImage(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     depth,
+    int x, int y, int w, int h,
+    int     leftPad,
+    int     format,
+    char    *pImage )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPutImage");
+    VGAGet_GC();
+    (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+              leftPad, format, pImage);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static RegionPtr
+VGAarbiterCopyArea(
+    DrawablePtr pSrc,
+    DrawablePtr pDst,
+    GC *pGC,
+    int srcx, int srcy,
+    int width, int height,
+    int dstx, int dsty )
+{
+    RegionPtr ret;
+
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterCopyArea");
+    VGAGet_GC();
+    ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+                pGC, srcx, srcy, width, height, dstx, dsty);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+    return ret;
+}
+
+static RegionPtr
+VGAarbiterCopyPlane(
+    DrawablePtr pSrc,
+    DrawablePtr pDst,
+    GCPtr pGC,
+    int srcx, int srcy,
+    int width, int height,
+    int dstx, int dsty,
+    unsigned long bitPlane )
+{
+    RegionPtr ret;
+
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterCopyPlane");
+    VGAGet_GC();
+    ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
+                 width, height, dstx, dsty, bitPlane);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+    return ret;
+}
+
+static void
+VGAarbiterPolyPoint(
+    DrawablePtr pDraw,
+    GCPtr pGC,
+    int mode,
+    int npt,
+    xPoint *pptInit )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyPoint");
+    VGAGet_GC();
+    (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterPolylines(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     mode,
+    int     npt,
+    DDXPointPtr pptInit )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolylines");
+    VGAGet_GC();
+    (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolySegment(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     nseg,
+    xSegment    *pSeg )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolySegment");
+    VGAGet_GC();
+    (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyRectangle(
+    DrawablePtr  pDraw,
+    GCPtr        pGC,
+    int          nRectsInit,
+    xRectangle  *pRectsInit )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyRectangle");
+    VGAGet_GC();
+    (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyArc(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     narcs,
+    xArc    *parcs )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyArc");
+    VGAGet_GC();
+    (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterFillPolygon(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     shape,
+    int     mode,
+    int     count,
+    DDXPointPtr ptsIn )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterFillPolygon");
+    VGAGet_GC();
+    (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillRect(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     nrectFill,
+    xRectangle  *prectInit)
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyFillRect");
+    VGAGet_GC();
+    (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillArc(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     narcs,
+    xArc    *parcs )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyFillArc");
+    VGAGet_GC();
+    (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static int
+VGAarbiterPolyText8(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     x,
+    int     y,
+    int     count,
+    char    *chars )
+{
+    int ret;
+
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyText8");
+    VGAGet_GC();
+    ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+    return ret;
+}
+
+static int
+VGAarbiterPolyText16(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     x,
+    int     y,
+    int     count,
+    unsigned short *chars )
+{
+    int ret;
+
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyText16");
+    VGAGet_GC();
+    ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+    return ret;
+}
+
+static void
+VGAarbiterImageText8(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     x,
+    int     y,
+    int     count,
+    char    *chars )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterImageText8");
+    VGAGet_GC();
+    (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterImageText16(
+    DrawablePtr pDraw,
+    GCPtr   pGC,
+    int     x,
+    int     y,
+    int     count,
+    unsigned short *chars )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterImageText16");
+    VGAGet_GC();
+    (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterImageGlyphBlt(
+    DrawablePtr pDraw,
+    GCPtr pGC,
+    int xInit, int yInit,
+    unsigned int nglyph,
+    CharInfoPtr *ppci,
+    pointer pglyphBase )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterImageGlyphBlt");
+    VGAGet_GC();
+    (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
+                   nglyph, ppci, pglyphBase);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyGlyphBlt(
+    DrawablePtr pDraw,
+    GCPtr pGC,
+    int xInit, int yInit,
+    unsigned int nglyph,
+    CharInfoPtr *ppci,
+    pointer pglyphBase )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPolyGlyphBlt");
+    VGAGet_GC();
+    (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
+                  nglyph, ppci, pglyphBase);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPushPixels(
+    GCPtr   pGC,
+    PixmapPtr   pBitMap,
+    DrawablePtr pDraw,
+    int dx, int dy, int xOrg, int yOrg )
+{
+    GC_UNWRAP(pGC);
+    DPRINT("VGAarbiterPushPixels");
+    VGAGet_GC();
+    (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+    VGAPut_GC();
+    GC_WRAP(pGC);
+}
+
+
+/* miSpriteFuncs */
+static Bool
+VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+    Bool val;
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterSpriteRealizeCursor",pScreen->myNum);
+    VGAGet();
+    val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
+    VGAPut();
+    SPRITE_EPILOG;
+    return val;
+}
+
+static Bool
+VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+    Bool val;
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterSpriteUnrealizeCursor",pScreen->myNum);
+    VGAGet();
+    val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
+    VGAPut();
+    SPRITE_EPILOG;
+    return val;
+}
+
+static void
+VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
+{
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterSpriteSetCursor",pScreen->myNum);
+    VGAGet();
+    PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
+    VGAPut();
+    SPRITE_EPILOG;
+}
+
+static void
+VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterSpriteMoveCursor",pScreen->myNum);
+    VGAGet();
+    PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
+    VGAPut();
+    SPRITE_EPILOG;
+}
+
+static Bool
+VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    Bool val;
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterDeviceCursorInitialize",pScreen->myNum);
+    VGAGet();
+    val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+    VGAPut();
+    SPRITE_EPILOG;
+    return val;
+}
+
+static void
+VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+    SPRITE_PROLOG;
+    DPRINT_S("VGAarbiterDeviceCursorCleanup",pScreen->myNum);
+    VGAGet();
+    PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
+    VGAPut();
+    SPRITE_EPILOG;
+}
+
+#ifdef RENDER
+static void
+VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+         PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
+         INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
+         CARD16 height)
+{
+    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    PICTURE_PROLOGUE(Composite);
+
+    VGAGet();
+    (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
+              yDst, width, height);
+    VGAPut();
+    PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
+}
+
+static void
+VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+      PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
+      GlyphListPtr list, GlyphPtr *glyphs)
+{
+    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    PICTURE_PROLOGUE(Glyphs);
+
+    VGAGet();
+    (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+    VGAPut();
+    PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
+}
+
+static void
+VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
+          xRectangle *rects)
+{
+    ScreenPtr       pScreen = pDst->pDrawable->pScreen;
+    PictureScreenPtr    ps = GetPictureScreen(pScreen);
+
+    PICTURE_PROLOGUE(CompositeRects);
+
+    VGAGet();
+    (*ps->CompositeRects)(op, pDst, color, nRect, rects);
+    VGAPut();
+    PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
+}
+#endif
+#else
+/* dummy functions */
+void xf86VGAarbiterInit(void) {}
+void xf86VGAarbiterFini(void) {}
+
+void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
+void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterWrapFunctions(ScreenPtr pScreen) { return FALSE; }
+
+#endif
diff --git a/hw/xfree86/common/xf86VGAarbiter.h b/hw/xfree86/common/xf86VGAarbiter.h
new file mode 100644
index 0000000..145d31c
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiter.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009 Tiago Vignatti
+ *
+ * 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, sublicense, 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 above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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.
+ */
+
+#ifndef __XF86VGAARBITER_H
+#define __XF86VGAARBITER_H
+
+#include "screenint.h"
+#include "misc.h"
+#include "xf86.h"
+
+/* Functions */
+extern void xf86VGAarbiterInit(void);
+extern void xf86VGAarbiterFini(void);
+void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn);
+extern Bool xf86VGAarbiterWrapFunctions(ScreenPtr pScreen);
+extern void xf86VGAarbiterLock(ScrnInfoPtr pScrn);
+extern void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn);
+
+/* allow a driver to remove itself from arbiter - really should be
+ * done in the kernel though */
+extern _X_EXPORT void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn);
+/* DRI and arbiter are really not possible together,
+ * you really want to remove the card from arbitration if you can */
+extern _X_EXPORT Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen);
+
+#endif /* __XF86VGAARBITER_H */
diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h
new file mode 100644
index 0000000..40d4368
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2009 Tiago Vignatti
+ *
+ * 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, sublicense, 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 above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * 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
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS 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.
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include <X11/X.h>
+#include "colormapst.h"
+#include "scrnintstr.h"
+#include "screenint.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "pixmap.h"
+#include "windowstr.h"
+#include "window.h"
+#include "xf86str.h"
+#include "mipointer.h"
+#include "mipointrst.h"
+#ifdef RENDER
+# include "picturestr.h"
+#endif
+
+
+#define WRAP_SCREEN(x,y) {pScreenPriv->x = pScreen->x; pScreen->x = y;}
+
+#define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x
+
+#define SCREEN_PROLOG(x) pScreen->x = ((VGAarbiterScreenPtr) \
+    dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))->x
+
+#define SCREEN_EPILOG(x,y) pScreen->x = y;
+
+#define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\
+    ps->x = y;}
+
+#define UNWRAP_PICT(x) if (ps) {ps->x = pScreenPriv->x;}
+
+#define PICTURE_PROLOGUE(field) ps->field = \
+    ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \
+    VGAarbiterScreenKey))->field
+
+#define PICTURE_EPILOGUE(field, wrap) ps->field = wrap
+
+#define WRAP_SCREEN_INFO(x,y) do {pScreenPriv->x = pScrn->x; pScrn->x = y;} while(0)
+
+#define UNWRAP_SCREEN_INFO(x) pScrn->x = pScreenPriv->x
+
+#define SPRITE_PROLOG miPointerScreenPtr PointPriv = \
+    (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates, \
+    miPointerScreenKey); VGAarbiterScreenPtr pScreenPriv = \
+    ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \
+    VGAarbiterScreenKey)); PointPriv->spriteFuncs = pScreenPriv->miSprite;
+
+#define SPRITE_EPILOG pScreenPriv->miSprite = PointPriv->spriteFuncs;\
+    PointPriv->spriteFuncs  = &VGAarbiterSpriteFuncs;
+
+#define WRAP_SPRITE do { pScreenPriv->miSprite = PointPriv->spriteFuncs;\
+    	PointPriv->spriteFuncs  = &VGAarbiterSpriteFuncs; 		\
+	} while (0)
+
+#define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite
+
+#define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\
+    pGCPriv->wrapFuncs = (x)->funcs; (x)->ops = &VGAarbiterGCOps;\
+    (x)->funcs = &VGAarbiterGCFuncs;
+
+#define GC_UNWRAP(x) VGAarbiterGCPtr  pGCPriv = \
+    (VGAarbiterGCPtr)dixLookupPrivate(&(x)->devPrivates, VGAarbiterGCKey);\
+    (x)->ops = pGCPriv->wrapOps; (x)->funcs = pGCPriv->wrapFuncs;
+
+#define GC_SCREEN register ScrnInfoPtr pScrn = \
+    xf86Screens[pGC->pScreen->myNum]
+
+#define VGAGet(x)\
+    pci_device_vgaarb_set_target(xf86Screens[pScreen->myNum]->vgaDev); \
+    pci_device_vgaarb_lock();
+
+#define VGAGet_GC(x)\
+    pci_device_vgaarb_set_target(xf86Screens[pGC->pScreen->myNum]->vgaDev); \
+    pci_device_vgaarb_lock();
+
+#define VGAPut(x)\
+    pci_device_vgaarb_unlock();
+
+#define VGAPut_GC(x)\
+    pci_device_vgaarb_unlock();
+
+
+typedef struct _VGAarbiterScreen {
+    CreateGCProcPtr             CreateGC;
+    CloseScreenProcPtr          CloseScreen;
+    ScreenBlockHandlerProcPtr   BlockHandler;
+    ScreenWakeupHandlerProcPtr  WakeupHandler;
+    GetImageProcPtr             GetImage;
+    GetSpansProcPtr             GetSpans;
+    SourceValidateProcPtr       SourceValidate;
+    CopyWindowProcPtr           CopyWindow;
+    ClearToBackgroundProcPtr    ClearToBackground;
+    CreatePixmapProcPtr         CreatePixmap;
+    SaveScreenProcPtr           SaveScreen;
+    /* Colormap */
+    StoreColorsProcPtr          StoreColors;
+    /* Cursor */
+    DisplayCursorProcPtr        DisplayCursor;
+    RealizeCursorProcPtr        RealizeCursor;
+    UnrealizeCursorProcPtr      UnrealizeCursor;
+    RecolorCursorProcPtr        RecolorCursor;
+    SetCursorPositionProcPtr    SetCursorPosition;
+    void                        (*AdjustFrame)(int,int,int,int);
+    Bool                        (*SwitchMode)(int, DisplayModePtr,int);
+    Bool                        (*EnterVT)(int, int);
+    void                        (*LeaveVT)(int, int);
+    void                        (*FreeScreen)(int, int);
+    miPointerSpriteFuncPtr      miSprite;
+#ifdef RENDER
+    CompositeProcPtr            Composite;
+    GlyphsProcPtr               Glyphs;
+    CompositeRectsProcPtr       CompositeRects;
+#endif
+} VGAarbiterScreenRec, *VGAarbiterScreenPtr;
+
+typedef struct _VGAarbiterGC {
+    GCOps                       *wrapOps;
+    GCFuncs                     *wrapFuncs;
+} VGAarbiterGCRec, *VGAarbiterGCPtr;
+
+/* Screen funcs */
+static void VGAarbiterBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask);
+static void VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask);
+static Bool VGAarbiterCloseScreen (int i, ScreenPtr pScreen);
+static void VGAarbiterGetImage (DrawablePtr pDrawable, int sx, int sy, int w,
+    int h, unsigned int format, unsigned long planemask, char *pdstLine);
+static void VGAarbiterGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr
+    ppt, int *pwidth, int nspans, char  *pdstStart);
+static void VGAarbiterSourceValidate (DrawablePtr pDrawable, int x, int y,
+    int width, int height);
+static void VGAarbiterCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg,
+    RegionPtr prgnSrc);
+static void VGAarbiterClearToBackground (WindowPtr pWin, int x, int y, int w,
+    int h, Bool generateExposures);
+static PixmapPtr VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h,
+    int depth, unsigned int usage_hint);
+static Bool  VGAarbiterCreateGC(GCPtr pGC);
+static Bool VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank);
+static void VGAarbiterStoreColors (ColormapPtr pmap, int ndef, xColorItem
+    *pdefs);
+static void VGAarbiterRecolorCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
+    CursorPtr pCurs, Bool displayed);
+static Bool VGAarbiterRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
+    CursorPtr pCursor);
+static Bool VGAarbiterUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
+    CursorPtr pCursor);
+static Bool VGAarbiterDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen,
+    CursorPtr pCursor);
+static Bool VGAarbiterSetCursorPosition (DeviceIntPtr pDev, ScreenPtr
+    pScreen, int x, int y, Bool generateEvent);
+static void VGAarbiterAdjustFrame(int index, int x, int y, int flags);
+static Bool VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags);
+static Bool VGAarbiterEnterVT(int index, int flags);
+static void VGAarbiterLeaveVT(int index, int flags);
+static void VGAarbiterFreeScreen(int index, int flags);
+
+/* GC funcs */
+static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes,
+    DrawablePtr pDraw);
+static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask);
+static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void VGAarbiterDestroyGC(GCPtr pGC);
+static void VGAarbiterChangeClip(GCPtr pGC, int type, pointer pvalue,
+    int nrects);
+static void VGAarbiterDestroyClip(GCPtr pGC);
+static void VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+/* GC ops */
+static void VGAarbiterFillSpans( DrawablePtr pDraw, GC *pGC, int nInit,
+    DDXPointPtr pptInit, int *pwidthInit, int fSorted);
+static void VGAarbiterSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc,
+    register DDXPointPtr ppt, int *pwidth, int nspans, int fSorted);
+static void VGAarbiterPutImage(DrawablePtr pDraw, GCPtr pGC, int depth,
+    int x, int y, int w, int h, int leftPad, int format, char *pImage);
+static RegionPtr VGAarbiterCopyArea(DrawablePtr pSrc, DrawablePtr pDst,
+    GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty);
+static RegionPtr VGAarbiterCopyPlane(DrawablePtr pSrc, DrawablePtr pDst,
+    GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty,
+    unsigned long bitPlane);
+static void VGAarbiterPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode,
+    int npt, xPoint *pptInit);
+static void VGAarbiterPolylines(DrawablePtr pDraw, GCPtr pGC, int mode,
+    int npt, DDXPointPtr pptInit);
+static void VGAarbiterPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg,
+    xSegment *pSeg);
+static void VGAarbiterPolyRectangle(DrawablePtr pDraw, GCPtr pGC,
+    int nRectsInit, xRectangle *pRectsInit);
+static void VGAarbiterPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
+    xArc *parcs);
+static void VGAarbiterFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape,
+    int mode, int count, DDXPointPtr ptsIn);
+static void VGAarbiterPolyFillRect( DrawablePtr pDraw, GCPtr pGC,
+    int nrectFill, xRectangle *prectInit);
+static void VGAarbiterPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs,
+    xArc *parcs);
+static int VGAarbiterPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+    int count, char *chars);
+static int VGAarbiterPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+    int count, unsigned short *chars);
+static void VGAarbiterImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+    int count, char *chars);
+static void VGAarbiterImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+    int count, unsigned short *chars);
+static void VGAarbiterImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
+    int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);
+static void VGAarbiterPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit,
+    int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase);
+static void VGAarbiterPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr
+    pDraw, int dx, int dy, int xOrg, int yOrg);
+
+/* miSpriteFuncs */
+static Bool VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr
+    pScreen, CursorPtr pCur);
+static Bool VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr
+    pScreen, CursorPtr pCur);
+static void VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+    CursorPtr pCur, int x, int y);
+static void VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+    int x, int y);
+static Bool VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen);
+static void VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen);
+
+
+#ifdef RENDER
+static void VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+    PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
+    INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+static void VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+    PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr
+    list, GlyphPtr *glyphs);
+static void VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor
+    *color, int nRect, xRectangle *rects);
+#endif
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 9cb66eb..5c3ee44 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -517,7 +517,7 @@ typedef struct _confdrirec {
 
 /* These values should be adjusted when new fields are added to ScrnInfoRec */
 #define NUM_RESERVED_INTS		16
-#define NUM_RESERVED_POINTERS		15
+#define NUM_RESERVED_POINTERS		14
 #define NUM_RESERVED_FUNCS		11
 
 typedef pointer (*funcPointer)(void);
@@ -808,6 +808,8 @@ typedef struct _ScrnInfoRec {
     int			reservedInt[NUM_RESERVED_INTS];
 
     int *		entityInstanceList;
+    struct pci_device   *vgaDev;
+
     pointer		reservedPtr[NUM_RESERVED_POINTERS];
 
     /*
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 3af9878..d32b284 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -69,6 +69,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "mipointer.h"
 #include "xf86_OSproc.h"
 #include "inputstr.h"
+#include "xf86VGAarbiter.h"
 
 #define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
 
@@ -333,6 +334,12 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
 	return FALSE;
     }
 
+    if (!xf86VGAarbiterAllowDRI(pScreen)) {
+        DRIDrvMsg(pScreen->myNum, X_WARNING,
+                  "Direct rendering is not supported when VGA arb is necessary for the device\n");
+	return FALSE;
+    }
+		
     /*
      * If Xinerama is on, don't allow DRI to initialise.  It won't be usable
      * anyway.
diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c
index 8795cd1..d15ced1 100644
--- a/hw/xfree86/dri2/dri2.c
+++ b/hw/xfree86/dri2/dri2.c
@@ -39,6 +39,7 @@
 #include "scrnintstr.h"
 #include "windowstr.h"
 #include "dri2.h"
+#include "xf86VGAarbiter.h"
 
 #include "xf86.h"
 
@@ -414,6 +415,12 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
     if (info->version < 3)
 	return FALSE;
 
+    if (!xf86VGAarbiterAllowDRI(pScreen)) {
+        xf86DrvMsg(pScreen->myNum, X_WARNING,
+                  "[DRI2] Direct rendering is not supported when VGA arb is necessary for the device\n");
+        return FALSE;
+    }
+
     ds = xalloc(sizeof *ds);
     if (!ds)
 	return FALSE;
diff --git a/hw/xfree86/int10/generic.c b/hw/xfree86/int10/generic.c
index 9d39e99..655e535 100644
--- a/hw/xfree86/int10/generic.c
+++ b/hw/xfree86/int10/generic.c
@@ -224,11 +224,13 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 	default:
 	    goto error1;
 	}
+#if 0
 	pInt->BIOSseg = V_BIOS >> 4;
 	pInt->num = 0xe6;
 	LockLegacyVGA(pInt, &vga);
 	xf86ExecX86int10(pInt);
 	UnlockLegacyVGA(pInt, &vga);
+#endif
     }
 #else
     if (!sysMem) {
diff --git a/hw/xfree86/loader/sdksyms.sh b/hw/xfree86/loader/sdksyms.sh
index 8bda8d7..1186547 100755
--- a/hw/xfree86/loader/sdksyms.sh
+++ b/hw/xfree86/loader/sdksyms.sh
@@ -121,6 +121,7 @@ cat > sdksyms.c << EOF
 #include "xf86fbman.h"
 #include "xf86str.h"
 #include "xf86Xinput.h"
+#include "xf86VGAarbiter.h"
 #include "xisb.h"
 #if XV
 # include "xf86xv.h"
diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in
index ffb35f8..603ae13 100644
--- a/include/xorg-config.h.in
+++ b/include/xorg-config.h.in
@@ -124,6 +124,9 @@
 /* Have pci_enable_device */
 #undef HAVE_PCI_DEVICE_ENABLE
 
+/* Define to 1 if you have the `pci_device_vgaarb_init' function. */
+#undef HAVE_PCI_DEVICE_VGAARB_INIT
+
 /* Path to text files containing PCI IDs */
 #undef PCI_TXT_IDS_PATH
 
-- 
1.6.4