summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorSam Bobroff <sbobroff@linux.ibm.com>2018-05-25 13:11:37 +1000
committerMichael Ellerman <mpe@ellerman.id.au>2018-06-03 20:43:40 +1000
commit47cc8c1cc2f2d9889e84d59cbbe8cb1cc6e24ed1 (patch)
treee86d1ff666b092319032b640e9c99f5fba65a215 /arch/powerpc/kernel
parente2b810d51b2b36d41e3e5522e12cc752e0d865ec (diff)
downloadop-kernel-dev-47cc8c1cc2f2d9889e84d59cbbe8cb1cc6e24ed1.zip
op-kernel-dev-47cc8c1cc2f2d9889e84d59cbbe8cb1cc6e24ed1.tar.gz
powerpc/eeh: Introduce eeh_set_channel_state()
To ease future refactoring, extract setting of the channel state from the report functions out into their own functions. This increases the amount of code that is identical across all of the report functions. Signed-off-by: Sam Bobroff <sbobroff@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/eeh_driver.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 127f2bb..52b5acd 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -205,6 +205,17 @@ static void *eeh_dev_save_state(struct eeh_dev *edev, void *userdata)
return NULL;
}
+static void eeh_set_channel_state(struct eeh_pe *root, enum pci_channel_state s)
+{
+ struct eeh_pe *pe;
+ struct eeh_dev *edev, *tmp;
+
+ eeh_for_each_pe(root, pe)
+ eeh_pe_for_each_dev(pe, edev, tmp)
+ if (eeh_edev_actionable(edev))
+ edev->pdev->error_state = s;
+}
+
/**
* eeh_report_error - Report pci error to each device driver
* @data: eeh device
@@ -224,7 +235,6 @@ static void *eeh_report_error(struct eeh_dev *edev, void *userdata)
return NULL;
device_lock(&dev->dev);
- dev->error_state = pci_channel_io_frozen;
driver = eeh_pcid_get(dev);
if (!driver) goto out_no_dev;
@@ -307,7 +317,6 @@ static void *eeh_report_reset(struct eeh_dev *edev, void *userdata)
return NULL;
device_lock(&dev->dev);
- dev->error_state = pci_channel_io_normal;
driver = eeh_pcid_get(dev);
if (!driver) goto out_no_dev;
@@ -377,7 +386,6 @@ static void *eeh_report_resume(struct eeh_dev *edev, void *userdata)
return NULL;
device_lock(&dev->dev);
- dev->error_state = pci_channel_io_normal;
driver = eeh_pcid_get(dev);
if (!driver) goto out_no_dev;
@@ -801,6 +809,7 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
* hotplug for this case.
*/
pr_info("EEH: Notify device drivers to shutdown\n");
+ eeh_set_channel_state(pe, pci_channel_io_frozen);
eeh_pe_dev_traverse(pe, eeh_report_error, &result);
if ((pe->type & EEH_PE_PHB) &&
result != PCI_ERS_RESULT_NONE &&
@@ -891,6 +900,7 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
pr_info("EEH: Notify device drivers "
"the completion of reset\n");
result = PCI_ERS_RESULT_NONE;
+ eeh_set_channel_state(pe, pci_channel_io_normal);
eeh_pe_dev_traverse(pe, eeh_report_reset, &result);
}
@@ -912,6 +922,7 @@ void eeh_handle_normal_event(struct eeh_pe *pe)
/* Tell all device drivers that they can resume operations */
pr_info("EEH: Notify device driver to resume\n");
+ eeh_set_channel_state(pe, pci_channel_io_normal);
eeh_pe_dev_traverse(pe, eeh_report_resume, NULL);
pr_info("EEH: Recovery successful.\n");
@@ -930,6 +941,7 @@ hard_fail:
eeh_slot_error_detail(pe, EEH_LOG_PERM);
/* Notify all devices that they're about to go down. */
+ eeh_set_channel_state(pe, pci_channel_io_perm_failure);
eeh_pe_dev_traverse(pe, eeh_report_failure, NULL);
/* Mark the PE to be removed permanently */
@@ -1039,6 +1051,7 @@ void eeh_handle_special_event(void)
/* Notify all devices to be down */
eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ eeh_set_channel_state(pe, pci_channel_io_perm_failure);
eeh_pe_dev_traverse(pe,
eeh_report_failure, NULL);
bus = eeh_pe_bus_get(phb_pe);
OpenPOWER on IntegriCloud