summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorMatthias Hopf <mhopf@suse.de>2006-11-02 15:42:03 +0100
committerMatthias Hopf <mhopf@suse.de>2006-11-03 18:59:51 +0100
commit5afc6c1a14fea2966017493b045fa7209faeb8eb (patch)
tree969eefe2b9a767402f92de055574b9f5869463b9 /hw
parent6319f7d713971f70f06166480f069eca3bcace36 (diff)
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.
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/os-support/bus/Pci.c8
-rw-r--r--hw/xfree86/os-support/bus/xf86Pci.h1
-rw-r--r--hw/xfree86/os-support/linux/lnx_pci.c71
3 files changed, 67 insertions, 13 deletions
diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index ea6ac4ec0..b80371d83 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 funcnum)
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 fdb88e832..c444a0cd1 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, int offset, CARD8 mask, CARD8 val);
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 a1dbc7604..aff6bb0ae 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 *xf86OSLinuxGetPciDevs(void) {
"\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 index, int* bits)
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 index, unsigned long* bases)
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 space, unsigned long base)
}
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);