xserver: Branch 'master' - 11 commits

Matthias Hopf mhopf at kemper.freedesktop.org
Fri Nov 3 20:08:39 EET 2006


 hw/xfree86/common/xf86pciBus.c        |    6 
 hw/xfree86/int10/Makefile.am          |   11 +
 hw/xfree86/int10/helper_exec.c        |   13 --
 hw/xfree86/os-support/bus/Pci.c       |    8 +
 hw/xfree86/os-support/bus/Pci.h       |    4 
 hw/xfree86/os-support/bus/altixPCI.c  |    9 -
 hw/xfree86/os-support/bus/linuxPci.c  |  221 +++++++++++++++++++++++++++-------
 hw/xfree86/os-support/bus/xf86Pci.h   |    1 
 hw/xfree86/os-support/linux/lnx_pci.c |   80 +++++++++---
 9 files changed, 277 insertions(+), 76 deletions(-)

New commits:
diff-tree bd0c829654903ca45543dfa59cda967c4fafd8ac (from c1828a8ff51c8db326c47e6710f4f42fab94fb6d)
Author: Bjorn Helgaas <bjorn.helgaas at hp.com>
Date:   Fri Nov 3 18:54:06 2006 +0100

    Do not map full 0-1MB legacy range
    
    If we're mapping something in the "legacy range" (0-1Mb), we shouldn't
    expand the requested range to the entire 0-1Mb range.  Typically this
    is for mapping the VGA frame buffer, and some platforms support mmap of
    the frame buffer but not the entire 0-1Mb range.
    
    For example, HP sx1000 and sx2000 ia64 platforms can have memory from
    0-0x9ffff, VGA frame buffer from 0xa0000-0xbffff, and memory from
    0xc0000-0xfffff.  On these platforms, we can't map the entire 0-1Mb
    range with the same attribute because the memory only supports WB,
    while the frame buffer supports only UC.  But an mmap of just the
    frame buffer should work fine.

diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index afb3819..15fc2b8 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -627,7 +627,6 @@ linuxMapPci(int ScreenNum, int Flags, PC
 
 #define MAX_DOMAINS 257
 static pointer DomainMmappedIO[MAX_DOMAINS];
-static pointer DomainMmappedMem[MAX_DOMAINS];
 
 static int
 linuxOpenLegacy(PCITAG Tag, char *name)
@@ -685,6 +684,7 @@ xf86MapDomainMemory(int ScreenNum, int F
 {
     int domain = xf86GetPciDomain(Tag);
     int fd;
+    pointer addr;
 
     /*
      * We use /proc/bus/pci on non-legacy addresses or if the Linux sysfs
@@ -698,20 +698,14 @@ xf86MapDomainMemory(int ScreenNum, int F
 	return linuxMapPci(ScreenNum, Flags, Tag, Base, Size,
 			   PCIIOC_MMAP_IS_MEM);
 
-
-    /* If we haven't already mapped this legacy space, try to. */
-    if (!DomainMmappedMem[domain]) {
-	DomainMmappedMem[domain] = mmap(NULL, 1024*1024, PROT_READ|PROT_WRITE,
-					MAP_SHARED, fd, 0);
-	if (DomainMmappedMem[domain] == MAP_FAILED) {
-	    close(fd);
-	    perror("mmap failure");
-	    FatalError("xf86MapDomainMem():  mmap() failure\n");
-	}
+    addr = mmap(NULL, Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Base);
+    if (addr == MAP_FAILED) {
+	close (fd);
+	perror("mmap failure");
+	FatalError("xf86MapDomainMem():  mmap() failure\n");
     }
-
     close(fd);
-    return (pointer)((char *)DomainMmappedMem[domain] + Base);
+    return addr;
 }
 
 /*
diff-tree c1828a8ff51c8db326c47e6710f4f42fab94fb6d (from d50fc413b39f52663b46084c28e81fc4933a7b49)
Author: Egbert Eich <eich at freedesktop.org>
Date:   Fri Nov 3 18:32:48 2006 +0100

    Fixing mach64 driver bailing out on ia64
    
    Mach64 driver bails out on ia64 because it cannot map device
    memory. It turns out that some bogus and unneeded code attempts
    to find the root bridge of the device and fails to do so proberly
    as there this host-to-pci bridge is not existant. This code has
    been around for years although it completely unclear what it had
    been intended for. Fixing this by eliminating the bogus code.

diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 97d60f5..afb3819 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -570,9 +570,7 @@ linuxMapPci(int ScreenNum, int Flags, PC
 
 	xf86InitVidMem();
 
-	pPCI = xf86GetPciHostConfigFromTag(Tag);
-
-	if (((fd = linuxPciOpenFile(pPCI ? pPCI->tag : 0,FALSE)) < 0) ||
+	if (((fd = linuxPciOpenFile(Tag ,FALSE)) < 0) ||
 	    (ioctl(fd, mmap_ioctl, 0) < 0))
 	    break;
 
diff-tree d50fc413b39f52663b46084c28e81fc4933a7b49 (from 1d731fc54a2cf5d3f353d8ee1c7c4989df27f011)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 18:53:41 2006 +0100

    Fix device path in altixPCI.c to be domain aware.

diff --git a/hw/xfree86/os-support/bus/altixPCI.c b/hw/xfree86/os-support/bus/altixPCI.c
index 010f661..7a72ec6 100644
--- a/hw/xfree86/os-support/bus/altixPCI.c
+++ b/hw/xfree86/os-support/bus/altixPCI.c
@@ -41,13 +41,14 @@ static pciDevice *get_dev_on_bus(unsigne
 static void get_bridge_info(pciBusInfo_t *bus_info, pciDevice *pdev)
 {
 	unsigned int parent_segnum, segnum = PCI_DOM_FROM_TAG(pdev->tag);
-	unsigned int parent_busnum, busnum = pdev->busnum;
+	unsigned int parent_busnum, parent_nodombus, busnum = pdev->busnum;
+	unsigned int nodombus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(pdev->tag));
 	char bridge_path[] = "/sys/class/pci_bus/0000:00/bridge";
 	char bridge_target[] = "../../../devices/pci0000:00";
 
 	/* Path to this device's bridge */
 	sprintf(bridge_path, "/sys/class/pci_bus/%04x:%02x/bridge", segnum,
-		busnum);
+		nodombus);
 
 	if (readlink(bridge_path, bridge_target, strlen(bridge_target)) < 0) {
 		perror("failed to dereference bridge link");
@@ -56,7 +57,9 @@ static void get_bridge_info(pciBusInfo_t
 	}
 
 	sscanf(bridge_target, "../../../devices/pci%04x:%02x", &parent_segnum,
-	       &parent_busnum);
+	       &parent_nodombus);
+
+	parent_busnum = PCI_MAKE_BUS(parent_segnum, parent_nodombus);
 
 	/*
 	 * If there's no bridge or the bridge points to the device, use
diff-tree 1d731fc54a2cf5d3f353d8ee1c7c4989df27f011 (from caaa113acf4144fd47a1ac93ca440d78d1983e54)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 18:50:15 2006 +0100

    Add domain support to linuxPciOpenFile().
    
    Loosely based on patch from David S. Miller <davem at davemloft.net>
    See also bug #2368.

diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 0f7fc47..97d60f5 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -54,6 +54,7 @@
 #include "xf86Priv.h"
 #include "xf86_OSlib.h"
 #include "Pci.h"
+#include <dirent.h>
 
 /*
  * linux platform specific PCI access functions -- using /proc/bus/pci
@@ -73,6 +74,7 @@ static void linuxPciCfgWriteByte(PCITAG 
 static CARD16 linuxPciCfgReadWord(PCITAG tag, int off);
 static void linuxPciCfgWriteWord(PCITAG tag, int off, CARD16 val);
 static int linuxPciHandleBIOS(PCITAG Tag, int basereg, unsigned char *buf, int len);
+static Bool linuxDomainSupport(void);
 
 static pciBusFuncs_t linuxFuncs0 = {
 /* pciReadLong      */	linuxPciCfgRead,
@@ -116,6 +118,8 @@ static pciBusInfo_t linuxPci0 = {
 /* from lnx_pci.c. */
 extern int lnxPciInit(void);
 
+static Bool	domain_support = FALSE;
+
 void
 linuxPciInit()
 {
@@ -126,6 +130,9 @@ linuxPciInit()
 		   we'll need a fallback for 2.0 kernels here */
 		return;
 	}
+#ifndef INCLUDE_XF86_NO_DOMAIN
+	domain_support = linuxDomainSupport();
+#endif
 	pciNumBuses    = 1;
 	pciBusInfo[0]  = &linuxPci0;
 	pciFindFirstFP = pciGenFindFirst;
@@ -137,13 +144,14 @@ linuxPciInit()
 static int
 linuxPciOpenFile(PCITAG tag, Bool write)
 {
-	static int	lbus,ldev,lfunc,fd = -1,is_write = 0;
-	int		bus, dev, func;
+	static int	ldomain, lbus,ldev,lfunc,fd = -1,is_write = 0;
+	int		domain, bus, dev, func;
 	char		file[64];
 	struct stat	ignored;
 	static int is26 = -1;
 
-	bus  = PCI_BUS_FROM_TAG(tag);
+	domain = PCI_DOM_FROM_TAG(tag);
+	bus  = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag));
 	dev  = PCI_DEV_FROM_TAG(tag);
 	func = PCI_FUNC_FROM_TAG(tag);
 	if (is26 == -1) {
@@ -153,30 +161,41 @@ linuxPciOpenFile(PCITAG tag, Bool write)
 			is26 = 1;
 	}
 	
-	if (fd == -1 || (write && (!is_write))
+	if (!domain_support && domain > 0)
+	    return -1;
+
+	if (fd == -1 || (write && (!is_write)) || domain != ldomain
 	    || bus != lbus || dev != ldev || func != lfunc) {
-		if (fd != -1)
+		if (fd != -1) {
 			close(fd);
+			fd = -1;
+		}
 		if (is26)
-			sprintf(file,"/sys/bus/pci/devices/0000:%02x:%02x.%01x/config",
-				bus, dev, func);
+			sprintf(file,"/sys/bus/pci/devices/%04x:%02x:%02x.%01x/config",
+				domain, 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);
+				sprintf(file, "/proc/bus/pci/%04x:%02x", domain, bus);
+				if (stat(file, &ignored) < 0) {
+					if (domain == 0) 
+						sprintf(file, "/proc/bus/pci/%02x/%02x.%1x",
+							bus, dev, func);
+					else
+						goto bail;
+				} else
+					sprintf(file, "/proc/bus/pci/%04x:%02x/%02x.%1x",
+						domain, 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);
+				sprintf(file, "/proc/bus/pci/%04x:%04x", domain, bus);
+				if (stat(file, &ignored) < 0) {
+					if (domain == 0)
+						sprintf(file, "/proc/bus/pci/%04x/%02x.%1x",
+							bus, dev, func);
+					else
+						goto bail;
+				} else
+					sprintf(file, "/proc/bus/pci/%04x:%04x/%02x.%1x",
+						domain, bus, dev, func);
 			}
 		}
 		if (write) {
@@ -191,7 +210,8 @@ linuxPciOpenFile(PCITAG tag, Bool write)
 			    fd = open(file,O_RDONLY);
 			    is_write = FALSE;
 		}
-		
+	bail:
+		ldomain = domain;
 		lbus  = bus;
 		ldev  = dev;
 		lfunc = func;
@@ -489,6 +509,32 @@ linuxGetSizes(PCITAG Tag, unsigned long 
     *mem_size = sizes->mem_size;
 }
 
+static Bool
+linuxDomainSupport(void)
+{
+    DIR *dir;
+    struct dirent *dirent;
+    char *end;
+
+    if (!(dir = opendir("/proc/bus/pci")))
+       return FALSE;
+    while (1) {
+	if (!(dirent = readdir(dir)))
+	    return FALSE;
+	strtol(dirent->d_name,&end,16);
+	/* entry of the form xx or xxxx : x=[0..f] no domain */
+	if (*end == '\0')
+	    return FALSE;
+	else if (*end == ':') {
+	    /* ':' found immediately after: verify for xxxx:xx or xxxx:xxxx */
+	    strtol(end + 1,&end,16);
+	    if (*end == '\0')
+		return TRUE;
+	}
+    }
+    return FALSE;
+} 
+
 _X_EXPORT int
 xf86GetPciDomain(PCITAG Tag)
 {
diff-tree caaa113acf4144fd47a1ac93ca440d78d1983e54 (from 16c5043fc0c84b14323cd211c2645106455ac320)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 18:38:45 2006 +0100

    Fixing domain support for ia64
    
    ia64 specific functions + defines.
    Still uses /proc interface for some scaning code.
    Based on code from Egbert Eich <eich at freedesktop.org>.

diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index 0f1af20..7cc882d 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -119,7 +119,7 @@
 				/* by xf86scanpci		     */
 #if defined(sun) && defined(SVR4) && defined(sparc)
 # define MAX_PCI_BUSES   4096	/* Max number of PCI buses           */
-#elif defined(__alpha__) && defined (linux)
+#elif (defined(__alpha__) || defined(__ia64__)) && defined (linux)
 # define MAX_PCI_DOMAINS	512
 # define PCI_DOM_MASK	0x01fful
 # define MAX_PCI_BUSES	(MAX_PCI_DOMAINS*256) /* 256 per domain      */
@@ -258,7 +258,7 @@
 # endif
 #elif defined(__ia64__)
 # if defined(linux)
-#  define ARCH_PCI_INIT linuxPciInit
+#  define ARCH_PCI_INIT ia64linuxPciInit
 #  define INCLUDE_XF86_MAP_PCI_MEM
 # elif defined(FreeBSD)
 #  define ARCH_PCI_INIT freebsdPciInit
diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index bda265c..0f7fc47 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -940,3 +940,106 @@ int linuxPciHandleBIOS(PCITAG Tag, int b
   }
   return 0;
 }
+
+#ifdef __ia64__
+static PCITAG ia64linuxPciFindFirst(void);
+static PCITAG ia64linuxPciFindNext(void);
+
+void   
+ia64linuxPciInit()
+{
+    struct stat st;
+
+    linuxPciInit();
+	   
+    if (!stat("/proc/sgi_sn/licenseID", &st) && pciNumBuses) {
+       /* Be a little paranoid here and only use this code for Altix systems.
+	* It is generic, so it should work on any system, but depends on
+	* /proc/bus/pci entries for each domain/bus combination. Altix is
+	* guaranteed a recent enough kernel to have them.
+	*/
+       pciFindFirstFP = ia64linuxPciFindFirst;
+       pciFindNextFP  = ia64linuxPciFindNext;
+    }
+}
+
+static DIR *busdomdir;
+static DIR *devdir;
+	       
+static PCITAG
+ia64linuxPciFindFirst(void)
+{   
+       busdomdir = opendir("/proc/bus/pci");
+       devdir = NULL;
+
+       return ia64linuxPciFindNext();
+}   
+
+static struct dirent *getnextbus(int *domain, int *bus)
+{
+    struct dirent *entry;
+    int dombus;
+
+    for (;;) {
+	entry = readdir(busdomdir);
+	if (entry == NULL) {
+	    *domain = 0;
+	    *bus = 0;
+	    closedir(busdomdir);
+	    return NULL;
+	}
+	if (sscanf(entry->d_name, "%04x:%02x", domain, bus) != 2)
+	    continue;
+	dombus = PCI_MAKE_BUS(*domain, *bus);
+
+	if (pciNumBuses <= dombus)
+	    pciNumBuses = dombus + 1;
+	if (!pciBusInfo[dombus]) {
+	    pciBusInfo[dombus] = xnfalloc(sizeof(pciBusInfo_t));
+	    *pciBusInfo[dombus] = *pciBusInfo[0];
+	}
+
+	return entry;
+    }
+}
+
+static PCITAG
+ia64linuxPciFindNext(void)
+{
+    struct dirent *entry;
+    char file[40];
+    static int bus, dev, func, domain;
+    PCITAG pciDeviceTag;
+    CARD32 devid;
+
+    for (;;) {
+	if (devdir == NULL) {
+	    entry = getnextbus(&domain, &bus);
+	    if (!entry)
+		return PCI_NOT_FOUND;
+	    snprintf(file, 40, "/proc/bus/pci/%s", entry->d_name);
+	    devdir = opendir(file);
+	    if (!devdir)
+		return PCI_NOT_FOUND;
+
+	}
+
+	entry = readdir(devdir);
+
+	if (entry == NULL) {
+	    closedir(devdir);
+	    devdir = NULL;
+	    continue;
+	}
+
+	if (sscanf(entry->d_name, "%02x . %01x", &dev, &func) == 2) {
+	    pciDeviceTag = PCI_MAKE_TAG(PCI_MAKE_BUS(domain, bus), dev, func);
+	    devid = pciReadLong(pciDeviceTag, PCI_ID_REG);
+	    if ((devid & pciDevidMask) == pciDevid)
+		/* Yes - Return it.  Otherwise, next device */
+		return pciDeviceTag;
+	}
+    }
+}
+#endif
+
diff-tree 16c5043fc0c84b14323cd211c2645106455ac320 (from 072c022e731c3aadf34096f16364e29df47280d2)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 18:22:09 2006 +0100

    Fix 2 warnings.

diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index b763042..ae33568 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -1398,7 +1398,7 @@ fixPciResource(int prt, memType alignmen
     (*p_base) = H2B(tag,range.rBegin,type);
 #ifdef DEBUG
     ErrorF("New PCI res %i base: 0x%lx, size: 0x%lx, type %s\n",
-	   res_n,(*p_base),(1 << (*p_size)),
+	   res_n,(*p_base),(1L << (*p_size)),
 	   ((type & ResPhysMask) == ResMem) ? "Mem" : "Io");
 #endif
     if (res_n != 0xff) {
@@ -1577,8 +1577,8 @@ findPciRange(PCITAG tag, resPtr m, resPt
     return 0;
 }
 
-pciVideoPtr
-getPciVideoPtr(tag)
+static pciVideoPtr
+getPciVideoPtr(PCITAG tag)
 {
     int n = 0;
 
diff-tree 072c022e731c3aadf34096f16364e29df47280d2 (from 5afc6c1a14fea2966017493b045fa7209faeb8eb)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 17:58:19 2006 +0100

    Fix obviously wrong boundary checks + cleanup unused vars.
    
    Also disable compilation of code that is no longer used anywhere in the whole
    Xserver tree.

diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c
index aff6bb0..a957038 100644
--- a/hw/xfree86/os-support/linux/lnx_pci.c
+++ b/hw/xfree86/os-support/linux/lnx_pci.c
@@ -149,11 +149,10 @@ int lnxPciInit(void) {
 Bool
 xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
 {
-    unsigned int dev, fn;
     signed PCIADDR_TYPE Size;
     struct pci_dev *device;
 
-    if (index > 7)
+    if (index >= 7)
         return FALSE;
     
     if (!xf86OSLinuxPCIDevs) {
@@ -181,14 +180,14 @@ xf86GetPciSizeFromOS(PCITAG tag, int ind
 
 
 
+#if 0
 /* Query the kvirt address (64bit) of a BAR range from TAG */
 Bool
 xf86GetPciOffsetFromOS(PCITAG tag, int index, unsigned long* bases)
 {
-    unsigned int dev, fn;
     struct pci_dev *device;
 
-    if (index > 7)
+    if (index >= 7)
         return FALSE;
 
     if (!xf86OSLinuxPCIDevs) {
@@ -208,12 +207,12 @@ xf86GetPciOffsetFromOS(PCITAG tag, int i
 
     return FALSE;
 }
+#endif
 
 /* Query the kvirt address (64bit) of a BAR range from size for a given TAG */
 unsigned long
 xf86GetOSOffsetFromPCI(PCITAG tag, int space, unsigned long base)
 {
-    unsigned int dev, fn;
     unsigned int ndx;
     struct pci_dev *device;
 
diff-tree 5afc6c1a14fea2966017493b045fa7209faeb8eb (from 6319f7d713971f70f06166480f069eca3bcace36)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 15:42:03 2006 +0100

    Added linux 2.6 compatible domain aware device scanning code.
    
    Additional scanning code uses the /sys interface of 2.6 kernels.
    Cleaned up the use of tags and already split domain/bus/dev/fn.

diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index ea6ac4e..b80371d 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -20,6 +20,8 @@
  *	pciSetBitsByte()       - Write an 8 bit value against a mask
  *	pciTag()               - Return tag for a given PCI bus, device, &
  *                               function
+ *	pciDomTag()            - Return tag for a given PCI domain, bus,
+ *                               device & function
  *	pciBusAddrToHostAddr() - Convert a PCI address to a host address
  *	pciHostAddrToBusAddr() - Convert a host address to a PCI address
  *	pciGetBaseSize()       - Returns the number of bits in a PCI base
@@ -614,6 +616,12 @@ pciTag(int busnum, int devnum, int funcn
 	return(PCI_MAKE_TAG(busnum,devnum,funcnum));
 }
 
+_X_EXPORT PCITAG
+pciDomTag(int domnum, int busnum, int devnum, int funcnum)
+{
+	return(PCI_MAKE_TAG(PCI_MAKE_BUS(domnum,busnum),devnum,funcnum));
+}
+
 #if defined(PCI_MFDEV_SUPPORT)
 
 Bool
diff --git a/hw/xfree86/os-support/bus/xf86Pci.h b/hw/xfree86/os-support/bus/xf86Pci.h
index fdb88e8..c444a0c 100644
--- a/hw/xfree86/os-support/bus/xf86Pci.h
+++ b/hw/xfree86/os-support/bus/xf86Pci.h
@@ -766,6 +766,7 @@ void	      pciSetBitsByte(PCITAG tag, in
 ADDRESS	      pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
 ADDRESS	      pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr);
 PCITAG	      pciTag(int busnum, int devnum, int funcnum);
+PCITAG	      pciDomTag(int domnum, int busnum, int devnum, int funcnum);
 int	      pciGetBaseSize(PCITAG tag, int indx, Bool destructive, Bool *min);
 CARD32	      pciCheckForBrokenBase(PCITAG tag,int basereg);
 pointer	      xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag,
diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c
index a1dbc76..aff6bb0 100644
--- a/hw/xfree86/os-support/linux/lnx_pci.c
+++ b/hw/xfree86/os-support/linux/lnx_pci.c
@@ -3,7 +3,9 @@
 #include <xorg-config.h>
 #endif
 
+#include <sys/types.h>
 #include <stdio.h>
+#include <dirent.h>
 #include <X11/X.h>
 #include "os.h"
 #include "xf86.h"
@@ -25,8 +27,10 @@
 int lnxPciInit(void);
 
 struct pci_dev {
+    unsigned int domain;
     unsigned int bus;
-    unsigned int devfn;
+    unsigned int dev;
+    unsigned int fn;
     PCIADDR_TYPE offset[7];
     PCIADDR_TYPE size[7];
     struct pci_dev *next;
@@ -38,10 +42,53 @@ int xf86OSLinuxNumPciDevs = 0;
 static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
     char c[0x200];
     FILE *file = NULL;
+    DIR  *dir;
+    struct dirent *dirent;
     struct pci_dev *tmp, *ret = NULL;
-    unsigned int num;
+    unsigned int i, num, devfn;
+    unsigned PCIADDR_TYPE begin, end;
     char *res;
     
+    /* Try 2.6 devices first, with domain support */
+    if ( (dir = opendir ("/sys/bus/pci/devices")) ) {
+	xf86OSLinuxNumPciDevs = 0;
+	while ( (dirent = readdir (dir)) ) {
+	    unsigned int domain, bus, dev, fn;
+	    if (sscanf (dirent->d_name, "%04x:%02x:%02x.%01x",
+			&domain, &bus, &dev, &fn) == 4) {
+		tmp = xcalloc (sizeof(struct pci_dev), 1);
+		tmp->domain = domain;
+		tmp->bus    = bus;
+		tmp->dev    = dev;
+		tmp->fn     = fn;
+		sprintf (c, "/sys/bus/pci/devices/%12s/resource",
+			 dirent->d_name);
+		i = 0;
+		if ( (file = fopen (c, "r")) ) {
+		    while (i < 7 && fgets (c, 0x200, file)) {
+			if (sscanf (c, PCIADDR_FMT " " PCIADDR_FMT " "
+				    PCIADDR_IGNORE_FMT, &begin, &end) == 2) {
+			    tmp->offset[i] = begin;
+			    tmp->size[i]   = begin ? end-begin+1 : 0;
+			    i++;
+			}
+		    }
+		    fclose (file);
+		}
+		if (i > 0) {
+		    tmp->next = ret;
+		    ret       = tmp;
+		    xf86OSLinuxNumPciDevs++;
+		} else
+		    xfree (tmp);
+	    }
+	}
+	closedir (dir);
+    }
+
+    if (ret)
+	return ret;
+
     file = fopen("/proc/bus/pci/devices", "r");
     if (!file) return NULL;
 
@@ -70,9 +117,11 @@ static struct pci_dev *xf86OSLinuxGetPci
                 "\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->bus,&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]);
+            tmp->dev = devfn >> 3;
+            tmp->fn  = devfn & 0x7;
             if (num != 16) {  /* apparantly not 2.3 style */
                 xfree(tmp);
                 fclose(file);
@@ -114,10 +163,8 @@ xf86GetPciSizeFromOS(PCITAG tag, int ind
         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 (tag == pciDomTag (device->domain, device->bus,
+			      device->dev, device->fn)) {
             if (device->size[index] != 0) {
                 Size = device->size[index] - ((PCIADDR_TYPE) 1);
                 while (Size & ((PCIADDR_TYPE) 0x01)) {
@@ -151,9 +198,8 @@ xf86GetPciOffsetFromOS(PCITAG tag, int i
         return FALSE;
 
     for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
-        dev = device->devfn >> 3;
-        fn = device->devfn & 0x7;
-        if (tag == pciTag(device->bus,dev,fn)) {
+        if (tag == pciDomTag (device->domain, device->bus,
+			      device->dev, device->fn)) {
             /* return the offset for the index requested */
             *bases = device->offset[index];
             return TRUE;
@@ -179,9 +225,8 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int s
     }
 
     for (device = xf86OSLinuxPCIDevs; device; device = device->next) {
-        dev = device->devfn >> 3;
-        fn = device->devfn & 0x7;
-        if (tag == pciTag(device->bus, dev, fn)) {
+        if (tag == pciDomTag (device->domain, device->bus,
+			      device->dev, device->fn)) {
             /* ok now look through all the BAR values of this device */
             pciConfigPtr pDev = xf86GetPciConfigFromTag(tag);
 
diff-tree 6319f7d713971f70f06166480f069eca3bcace36 (from f4dd2665b0f9aa9c00a5152c73bc72cb7514eeb5)
Author: Egbert Eich <eich at freedesktop.org>
Date:   Thu Nov 2 12:50:52 2006 +0100

    Make int10 fully domain aware.

diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c
index 734d847..d80de89 100644
--- a/hw/xfree86/int10/helper_exec.c
+++ b/hw/xfree86/int10/helper_exec.c
@@ -469,7 +469,6 @@ Mem_wl(CARD32 addr, CARD32 val)
 
 static CARD32 PciCfg1Addr = 0;
 
-#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00)
 #define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
 
 static int
@@ -480,7 +479,7 @@ pciCfg1in(CARD16 addr, CARD32 *val)
 	return 1;
     }
     if (addr == 0xCFC) {
-	*val = pciReadLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr));
+	*val = pciReadLong(Int10Current->Tag, OFFSET(PciCfg1Addr));
 	return 1;
     }
     return 0;
@@ -494,7 +493,7 @@ pciCfg1out(CARD16 addr, CARD32 val)
 	return 1;
     }
     if (addr == 0xCFC) {
-	pciWriteLong(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr), val);
+	pciWriteLong(Int10Current->Tag, OFFSET(PciCfg1Addr), val);
 	return 1;
     }
     return 0;
@@ -512,7 +511,7 @@ pciCfg1inw(CARD16 addr, CARD16 *val)
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
 	offset = addr - 0xCFC;
-	*val = pciReadWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset);
+	*val = pciReadWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
 	return 1;
     }
     return 0;
@@ -531,7 +530,7 @@ pciCfg1outw(CARD16 addr, CARD16 val)
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
 	offset = addr - 0xCFC;
-	pciWriteWord(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val);
+	pciWriteWord(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
 	return 1;
     }
     return 0;
@@ -549,7 +548,7 @@ pciCfg1inb(CARD16 addr, CARD8 *val)
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
 	offset = addr - 0xCFC;
-	*val = pciReadByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset);
+	*val = pciReadByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset);
 	return 1;
     }
     return 0;
@@ -568,7 +567,7 @@ pciCfg1outb(CARD16 addr, CARD8 val)
     }
     if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
 	offset = addr - 0xCFC;
-	pciWriteByte(TAG(PciCfg1Addr), OFFSET(PciCfg1Addr) + offset, val);
+	pciWriteByte(Int10Current->Tag, OFFSET(PciCfg1Addr) + offset, val);
 	return 1;
     }
     return 0;
diff-tree f4dd2665b0f9aa9c00a5152c73bc72cb7514eeb5 (from 46901063e8edc82b67989f4e5eec39d17c67dc98)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 12:36:12 2006 +0100

    Added missing domain stripping in already domain aware code.

diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 7d220d0..bda265c 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -731,7 +731,7 @@ xf86ReadDomainMemory(PCITAG Tag, ADDRESS
     struct stat st;
 
     dom  = PCI_DOM_FROM_TAG(Tag);
-    bus  = PCI_BUS_FROM_TAG(Tag);
+    bus  = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag));
     dev  = PCI_DEV_FROM_TAG(Tag);
     func = PCI_FUNC_FROM_TAG(Tag);
     sprintf(file, "/sys/devices/pci%04x:%02x/%04x:%02x:%02x.%1x/rom",
@@ -910,7 +910,7 @@ int linuxPciHandleBIOS(PCITAG Tag, int b
   int sofar = 0;
 
   dom  = PCI_DOM_FROM_TAG(Tag);
-  bus  = PCI_BUS_FROM_TAG(Tag);
+  bus  = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(Tag));
   dev  = PCI_DEV_FROM_TAG(Tag);
   func = PCI_FUNC_FROM_TAG(Tag);
   sprintf(file, "/sys/bus/pci/devices/%04x:%02x:%02x.%1x/rom",
diff-tree 46901063e8edc82b67989f4e5eec39d17c67dc98 (from 037f23e6f8fbe6e6fc8e71ed21958fc553df72d0)
Author: Matthias Hopf <mhopf at suse.de>
Date:   Thu Nov 2 12:25:03 2006 +0100

    Build with -D_PC on ix86 only.

diff --git a/hw/xfree86/int10/Makefile.am b/hw/xfree86/int10/Makefile.am
index c059070..3a18afb 100644
--- a/hw/xfree86/int10/Makefile.am
+++ b/hw/xfree86/int10/Makefile.am
@@ -13,8 +13,12 @@ COMMON_SOURCES = \
 	xf86int10.c \
 	xf86int10module.c
 
+if I386_VIDEO
+I386_VIDEO_CFLAGS = -D_PC
+endif
+
 if INT10_VM86
-AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
+AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
 INCLUDES = $(XORG_INCS)
 libint10_la_SOURCES = \
 	$(COMMON_SOURCES) \
@@ -23,7 +27,8 @@ libint10_la_SOURCES = \
 endif
 
 if INT10_X86EMU
-AM_CFLAGS = -D_X86EMU -DNO_SYS_HEADERS -D_PC $(XORG_CFLAGS) $(EXTRA_CFLAGS)
+AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_X86EMU -DNO_SYS_HEADERS \
+           $(XORG_CFLAGS) $(EXTRA_CFLAGS)
 INCLUDES = $(XORG_INCS) -I$(srcdir)/../x86emu
 libint10_la_SOURCES = \
 	$(COMMON_SOURCES) \
@@ -33,7 +38,7 @@ libint10_la_SOURCES = \
 endif
 
 if INT10_STUB
-AM_CFLAGS = -D_PC -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
+AM_CFLAGS = $(I386_VIDEO_CFLAGS) -D_VM86_LINUX $(XORG_CFLAGS) $(EXTRA_CFLAGS)
 libint10_la_SOURCES = stub.c xf86int10module.c
 endif
 



More information about the xorg-commit mailing list