From: Paul Mackerras <paulus@samba.org>
To: Greg KH <greg@kroah.com>
Cc: linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
linas@austin.ibm.com
Subject: [PATCH] Add pci_walk_bus function to PCI core (nonrecursive)
Date: Thu, 18 Aug 2005 14:33:01 +1000 [thread overview]
Message-ID: <17156.3965.483826.692623@cargo.ozlabs.ibm.com> (raw)
The PCI error recovery infrastructure needs to be able to contact all
the drivers affected by a PCI error event, which may mean traversing
all the devices under a given PCI-PCI bridge. This patch adds a
function to the PCI core that traverses all the PCI devices on a PCI
bus and under any PCI-PCI bridges on that bus (and so on), calling a
given function for each device. This provides a way for the error
recovery code to iterate through all devices that are affected by an
error event.
This version is not implemented as a recursive function. Instead,
when we reach a PCI-PCI bridge, we set the pointers to start doing the
devices on the bus under the bridge, and when we reach the end of a
bus's devices, we use the bus->self pointer to go back up to the next
higher bus and continue doing its devices.
Signed-off-by: Paul Mackerras <paulus@samba.org>
---
diff -urN linux-2.6/drivers/pci/bus.c test-pseries/drivers/pci/bus.c
--- linux-2.6/drivers/pci/bus.c 2005-08-03 10:51:36.000000000 +1000
+++ test-pseries/drivers/pci/bus.c 2005-08-18 14:03:28.000000000 +1000
@@ -150,6 +150,54 @@
}
}
+/** pci_walk_bus - walk devices on/under bus, calling callback.
+ * @top bus whose devices should be walked
+ * @cb callback to be called for each device found
+ * @userdata arbitrary pointer to be passed to callback.
+ *
+ * Walk the given bus, including any bridged devices
+ * on buses under this bus. Call the provided callback
+ * on each device found.
+ */
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+ void *userdata)
+{
+ struct pci_dev *dev;
+ struct pci_bus *bus;
+ struct list_head *next;
+
+ bus = top;
+ spin_lock(&pci_bus_lock);
+ next = top->devices.next;
+ for (;;) {
+ if (next == &bus->devices) {
+ /* end of this bus, go up or finish */
+ if (bus == top)
+ break;
+ next = bus->self->bus_list.next;
+ bus = bus->self->bus;
+ continue;
+ }
+ dev = list_entry(next, struct pci_dev, bus_list);
+ pci_dev_get(dev);
+ if (dev->subordinate) {
+ /* this is a pci-pci bridge, do its devices next */
+ next = dev->subordinate->devices.next;
+ bus = dev->subordinate;
+ } else
+ next = dev->bus_list.next;
+ spin_unlock(&pci_bus_lock);
+
+ /* Run device routines with the bus unlocked */
+ cb(dev, userdata);
+
+ spin_lock(&pci_bus_lock);
+ pci_dev_put(dev);
+ }
+ spin_unlock(&pci_bus_lock);
+}
+EXPORT_SYMBOL_GPL(pci_walk_bus);
+
EXPORT_SYMBOL(pci_bus_alloc_resource);
EXPORT_SYMBOL_GPL(pci_bus_add_device);
EXPORT_SYMBOL(pci_bus_add_devices);
diff -urN linux-2.6/include/linux/pci.h test-pseries/include/linux/pci.h
--- linux-2.6/include/linux/pci.h 2005-08-18 12:59:18.000000000 +1000
+++ test-pseries/include/linux/pci.h 2005-08-18 13:54:38.000000000 +1000
@@ -865,6 +865,9 @@
const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev);
int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass);
+void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
+ void *userdata);
+
/* kmem_cache style wrapper around pci_alloc_consistent() */
#include <linux/dmapool.h>
next reply other threads:[~2005-08-18 4:32 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-08-18 4:33 Paul Mackerras [this message]
2005-08-18 4:58 ` Benjamin Herrenschmidt
2005-08-18 5:13 ` Greg KH
2005-08-18 8:02 ` Benjamin Herrenschmidt
2005-08-19 16:30 ` Linas Vepstas
2005-08-20 0:10 ` Benjamin Herrenschmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=17156.3965.483826.692623@cargo.ozlabs.ibm.com \
--to=paulus@samba.org \
--cc=greg@kroah.com \
--cc=linas@austin.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®