@@ -54,6 +54,7 @@ static inline bool ers_result_indicates_abort(pci_ers_result_t ers_res)
54
54
case PCI_ERS_RESULT_CAN_RECOVER :
55
55
case PCI_ERS_RESULT_RECOVERED :
56
56
case PCI_ERS_RESULT_NEED_RESET :
57
+ case PCI_ERS_RESULT_NONE :
57
58
return false;
58
59
default :
59
60
return true;
@@ -78,10 +79,6 @@ static bool is_driver_supported(struct pci_driver *driver)
78
79
return false;
79
80
if (!driver -> err_handler -> error_detected )
80
81
return false;
81
- if (!driver -> err_handler -> slot_reset )
82
- return false;
83
- if (!driver -> err_handler -> resume )
84
- return false;
85
82
return true;
86
83
}
87
84
@@ -106,6 +103,10 @@ static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
106
103
struct zpci_dev * zdev = to_zpci (pdev );
107
104
int rc ;
108
105
106
+ /* The underlying device may have been disabled by the event */
107
+ if (!zdev_enabled (zdev ))
108
+ return PCI_ERS_RESULT_NEED_RESET ;
109
+
109
110
pr_info ("%s: Unblocking device access for examination\n" , pci_name (pdev ));
110
111
rc = zpci_reset_load_store_blocked (zdev );
111
112
if (rc ) {
@@ -114,16 +115,18 @@ static pci_ers_result_t zpci_event_do_error_state_clear(struct pci_dev *pdev,
114
115
return PCI_ERS_RESULT_NEED_RESET ;
115
116
}
116
117
117
- if (driver -> err_handler -> mmio_enabled ) {
118
+ if (driver -> err_handler -> mmio_enabled )
118
119
ers_res = driver -> err_handler -> mmio_enabled (pdev );
119
- if (ers_result_indicates_abort (ers_res )) {
120
- pr_info ("%s: Automatic recovery failed after MMIO re-enable\n" ,
121
- pci_name (pdev ));
122
- return ers_res ;
123
- } else if (ers_res == PCI_ERS_RESULT_NEED_RESET ) {
124
- pr_debug ("%s: Driver needs reset to recover\n" , pci_name (pdev ));
125
- return ers_res ;
126
- }
120
+ else
121
+ ers_res = PCI_ERS_RESULT_NONE ;
122
+
123
+ if (ers_result_indicates_abort (ers_res )) {
124
+ pr_info ("%s: Automatic recovery failed after MMIO re-enable\n" ,
125
+ pci_name (pdev ));
126
+ return ers_res ;
127
+ } else if (ers_res == PCI_ERS_RESULT_NEED_RESET ) {
128
+ pr_debug ("%s: Driver needs reset to recover\n" , pci_name (pdev ));
129
+ return ers_res ;
127
130
}
128
131
129
132
pr_debug ("%s: Unblocking DMA\n" , pci_name (pdev ));
@@ -150,7 +153,12 @@ static pci_ers_result_t zpci_event_do_reset(struct pci_dev *pdev,
150
153
return ers_res ;
151
154
}
152
155
pdev -> error_state = pci_channel_io_normal ;
153
- ers_res = driver -> err_handler -> slot_reset (pdev );
156
+
157
+ if (driver -> err_handler -> slot_reset )
158
+ ers_res = driver -> err_handler -> slot_reset (pdev );
159
+ else
160
+ ers_res = PCI_ERS_RESULT_NONE ;
161
+
154
162
if (ers_result_indicates_abort (ers_res )) {
155
163
pr_info ("%s: Automatic recovery failed after slot reset\n" , pci_name (pdev ));
156
164
return ers_res ;
@@ -214,7 +222,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
214
222
goto out_unlock ;
215
223
}
216
224
217
- if (ers_res == PCI_ERS_RESULT_CAN_RECOVER ) {
225
+ if (ers_res != PCI_ERS_RESULT_NEED_RESET ) {
218
226
ers_res = zpci_event_do_error_state_clear (pdev , driver );
219
227
if (ers_result_indicates_abort (ers_res )) {
220
228
status_str = "failed (abort on MMIO enable)" ;
@@ -225,6 +233,16 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
225
233
if (ers_res == PCI_ERS_RESULT_NEED_RESET )
226
234
ers_res = zpci_event_do_reset (pdev , driver );
227
235
236
+ /*
237
+ * ers_res can be PCI_ERS_RESULT_NONE either because the driver
238
+ * decided to return it, indicating that it abstains from voting
239
+ * on how to recover, or because it didn't implement the callback.
240
+ * Both cases assume, that if there is nothing else causing a
241
+ * disconnect, we recovered successfully.
242
+ */
243
+ if (ers_res == PCI_ERS_RESULT_NONE )
244
+ ers_res = PCI_ERS_RESULT_RECOVERED ;
245
+
228
246
if (ers_res != PCI_ERS_RESULT_RECOVERED ) {
229
247
pr_err ("%s: Automatic recovery failed; operator intervention is required\n" ,
230
248
pci_name (pdev ));
@@ -273,6 +291,8 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
273
291
struct zpci_dev * zdev = get_zdev_by_fid (ccdf -> fid );
274
292
struct pci_dev * pdev = NULL ;
275
293
pci_ers_result_t ers_res ;
294
+ u32 fh = 0 ;
295
+ int rc ;
276
296
277
297
zpci_dbg (3 , "err fid:%x, fh:%x, pec:%x\n" ,
278
298
ccdf -> fid , ccdf -> fh , ccdf -> pec );
@@ -281,6 +301,15 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf)
281
301
282
302
if (zdev ) {
283
303
mutex_lock (& zdev -> state_lock );
304
+ rc = clp_refresh_fh (zdev -> fid , & fh );
305
+ if (rc )
306
+ goto no_pdev ;
307
+ if (!fh || ccdf -> fh != fh ) {
308
+ /* Ignore events with stale handles */
309
+ zpci_dbg (3 , "err fid:%x, fh:%x (stale %x)\n" ,
310
+ ccdf -> fid , fh , ccdf -> fh );
311
+ goto no_pdev ;
312
+ }
284
313
zpci_update_fh (zdev , ccdf -> fh );
285
314
if (zdev -> zbus -> bus )
286
315
pdev = pci_get_slot (zdev -> zbus -> bus , zdev -> devfn );
0 commit comments