diff options
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv.h | 5 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 21 |
2 files changed, 22 insertions, 4 deletions
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 94a7598eb262..22f840f4dda1 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -87,6 +87,9 @@ struct aer_broadcast_data { | |||
87 | static inline pci_ers_result_t merge_result(enum pci_ers_result orig, | 87 | static 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 06bad96af415..eb2f19a9c3cd 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -231,11 +231,26 @@ static int report_error_detected(struct pci_dev *dev, void *data) | |||
231 | dev->driver ? | 231 | dev->driver ? |
232 | "no AER-aware driver" : "no driver"); | 232 | "no AER-aware driver" : "no driver"); |
233 | } | 233 | } |
234 | return 0; | 234 | |
235 | /* | ||
236 | * If there's any device in the subtree that does not | ||
237 | * have an error_detected callback, returning | ||
238 | * PCI_ERS_RESULT_NO_AER_DRIVER prevents calling of | ||
239 | * the subsequent mmio_enabled/slot_reset/resume | ||
240 | * callbacks of "any" device in the subtree. All the | ||
241 | * devices in the subtree are left in the error state | ||
242 | * without recovery. | ||
243 | */ | ||
244 | |||
245 | if (!(dev->hdr_type & PCI_HEADER_TYPE_BRIDGE)) | ||
246 | vote = PCI_ERS_RESULT_NO_AER_DRIVER; | ||
247 | else | ||
248 | vote = PCI_ERS_RESULT_NONE; | ||
249 | } else { | ||
250 | err_handler = dev->driver->err_handler; | ||
251 | vote = err_handler->error_detected(dev, result_data->state); | ||
235 | } | 252 | } |
236 | 253 | ||
237 | err_handler = dev->driver->err_handler; | ||
238 | vote = err_handler->error_detected(dev, result_data->state); | ||
239 | result_data->result = merge_result(result_data->result, vote); | 254 | result_data->result = merge_result(result_data->result, vote); |
240 | return 0; | 255 | return 0; |
241 | } | 256 | } |