aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/eeh_event.c
diff options
context:
space:
mode:
authorLinas Vepstas <linas@linas.org>2005-11-03 19:52:49 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-09 23:28:32 -0500
commit77bd741561016134d1761d6101c4f0361025062f (patch)
tree5e3389b6941add4b24a2be64c730b7a9087c1f2f /arch/powerpc/platforms/pseries/eeh_event.c
parent977127174a7dff52d17faeeb4c4949a54221881f (diff)
[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_event.c')
-rw-r--r--arch/powerpc/platforms/pseries/eeh_event.c39
1 files changed, 12 insertions, 27 deletions
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c
index 92497333c2b..9a9961f2748 100644
--- a/arch/powerpc/platforms/pseries/eeh_event.c
+++ b/arch/powerpc/platforms/pseries/eeh_event.c
@@ -21,6 +21,7 @@
21#include <linux/list.h> 21#include <linux/list.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <asm/eeh_event.h> 23#include <asm/eeh_event.h>
24#include <asm/ppc-pci.h>
24 25
25/** Overview: 26/** Overview:
26 * EEH error states may be detected within exception handlers; 27 * EEH error states may be detected within exception handlers;
@@ -37,31 +38,6 @@ static void eeh_thread_launcher(void *);
37DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL); 38DECLARE_WORK(eeh_event_wq, eeh_thread_launcher, NULL);
38 39
39/** 40/**
40 * eeh_panic - call panic() for an eeh event that cannot be handled.
41 * The philosophy of this routine is that it is better to panic and
42 * halt the OS than it is to risk possible data corruption by
43 * oblivious device drivers that don't know better.
44 *
45 * @dev pci device that had an eeh event
46 * @reset_state current reset state of the device slot
47 */
48static void eeh_panic(struct pci_dev *dev, int reset_state)
49{
50 /*
51 * Since the panic_on_oops sysctl is used to halt the system
52 * in light of potential corruption, we can use it here.
53 */
54 if (panic_on_oops) {
55 panic("EEH: MMIO failure (%d) on device:%s\n", reset_state,
56 pci_name(dev));
57 }
58 else {
59 printk(KERN_INFO "EEH: Ignored MMIO failure (%d) on device:%s\n",
60 reset_state, pci_name(dev));
61 }
62}
63
64/**
65 * eeh_event_handler - dispatch EEH events. The detection of a frozen 41 * eeh_event_handler - dispatch EEH events. The detection of a frozen
66 * slot can occur inside an interrupt, where it can be hard to do 42 * slot can occur inside an interrupt, where it can be hard to do
67 * anything about it. The goal of this routine is to pull these 43 * anything about it. The goal of this routine is to pull these
@@ -82,10 +58,16 @@ static int eeh_event_handler(void * dummy)
82 58
83 spin_lock_irqsave(&eeh_eventlist_lock, flags); 59 spin_lock_irqsave(&eeh_eventlist_lock, flags);
84 event = NULL; 60 event = NULL;
61
62 /* Unqueue the event, get ready to process. */
85 if (!list_empty(&eeh_eventlist)) { 63 if (!list_empty(&eeh_eventlist)) {
86 event = list_entry(eeh_eventlist.next, struct eeh_event, list); 64 event = list_entry(eeh_eventlist.next, struct eeh_event, list);
87 list_del(&event->list); 65 list_del(&event->list);
88 } 66 }
67
68 if (event)
69 eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
70
89 spin_unlock_irqrestore(&eeh_eventlist_lock, flags); 71 spin_unlock_irqrestore(&eeh_eventlist_lock, flags);
90 if (event == NULL) 72 if (event == NULL)
91 break; 73 break;
@@ -93,8 +75,11 @@ static int eeh_event_handler(void * dummy)
93 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", 75 printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n",
94 pci_name(event->dev)); 76 pci_name(event->dev));
95 77
96 eeh_panic (event->dev, event->state); 78 handle_eeh_events(event);
79
80 eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
97 81
82 pci_dev_put(event->dev);
98 kfree(event); 83 kfree(event);
99 } 84 }
100 85
@@ -122,7 +107,7 @@ static void eeh_thread_launcher(void *dummy)
122 */ 107 */
123int eeh_send_failure_event (struct device_node *dn, 108int eeh_send_failure_event (struct device_node *dn,
124 struct pci_dev *dev, 109 struct pci_dev *dev,
125 int state, 110 enum pci_channel_state state,
126 int time_unavail) 111 int time_unavail)
127{ 112{
128 unsigned long flags; 113 unsigned long flags;