summaryrefslogtreecommitdiffstats
path: root/cpukit/libpci/pci_for_each.c
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2011-11-28 10:11:10 +0100
committerDaniel Hellstrom <daniel@gaisler.com>2015-04-17 01:10:15 +0200
commita31845f7f9b4770cf9ddd8b6820641d2f4f4c1da (patch)
tree0d7f215ec45d7c4cf6f1293af72ece2fbde1ddc3 /cpukit/libpci/pci_for_each.c
parentleon3,ngmp: simplify cpucounter initialization (diff)
downloadrtems-a31845f7f9b4770cf9ddd8b6820641d2f4f4c1da.tar.bz2
LIBPCI: added PCI layer to cpukit/libpci
Diffstat (limited to 'cpukit/libpci/pci_for_each.c')
-rw-r--r--cpukit/libpci/pci_for_each.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/cpukit/libpci/pci_for_each.c b/cpukit/libpci/pci_for_each.c
new file mode 100644
index 0000000000..dc0a9a16f1
--- /dev/null
+++ b/cpukit/libpci/pci_for_each.c
@@ -0,0 +1,62 @@
+/* PCI Help Function, iterate over all PCI devices. Find devices by cfg access.
+ *
+ * COPYRIGHT (c) 2010.
+ * Cobham Gaisler AB.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#include <pci.h>
+#include <pci/access.h>
+
+/*#define DEBUG*/
+
+#ifdef DEBUG
+#include <rtems/bspIo.h>
+#define DBG(args...) printk(args)
+#else
+#define DBG(args...)
+#endif
+
+int pci_for_each(int (*func)(pci_dev_t, void*), void *arg)
+{
+ uint32_t id;
+ uint8_t hd;
+ int bus, dev, fun, result, fail;
+ int maxbus = pci_bus_count();
+ pci_dev_t pcidev;
+
+ for (bus = 0; bus < maxbus ; bus++) {
+ for (dev = 0; dev < PCI_MAX_DEVICES; dev++) {
+ pcidev = PCI_DEV(bus, dev, 0);
+
+ for (fun = 0; fun < PCI_MAX_FUNCTIONS; fun++, pcidev++) {
+ fail = pci_cfg_r32(pcidev, PCI_VENDOR_ID, &id);
+ if (fail || (0xffffffff == id) || (0 == id)) {
+ if (fun == 0)
+ break;
+ else
+ continue;
+ }
+
+ DBG("pcibus_for_each: found 0x%08lx at"
+ " %d/%d/%d\n", id, bus, dev, fun);
+ result = func(pcidev, arg);
+ if (result != 0)
+ return result; /* Stopped */
+
+ /* Stop if not a multi-function device */
+ if (fun == 0) {
+ pci_cfg_r8(pcidev, PCI_HEADER_TYPE,
+ &hd);
+ if ((hd & PCI_MULTI_FUNCTION) == 0)
+ break;
+ }
+ }
+ }
+ }
+
+ return 0; /* scanned all */
+}