aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2014-01-12 01:13:45 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-01-14 21:58:29 -0500
commitf26c7a035b7f2f1a7505ce42e4ba946b12f7df91 (patch)
tree2903a8f9ca7ea27b2e1ebd18468f1b809ef3af6a /arch/powerpc/kernel
parent9be3becc2f99f4f2b1b697a616b1aa9e7889d68f (diff)
powerpc/eeh: Hotplug improvement
When EEH error comes to one specific PCI device before its driver is loaded, we will apply hotplug to recover the error. During the plug time, the PCI device will be probed and its driver is loaded. Then we wrongly calls to the error handlers if the driver supports EEH explicitly. The patch intends to fix by introducing flag EEH_DEV_NO_HANDLER and set it before we remove the PCI device. In turn, we can avoid wrongly calls the error handlers of the PCI device after its driver loaded. Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/eeh.c15
-rw-r--r--arch/powerpc/kernel/eeh_driver.c10
2 files changed, 22 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index f4b7a227f183..148db72a8c43 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -921,6 +921,13 @@ void eeh_add_device_late(struct pci_dev *dev)
921 eeh_sysfs_remove_device(edev->pdev); 921 eeh_sysfs_remove_device(edev->pdev);
922 edev->mode &= ~EEH_DEV_SYSFS; 922 edev->mode &= ~EEH_DEV_SYSFS;
923 923
924 /*
925 * We definitely should have the PCI device removed
926 * though it wasn't correctly. So we needn't call
927 * into error handler afterwards.
928 */
929 edev->mode |= EEH_DEV_NO_HANDLER;
930
924 edev->pdev = NULL; 931 edev->pdev = NULL;
925 dev->dev.archdata.edev = NULL; 932 dev->dev.archdata.edev = NULL;
926 } 933 }
@@ -1023,6 +1030,14 @@ void eeh_remove_device(struct pci_dev *dev)
1023 else 1030 else
1024 edev->mode |= EEH_DEV_DISCONNECTED; 1031 edev->mode |= EEH_DEV_DISCONNECTED;
1025 1032
1033 /*
1034 * We're removing from the PCI subsystem, that means
1035 * the PCI device driver can't support EEH or not
1036 * well. So we rely on hotplug completely to do recovery
1037 * for the specific PCI device.
1038 */
1039 edev->mode |= EEH_DEV_NO_HANDLER;
1040
1026 eeh_addr_cache_rmv_dev(dev); 1041 eeh_addr_cache_rmv_dev(dev);
1027 eeh_sysfs_remove_device(dev); 1042 eeh_sysfs_remove_device(dev);
1028 edev->mode &= ~EEH_DEV_SYSFS; 1043 edev->mode &= ~EEH_DEV_SYSFS;
diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
index 4ef59c33777f..7db39203a073 100644
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -217,7 +217,8 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata)
217 if (!driver) return NULL; 217 if (!driver) return NULL;
218 218
219 if (!driver->err_handler || 219 if (!driver->err_handler ||
220 !driver->err_handler->mmio_enabled) { 220 !driver->err_handler->mmio_enabled ||
221 (edev->mode & EEH_DEV_NO_HANDLER)) {
221 eeh_pcid_put(dev); 222 eeh_pcid_put(dev);
222 return NULL; 223 return NULL;
223 } 224 }
@@ -258,7 +259,8 @@ static void *eeh_report_reset(void *data, void *userdata)
258 eeh_enable_irq(dev); 259 eeh_enable_irq(dev);
259 260
260 if (!driver->err_handler || 261 if (!driver->err_handler ||
261 !driver->err_handler->slot_reset) { 262 !driver->err_handler->slot_reset ||
263 (edev->mode & EEH_DEV_NO_HANDLER)) {
262 eeh_pcid_put(dev); 264 eeh_pcid_put(dev);
263 return NULL; 265 return NULL;
264 } 266 }
@@ -297,7 +299,9 @@ static void *eeh_report_resume(void *data, void *userdata)
297 eeh_enable_irq(dev); 299 eeh_enable_irq(dev);
298 300
299 if (!driver->err_handler || 301 if (!driver->err_handler ||
300 !driver->err_handler->resume) { 302 !driver->err_handler->resume ||
303 (edev->mode & EEH_DEV_NO_HANDLER)) {
304 edev->mode &= ~EEH_DEV_NO_HANDLER;
301 eeh_pcid_put(dev); 305 eeh_pcid_put(dev);
302 return NULL; 306 return NULL;
303 } 307 }