|
@@ -584,6 +584,8 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
|
|
|
{
|
|
{
|
|
|
struct eeh_pe *pe = (struct eeh_pe *)data;
|
|
struct eeh_pe *pe = (struct eeh_pe *)data;
|
|
|
int state = *((int *)flag);
|
|
int state = *((int *)flag);
|
|
|
|
|
+ struct eeh_dev *edev, *tmp;
|
|
|
|
|
+ struct pci_dev *pdev;
|
|
|
|
|
|
|
|
/* Keep the state of permanently removed PE intact */
|
|
/* Keep the state of permanently removed PE intact */
|
|
|
if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) &&
|
|
if ((pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) &&
|
|
@@ -592,9 +594,22 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
|
|
|
|
|
|
|
|
pe->state &= ~state;
|
|
pe->state &= ~state;
|
|
|
|
|
|
|
|
- /* Clear check count since last isolation */
|
|
|
|
|
- if (state & EEH_PE_ISOLATED)
|
|
|
|
|
- pe->check_count = 0;
|
|
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Special treatment on clearing isolated state. Clear
|
|
|
|
|
+ * check count since last isolation and put all affected
|
|
|
|
|
+ * devices to normal state.
|
|
|
|
|
+ */
|
|
|
|
|
+ if (!(state & EEH_PE_ISOLATED))
|
|
|
|
|
+ return NULL;
|
|
|
|
|
+
|
|
|
|
|
+ pe->check_count = 0;
|
|
|
|
|
+ eeh_pe_for_each_dev(pe, edev, tmp) {
|
|
|
|
|
+ pdev = eeh_dev_to_pci_dev(edev);
|
|
|
|
|
+ if (!pdev)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
|
|
+ pdev->error_state = pci_channel_io_normal;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
return NULL;
|
|
return NULL;
|
|
|
}
|
|
}
|