@@ -116,6 +116,7 @@ static unsigned int reload; /* the computed soft_margin */
116
116
static int nowayout = WATCHDOG_NOWAYOUT ;
117
117
static char expect_release ;
118
118
static unsigned long hpwdt_is_open ;
119
+ static unsigned int allow_kdump ;
119
120
120
121
static void __iomem * pci_mem_addr ; /* the PCI-memory address */
121
122
static unsigned long __iomem * hpwdt_timer_reg ;
@@ -221,19 +222,19 @@ static int __devinit cru_detect(unsigned long map_entry,
221
222
222
223
if (cmn_regs .u1 .ral != 0 ) {
223
224
printk (KERN_WARNING
224
- "hpwdt: Call succeeded but with an error: 0x%x\n" ,
225
- cmn_regs .u1 .ral );
225
+ "hpwdt: Call succeeded but with an error: 0x%x\n" ,
226
+ cmn_regs .u1 .ral );
226
227
} else {
227
228
physical_bios_base = cmn_regs .u2 .rebx ;
228
229
physical_bios_offset = cmn_regs .u4 .redx ;
229
230
cru_length = cmn_regs .u3 .recx ;
230
231
cru_physical_address =
231
- physical_bios_base + physical_bios_offset ;
232
+ physical_bios_base + physical_bios_offset ;
232
233
233
234
/* If the values look OK, then map it in. */
234
235
if ((physical_bios_base + physical_bios_offset )) {
235
236
cru_rom_addr =
236
- ioremap (cru_physical_address , cru_length );
237
+ ioremap (cru_physical_address , cru_length );
237
238
if (cru_rom_addr )
238
239
retval = 0 ;
239
240
}
@@ -356,7 +357,6 @@ asm(".text \n\t"
356
357
"call *%r12 \n\t"
357
358
"pushfq \n\t"
358
359
"popq %r12 \n\t"
359
- "popfq \n\t"
360
360
"movl %eax, (%r9) \n\t"
361
361
"movl %ebx, 4(%r9) \n\t"
362
362
"movl %ecx, 8(%r9) \n\t"
@@ -390,10 +390,10 @@ static void __devinit dmi_find_cru(const struct dmi_header *dm)
390
390
smbios_cru64_ptr = (struct smbios_cru64_info * ) dm ;
391
391
if (smbios_cru64_ptr -> signature == CRU_BIOS_SIGNATURE_VALUE ) {
392
392
cru_physical_address =
393
- smbios_cru64_ptr -> physical_address +
394
- smbios_cru64_ptr -> double_offset ;
393
+ smbios_cru64_ptr -> physical_address +
394
+ smbios_cru64_ptr -> double_offset ;
395
395
cru_rom_addr = ioremap (cru_physical_address ,
396
- smbios_cru64_ptr -> double_length );
396
+ smbios_cru64_ptr -> double_length );
397
397
}
398
398
}
399
399
}
@@ -405,41 +405,13 @@ static int __devinit detect_cru_service(void)
405
405
dmi_walk (dmi_find_cru );
406
406
407
407
/* if cru_rom_addr has been set then we found a CRU service */
408
- return ((cru_rom_addr != NULL ) ? 0 : - ENODEV );
408
+ return ((cru_rom_addr != NULL ) ? 0 : - ENODEV );
409
409
}
410
410
411
411
/* ------------------------------------------------------------------------- */
412
412
413
413
#endif
414
414
415
- /*
416
- * NMI Handler
417
- */
418
- static int hpwdt_pretimeout (struct notifier_block * nb , unsigned long ulReason ,
419
- void * data )
420
- {
421
- unsigned long rom_pl ;
422
- static int die_nmi_called ;
423
-
424
- if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI )
425
- return NOTIFY_OK ;
426
-
427
- spin_lock_irqsave (& rom_lock , rom_pl );
428
- if (!die_nmi_called )
429
- asminline_call (& cmn_regs , cru_rom_addr );
430
- die_nmi_called = 1 ;
431
- spin_unlock_irqrestore (& rom_lock , rom_pl );
432
- if (cmn_regs .u1 .ral == 0 ) {
433
- printk (KERN_WARNING "hpwdt: An NMI occurred, "
434
- "but unable to determine source.\n" );
435
- } else {
436
- panic ("An NMI occurred, please see the Integrated "
437
- "Management Log for details.\n" );
438
- }
439
-
440
- return NOTIFY_STOP ;
441
- }
442
-
443
415
/*
444
416
* Watchdog operations
445
417
*/
@@ -483,6 +455,36 @@ static int hpwdt_change_timer(int new_margin)
483
455
return 0 ;
484
456
}
485
457
458
+ /*
459
+ * NMI Handler
460
+ */
461
+ static int hpwdt_pretimeout (struct notifier_block * nb , unsigned long ulReason ,
462
+ void * data )
463
+ {
464
+ unsigned long rom_pl ;
465
+ static int die_nmi_called ;
466
+
467
+ if (ulReason != DIE_NMI && ulReason != DIE_NMI_IPI )
468
+ return NOTIFY_OK ;
469
+
470
+ spin_lock_irqsave (& rom_lock , rom_pl );
471
+ if (!die_nmi_called )
472
+ asminline_call (& cmn_regs , cru_rom_addr );
473
+ die_nmi_called = 1 ;
474
+ spin_unlock_irqrestore (& rom_lock , rom_pl );
475
+ if (cmn_regs .u1 .ral == 0 ) {
476
+ printk (KERN_WARNING "hpwdt: An NMI occurred, "
477
+ "but unable to determine source.\n" );
478
+ } else {
479
+ if (allow_kdump )
480
+ hpwdt_stop ();
481
+ panic ("An NMI occurred, please see the Integrated "
482
+ "Management Log for details.\n" );
483
+ }
484
+
485
+ return NOTIFY_STOP ;
486
+ }
487
+
486
488
/*
487
489
* /dev/watchdog handling
488
490
*/
@@ -625,17 +627,18 @@ static struct notifier_block die_notifier = {
625
627
*/
626
628
627
629
static int __devinit hpwdt_init_one (struct pci_dev * dev ,
628
- const struct pci_device_id * ent )
630
+ const struct pci_device_id * ent )
629
631
{
630
632
int retval ;
631
633
632
634
/*
633
635
* First let's find out if we are on an iLO2 server. We will
634
636
* not run on a legacy ASM box.
637
+ * So we only support the G5 ProLiant servers and higher.
635
638
*/
636
639
if (dev -> subsystem_vendor != PCI_VENDOR_ID_HP ) {
637
640
dev_warn (& dev -> dev ,
638
- "This server does not have an iLO2 ASIC.\n" );
641
+ "This server does not have an iLO2 ASIC.\n" );
639
642
return - ENODEV ;
640
643
}
641
644
@@ -669,7 +672,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
669
672
retval = detect_cru_service ();
670
673
if (retval < 0 ) {
671
674
dev_warn (& dev -> dev ,
672
- "Unable to detect the %d Bit CRU Service.\n" ,
675
+ "Unable to detect the %d Bit CRU Service.\n" ,
673
676
HPWDT_ARCH );
674
677
goto error_get_cru ;
675
678
}
@@ -684,7 +687,7 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
684
687
retval = register_die_notifier (& die_notifier );
685
688
if (retval != 0 ) {
686
689
dev_warn (& dev -> dev ,
687
- "Unable to register a die notifier (err=%d).\n" ,
690
+ "Unable to register a die notifier (err=%d).\n" ,
688
691
retval );
689
692
goto error_die_notifier ;
690
693
}
@@ -699,8 +702,9 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
699
702
700
703
printk (KERN_INFO
701
704
"hp Watchdog Timer Driver: 1.00"
702
- ", timer margin: %d seconds( nowayout=%d).\n" ,
703
- soft_margin , nowayout );
705
+ ", timer margin: %d seconds (nowayout=%d)"
706
+ ", allow kernel dump: %s (default = 0/OFF).\n" ,
707
+ soft_margin , nowayout , (allow_kdump == 0 ) ? "OFF" : "ON" );
704
708
705
709
return 0 ;
706
710
@@ -755,6 +759,9 @@ MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
755
759
module_param (soft_margin , int , 0 );
756
760
MODULE_PARM_DESC (soft_margin , "Watchdog timeout in seconds" );
757
761
762
+ module_param (allow_kdump , int , 0 );
763
+ MODULE_PARM_DESC (allow_kdump , "Start a kernel dump after NMI occurs" );
764
+
758
765
module_param (nowayout , int , 0 );
759
766
MODULE_PARM_DESC (nowayout , "Watchdog cannot be stopped once started (default="
760
767
__MODULE_STRING (WATCHDOG_NOWAYOUT ) ")" );
0 commit comments