summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh.c
diff options
context:
space:
mode:
authorLinas Vepstas <linas@linas.org>2005-11-04 01:52:49 +0100
committerPaul Mackerras <paulus@samba.org>2006-01-10 05:28:32 +0100
commit77bd741561016134d1761d6101c4f0361025062f (patch)
tree5e3389b6941add4b24a2be64c730b7a9087c1f2f /arch/powerpc/platforms/pseries/eeh.c
parentMerge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6 (diff)
downloadlinux-77bd741561016134d1761d6101c4f0361025062f.tar.xz
linux-77bd741561016134d1761d6101c4f0361025062f.zip
[PATCH] powerpc: PCI Error Recovery: PPC64 core recovery routines
Various PCI bus errors can be signaled by newer PCI controllers. The core error recovery routines are architecture dependent. This patch adds a recovery infrastructure for the PPC64 pSeries systems. Signed-off-by: Linas Vepstas <linas@austin.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> (cherry picked from e8ca11b460c4c9c7fa6b529be221529ebd770e38 commit)
Diffstat (limited to 'arch/powerpc/platforms/pseries/eeh.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 7fbfd16d72b7..d6560c45637b 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -485,6 +485,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
if (PCI_DN(dn)) {
PCI_DN(dn)->eeh_mode |= mode_flag;
+ /* Mark the pci device driver too */
+ struct pci_dev *dev = PCI_DN(dn)->pcidev;
+ if (dev && dev->driver)
+ dev->error_state = pci_channel_io_frozen;
+
if (dn->child)
__eeh_mark_slot (dn->child, mode_flag);
}
@@ -544,6 +549,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
int rets[3];
unsigned long flags;
struct pci_dn *pdn;
+ enum pci_channel_state state;
int rc = 0;
__get_cpu_var(total_mmio_ffs)++;
@@ -648,8 +654,13 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
eeh_mark_slot (dn, EEH_MODE_ISOLATED);
spin_unlock_irqrestore(&confirm_error_lock, flags);
- eeh_send_failure_event (dn, dev, rets[0], rets[2]);
-
+ state = pci_channel_io_normal;
+ if ((rets[0] == 2) || (rets[0] == 4))
+ state = pci_channel_io_frozen;
+ if (rets[0] == 5)
+ state = pci_channel_io_perm_failure;
+ eeh_send_failure_event (dn, dev, state, rets[2]);
+
/* Most EEH events are due to device driver bugs. Having
* a stack trace will help the device-driver authors figure
* out what happened. So print that out. */
@@ -953,8 +964,10 @@ static void *early_enable_eeh(struct device_node *dn, void *data)
* But there are a few cases like display devices that make sense.
*/
enable = 1; /* i.e. we will do checking */
+#if 0
if ((*class_code >> 16) == PCI_BASE_CLASS_DISPLAY)
enable = 0;
+#endif
if (!enable)
pdn->eeh_mode |= EEH_MODE_NOCHECK;