[PATCH 6/9] pci: Port xf86MapLegacyIO to pciaccess

Adam Jackson ajax at redhat.com
Tue Sep 21 16:28:36 PDT 2010


Per-domain I/O is now something drivers must manually request, and must
keep track of within their own state rather than in the ScrnInfoRec.
It's not really possible to split that into two steps without an
additional intermediate ABI break, so don't even try.  Drivers that want
source compatibility should ifdef on the presence of xf86UnmapLegacyIO.

As a fringe benefit, domain-aware I/O is now OS-independent, relying
only on support in pciaccess.  Simplify OS PCI setup to reflect this.

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 hw/xfree86/common/xf86Bus.c          |    1 -
 hw/xfree86/common/xf86Bus.h          |    1 -
 hw/xfree86/common/xf86pciBus.c       |   17 +++--
 hw/xfree86/common/xf86str.h          |    1 -
 hw/xfree86/os-support/bus/Pci.c      |    2 +-
 hw/xfree86/os-support/bus/Pci.h      |   16 ++---
 hw/xfree86/os-support/bus/bsd_pci.c  |    9 +--
 hw/xfree86/os-support/bus/linuxPci.c |  127 ----------------------------------
 hw/xfree86/os-support/bus/xf86Pci.h  |    4 +-
 9 files changed, 21 insertions(+), 157 deletions(-)

diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 90c1914..cd1021c 100644
--- a/hw/xfree86/common/xf86Bus.c
+++ b/hw/xfree86/common/xf86Bus.c
@@ -308,7 +308,6 @@ xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
     pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
 				    pScrn->numEntities * sizeof(int));
     pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
-    pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
 }
 
 void
diff --git a/hw/xfree86/common/xf86Bus.h b/hw/xfree86/common/xf86Bus.h
index e161c7f..0b2ebdb 100644
--- a/hw/xfree86/common/xf86Bus.h
+++ b/hw/xfree86/common/xf86Bus.h
@@ -58,7 +58,6 @@ typedef struct {
     DevUnion *                  entityPrivates;
     int                         numInstances;
     GDevPtr *                   devices;   
-    IOADDRESS                   domainIO;
 } EntityRec, *EntityPtr;
 
 #define ACCEL_IS_SHARABLE 0x100
diff --git a/hw/xfree86/common/xf86pciBus.c b/hw/xfree86/common/xf86pciBus.c
index 74016af..cc387f1 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -230,11 +230,6 @@ xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp,
             xf86AddDevToEntity(num, dev);
 	pciSlotClaimed = TRUE;
 
-	if (active) {
-	    /* Map in this domain's I/O space */
-	   p->domainIO = xf86MapLegacyIO(d);
-	}
-	
  	return num;
     } else
  	return -1;
@@ -1322,3 +1317,15 @@ xf86PciMatchDriver(char* matches[], int nmatches) {
 
     return i;
 }
+
+struct pci_io_handle *
+xf86MapLegacyIO(struct pci_device *dev)
+{
+    return pci_legacy_open_io(dev, 0, 64 * 1024);
+}
+
+void
+xf86UnmapLegacyIO(struct pci_device *dev, struct pci_io_handle *handle)
+{
+    pci_device_close_io(dev, handle);
+}
diff --git a/hw/xfree86/common/xf86str.h b/hw/xfree86/common/xf86str.h
index c9b261d..3c59231 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -754,7 +754,6 @@ typedef struct _ScrnInfoRec {
     unsigned long	biosBase;		/* Base address of video BIOS */
     unsigned long	memPhysBase;		/* Physical address of FB */
     unsigned long 	fbOffset;		/* Offset of FB in the above */
-    IOADDRESS    	domainIOBase;		/* Domain I/O base address */
     int			memClk;			/* memory clock */
     int			textClockFreq;		/* clock of text mode */
     Bool		flipPixels;		/* swap default black/white */
diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index a0a597d..e32932c 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -151,7 +151,7 @@ xf86scanpci(void)
     success = (pci_system_init() == 0);
 
     /* choose correct platform/OS specific PCI init routine */
-	ARCH_PCI_INIT();
+    osPciInit();
 
     return success;
 }
diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index e001c30..a2846fb 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -142,20 +142,14 @@
 #define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
 #define PCI_TAG_NO_DOMAIN(tag) ((tag) & 0x00ffff00u)
 
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
+#if defined(linux)
+#define osPciInit(x) do {} while (0)
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \
 	defined(__OpenBSD__) || defined(__NetBSD__) || \
 	defined(__DragonFly__) || defined(__sun) || defined(__GNU__)
-#define ARCH_PCI_INIT bsdPciInit
-#endif
-
-#if defined(linux)
-#define ARCH_PCI_INIT linuxPciInit
-#endif /* defined(linux) */
-
-#ifndef ARCH_PCI_INIT
+extern void osPciInit(void);
+#else
 #error No PCI support available for this architecture/OS combination
 #endif
 
-extern void ARCH_PCI_INIT(void);
-
 #endif /* _PCI_H */
diff --git a/hw/xfree86/os-support/bus/bsd_pci.c b/hw/xfree86/os-support/bus/bsd_pci.c
index 17b52db..f51d5c0 100644
--- a/hw/xfree86/os-support/bus/bsd_pci.c
+++ b/hw/xfree86/os-support/bus/bsd_pci.c
@@ -55,15 +55,8 @@ xf86MapDomainMemory(int ScreenNum, int Flags, struct pci_device *dev,
     return xf86MapVidMem(ScreenNum, Flags, Base, Size);
 }
 
-IOADDRESS
-xf86MapLegacyIO(struct pci_device *dev)
-{
-    (void)dev;
-    return 0;
-}
-
 void
-bsdPciInit(void)
+osPciInit(void)
 {
     xf86InitVidMem();
 }
diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 289315e..3fbe52d 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -56,21 +56,6 @@
 #include "Pci.h"
 #include <dirent.h>
 
-static const struct pci_id_match match_host_bridge = {
-    PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
-    (PCI_CLASS_BRIDGE << 16) | (PCI_SUBCLASS_BRIDGE_HOST << 8),
-    0x0000ffff00, 0
-};
-
-#define MAX_DOMAINS 257
-static pointer DomainMmappedIO[MAX_DOMAINS];
-
-void
-linuxPciInit(void)
-{
-    memset(DomainMmappedIO, 0, sizeof(DomainMmappedIO));
-}
-
 /**
  * \bug
  * The generation of the procfs file name for the domain != 0 case may not be 
@@ -157,15 +142,6 @@ linuxPciOpenFile(struct pci_device *dev, Bool write)
  * functionality is almost, but not quite there yet.  Alpha and other kernel
  * ports to multi-domain architectures still need to implement this.
  *
- * This scheme is also predicated on the use of an IOADDRESS compatible type to
- * designate I/O addresses.  Although IOADDRESS is defined as an unsigned
- * integral type, it is actually the virtual address of, i.e. a pointer to, the
- * I/O port to access.  And so, the inX/outX macros in "compiler.h" need to be
- * #define'd appropriately (as is done on SPARC's).
- *
- * Another requirement to port this scheme to another multi-domain architecture
- * is to add the appropriate entries in the pciControllerSizes array below.
- *
  * TO DO:  Address the deleterious reaction some host bridges have to master
  *         aborts.  This is already done for secondary PCI buses, but not yet
  *         for accesses to primary buses (except for the SPARC port, where
@@ -227,67 +203,6 @@ get_parent_bridge(struct pci_device *dev)
     return bridge;
 }
 
-/*
- * This is ugly, but until I can extract this information from the kernel,
- * it'll have to do.  The default I/O space size is 64K, and 4G for memory.
- * Anything else needs to go in this table.  (PowerPC folk take note.)
- *
- * Note that Linux/SPARC userland is 32-bit, so 4G overflows to zero here.
- *
- * Please keep this table in ascending vendor/device order.
- */
-static const struct pciSizes {
-    unsigned short vendor, device;
-    unsigned long io_size, mem_size;
-} pciControllerSizes[] = {
-    {
-	PCI_VENDOR_SUN, PCI_CHIP_PSYCHO,
-	1U << 16, 1U << 31
-    },
-    {
-	PCI_VENDOR_SUN, PCI_CHIP_SCHIZO,
-	1U << 24, 1U << 31	/* ??? */
-    },
-    {
-	PCI_VENDOR_SUN, PCI_CHIP_SABRE,
-	1U << 24, (unsigned long)(1ULL << 32)
-    },
-    {
-	PCI_VENDOR_SUN, PCI_CHIP_HUMMINGBIRD,
-	1U << 24, (unsigned long)(1ULL << 32)
-    }
-};
-#define NUM_SIZES (sizeof(pciControllerSizes) / sizeof(pciControllerSizes[0]))
-
-static const struct pciSizes *
-linuxGetSizesStruct(const struct pci_device *dev)
-{
-    static const struct pciSizes default_size = {
-	0, 0, 1U << 16, (unsigned long)(1ULL << 32)
-    };
-    int          i;
-
-    /* Look up vendor/device */
-    if (dev != NULL) {
-	for (i = 0;  i < NUM_SIZES;  i++) {
-	    if ((dev->vendor_id == pciControllerSizes[i].vendor)
-		&& (dev->device_id == pciControllerSizes[i].device)) {
-		return & pciControllerSizes[i];
-	    }
-	}
-    }
-
-    /* Default to 64KB I/O and 4GB memory. */
-    return & default_size;
-}
-
-static __inline__ unsigned long
-linuxGetIOSize(const struct pci_device *dev)
-{
-    const struct pciSizes * const sizes = linuxGetSizesStruct(dev);
-    return sizes->io_size;
-}
-
 static pointer
 linuxMapPci(int ScreenNum, int Flags, struct pci_device *dev,
 	    ADDRESS Base, unsigned long Size, int mmap_ioctl)
@@ -410,45 +325,3 @@ xf86MapDomainMemory(int ScreenNum, int Flags, struct pci_device *dev,
     }
     return addr;
 }
-
-/**
- * Map I/O space in this domain
- *
- * Each domain has a legacy ISA I/O space.  This routine will try to
- * map it using the Linux sysfs legacy_io interface.  If that fails,
- * it'll fall back to using /proc/bus/pci.
- *
- * If the legacy_io interface \b does exist, the file descriptor (\c fd below)
- * will be saved in the \c DomainMmappedIO array in the upper bits of the
- * pointer.  Callers will do I/O with small port numbers (<64k values), so
- * the platform I/O code can extract the port number and the \c fd, \c lseek
- * to the port number in the legacy_io file, and issue the read or write.
- *
- * This has no means of returning failure, so all errors are fatal
- */
-IOADDRESS
-xf86MapLegacyIO(struct pci_device *dev)
-{
-    const int domain = dev->domain;
-    struct pci_device *bridge = get_parent_bridge(dev);
-    int fd;
-
-    if (domain >= MAX_DOMAINS)
-	FatalError("xf86MapLegacyIO():  domain out of range\n");
-
-    if (DomainMmappedIO[domain] == NULL) {
-	/* Permanently map all of I/O space */
-	fd = linuxOpenLegacy(bridge, "legacy_io");
-	if (fd < 0) {
-	    DomainMmappedIO[domain] = linuxMapPci(-1, VIDMEM_MMIO, bridge,
-						  0, linuxGetIOSize(bridge),
-						  PCIIOC_MMAP_IS_IO);
-	}
-	else { /* legacy_io file exists, encode fd */
-	    DomainMmappedIO[domain] = (pointer)(intptr_t)(fd << 24);
-	}
-    }
-
-    return (IOADDRESS)DomainMmappedIO[domain];
-}
-
diff --git a/hw/xfree86/os-support/bus/xf86Pci.h b/hw/xfree86/os-support/bus/xf86Pci.h
index ce1336b..4f2f07e 100644
--- a/hw/xfree86/os-support/bus/xf86Pci.h
+++ b/hw/xfree86/os-support/bus/xf86Pci.h
@@ -235,7 +235,6 @@
 
 /* Primitive Types */
 typedef unsigned long ADDRESS;		/* Memory/PCI address */
-typedef unsigned long IOADDRESS;	/* Must be large enough for a pointer */
 typedef unsigned long PCITAG;
 
 typedef enum {
@@ -257,6 +256,7 @@ extern _X_EXPORT Bool xf86scanpci(void);
 /* Domain access functions.  Some of these probably shouldn't be public */
 extern _X_EXPORT pointer xf86MapDomainMemory(int ScreenNum, int Flags, struct pci_device *dev,
     ADDRESS Base, unsigned long Size);
-extern _X_EXPORT IOADDRESS xf86MapLegacyIO(struct pci_device *dev);
+extern _X_EXPORT struct pci_io_handle *xf86MapLegacyIO(struct pci_device *dev);
+extern _X_EXPORT void xf86UnmapLegacyIO(struct pci_device *, struct pci_io_handle *);
 
 #endif /* _XF86PCI_H */
-- 
1.7.2.2



More information about the xorg-devel mailing list