From fc5368edfd81edc74f0b1cb9c3bdde7dc2d99310 Mon Sep 17 00:00:00 2001
From: Boiko <boiko@ageless.conectiva>
Date: Thu, 8 Jun 2006 11:24:18 -0300
Subject: [PATCH] Bug #6583: Only open /proc/bus/pci/devices once. (Bill Nottingham)

(cherry picked from 56f21bda1ce95741c88c423b60bd709eef26eb12 commit)
---
 ChangeLog                             |  197 +++++++++++++++++++++
 hw/xfree86/os-support/bus/linuxPci.c  |   47 +++--
 hw/xfree86/os-support/linux/lnx_pci.c |  304 +++++++++++++++------------------
 3 files changed, 362 insertions(+), 186 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e0474b9..94bf9c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,200 @@
+2006-06-01  Adam Jackson  <ajax@freedesktop.org>
+
+	* hw/xfree86/common/xf86Init.c:
+	* hw/xfree86/dixmods/Makefile.am:
+	* hw/xfree86/dixmods/bitmapmod.c:
+	Bug #5089: Die, libbitmap, die!
+
+	* hw/xfree86/common/xf86Config.c:
+	Add bitmap to the ignored module list.
+
+2006-06-01  Daniel Stone  <daniel@freedesktop.org>
+
+	* Xext/Makefile.am:
+	* Xext/README.xtest1-ddx:
+	* Xext/xtest1di.c:
+	* Xext/xtest1dd.h:
+	* Xext/xtest1dd.c:
+	* Xprint/ddxInit.c:
+	* hw/kdrive/src/kdrive.c:
+	* hw/xfree86/common/xf86Events.c:
+	* hw/xfree86/common/xf86Init.c:
+	* hw/xfree86/os-support/solaris/sun_kbdEv.c:
+	* hw/xnest/TestExt.c:
+	* hw/xwin/InitInput.c:
+	* hw/vfb/InitInput.c:
+	* mi/miinitext.c:
+	* os/WaitFor.c:
+	Die, XTESTEXT1, die!
+
+	* dix/devices.c:
+	* include/input.h:
+	* mi/mipointer.h:
+	* mi/mipointer.c:
+	Get rid of horrendous, somewhat misguided, DDX binary-compatibility
+	glue.
+
+	* hw/xfree86/common/xf86Config.c:
+	* hw/xfree86/common/xf86Configure.c:
+	* parser/Module.c:
+	* parser/xf86Parser.c:
+	Ignore requests to load deprecated GLcore and speedo modules
+	(properly, this time).
+
+	* configure.ac:
+	* hw/xfree86/common/xf86Globals.c:
+	* hw/xfree86/loader/Makefile.am:
+	* hw/xfree86/loader/loader.c:
+	* hw/xfree86/loader/loader.h:
+	* hw/xfree86/loader/loadmod.c:
+	* hw/xfree86/loader/ar.h:
+	* hw/xfree86/loader/aout.h:
+	* hw/xfree86/loader/aoutloader.h:
+	* hw/xfree86/loader/aoutloader.c:
+	* hw/xfree86/loader/coff.h:
+	* hw/xfree86/loader/coffloader.h:
+	* hw/xfree86/loader/coffloader.c:
+	* hw/xfree86/loader/elf.h:
+	* hw/xfree86/loader/elfloader.h:
+	* hw/xfree86/loader/elfloader.c:
+	* include/xorg-config.h.in:
+	* include/xorg-server.h.in:
+	Kill the a.out, ELF and COFF loaders with extreme prejudice.  Good
+	riddance.  There's more where this came from, too.
+
+	* xkb/xkb.c:
+	* xkb/xkbLEDs.c:
+	Simplify the 'unsupported' list.
+
+	* configure.ac:
+	* Makefile.am:
+	* Xext/security.c:
+	* dix/colormap.c:
+	* dix/devices.c:
+	* dix/dixfonts.c:
+	* dix/dispatch.c:
+	* dix/extension.c:
+	* dix/property.c:
+	* dix/swaprep.c:
+	* include/dix.h:
+	* include/dix-config.h:
+	* include/dixstruct.h:
+	* include/globals.h:
+	* include/os.h:
+	* include/propertyst.h:
+	* include/swaprep.h:
+	* lbx/*:
+	* mi/miinitext.c:
+	* os/Makefile.am:
+	* os/access.c:
+	* os/connection.c:
+	* os/io.c:
+	* os/lbxio.c:
+	* os/osdep.h:
+	* os/utils.c:
+	Remove LBX.  Goodbye.
+
+	* hw/xfree86/os-support/bus/linuxPci.c:
+	* hw/xfree86/os-support/linux/lnx_pci.c:
+	Bug #6583: Only parse /proc/bus/pci/devices once.  (Bill Nottingham)
+
+2006-05-30  Matthieu Herrb <matthieu.herrb@laas.fr>
+
+	* hw/xfree86/os-support/bsd/Makefile.am:
+	Powerpc machines also need ioperm_noop.c
+
+2006-05-30  Adam Jackson  <ajax@freedesktop.org>
+
+	* hw/xfree86/doc/man/xorg.conf.man.pre:
+	Properly document the DPMS, SyncOnGreen, and TargetRefresh options.
+
+2006-05-29  Kristian Høgsberg  <krh@redhat.com>
+
+	* GL/glx/glxcmds.c: Remove superfluous definition of tfp tokens.
+
+2005-05-24  Daniel Stone  <daniel@freedesktop.org>
+
+	* xkb/ddxKillSrv.c:
+	* xkb/ddxPrivate.c:
+	* xkb/ddxVT.c:
+	Minor #include cleanups.
+
+	* xkb/xkb.c:
+	* xkb/xkbUtils.c:
+	* hw/xfree86/common/xf86Config.c:
+	* hw/xfree86/common/xf86Io.c:
+	* hw/xfree86/os-support/sysv/xqueue.c:
+	* hw/xnest/Keyboard.c:
+	* hw/kdrive/src/kinput.c:
+	* hw/xgl/egl/kinput.c:
+	* hw/dmx/input/dmxinputinit.c:
+	* hw/xgl/glx/xglx.c:
+	* hw/xwin/winconfig.c:
+	* hw/xwin/winkeybd.c:
+	Remove -xkbmap argument.
+
+2006-05-26  Matthieu Herrb <matthieu.herrb@laas.fr>
+
+	* hw/xfree86/os-support/bsd/bsd_mouse.c:
+	check buffersize before reading next char, fixes the 
+	"mouse stuck at left" bug (bugzilla #3113) for BSD systems using 
+	wscons. (Dale Rahn).
+
+2006-05-25  Jeremy C. Reed  <reed@reedmedia.net>
+
+	* doc/Xserver.man.pre:
+	* hw/xfree86/doc/man/Xorg.man.pre:
+	* hw/xfree86/doc/man/xorg.conf.man.pre:
+	RGB color database and XErrorDB install to "share" not
+	"lib" by default (by app/rgb and libX11). (TODO: They are
+	customizable, so maybe cpprules.in should be extended.)
+
+2006-05-25  Jeremy C. Reed  <reed@reedmedia.net>
+
+	reviewed by: Adam Jackson
+
+	* hw/xfree86/common/xf86Config.c: (GenerateDriverlist):
+	Don't do fixup_video_driver_list if no drivers.  (I had
+	signal 11 and core dump when drivers not installed yet.)
+	(TODO: fix fixup_video_driver_list to handle NULL argument.)
+
+2006-05-25  Matthieu Herrb <matthieu.herrb@laas.fr>
+
+	* mi/midispcur.c: (miDCCloseScreen)
+	Don't destroy a pixmap twice on server exit (bugzilla #4247).
+	* GL/symlink-mesa.sh:
+	* GL/mesa/main/Makefile.am:
+	update to build against Mesa CVS HEAD 
+	(Carlos Eduardo Rodrigues Diógenes)
+
+2006-05-24  Jeremy C. Reed  <reed@reedmedia.net>
+
+	* hw/xfree86/utils/xorgcfg/text-mode.c:
+	NetBSD also has curses.h instead of ncurses.h. (TODO:
+	Maybe instead of checking for SCO, UnixWare, Sun SVR4 and
+	NetBSD, the curses.h versus ncurses.h should be tested in
+	configure.)
+
+2006-05-24  Jeremy C. Reed  <reed@reedmedia.net>
+
+	* configure.ac:
+	On NetBSD, add -li386 for i386 and -lx86_64 for x86_64 to
+	SYS_LIBS. (x86_64 on NetBSD not tested.)
+
+2006-05-24  Jeremy C. Reed  <reed@reedmedia.net>
+
+	reviewed by: Daniel Stone
+
+	* xkb/maprules.c: (XkbRF_LoadDescriptions):
+	Remove tolower() which was missed in the _XkbStrCaseCmp/strcmp
+	changes.
+
+2006-05-23  Alan Coopersmith  <alan.coopersmith@sun.com>
+
+	* configure.ac:
+	Add AC_SUBST([SOLARIS_ASM_CFLAGS]) that I forgot when splitting
+	them out of the XORG_CFLAGS.
+
 2006-05-22  Adam Jackson  <ajax@freedesktop.org>
 
 	* dix/colormap.c:
diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 092f28f..3e82f21 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -130,32 +130,45 @@ linuxPciOpenFile(PCITAG tag, Bool write)
 {
 	static int	lbus,ldev,lfunc,fd = -1,is_write = 0;
 	int		bus, dev, func;
-	char		file[32];
+	char		file[64];
 	struct stat	ignored;
+	static int is26 = -1;
 
 	bus  = PCI_BUS_FROM_TAG(tag);
 	dev  = PCI_DEV_FROM_TAG(tag);
 	func = PCI_FUNC_FROM_TAG(tag);
+	if (is26 == -1) {
+		if (stat("/sys/bus/pci",&ignored) < 0)
+			is26 = 0;
+		else
+			is26 = 1;
+	}
+	
 	if (fd == -1 || (write && (!is_write))
 	    || bus != lbus || dev != ldev || func != lfunc) {
 		if (fd != -1)
 			close(fd);
-		if (bus < 256) {
-		        sprintf(file,"/proc/bus/pci/%02x",bus);
-			if (stat(file, &ignored) < 0)
-				sprintf(file, "/proc/bus/pci/0000:%02x/%02x.%1x",
-					bus, dev, func);
-			else
-				sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
-					bus, dev, func);
-		} else {
-		        sprintf(file,"/proc/bus/pci/%04x",bus);
-			if (stat(file, &ignored) < 0)
-				sprintf(file, "/proc/bus/pci/0000:%04x/%02x.%1x",
-					bus, dev, func);
-			else
-				sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
-					bus, dev, func);
+		if (is26)
+			sprintf(file,"/sys/bus/pci/devices/0000:%02x:%02x.%01x/config",
+				bus, dev, func);
+		else {
+			if (bus < 256) {
+				sprintf(file,"/proc/bus/pci/%02x",bus);
+				if (stat(file, &ignored) < 0)
+					sprintf(file, "/proc/bus/pci/0000:%02x/%02x.%1x",
+						bus, dev, func);
+				else
+					sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
+						bus, dev, func);
+			} else {
+				sprintf(file,"/proc/bus/pci/%04x",bus);
+				if (stat(file, &ignored) < 0)
+					sprintf(file, "/proc/bus/pci/0000:%04x/%02x.%1x",
+						bus, dev, func);
+				else
+					sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
+						bus, dev, func);
+			}
 		}
 		if (write) {
 		    fd = open(file,O_RDWR);
diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c
index 4d88314..4a80786 100644
--- a/hw/xfree86/os-support/linux/lnx_pci.c
+++ b/hw/xfree86/os-support/linux/lnx_pci.c
@@ -23,70 +23,99 @@ #define PCIADDR_IGNORE_FMT	"%*x"
 #define PCIADDR_FMT		"%lx"
 #endif
 
-FILE *xf86OSLinuxPCIFile = NULL;
+struct pci_dev {
+    unsigned int bus;
+    unsigned int devfn;
+    PCIADDR_TYPE offset[7];
+    PCIADDR_TYPE size[7];
+    struct pci_dev *next;
+};
+
+struct pci_dev *xf86OSLinuxPCIDevs = NULL;
+
+static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
+    char c[0x200];
+    FILE *file = NULL;
+    struct pci_dev *tmp, *ret = NULL;
+    unsigned int num;
+    char *res;
+    
+    file = fopen("/proc/bus/pci/devices", "r");
+    if (!file) return NULL;
+    
+    do {
+        res = fgets(c, 0x1ff, file);
+        if (res) {
+            tmp = xcalloc(sizeof(struct pci_dev),1);
+            num = sscanf(res,
+                /*bus+dev vendorid deviceid irq */
+                "%02x%02x\t%*04x%*04x\t%*x"
+                /* 7 PCI resource base addresses */
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                /* 7 PCI resource sizes, and then optionally a driver name */
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT
+                "\t" PCIADDR_FMT,
+                &tmp->bus,&tmp->devfn,&tmp->offset[0],&tmp->offset[1],&tmp->offset[2],&tmp->offset[3],
+                &tmp->offset[4],&tmp->offset[5],&tmp->offset[6], &tmp->size[0], &tmp->size[1], &tmp->size[2],
+                &tmp->size[3], &tmp->size[4], &tmp->size[5], &tmp->size[6]);
+            if (num != 16) {  /* apparantly not 2.3 style */
+                xfree(tmp);
+                fclose(file);
+                return NULL;
+            }
+            if (ret) {
+                tmp->next = ret;
+            }
+            ret = tmp;
+        }
+    } while (res);
+    fclose(file);
+    return ret;
+}
 
 Bool
 xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
 {
-    char c[0x200];
-    char *res;
-    unsigned int bus, devfn, dev, fn;
-    unsigned PCIADDR_TYPE size[7];
-    unsigned int num;
+    unsigned int dev, fn;
     signed PCIADDR_TYPE Size;
+    struct pci_dev *device;
 
     if (index > 7)
-	return FALSE;
+        return FALSE;
     
-    if (!xf86OSLinuxPCIFile && \
-        !(xf86OSLinuxPCIFile = fopen("/proc/bus/pci/devices","r")))
-	return FALSE;
-    do {
-	res = fgets(c,0x1ff,xf86OSLinuxPCIFile);
-	if (res) {
-	    num = sscanf(res,
-			 /*bus+dev vendorid deviceid irq */
-			 "%02x%02x\t%*04x%*04x\t%*x"
-			 /* 7 PCI resource base addresses */
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 "\t" PCIADDR_IGNORE_FMT
-			 /* 7 PCI resource sizes, and then optionally a driver name */
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT
-			 "\t" PCIADDR_FMT,
-			 &bus,&devfn,&size[0],&size[1],&size[2],&size[3],
-			 &size[4],&size[5],&size[6]);
-	    if (num != 9) {  /* apparantly not 2.3 style */ 
-		fseek(xf86OSLinuxPCIFile, 0L, SEEK_SET);
-		return FALSE;
-	    }
-	    dev = devfn >> 3;
-	    fn = devfn & 0x7;
-	    if (tag == pciTag(bus,dev,fn)) {
-		*bits = 0;
-		if (size[index] != 0) {
-		    Size = size[index] - ((PCIADDR_TYPE) 1);
-		    while (Size & ((PCIADDR_TYPE) 0x01)) {
-			Size = Size >> ((PCIADDR_TYPE) 1);
-			(*bits)++;
-		    }
-		}
-		fseek(xf86OSLinuxPCIFile, 0L, SEEK_SET);
-		return TRUE;
-	    }
-	}
-    } while (res);
+    if (!xf86OSLinuxPCIDevs) {
+        xf86OSLinuxPCIDevs = xf86OSLinuxGetPciDevs();
+    }
+    if (!xf86OSLinuxPCIDevs)
+        return FALSE;
+    
+    for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
+        dev = device->devfn >> 3;
+	fn = device->devfn & 0x7;
+        if (tag == pciTag(device->bus,dev,fn)) {
+            *bits = 0;
+            if (device->size[index] != 0) {
+                Size = device->size[index] - ((PCIADDR_TYPE) 1);
+                while (Size & ((PCIADDR_TYPE) 0x01)) {
+                    Size = Size >> ((PCIADDR_TYPE) 1);
+                    (*bits)++;
+                }
+            }
+            return TRUE;
+        }
+    }
 
-    fseek(xf86OSLinuxPCIFile, 0L, SEEK_SET);
     return FALSE;
 }
 
@@ -96,59 +125,28 @@ xf86GetPciSizeFromOS(PCITAG tag, int ind
 Bool
 xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
 {
-    FILE *file;
-    char c[0x200];
-    char *res;
-    unsigned int bus, devfn, dev, fn;
-    unsigned PCIADDR_TYPE offset[7];
-    unsigned int num;
+    unsigned int dev, fn;
+    struct pci_dev *device;
 
     if (index > 7)
         return FALSE;
 
-    if (!(file = fopen("/proc/bus/pci/devices","r")))
+    if (!xf86OSLinuxPCIDevs) {
+        xf86OSLinuxPCIDevs = xf86OSLinuxGetPciDevs();
+    }
+    if (!xf86OSLinuxPCIDevs)
         return FALSE;
-    do {
-        res = fgets(c,0x1ff,file);
-        if (res) {
-            num = sscanf(res,
-                         /*bus+dev vendorid deviceid irq */
-                         "%02x%02x\t%*04x%*04x\t%*x"
-                         /* 7 PCI resource base addresses */
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         /* 7 PCI resource sizes, and then optionally a driver name */
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT
-                         "\t" PCIADDR_IGNORE_FMT,
-                         &bus,&devfn,&offset[0],&offset[1],&offset[2],&offset[3],
-                         &offset[4],&offset[5],&offset[6]);
-            if (num != 9) {  /* apparantly not 2.3 style */
-                fclose(file);
-                return FALSE;
-            }
 
-            dev = devfn >> 3;
-            fn = devfn & 0x7;
-            if (tag == pciTag(bus,dev,fn)) {
-                /* return the offset for the index requested */
-                *bases = offset[index];
-                fclose(file);
-                return TRUE;
-            }
+    for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
+        dev = device->devfn >> 3;
+        fn = device->devfn & 0x7;
+        if (tag == pciTag(device->bus,dev,fn)) {
+            /* return the offset for the index requested */
+            *bases = device->offset[index];
+            return TRUE;
         }
-    } while (res);
+    }
 
-    fclose(file);
     return FALSE;
 }
 
@@ -156,81 +154,49 @@ xf86GetPciOffsetFromOS(PCITAG tag, int i
 unsigned long
 xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
 {
-    FILE *file;
-    char c[0x200];
-    char *res;
-    unsigned int bus, devfn, dev, fn;
-    unsigned PCIADDR_TYPE offset[7];
-    unsigned PCIADDR_TYPE size[7];
-    unsigned int num;
+    unsigned int dev, fn;
     unsigned int ndx;
+    struct pci_dev *device;
 
-    if (!(file = fopen("/proc/bus/pci/devices","r")))
-        return 0;
-    do {
-        res = fgets(c,0x1ff,file);
-        if (res) {
-            num = sscanf(res,
-                         /*bus+dev vendorid deviceid irq */
-                         "%02x%02x\t%*04x%*04x\t%*x"
-                         /* 7 PCI resource base addresses */
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         /* 7 PCI resource sizes, and then optionally a driver name */
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT
-                         "\t" PCIADDR_FMT,
-                         &bus,&devfn,&offset[0],&offset[1],&offset[2],&offset[3],
-                         &offset[4],&offset[5],&offset[6], &size[0], &size[1], &size[2],
-		         &size[3], &size[4], &size[5], &size[6]);
-            if (num != 16) {  /* apparantly not 2.3 style */
-                fclose(file);
-                return 0;
-            }
-
-            dev = devfn >> 3;
-            fn = devfn & 0x7;
-            if (tag == pciTag(bus,dev,fn)) {
-                /* ok now look through all the BAR values of this device */
-		pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
-
-                for (ndx=0; ndx<7; ndx++) {
-                    unsigned long savePtr, flagMask;
-		    if (ndx == 6) 
-			savePtr = pDev->pci_baserom;
-		    else /* this the ROM bar */
-			savePtr = (&pDev->pci_base0)[ndx];
-                    /* Ignore unset base addresses. The kernel may
-                     * have reported non-zero size and address even
-                     * if they are disabled (e.g. disabled ROM BAR).
-                     */
-                    if (savePtr == 0)
-                        continue;
-                    /* Remove memory attribute bits, different for IO
-                     * and memory ranges. */
-                    flagMask = (savePtr & 0x1) ? ~0x3UL : ~0xFUL;
-                    savePtr &= flagMask;
-
-                    /* find the index of the incoming base */
-                    if (base >= savePtr && base < (savePtr + size[ndx])) {
-                        fclose(file);
-                        return (offset[ndx] & flagMask) + (base - savePtr);
-                    }
+    if (!xf86OSLinuxPCIDevs) {
+        xf86OSLinuxPCIDevs = xf86OSLinuxGetPciDevs();
+    }
+    if (!xf86OSLinuxPCIDevs) {
+        return FALSE;
+    }
+
+    for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
+        dev = device->devfn >> 3;
+        fn = device->devfn & 0x7;
+        if (tag == pciTag(device->bus, dev, fn)) {
+            /* ok now look through all the BAR values of this device */
+            pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
+
+            for (ndx=0; ndx<7; ndx++) {
+                unsigned long savePtr, flagMask;
+                if (ndx == 6) 
+                    savePtr = pDev->pci_baserom;
+                else /* this the ROM bar */
+                    savePtr = (&pDev->pci_base0)[ndx];
+                /* Ignore unset base addresses. The kernel may
+                 * have reported non-zero size and address even
+                 * if they are disabled (e.g. disabled ROM BAR).
+                 */
+                if (savePtr == 0)
+                    continue;
+                /* Remove memory attribute bits, different for IO
+                 * and memory ranges. */
+                flagMask = (savePtr & 0x1) ? ~0x3UL : ~0xFUL;
+                savePtr &= flagMask;
+
+                /* find the index of the incoming base */
+                if (base >= savePtr && base < (savePtr + device->size[ndx])) {
+                    return (device->offset[ndx] & flagMask) + (base - savePtr);
                 }
             }
         }
-    } while (res);
+    };
 
-    fclose(file);
     return 0;
 
 }
-- 
1.4.0

