From f8bae6529005a67cccd3866f0c4b0762bedf610e Mon Sep 17 00:00:00 2001
From: Boiko <boiko@ageless.conectiva>
Date: Thu, 8 Jun 2006 13:42:12 -0300
Subject: [PATCH] When we can, bound the maximum number of PCI devices to attempt to scan, by the number found on the system. Only implemented for Linux right now.

(cherry picked from 8444bb77c91cf8a23d32b3cc9749e2a3d3f9f9eb commit)
---
 hw/xfree86/os-support/bus/Pci.c       |    6 +++++-
 hw/xfree86/os-support/bus/Pci.h       |    2 ++
 hw/xfree86/os-support/bus/linuxPci.c  |    4 ++++
 hw/xfree86/os-support/linux/lnx_pci.c |   15 ++++++++++++++-
 4 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index eeed8b0..15006e1 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -238,6 +238,8 @@ static int readPciBios( PCITAG Tag, CARD
 
 static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len);
 
+int xf86MaxPciDevs = MAX_PCI_DEVICES;
+
 /*
  * Platform specific PCI function pointers.
  *
@@ -938,7 +940,7 @@ #ifndef OLD_FORMAT
     xf86MsgVerb(X_INFO, 2, "PCI: PCI scan (all values are in hex)\n");
 #endif
 
-    while (idx < MAX_PCI_DEVICES && tag != PCI_NOT_FOUND) {
+    while (idx < xf86MaxPciDevs && tag != PCI_NOT_FOUND) {
 	devp = xcalloc(1, sizeof(pciDevice));
 	if (!devp) {
 	    xf86Msg(X_ERROR,
@@ -1001,6 +1003,8 @@ #else
 #endif
 
 	pci_devp[idx++] = devp;
+        if (idx == xf86MaxPciDevs)
+            break;
 	tag = pciFindNext();
 
 #ifdef DEBUGPCI
diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h
index 32088fe..79d8d32 100644
--- a/hw/xfree86/os-support/bus/Pci.h
+++ b/hw/xfree86/os-support/bus/Pci.h
@@ -439,6 +439,8 @@ extern int    pciDevNum;
 extern int    pciFuncNum;
 extern PCITAG pciDeviceTag;
 
+extern int    xf86MaxPciDevs;
+
 extern pciBusInfo_t  *pciBusInfo[];
 
 #endif /* _PCI_H */
diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c
index 3e82f21..0714c9c 100644
--- a/hw/xfree86/os-support/bus/linuxPci.c
+++ b/hw/xfree86/os-support/bus/linuxPci.c
@@ -108,6 +108,9 @@ static pciBusInfo_t linuxPci0 = {
 /* bridge      */	NULL
 };
 
+/* from lnx_pci.c. */
+extern int lnxPciInit(void);
+
 void
 linuxPciInit()
 {
@@ -123,6 +126,7 @@ linuxPciInit()
 	pciFindFirstFP = pciGenFindFirst;
 	pciFindNextFP  = pciGenFindNext;
 	pciSetOSBIOSPtr(linuxPciHandleBIOS);
+        xf86MaxPciDevs = lnxPciInit();
 }
 
 static int
diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c
index 4a80786..72939f4 100644
--- a/hw/xfree86/os-support/linux/lnx_pci.c
+++ b/hw/xfree86/os-support/linux/lnx_pci.c
@@ -23,6 +23,8 @@ #define PCIADDR_IGNORE_FMT	"%*x"
 #define PCIADDR_FMT		"%lx"
 #endif
 
+int lnxPciInit(void);
+
 struct pci_dev {
     unsigned int bus;
     unsigned int devfn;
@@ -32,6 +34,7 @@ struct pci_dev {
 };
 
 struct pci_dev *xf86OSLinuxPCIDevs = NULL;
+int xf86OSLinuxNumPciDevs = 0;
 
 static struct pci_dev *xf86OSLinuxGetPciDevs(void) {
     char c[0x200];
@@ -42,6 +45,8 @@ static struct pci_dev *xf86OSLinuxGetPci
     
     file = fopen("/proc/bus/pci/devices", "r");
     if (!file) return NULL;
+
+    xf86OSLinuxNumPciDevs = 0;
     
     do {
         res = fgets(c, 0x1ff, file);
@@ -78,12 +83,21 @@ static struct pci_dev *xf86OSLinuxGetPci
                 tmp->next = ret;
             }
             ret = tmp;
+            xf86OSLinuxNumPciDevs++;
         }
     } while (res);
     fclose(file);
     return ret;
 }
 
+/* not to be confused with linuxPciInit (i.e. ARCH_PCI_INIT), found in
+ * os-support/bus/linuxPci.c. */
+int lnxPciInit(void) {
+    if (!xf86OSLinuxPCIDevs)
+        xf86OSLinuxPCIDevs = xf86OSLinuxGetPciDevs();
+    return xf86OSLinuxNumPciDevs;
+}
+
 Bool
 xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits)
 {
@@ -198,5 +212,4 @@ xf86GetOSOffsetFromPCI(PCITAG tag, int s
     };
 
     return 0;
-
 }
-- 
1.4.0

