summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2011-09-16 13:33:04 -0400
committerJeremy Huddleston <jeremyhu@apple.com>2011-10-15 21:18:46 -0700
commit858fbbb40d7c69540cd1fb5315cebf811c6e7b3f (patch)
treed71e30fe12d2156af7203169ada24bdb05bfb3a7
parent6d9efdce0d06df6b85f0681bea306c0b1e851502 (diff)
pci: Port xf86MapLegacyIO to pciaccess
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. The IOADDRESS type is kept around to help drivers through the API transition and will be removed at some point in the future. Reviewed-by: Jeremy Huddleston <jeremyhu@apple.com> Tested-by: Jeremy Huddleston <jeremyhu@apple.com> Signed-off-by: Adam Jackson <ajax@redhat.com> Reviewed-by: Jamey Sharp <jamey@minilop.net>
-rw-r--r--hw/xfree86/common/xf86Bus.c1
-rw-r--r--hw/xfree86/common/xf86Bus.h1
-rw-r--r--hw/xfree86/common/xf86pciBus.c17
-rw-r--r--hw/xfree86/common/xf86str.h1
-rw-r--r--hw/xfree86/os-support/bus/Pci.c2
-rw-r--r--hw/xfree86/os-support/bus/Pci.h16
-rw-r--r--hw/xfree86/os-support/bus/bsd_pci.c9
-rw-r--r--hw/xfree86/os-support/bus/linuxPci.c127
-rw-r--r--hw/xfree86/os-support/bus/xf86Pci.h5
9 files changed, 22 insertions, 157 deletions
diff --git a/hw/xfree86/common/xf86Bus.c b/hw/xfree86/common/xf86Bus.c
index 3b0896863..8749a2981 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 e161c7f4c..0b2ebdb44 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 447b19229..2acf48606 100644
--- a/hw/xfree86/common/xf86pciBus.c
+++ b/hw/xfree86/common/xf86pciBus.c
@@ -235,11 +235,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;
@@ -1357,3 +1352,15 @@ xf86PciConfigureNewDev(void *busData, struct pci_device *pVideo,
if (*chipset < 0)
*chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
}
+
+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 0493dc53c..43e9d1d35 100644
--- a/hw/xfree86/common/xf86str.h
+++ b/hw/xfree86/common/xf86str.h
@@ -742,7 +742,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 fe4850ecd..f1dbfc216 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -140,7 +140,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 349301315..88560ecdc 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -137,20 +137,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 17b52db49..f51d5c078 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 fcfdbcb67..28bba019e 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -52,21 +52,6 @@
#include "xf86_OSlib.h"
#include "Pci.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
@@ -153,15 +138,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
@@ -223,67 +199,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)
@@ -406,45 +321,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 ce1336bf2..3a17c3040 100644
--- a/hw/xfree86/os-support/bus/xf86Pci.h
+++ b/hw/xfree86/os-support/bus/xf86Pci.h
@@ -235,7 +235,7 @@
/* Primitive Types */
typedef unsigned long ADDRESS; /* Memory/PCI address */
-typedef unsigned long IOADDRESS; /* Must be large enough for a pointer */
+typedef unsigned long IOADDRESS _X_DEPRECATED; /* Must be large enough for a pointer */
typedef unsigned long PCITAG;
typedef enum {
@@ -257,6 +257,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 */