[WATCHDOG] hpwdt: Add NMI sourcing

Add NMI sourcing functionality (Can only be active if nmi_watchdog is
inactive).

Signed-off-by: Thomas Mingarelli <[email protected]>
Signed-off-by: Wim Van Sebroeck <[email protected]>
This commit is contained in:
Thomas Mingarelli 2009-06-04 19:50:45 +00:00 • committed by Wim Van Sebroeck
commit 47bece87b1
2 changed files with 128 additions and 15 deletions

View file

@ -19,6 +19,7 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/nmi.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/mm.h>
@ -47,7 +48,7 @@
#define PCI_BIOS32_PARAGRAPH_LEN 16
#define PCI_ROM_BASE1 0x000F0000
#define ROM_SIZE 0x10000
#define HPWDT_VERSION "1.01"
#define HPWDT_VERSION "1.1.1"
struct bios32_service_dir {
u32 signature;
@ -119,6 +120,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
static char expect_release;
static unsigned long hpwdt_is_open;
static unsigned int allow_kdump;
static int hpwdt_nmi_sourcing;
static void __iomem *pci_mem_addr; /* the PCI-memory address */
static unsigned long __iomem *hpwdt_timer_reg;
@ -468,21 +470,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI)
return NOTIFY_OK;
spin_lock_irqsave(&rom_lock, rom_pl);
if (!die_nmi_called)
asminline_call(&cmn_regs, cru_rom_addr);
die_nmi_called = 1;
spin_unlock_irqrestore(&rom_lock, rom_pl);
if (cmn_regs.u1.ral == 0) {
printk(KERN_WARNING "hpwdt: An NMI occurred, "
"but unable to determine source.\n");
} else {
if (allow_kdump)
hpwdt_stop();
panic("An NMI occurred, please see the Integrated "
"Management Log for details.\n");
if (hpwdt_nmi_sourcing) {
spin_lock_irqsave(&rom_lock, rom_pl);
if (!die_nmi_called)
asminline_call(&cmn_regs, cru_rom_addr);
die_nmi_called = 1;
spin_unlock_irqrestore(&rom_lock, rom_pl);
if (cmn_regs.u1.ral == 0) {
printk(KERN_WARNING "hpwdt: An NMI occurred, "
"but unable to determine source.\n");
} else {
if (allow_kdump)
hpwdt_stop();
panic("An NMI occurred, please see the Integrated "
"Management Log for details.\n");
}
}
return NOTIFY_OK;
}
@ -627,11 +630,37 @@ static struct notifier_block die_notifier = {
* Init & Exit
*/
#ifdef ARCH_HAS_NMI_WATCHDOG
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
{
/*
* If nmi_watchdog is turned off then we can turn on
* our nmi sourcing capability.
*/
if (!nmi_watchdog_active())
hpwdt_nmi_sourcing = 1;
else
dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
"functionality you must reboot with nmi_watchdog=0.\n");
}
#else
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
{
dev_warn(&dev->dev, "NMI sourcing is disabled. "
"Your kernel does not support a NMI Watchdog.\n");
}
#endif
static int __devinit hpwdt_init_one(struct pci_dev *dev,
const struct pci_device_id *ent)
{
int retval;
/*
* Check if we can do NMI sourcing or not
*/
hpwdt_check_nmi_sourcing(dev);
/*
* First let's find out if we are on an iLO2 server. We will
* not run on a legacy ASM box.