aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/bus.c
diff options
context:
space:
mode:
authorZhang, Yanmin <yanmin_zhang@linux.intel.com>2009-06-16 01:34:38 -0400
committerJesse Barnes <jbarnes@virtuousgeek.org>2009-06-16 17:30:13 -0400
commit70298c6e6c1ba68346336b4ea54bd5c0abbf73c8 (patch)
tree363d0a784d8a28688c0fda006279563a7fd3629b /drivers/pci/bus.c
parenta6c0d5c6ebb3d988b1f18a1612b5188f3f555637 (diff)
PCI AER: support Multiple Error Received and no error source id
Based on PCI Express AER specs, a root port might receive multiple TLP errors while it could only save a correctable error source id and an uncorrectable error source id at the same time. In addition, some root port hardware might be unable to provide a correct source id, i.e., the source id, or the bus id part of the source id provided by root port might be equal to 0. The patchset implements the support in kernel by searching the device tree under the root port. Patch 1 changes parameter cb of function pci_walk_bus to return a value. When cb return non-zero, pci_walk_bus stops more searching on the device tree. Reviewed-by: Andrew Patterson <andrew.patterson@hp.com> Signed-off-by: Zhang Yanmin <yanmin_zhang@linux.intel.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/bus.c')
-rw-r--r--drivers/pci/bus.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 40af27f31043..cef28a79103f 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -206,13 +206,18 @@ void pci_enable_bridges(struct pci_bus *bus)
206 * Walk the given bus, including any bridged devices 206 * Walk the given bus, including any bridged devices
207 * on buses under this bus. Call the provided callback 207 * on buses under this bus. Call the provided callback
208 * on each device found. 208 * on each device found.
209 *
210 * We check the return of @cb each time. If it returns anything
211 * other than 0, we break out.
212 *
209 */ 213 */
210void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), 214void pci_walk_bus(struct pci_bus *top, int (*cb)(struct pci_dev *, void *),
211 void *userdata) 215 void *userdata)
212{ 216{
213 struct pci_dev *dev; 217 struct pci_dev *dev;
214 struct pci_bus *bus; 218 struct pci_bus *bus;
215 struct list_head *next; 219 struct list_head *next;
220 int retval;
216 221
217 bus = top; 222 bus = top;
218 down_read(&pci_bus_sem); 223 down_read(&pci_bus_sem);
@@ -236,8 +241,10 @@ void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *),
236 241
237 /* Run device routines with the device locked */ 242 /* Run device routines with the device locked */
238 down(&dev->dev.sem); 243 down(&dev->dev.sem);
239 cb(dev, userdata); 244 retval = cb(dev, userdata);
240 up(&dev->dev.sem); 245 up(&dev->dev.sem);
246 if (retval)
247 break;
241 } 248 }
242 up_read(&pci_bus_sem); 249 up_read(&pci_bus_sem);
243} 250}