diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 3302586655c4..c2917ffad2c2 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c | |||
@@ -65,6 +65,7 @@ | |||
65 | * mechanism for it at that time. | 65 | * mechanism for it at that time. |
66 | */ | 66 | */ |
67 | #include <asm/kdebug.h> | 67 | #include <asm/kdebug.h> |
68 | #include <asm/nmi.h> | ||
68 | #define HAVE_DIE_NMI | 69 | #define HAVE_DIE_NMI |
69 | #endif | 70 | #endif |
70 | 71 | ||
@@ -1077,17 +1078,8 @@ static void ipmi_unregister_watchdog(int ipmi_intf) | |||
1077 | 1078 | ||
1078 | #ifdef HAVE_DIE_NMI | 1079 | #ifdef HAVE_DIE_NMI |
1079 | static int | 1080 | static int |
1080 | ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) | 1081 | ipmi_nmi(unsigned int val, struct pt_regs *regs) |
1081 | { | 1082 | { |
1082 | struct die_args *args = data; | ||
1083 | |||
1084 | if (val != DIE_NMIUNKNOWN) | ||
1085 | return NOTIFY_OK; | ||
1086 | |||
1087 | /* Hack, if it's a memory or I/O error, ignore it. */ | ||
1088 | if (args->err & 0xc0) | ||
1089 | return NOTIFY_OK; | ||
1090 | |||
1091 | /* | 1083 | /* |
1092 | * If we get here, it's an NMI that's not a memory or I/O | 1084 | * If we get here, it's an NMI that's not a memory or I/O |
1093 | * error. We can't truly tell if it's from IPMI or not | 1085 | * error. We can't truly tell if it's from IPMI or not |
@@ -1097,15 +1089,15 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) | |||
1097 | 1089 | ||
1098 | if (testing_nmi) { | 1090 | if (testing_nmi) { |
1099 | testing_nmi = 2; | 1091 | testing_nmi = 2; |
1100 | return NOTIFY_STOP; | 1092 | return NMI_HANDLED; |
1101 | } | 1093 | } |
1102 | 1094 | ||
1103 | /* If we are not expecting a timeout, ignore it. */ | 1095 | /* If we are not expecting a timeout, ignore it. */ |
1104 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) | 1096 | if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) |
1105 | return NOTIFY_OK; | 1097 | return NMI_DONE; |
1106 | 1098 | ||
1107 | if (preaction_val != WDOG_PRETIMEOUT_NMI) | 1099 | if (preaction_val != WDOG_PRETIMEOUT_NMI) |
1108 | return NOTIFY_OK; | 1100 | return NMI_DONE; |
1109 | 1101 | ||
1110 | /* | 1102 | /* |
1111 | * If no one else handled the NMI, we assume it was the IPMI | 1103 | * If no one else handled the NMI, we assume it was the IPMI |
@@ -1120,12 +1112,8 @@ ipmi_nmi(struct notifier_block *self, unsigned long val, void *data) | |||
1120 | panic(PFX "pre-timeout"); | 1112 | panic(PFX "pre-timeout"); |
1121 | } | 1113 | } |
1122 | 1114 | ||
1123 | return NOTIFY_STOP; | 1115 | return NMI_HANDLED; |
1124 | } | 1116 | } |
1125 | |||
1126 | static struct notifier_block ipmi_nmi_handler = { | ||
1127 | .notifier_call = ipmi_nmi | ||
1128 | }; | ||
1129 | #endif | 1117 | #endif |
1130 | 1118 | ||
1131 | static int wdog_reboot_handler(struct notifier_block *this, | 1119 | static int wdog_reboot_handler(struct notifier_block *this, |
@@ -1290,7 +1278,8 @@ static void check_parms(void) | |||
1290 | } | 1278 | } |
1291 | } | 1279 | } |
1292 | if (do_nmi && !nmi_handler_registered) { | 1280 | if (do_nmi && !nmi_handler_registered) { |
1293 | rv = register_die_notifier(&ipmi_nmi_handler); | 1281 | rv = register_nmi_handler(NMI_UNKNOWN, ipmi_nmi, 0, |
1282 | "ipmi"); | ||
1294 | if (rv) { | 1283 | if (rv) { |
1295 | printk(KERN_WARNING PFX | 1284 | printk(KERN_WARNING PFX |
1296 | "Can't register nmi handler\n"); | 1285 | "Can't register nmi handler\n"); |
@@ -1298,7 +1287,7 @@ static void check_parms(void) | |||
1298 | } else | 1287 | } else |
1299 | nmi_handler_registered = 1; | 1288 | nmi_handler_registered = 1; |
1300 | } else if (!do_nmi && nmi_handler_registered) { | 1289 | } else if (!do_nmi && nmi_handler_registered) { |
1301 | unregister_die_notifier(&ipmi_nmi_handler); | 1290 | unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); |
1302 | nmi_handler_registered = 0; | 1291 | nmi_handler_registered = 0; |
1303 | } | 1292 | } |
1304 | #endif | 1293 | #endif |
@@ -1336,7 +1325,7 @@ static int __init ipmi_wdog_init(void) | |||
1336 | if (rv) { | 1325 | if (rv) { |
1337 | #ifdef HAVE_DIE_NMI | 1326 | #ifdef HAVE_DIE_NMI |
1338 | if (nmi_handler_registered) | 1327 | if (nmi_handler_registered) |
1339 | unregister_die_notifier(&ipmi_nmi_handler); | 1328 | unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); |
1340 | #endif | 1329 | #endif |
1341 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1330 | atomic_notifier_chain_unregister(&panic_notifier_list, |
1342 | &wdog_panic_notifier); | 1331 | &wdog_panic_notifier); |
@@ -1357,7 +1346,7 @@ static void __exit ipmi_wdog_exit(void) | |||
1357 | 1346 | ||
1358 | #ifdef HAVE_DIE_NMI | 1347 | #ifdef HAVE_DIE_NMI |
1359 | if (nmi_handler_registered) | 1348 | if (nmi_handler_registered) |
1360 | unregister_die_notifier(&ipmi_nmi_handler); | 1349 | unregister_nmi_handler(NMI_UNKNOWN, "ipmi"); |
1361 | #endif | 1350 | #endif |
1362 | 1351 | ||
1363 | atomic_notifier_chain_unregister(&panic_notifier_list, | 1352 | atomic_notifier_chain_unregister(&panic_notifier_list, |