mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 12:16:20 +00:00
[WATCHDOG] hpwdt.c kdebug support
add kdebug support for the hpwdt.c driver. Signed-off-by: Thomas Mingarelli <Thomas.Mingarelli@hp.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
This commit is contained in:
parent
03ec58568a
commit
ab4ba3cdeb
1 changed files with 50 additions and 43 deletions
|
@ -116,6 +116,7 @@ static unsigned int reload; /* the computed soft_margin */
|
|||
static int nowayout = WATCHDOG_NOWAYOUT;
|
||||
static char expect_release;
|
||||
static unsigned long hpwdt_is_open;
|
||||
static unsigned int allow_kdump;
|
||||
|
||||
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
||||
static unsigned long __iomem *hpwdt_timer_reg;
|
||||
|
@ -221,19 +222,19 @@ static int __devinit cru_detect(unsigned long map_entry,
|
|||
|
||||
if (cmn_regs.u1.ral != 0) {
|
||||
printk(KERN_WARNING
|
||||
"hpwdt: Call succeeded but with an error: 0x%x\n",
|
||||
cmn_regs.u1.ral);
|
||||
"hpwdt: Call succeeded but with an error: 0x%x\n",
|
||||
cmn_regs.u1.ral);
|
||||
} else {
|
||||
physical_bios_base = cmn_regs.u2.rebx;
|
||||
physical_bios_offset = cmn_regs.u4.redx;
|
||||
cru_length = cmn_regs.u3.recx;
|
||||
cru_physical_address =
|
||||
physical_bios_base + physical_bios_offset;
|
||||
physical_bios_base + physical_bios_offset;
|
||||
|
||||
/* If the values look OK, then map it in. */
|
||||
if ((physical_bios_base + physical_bios_offset)) {
|
||||
cru_rom_addr =
|
||||
ioremap(cru_physical_address, cru_length);
|
||||
ioremap(cru_physical_address, cru_length);
|
||||
if (cru_rom_addr)
|
||||
retval = 0;
|
||||
}
|
||||
|
@ -356,7 +357,6 @@ asm(".text \n\t"
|
|||
"call *%r12 \n\t"
|
||||
"pushfq \n\t"
|
||||
"popq %r12 \n\t"
|
||||
"popfq \n\t"
|
||||
"movl %eax, (%r9) \n\t"
|
||||
"movl %ebx, 4(%r9) \n\t"
|
||||
"movl %ecx, 8(%r9) \n\t"
|
||||
|
@ -390,10 +390,10 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm)
|
|||
smbios_cru64_ptr = (struct smbios_cru64_info *) dm;
|
||||
if (smbios_cru64_ptr->signature == CRU_BIOS_SIGNATURE_VALUE) {
|
||||
cru_physical_address =
|
||||
smbios_cru64_ptr->physical_address +
|
||||
smbios_cru64_ptr->double_offset;
|
||||
smbios_cru64_ptr->physical_address +
|
||||
smbios_cru64_ptr->double_offset;
|
||||
cru_rom_addr = ioremap(cru_physical_address,
|
||||
smbios_cru64_ptr->double_length);
|
||||
smbios_cru64_ptr->double_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -405,41 +405,13 @@ static int __devinit detect_cru_service(void)
|
|||
dmi_walk(dmi_find_cru);
|
||||
|
||||
/* if cru_rom_addr has been set then we found a CRU service */
|
||||
return ((cru_rom_addr != NULL) ? 0: -ENODEV);
|
||||
return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* NMI Handler
|
||||
*/
|
||||
static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
|
||||
void *data)
|
||||
{
|
||||
unsigned long rom_pl;
|
||||
static int die_nmi_called;
|
||||
|
||||
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 {
|
||||
panic("An NMI occurred, please see the Integrated "
|
||||
"Management Log for details.\n");
|
||||
}
|
||||
|
||||
return NOTIFY_STOP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Watchdog operations
|
||||
*/
|
||||
|
@ -483,6 +455,36 @@ static int hpwdt_change_timer(int new_margin)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* NMI Handler
|
||||
*/
|
||||
static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason,
|
||||
void *data)
|
||||
{
|
||||
unsigned long rom_pl;
|
||||
static int die_nmi_called;
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
return NOTIFY_STOP;
|
||||
}
|
||||
|
||||
/*
|
||||
* /dev/watchdog handling
|
||||
*/
|
||||
|
@ -625,17 +627,18 @@ static struct notifier_block die_notifier = {
|
|||
*/
|
||||
|
||||
static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
||||
const struct pci_device_id *ent)
|
||||
const struct pci_device_id *ent)
|
||||
{
|
||||
int retval;
|
||||
|
||||
/*
|
||||
* First let's find out if we are on an iLO2 server. We will
|
||||
* not run on a legacy ASM box.
|
||||
* So we only support the G5 ProLiant servers and higher.
|
||||
*/
|
||||
if (dev->subsystem_vendor != PCI_VENDOR_ID_HP) {
|
||||
dev_warn(&dev->dev,
|
||||
"This server does not have an iLO2 ASIC.\n");
|
||||
"This server does not have an iLO2 ASIC.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -669,7 +672,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
|||
retval = detect_cru_service();
|
||||
if (retval < 0) {
|
||||
dev_warn(&dev->dev,
|
||||
"Unable to detect the %d Bit CRU Service.\n",
|
||||
"Unable to detect the %d Bit CRU Service.\n",
|
||||
HPWDT_ARCH);
|
||||
goto error_get_cru;
|
||||
}
|
||||
|
@ -684,7 +687,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
|||
retval = register_die_notifier(&die_notifier);
|
||||
if (retval != 0) {
|
||||
dev_warn(&dev->dev,
|
||||
"Unable to register a die notifier (err=%d).\n",
|
||||
"Unable to register a die notifier (err=%d).\n",
|
||||
retval);
|
||||
goto error_die_notifier;
|
||||
}
|
||||
|
@ -699,8 +702,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
|||
|
||||
printk(KERN_INFO
|
||||
"hp Watchdog Timer Driver: 1.00"
|
||||
", timer margin: %d seconds( nowayout=%d).\n",
|
||||
soft_margin, nowayout);
|
||||
", timer margin: %d seconds (nowayout=%d)"
|
||||
", allow kernel dump: %s (default = 0/OFF).\n",
|
||||
soft_margin, nowayout, (allow_kdump == 0) ? "OFF" : "ON");
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -755,6 +759,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
|
|||
module_param(soft_margin, int, 0);
|
||||
MODULE_PARM_DESC(soft_margin, "Watchdog timeout in seconds");
|
||||
|
||||
module_param(allow_kdump, int, 0);
|
||||
MODULE_PARM_DESC(allow_kdump, "Start a kernel dump after NMI occurs");
|
||||
|
||||
module_param(nowayout, int, 0);
|
||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||
|
|
Loading…
Reference in a new issue