[RFC] Xorg VGA arbitration (again!) (xserver-vgaarbiter.diff)

Tiago Vignatti vignatti at freedesktop.org
Thu May 14 16:58:28 PDT 2009


diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am
index fbd052c..c257462 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 xf86RAC.c xf86Xinput.c xisb.c \
                       xf86Mode.c xorgHelper.c \
@@ -84,6 +84,7 @@ EXTRA_DIST = \
 	xorgVersion.h \
 	$(MODEDEFSOURCES) \
 	modeline2c.awk \
+	xf86VGAarbiter.h \
         $(DISTKBDSOURCES)
 
 if LNXACPI
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 8040f58..9e9527b 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -52,6 +52,7 @@
 
 #include "xf86RAC.h"
 #include "Pci.h"
+#include "xf86VGAarbiter.h"
 
 /* Entity data */
 EntityPtr *xf86Entities = NULL;	/* Bus slots claimed by drivers */
@@ -541,12 +542,14 @@ clearAccess(void)
 void
 xf86AccessInit(void)
 {
+#if 0
     initPciState();
     initPciBusState();
     DisablePciBusAccess();
     DisablePciAccess();
     
     xf86ResAccessEnter = TRUE;
+#endif
 }
 
 /*
@@ -556,6 +559,7 @@ xf86AccessInit(void)
 void
 xf86AccessEnter(void)
 {
+#if 0
     if (xf86ResAccessEnter) 
 	return;
 
@@ -571,6 +575,7 @@ xf86AccessEnter(void)
     notifyStateChange(NOTIFY_ENTER);
     xf86EnterServerState(SETUP);
     xf86ResAccessEnter = TRUE;
+#endif
 }
 
 /*
@@ -585,22 +590,26 @@ xf86AccessEnter(void)
 void
 xf86AccessLeave(void)
 {
+#if 0
     if (!xf86ResAccessEnter)
 	return;
     notifyStateChange(NOTIFY_LEAVE);
     disableAccess();
     DisablePciBusAccess();
     EntityLeave();
+#endif
 }
 
 void
 xf86AccessLeaveState(void)
 {
+#if 0
     if (!xf86ResAccessEnter)
 	return;
     xf86ResAccessEnter = FALSE;
     PciStateLeave();
     PciBusStateLeave();
+#endif
 }
 
 /*
@@ -642,12 +651,14 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
 #ifdef DEBUG
     ErrorF("Enable access %i\n",pScrn->scrnIndex);
 #endif
+    pci_device_vgaarb_lock(pScrn->VgaDev);
 
     /* Entity is not under access control or currently enabled */
     if (!pScrn->access) {
 	if (pScrn->busAccess) {
 	    ((BusAccPtr)pScrn->busAccess)->set_f(pScrn->busAccess);
 	}
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 	return;
     }
     
@@ -655,6 +666,7 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
     case IO:
 	pceAcc = pScrn->CurrentAccess->pIoAccess;
 	if (peAcc == pceAcc) {
+        pci_device_vgaarb_unlock(pScrn->VgaDev);
 	    return;
 	}
 	if (pScrn->CurrentAccess->pMemAccess == pceAcc)
@@ -674,8 +686,9 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
 	    peAcc = peAcc->next;
 	}
 	pScrn->CurrentAccess->pIoAccess = (EntityAccessPtr) pScrn->access;
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 	return;
-	
+
     case MEM_IO:
 	pceAcc = pScrn->CurrentAccess->pIoAccess;
 	if (peAcc != pceAcc) { /* current Io != pAccess */
@@ -699,6 +712,7 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
 	} else {    /* current Io == pAccess */
 	    pceAcc = pScrn->CurrentAccess->pMemAccess;
 	    if (pceAcc == peAcc) { /* current Mem == pAccess */
+        pci_device_vgaarb_unlock(pScrn->VgaDev);
 		return;
 	    }
 	    while (pceAcc) {  /* current Mem != pAccess */
@@ -718,11 +732,13 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
 	}
 	pScrn->CurrentAccess->pMemAccess =
 	    pScrn->CurrentAccess->pIoAccess = (EntityAccessPtr) pScrn->access;
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 	return;
 	
     case MEM:
 	pceAcc = pScrn->CurrentAccess->pMemAccess;
 	if (peAcc == pceAcc) {
+        pci_device_vgaarb_unlock(pScrn->VgaDev);
 	    return;
 	}
 	if (pScrn->CurrentAccess->pIoAccess == pceAcc)
@@ -742,12 +758,14 @@ xf86EnableAccess(ScrnInfoPtr pScrn)
 	    peAcc = peAcc->next;
 	}
 	pScrn->CurrentAccess->pMemAccess = (EntityAccessPtr) pScrn->access;
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 	return;
 
     case NONE:
 	if (pScrn->busAccess) {
 	    ((BusAccPtr)pScrn->busAccess)->set_f(pScrn->busAccess);
 	}
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 	return;
     }
 }
@@ -759,7 +777,7 @@ xf86SetCurrentAccess(Bool Enable, ScrnInfoPtr pScrn)
     register EntityAccessPtr pceAcc = NULL;
     register xf86AccessPtr pAcc;
 
-    
+    pci_device_vgaarb_lock(pScrn->VgaDev);
     switch(pScrn->resourceType) {
     case IO:
 	pceAcc = pScrn->CurrentAccess->pIoAccess;
@@ -790,6 +808,7 @@ xf86SetCurrentAccess(Bool Enable, ScrnInfoPtr pScrn)
 	    pceAcc2 = NULL;
 	}
     }
+    pci_device_vgaarb_unlock(pScrn->VgaDev);
 }
 
 void
@@ -1316,6 +1335,24 @@ xf86ConvertListToHost(int entityIndex, resPtr list)
     }
 }
 
+static resList
+xf86GetResourcesImplicitly(int entityIndex)
+{
+    if (entityIndex >= xf86NumEntities) return NULL;
+
+    switch (xf86Entities[entityIndex]->bus.type) {
+    case BUS_ISA:
+    case BUS_NONE:
+    case BUS_SBUS:
+    return NULL;
+    case BUS_PCI:
+    return GetImplicitPciResources(entityIndex);
+    case BUS_last:
+    return NULL;
+    }
+    return NULL;
+}
+
 /*
  * xf86RegisterResources() -- attempts to register listed resources.
  * Returns a resPtr listing all resources not successfully registered, by
@@ -1328,8 +1365,12 @@ xf86RegisterResources(int entityIndex, resList list, unsigned long access)
     resRange range;
     resList list_f = NULL;
 
-    if (!list)
-	return NULL;
+    if (!list) {
+    list = xf86GetResourcesImplicitly(entityIndex);
+    /* these resources have to be in host address space already */
+    if (!list) return NULL;
+    list_f = list;
+    }
 
     while(list->type != ResEnd) {
 	range = *list;
@@ -1545,6 +1586,7 @@ SetSIGIOForState(xf86State state)
 void
 xf86EnterServerState(xf86State state)
 {
+#if 0
     EntityPtr pEnt;
     ScrnInfoPtr pScrn;
     int i,j;
@@ -1643,6 +1685,7 @@ xf86EnterServerState(xf86State state)
 	notifyStateChange(NOTIFY_SETUP);
     else
 	notifyStateChange(NOTIFY_OPERATING);
+#endif
 }
 
 /*
@@ -1740,6 +1783,7 @@ xf86ClaimFixedResources(resList list, int entityIndex)
 static void
 checkRoutingForScreens(xf86State state)
 {
+#if 0
     resList list = resVgaUnusedExclusive;
     resPtr pResVGA = NULL;
     resPtr pResVGAHost;
@@ -1813,6 +1857,7 @@ checkRoutingForScreens(xf86State state)
 	}
     }
     xf86FreeResList(pResVGA);
+#endif
 }
 
 /*
@@ -2044,8 +2089,18 @@ xf86PostScreenInit(void)
 		flags |= xf86Screens[i]->racIoFlags;
 		xf86ErrorFVerb(3, "Screen %d is using RAC for io\n", i);
 	    }
-	    
-	    xf86RACInit(pScreen,flags);
+        
+        /*
+         * FIXME: need use the arbiter flags and not the RAC ones.
+         *
+         * TODO: need to double check if _all_ those functions really need to be
+         * wrapped by the arbiter. This is driver's responsibility.
+         */
+        xf86VGAarbiterWrapFunctions(pScreen, flags);
+
+        /* FIXME: disables RAC for now. Find a better way to do this.
+	       xf86RACInit(pScreen,flags); */
+        needRAC = FALSE;
 	}
     }
     
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index 0db7717..6f17eb8 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -61,6 +61,7 @@
 #include "xf86RAC.h"
 #include "xf86Bus.h"
 #include "xf86Crtc.h"
+#include "xf86Resources.h"
 
 /* For xf86GetClocks */
 #if defined(CSRG_BASED) || defined(__GNU__)
@@ -2482,12 +2483,22 @@ xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
     if (xf86IsEntityShared(entityIndex)) {
         return pScrn;
     }
+#if 0
     if (p_chip) {
 	for (p_id = p_chip; p_id->numChipset != -1; p_id++) {
 	    if (pEnt->chipset == p_id->numChipset) break;
 	}
 	xf86ClaimFixedResources(p_id->resList,entityIndex);
     }
+#endif
+    /* XXX: Some drivers aren't reporting correctly the resources being used
+     * in post-pciaccess Xorg. Until we don't build a nice scheme to arbitrate
+     * the resources (and given that I'm lazy to fix all drivers), lets assume
+     * that _all_ resources are RES_SHARED_VGA -- relax, it has no side effect
+     * with one-card machines.
+     */
+    xf86ClaimFixedResources((resRange*)RES_SHARED_VGA, entityIndex);
+
     xfree(pEnt);
 
     xf86ClaimFixedResources(res,entityIndex);
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index cf28ae7..977c97a 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -89,6 +89,7 @@
 #include <pciaccess.h>
 #include "Pci.h"
 #include "xf86Bus.h"
+#include "xf86VGAarbiter.h"
 
 /* forward declarations */
 static Bool probe_devices_from_device_sections(DriverPtr drvp);
@@ -950,6 +951,9 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
 	    "Screen %d deleted because of no matching config section.\n", i);
         xf86DeleteScreen(i--, 0);
       }
+
+      /* Initialize the legagy VGA arbitration */
+      xf86VGAarbiterInit(xf86Screens[i]);
     }
 
     /*
diff --git a/hw/xfree86/common/xf86VGAarbiter.c b/hw/xfree86/common/xf86VGAarbiter.c
new file mode 100644
index 0000000..c6f496c
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiter.c
@@ -0,0 +1,1058 @@
+/*
+ * 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 "xf86VGAarbiter.h"
+#include "xf86VGAarbiterPriv.h"
+#include "pciaccess.h"
+
+#ifdef DEBUG
+#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
+
+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
+};
+
+static int VGAarbiterKeyIndex;
+static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
+static int VGAarbiterGCIndex;
+static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
+
+void
+xf86VGAarbiterInit(ScrnInfoPtr pScrn)
+{
+    int bus, devi, func;
+    GDevPtr dev_tmp;
+    struct pci_device *dev;
+
+
+    dev_tmp = xf86GetDevFromEntity(pScrn->entityList[0],
+                                   pScrn->entityInstanceList[0]);
+
+    sscanf(dev_tmp->busID, "PCI:%d:%d:%d", &bus, &devi, &func);
+    ErrorF("VGA Arbiter: using PCI:%d:%d:%d\n", bus, devi, func);
+
+    dev = pci_device_find_by_slot(0, bus, devi, func);
+
+    /* Open vga arbiter fd */
+    if (pci_device_vgaarb_init(dev) != 0)
+        FatalError("VGA Arbiter: cannot open vga arbiter fd. Exiting\n");
+
+    /* Set the vga card target */
+    pci_device_vgaarb_set_target(dev);
+
+    /*
+     * Indicates to the arbiter if the card decodes legacy VGA IOs,
+     * legacy VGA Memory, both, or none. All cards default to both,
+     * the card driver (fbdev for example) should tell the arbiter
+     * if it has disabled legacy decoding, so the card can be left
+     * out of the arbitration process (and can be safe to take
+     * interrupts at any time.
+     *
+     * This is really driver dependent. So the driver must set up its
+     * own configuration probably in PreInit().
+     */
+    dev->vgaarb_rsrc = VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO;
+    pci_device_vgaarb_decodes(dev);
+
+    pScrn->VgaDev = dev;
+}
+
+/* TODO: implement properly
+void
+xf86VGAarbiterFini(void)
+{
+    pci_device_vgaarb_fini();
+}
+*/
+
+Bool
+xf86VGAarbiterWrapFunctions(ScreenPtr pScreen, unsigned int flag)
+{
+    ScrnInfoPtr pScrn;
+    VGAarbiterScreenPtr pScreenPriv;
+    miPointerScreenPtr PointPriv;
+#ifdef RENDER
+    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+    pScrn = xf86Screens[pScreen->myNum];
+    PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+    DPRINT_S("VGAarbiterInit",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_COND(CreateGC, VGAarbiterCreateGC, VGAARBITER_FB);
+    WRAP_SCREEN_COND(GetImage, VGAarbiterGetImage, VGAARBITER_FB);
+    WRAP_SCREEN_COND(GetSpans, VGAarbiterGetSpans, VGAARBITER_FB);
+    WRAP_SCREEN_COND(SourceValidate, VGAarbiterSourceValidate, VGAARBITER_FB);
+    WRAP_SCREEN_COND(CopyWindow, VGAarbiterCopyWindow, VGAARBITER_FB);
+    WRAP_SCREEN_COND(ClearToBackground, VGAarbiterClearToBackground, VGAARBITER_FB);
+    WRAP_SCREEN_COND(CreatePixmap, VGAarbiterCreatePixmap, VGAARBITER_FB);
+    WRAP_SCREEN_COND(StoreColors, VGAarbiterStoreColors, VGAARBITER_COLORMAP);
+    WRAP_SCREEN_COND(DisplayCursor, VGAarbiterDisplayCursor, VGAARBITER_CURSOR);
+    WRAP_SCREEN_COND(RealizeCursor, VGAarbiterRealizeCursor, VGAARBITER_CURSOR);
+    WRAP_SCREEN_COND(UnrealizeCursor, VGAarbiterUnrealizeCursor, VGAARBITER_CURSOR);
+    WRAP_SCREEN_COND(RecolorCursor, VGAarbiterRecolorCursor, VGAARBITER_CURSOR);
+    WRAP_SCREEN_COND(SetCursorPosition, VGAarbiterSetCursorPosition, VGAARBITER_CURSOR);
+#ifdef RENDER
+    WRAP_PICT_COND(Composite,VGAarbiterComposite,VGAARBITER_FB);
+    WRAP_PICT_COND(Glyphs,VGAarbiterGlyphs,VGAARBITER_FB);
+    WRAP_PICT_COND(CompositeRects,VGAarbiterCompositeRects,VGAARBITER_FB);
+#endif
+    WRAP_SCREEN_INFO_COND(AdjustFrame, VGAarbiterAdjustFrame, VGAARBITER_VIEWPORT);
+    WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
+    WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
+    WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
+    WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
+    WRAP_SPRITE_COND(VGAARBITER_CURSOR);
+
+    return TRUE;
+}
+
+/* Screen funcs */
+static Bool
+VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
+{
+    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);
+#if 0
+    if (xf86Screens[pScreen->myNum]->vtSema) {
+    xf86EnterServerState(SETUP);
+    xf86EnableAccess(xf86Screens[pScreen->myNum]);
+    }
+#endif
+    return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+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;
+}
+
+#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
diff --git a/hw/xfree86/common/xf86VGAarbiter.h b/hw/xfree86/common/xf86VGAarbiter.h
new file mode 100644
index 0000000..758cf21
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiter.h
@@ -0,0 +1,45 @@
+/*
+ * 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(ScrnInfoPtr pScrn);
+extern Bool xf86VGAarbiterWrapFunctions(ScreenPtr pScreen, unsigned int flag);
+
+
+/* flags XXX: We're using the same flags of RAC. KILL THEM ALL! */
+#define VGAARBITER_FB       0x01
+#define VGAARBITER_CURSOR   0x02
+#define VGAARBITER_COLORMAP 0x04
+#define VGAARBITER_VIEWPORT 0x08
+
+#endif /* __XF86VGAARBITER_H */
diff --git a/hw/xfree86/common/xf86VGAarbiterPriv.h b/hw/xfree86/common/xf86VGAarbiterPriv.h
new file mode 100644
index 0000000..ee20daa
--- /dev/null
+++ b/hw/xfree86/common/xf86VGAarbiterPriv.h
@@ -0,0 +1,263 @@
+/*
+ * 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 WRAP_SCREEN_COND(x,y,cond) {pScreenPriv->x = pScreen->x;\
+    if (flag & (cond)) 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_COND(x,y,cond) if (ps) {pScreenPriv->x = ps->x;\
+    if (flag & (cond)) 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) {pScreenPriv->x = pScrn->x; pScrn->x = y;}
+
+#define WRAP_SCREEN_INFO_COND(x,y,cond) {pScreenPriv->x = pScrn->x; \
+    if (flag & (cond)) pScrn->x = y;}
+
+#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_COND(cond){pScreenPriv->miSprite =\
+    PointPriv->spriteFuncs; if(flag & (cond))\
+    PointPriv->spriteFuncs  = &VGAarbiterSpriteFuncs;}
+
+#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_lock(xf86Screens[pScreen->myNum]->VgaDev);
+
+#define VGAGet_GC(x)\
+    pci_device_vgaarb_lock(xf86Screens[pGC->pScreen->myNum]->VgaDev);
+
+#define VGAPut(x)\
+    pci_device_vgaarb_unlock(xf86Screens[pScreen->myNum]->VgaDev);
+
+#define VGAPut_GC(x)\
+    pci_device_vgaarb_unlock(xf86Screens[pGC->pScreen->myNum]->VgaDev);
+
+
+typedef struct _VGAarbiterScreen {
+    CreateGCProcPtr             CreateGC;
+    CloseScreenProcPtr          CloseScreen;
+    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 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);
+
+#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/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 854a837..9315ae3 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -924,3 +924,35 @@ pciConvertRange2Host(int entityIndex, resRange *pRange)
     pRange->type &= ~(ResDomain | ResBus);
     pRange->type |= pvp->domain << 24;
 }
+
+resList
+GetImplicitPciResources(int entityIndex)
+{
+    int i, num = 0;
+    resList list = NULL;
+
+    struct pci_device *const dev = xf86GetPciInfoForEntity(entityIndex);
+    if (!dev)
+        return NULL;
+
+    for (i = 0; i < 6; i++) {
+        struct pci_mem_region *r = &dev->regions[i];
+        if (r->size && !r->is_IO) {
+            list = xnfrealloc(list,sizeof(resRange) * (++num));
+            list[num - 1].a = r->base_addr;
+            list[num - 1].b = r->base_addr + r->size - 1;
+            list[num - 1].type = ResShrMemBlock | ResBios;
+        }
+        /*TODO: not sure if this deals correctly with IO accesses.
+         else if (r->size && !r->is_IO) {
+            list = xnfrealloc(list,sizeof(resRange) * (++num));
+            list[num - 1].a = r->base_addr;
+            list[num - 1].b = r->base_addr + r->size - 1;
+            list[num - 1].type = ResShrIoBlock | ResBios;
+        }*/
+    }
+    list = xnfrealloc(list,sizeof(resRange) * (++num));
+    list[num - 1].type = ResEnd;
+
+    return list;
+}
diff --git a/hw/xfree86/common/xf86pciBus.h b/hw/xfree86/common/xf86pciBus.h
index 1cbfa38..d0d501f 100644
--- a/hw/xfree86/common/xf86pciBus.h
+++ b/hw/xfree86/common/xf86pciBus.h
@@ -70,5 +70,6 @@ void PciBusStateEnter(void);
 void PciStateLeave(void);
 void PciBusStateLeave(void);
 void pciConvertRange2Host(int entityIndex, resRange *pRange);
+resList GetImplicitPciResources(int entityIndex);
 
 #endif /* _XF86_PCI_BUS_H */
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index 904c369..42986cd 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -1000,6 +1000,13 @@ typedef struct _ScrnInfoRec {
      */
     funcPointer		reservedFuncs[NUM_RESERVED_FUNCS];
 
+    /*
+     * For now this field is only for the VGA arbiter usage.
+     *
+     * I'm not sure if the mapping 1:1 of the screen:arbiter is enough. Have
+     * to thought a little about this. I'm lazy.
+     */
+    struct pci_device *VgaDev;
 } ScrnInfoRec;
 
 
diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c
index 8274bbb..80f4128 100644
--- a/hw/xfree86/os-support/linux/int10/linux.c
+++ b/hw/xfree86/os-support/linux/int10/linux.c
@@ -98,9 +98,11 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
 
     options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
+    pci_device_vgaarb_lock(xf86Screens[screen]->VgaDev);
 
     if (int10skip(options)) {
 	xfree(options);
+    pci_device_vgaarb_unlock(xf86Screens[screen]->VgaDev);
 	return NULL;
     }
 
@@ -108,8 +110,10 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
     if (loadedSubModule == INT10_NOT_LOADED) 
 	loadedSubModule = int10LinuxLoadSubModule(xf86Screens[screen]);
 
-    if (loadedSubModule == INT10_LOAD_FAILED)
+    if (loadedSubModule == INT10_LOAD_FAILED) { 
+    pci_device_vgaarb_unlock(xf86Screens[screen]->VgaDev);
 	return NULL;
+    } 
 #endif
 
     if ((!vidMem) || (!sysMem)) {
@@ -300,15 +304,16 @@ xf86ExtendedInitInt10(int entityIndex, int Flags)
 	pInt->num = 0xe6;
 	reset_int_vect(pInt);
 	set_return_trap(pInt);
-	LockLegacyVGA(pInt, &vga);
+//	LockLegacyVGA(pInt, &vga);
 	xf86ExecX86int10(pInt);
-	UnlockLegacyVGA(pInt, &vga);
+//	UnlockLegacyVGA(pInt, &vga);
     }
 #ifdef DEBUG
     dprint(0xc0000, 0x20);
 #endif
 
     xfree(options);
+    pci_device_vgaarb_unlock(xf86Screens[screen]->VgaDev);
     return pInt;
 
 error3:
@@ -331,6 +336,8 @@ error1:
 error0:
     xfree(options);
     xfree(pInt);
+
+    pci_device_vgaarb_unlock(xf86Screens[screen]->VgaDev);
     return NULL;
 }
 
diff --git a/hw/xfree86/ramdac/xf86HWCurs.c b/hw/xfree86/ramdac/xf86HWCurs.c
index 4374e51..bbb268d 100644
--- a/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/hw/xfree86/ramdac/xf86HWCurs.c
@@ -118,8 +118,10 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
     unsigned char *bits;
 
+    pci_device_vgaarb_lock(infoPtr->pScrn->VgaDev);
     if (pCurs == NullCursor) {
 	(*infoPtr->HideCursor)(infoPtr->pScrn);
+    pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 	return;
     }
 
@@ -152,6 +154,8 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
     (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
 
     (*infoPtr->ShowCursor)(infoPtr->pScrn);
+
+    pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 }
 
 void
@@ -161,6 +165,7 @@ xf86SetTransparentCursor(ScreenPtr pScreen)
 	&pScreen->devPrivates, xf86CursorScreenKey);
     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
+    pci_device_vgaarb_lock(infoPtr->pScrn->VgaDev);
     if (!ScreenPriv->transparentData)
 	ScreenPriv->transparentData =
 	    (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
@@ -173,6 +178,7 @@ xf86SetTransparentCursor(ScreenPtr pScreen)
 				    ScreenPriv->transparentData);
 
     (*infoPtr->ShowCursor)(infoPtr->pScrn);
+    pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 }
 
 void
@@ -182,10 +188,12 @@ xf86MoveCursor(ScreenPtr pScreen, int x, int y)
 	&pScreen->devPrivates, xf86CursorScreenKey);
     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
+    pci_device_vgaarb_lock(infoPtr->pScrn->VgaDev);
     x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
     y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
 
     (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
+    pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 }
 
 void
@@ -195,19 +203,24 @@ xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
 	&pScreen->devPrivates, xf86CursorScreenKey);
     xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
 
+    pci_device_vgaarb_lock(infoPtr->pScrn->VgaDev);
 #ifdef ARGB_CURSOR
     /* recoloring isn't applicable to ARGB cursors and drivers 
        shouldn't have to ignore SetCursorColors requests */
-    if (pCurs->bits->argb)
+    if (pCurs->bits->argb) {
+        pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
         return;
+    }
 #endif
 
     if (ScreenPriv->PalettedCursor) {
 	xColorItem sourceColor, maskColor;
 	ColormapPtr pmap = ScreenPriv->pInstalledMap;
 	
-	if (!pmap)
+	if (!pmap) {
+        pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 	    return;
+    }
 
 	sourceColor.red = pCurs->foreRed;
 	sourceColor.green = pCurs->foreGreen;
@@ -231,6 +244,7 @@ xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
 	    ((pCurs->foreRed >> 8) << 16)
 	);
     }
+    pci_device_vgaarb_unlock(infoPtr->pScrn->VgaDev);
 }
 
 /* These functions assume that MaxWidth is a multiple of 32 */


More information about the xorg-devel mailing list