aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-11-28 13:39:19 -0500
committerBjorn Helgaas <bhelgaas@google.com>2012-11-28 13:39:19 -0500
commit3c282db1656733c1267e6af4c22179bb04faf2ef (patch)
tree141669ad06cfc2459ec93aeb9d86237328faa61d
parentd3fe3988fb24e5ed13b2243b789a652882d3b26c (diff)
parent918b4053184c0ca22236e70e299c5343eea35304 (diff)
Merge branch 'pci/misc' into next
* pci/misc: PCI/AER: Report success only when every device has AER-aware driver Conflicts: drivers/pci/pcie/aer/aerdrv_core.c
-rw-r--r--drivers/pci/pcie/aer/aerdrv.h5
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c22
-rw-r--r--include/linux/pci.h3
3 files changed, 25 insertions, 5 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
index 94a7598eb26..22f840f4dda 100644
--- a/drivers/pci/pcie/aer/aerdrv.h
+++ b/drivers/pci/pcie/aer/aerdrv.h
@@ -87,6 +87,9 @@ struct aer_broadcast_data {
87static inline pci_ers_result_t merge_result(enum pci_ers_result orig, 87static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
88 enum pci_ers_result new) 88 enum pci_ers_result new)
89{ 89{
90 if (new == PCI_ERS_RESULT_NO_AER_DRIVER)
91 return PCI_ERS_RESULT_NO_AER_DRIVER;
92
90 if (new == PCI_ERS_RESULT_NONE) 93 if (new == PCI_ERS_RESULT_NONE)
91 return orig; 94 return orig;
92 95
@@ -97,7 +100,7 @@ static inline pci_ers_result_t merge_result(enum pci_ers_result orig,
97 break; 100 break;
98 case PCI_ERS_RESULT_DISCONNECT: 101 case PCI_ERS_RESULT_DISCONNECT:
99 if (new == PCI_ERS_RESULT_NEED_RESET) 102 if (new == PCI_ERS_RESULT_NEED_RESET)
100 orig = new; 103 orig = PCI_ERS_RESULT_NEED_RESET;
101 break; 104 break;
102 default: 105 default:
103 break; 106 break;
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index af4e31cd3a3..421bbc5fee3 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -232,13 +232,27 @@ static int report_error_detected(struct pci_dev *dev, void *data)
232 dev->driver ? 232 dev->driver ?
233 "no AER-aware driver" : "no driver"); 233 "no AER-aware driver" : "no driver");
234 } 234 }
235 goto out; 235
236 /*
237 * If there's any device in the subtree that does not
238 * have an error_detected callback, returning
239 * PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of
240 * the subsequent mmio_enabled/slot_reset/resume
241 * callbacks of "any" device in the subtree. All the
242 * devices in the subtree are left in the error state
243 * without recovery.
244 */
245
246 if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE))
247 vote = PCI_ERS_RESULT_NO_AER_DRIVER;
248 else
249 vote = PCI_ERS_RESULT_NONE;
250 } else {
251 err_handler = dev->driver->err_handler;
252 vote = err_handler->error_detected(dev, result_data->state);
236 } 253 }
237 254
238 err_handler = dev->driver->err_handler;
239 vote = err_handler->error_detected(dev, result_data->state);
240 result_data->result = merge_result(result_data->result, vote); 255 result_data->result = merge_result(result_data->result, vote);
241out:
242 device_unlock(&dev->dev); 256 device_unlock(&dev->dev);
243 return 0; 257 return 0;
244} 258}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5b37d643b6b..a98a5f9ac1d 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -538,6 +538,9 @@ enum pci_ers_result {
538 538
539 /* Device driver is fully recovered and operational */ 539 /* Device driver is fully recovered and operational */
540 PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5, 540 PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,
541
542 /* No AER capabilities registered for the driver */
543 PCI_ERS_RESULT_NO_AER_DRIVER = (__force pci_ers_result_t) 6,
541}; 544};
542 545
543/* PCI bus error event callbacks */ 546/* PCI bus error event callbacks */