[PATCH 1/2] Unbreak dual head (xinerama)

Tormod Volden lists.tormod at gmail.com
Sat Oct 19 00:58:31 CEST 2013


From: Andy MacLean <andy-ub1 at themacleans.org.uk>

This patch has been used in Debian, Ubuntu and Gentoo for years.

https://bugs.freedesktop.org/show_bug.cgi?id=18472
https://launchpad.net/bugs/292214
https://bugs.gentoo.org/show_bug.cgi?id=265100

Signed-off-by: Andy MacLean <andy-ub1 at themacleans.org.uk>
Reviewed-by: Cyril Brulebois <kibi at debian.org>
Reviewed-by: Robert Jacobs <robert.n.jacobs at gmail.com>
Tested-by: Robert Jacobs <robert.n.jacobs at gmail.com>
---

Hi,

If there are no objections or other suggestions, I intend to commit
these patches next week, together with Egbert's patches from July.

Best regards,
Tormod


 src/mga.h        |    7 ++++
 src/mga_driver.c |  115 ++++++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 92 insertions(+), 30 deletions(-)

diff --git a/src/mga.h b/src/mga.h
index 0c5d71d..988ba93 100644
--- a/src/mga.h
+++ b/src/mga.h
@@ -343,6 +343,13 @@ typedef struct {
     int			mastervideoRam;
     int			slavevideoRam;
     Bool		directRenderingEnabled;
+
+    void *		mappedIOBase;
+    int			mappedIOUsage;
+
+    void *		mappedILOADBase;
+    int			mappedILOADUsage;
+
     ScrnInfoPtr 	pScrn_1;
     ScrnInfoPtr 	pScrn_2;
 } MGAEntRec, *MGAEntPtr;
diff --git a/src/mga_driver.c b/src/mga_driver.c
index 5cce7ac..3bd814e 100644
--- a/src/mga_driver.c
+++ b/src/mga_driver.c
@@ -2687,30 +2687,55 @@ MGAMapMem(ScrnInfoPtr pScrn)
 #ifdef XSERVER_LIBPCIACCESS
     struct pci_device *const dev = pMga->PciInfo;
     struct pci_mem_region *region;
-    void **memory[2];
     int i, err;
 #endif
 
 
     if (!pMga->FBDev) {
 #ifdef XSERVER_LIBPCIACCESS
-        memory[pMga->io_bar] = &pMga->IOBase;
-        memory[pMga->framebuffer_bar] = &pMga->FbBase;
+	pciaddr_t fbaddr = pMga->FbAddress;
+	pciaddr_t fbsize = pMga->FbMapSize;
+	err = pci_device_map_range(dev,
+				   fbaddr, fbsize,
+				   PCI_DEV_MAP_FLAG_WRITABLE,
+				   (void **)&pMga->FbBase);
 
-        for (i = 0; i < 2; i++) {
-            region = &dev->regions[i];
-            err = pci_device_map_range(dev,
-                                       region->base_addr, region->size,
-                                       PCI_DEV_MAP_FLAG_WRITABLE,
-                                       memory[i]);
+	if (err) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Unable to map Framebuffer %08llX %llx.  %s (%d)\n",
+		       (long long)fbaddr, (long long)fbsize,
+		       strerror(err), err);
+	    return FALSE;
+	}
+	else
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+		       "MAPPED Framebuffer %08llX %llx to %08llX.\n",
+		       (long long)fbaddr, (long long)fbsize,
+		       (long long)pMga->FbBase);
+
+	if(pMga->entityPrivate == NULL || pMga->entityPrivate->mappedIOUsage == 0) {
+	    region = &dev->regions[pMga->io_bar];
+	    err = pci_device_map_range(dev,
+				       region->base_addr, region->size,
+				       PCI_DEV_MAP_FLAG_WRITABLE,
+				       &pMga->IOBase);
+
+	    if (err) {
+	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			 "Unable to map IO Region %i.  %s (%d)\n",
+			 pMga->io_bar, strerror(err), err);
+	      return FALSE;
+	    }
+
+	    if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedIOBase = pMga->IOBase;
+	}
+	else
+		pMga->IOBase = pMga->entityPrivate->mappedIOBase;
+
+	if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedIOUsage ++;
 
-            if (err) {
-                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                           "Unable to map BAR %i.  %s (%d)\n",
-                           i, strerror(err), err);
-                return FALSE;
-            }
-        }
 #else
 	/*
 	 * For Alpha, we need to map SPARSE memory, since we need
@@ -2761,16 +2786,27 @@ MGAMapMem(ScrnInfoPtr pScrn)
     if (pMga->iload_bar != -1) {
 #ifdef XSERVER_LIBPCIACCESS
         region = &dev->regions[pMga->iload_bar];
-        err = pci_device_map_range(dev,
-                                   region->base_addr, region->size,
-                                   PCI_DEV_MAP_FLAG_WRITABLE,
-                                   (void *) &pMga->ILOADBase);
-	if (err) {
-	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-		       "Unable to map BAR 2 (ILOAD region).  %s (%d)\n",
-		       strerror(err), err);
-	    return FALSE;
+
+	if(pMga->entityPrivate == NULL || pMga->entityPrivate->mappedILOADUsage == 0) {
+	    err = pci_device_map_range(dev,
+				       region->base_addr, region->size,
+				       PCI_DEV_MAP_FLAG_WRITABLE,
+				       (void *) &pMga->ILOADBase);
+	    if (err) {
+	      xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			 "Unable to map BAR 2 (ILOAD region).  %s (%d)\n",
+			 strerror(err), err);
+	      return FALSE;
+	    }
+
+	    if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedILOADBase = pMga->ILOADBase;
 	}
+	else
+		pMga->ILOADBase = pMga->entityPrivate->mappedILOADBase;
+
+	if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedILOADUsage ++;
 #else
 	pMga->ILOADBase = xf86MapPciMem(pScrn->scrnIndex,
 					VIDMEM_MMIO | VIDMEM_MMIO_32BIT |
@@ -2800,10 +2836,20 @@ MGAUnmapMem(ScrnInfoPtr pScrn)
     
     if (!pMga->FBDev) {
 #ifdef XSERVER_LIBPCIACCESS
-        pci_device_unmap_range(dev, pMga->IOBase, 
-			       dev->regions[pMga->io_bar].size);
+	    if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedIOUsage--;
+
+	    if(pMga->entityPrivate == NULL || pMga->entityPrivate->mappedIOUsage == 0) {
+		pci_device_unmap_range(dev, pMga->IOBase,
+				       dev->regions[pMga->io_bar].size);
+
+		if(pMga->entityPrivate != NULL)
+			pMga->entityPrivate->mappedIOBase = NULL;
+	    }
+
+	    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UNMAPPING framebuffer 0x%08llX, 0x%llX.\n", (long long)pMga->FbBase, (long long)pMga->FbMapSize);
         pci_device_unmap_range(dev, pMga->FbBase, 
-			       dev->regions[pMga->framebuffer_bar].size);
+			       pMga->FbMapSize);
 #else
 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->IOBase, 0x4000);
 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->FbBase, pMga->FbMapSize);
@@ -2816,8 +2862,17 @@ MGAUnmapMem(ScrnInfoPtr pScrn)
 
     if ((pMga->iload_bar != -1) && (pMga->ILOADBase != NULL)) {
 #ifdef XSERVER_LIBPCIACCESS
-        pci_device_unmap_range(dev, pMga->ILOADBase,
-			       dev->regions[pMga->iload_bar].size);
+	    if(pMga->entityPrivate != NULL)
+		pMga->entityPrivate->mappedILOADUsage--;
+
+	    if(pMga->entityPrivate == NULL || pMga->entityPrivate->mappedILOADUsage == 0) {
+		pci_device_unmap_range(dev, pMga->ILOADBase,
+				       dev->regions[pMga->iload_bar].size);
+
+		if(pMga->entityPrivate != NULL)
+		    pMga->entityPrivate->mappedILOADBase = NULL;
+	    }
+
 #else
 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pMga->ILOADBase, 0x800000);
 #endif
-- 
1.7.10.4



More information about the xorg-devel mailing list