Loading drivers/watchdog/hpwdt.c +77 −27 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ #include <asm/cacheflush.h> #endif /* CONFIG_HPWDT_NMI_DECODING */ #define HPWDT_VERSION "1.2.0" #define HPWDT_VERSION "1.3.0" #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) Loading Loading @@ -87,6 +87,19 @@ struct smbios_cru64_info { }; #define SMBIOS_CRU64_INFORMATION 212 /* type 219 */ struct smbios_proliant_info { u8 type; u8 byte_length; u16 handle; u32 power_features; u32 omega_features; u32 reserved; u32 misc_features; }; #define SMBIOS_ICRU_INFORMATION 219 struct cmn_registers { union { struct { Loading Loading @@ -132,6 +145,7 @@ struct cmn_registers { static unsigned int hpwdt_nmi_decoding; static unsigned int allow_kdump; static unsigned int priority; /* hpwdt at end of die_notify list */ static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; static struct cmn_registers cmn_regs; Loading Loading @@ -476,19 +490,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, goto out; spin_lock_irqsave(&rom_lock, rom_pl); if (!die_nmi_called) if (!die_nmi_called && !is_icru) asminline_call(&cmn_regs, cru_rom_addr); die_nmi_called = 1; spin_unlock_irqrestore(&rom_lock, rom_pl); if (!is_icru) { 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"); } out: return NOTIFY_OK; } Loading Loading @@ -659,10 +676,42 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) } #endif /* CONFIG_X86_LOCAL_APIC */ /* * dmi_find_icru * * Routine Description: * This function checks whether or not we are on an iCRU-based server. * This check is independent of architecture and needs to be made for * any ProLiant system. */ static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy) { struct smbios_proliant_info *smbios_proliant_ptr; if (dm->type == SMBIOS_ICRU_INFORMATION) { smbios_proliant_ptr = (struct smbios_proliant_info *) dm; if (smbios_proliant_ptr->misc_features & 0x01) is_icru = 1; } } static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) { int retval; /* * On typical CRU-based systems we need to map that service in * the BIOS. For 32 bit Operating Systems we need to go through * the 32 Bit BIOS Service Directory. For 64 bit Operating * Systems we get that service through SMBIOS. * * On systems that support the new iCRU service all we need to * do is call dmi_walk to get the supported flag value and skip * the old cru detect code. */ dmi_walk(dmi_find_icru, NULL); if (!is_icru) { /* * We need to map the ROM to get the CRU service. * For 32 bit Operating Systems we need to go through the 32 Bit Loading @@ -683,6 +732,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) */ cmn_regs.u1.rah = 0x0D; cmn_regs.u1.ral = 0x02; } /* * If the priority is set to 1, then we will be put first on the Loading Loading
drivers/watchdog/hpwdt.c +77 −27 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ #include <asm/cacheflush.h> #endif /* CONFIG_HPWDT_NMI_DECODING */ #define HPWDT_VERSION "1.2.0" #define HPWDT_VERSION "1.3.0" #define SECS_TO_TICKS(secs) ((secs) * 1000 / 128) #define TICKS_TO_SECS(ticks) ((ticks) * 128 / 1000) #define HPWDT_MAX_TIMER TICKS_TO_SECS(65535) Loading Loading @@ -87,6 +87,19 @@ struct smbios_cru64_info { }; #define SMBIOS_CRU64_INFORMATION 212 /* type 219 */ struct smbios_proliant_info { u8 type; u8 byte_length; u16 handle; u32 power_features; u32 omega_features; u32 reserved; u32 misc_features; }; #define SMBIOS_ICRU_INFORMATION 219 struct cmn_registers { union { struct { Loading Loading @@ -132,6 +145,7 @@ struct cmn_registers { static unsigned int hpwdt_nmi_decoding; static unsigned int allow_kdump; static unsigned int priority; /* hpwdt at end of die_notify list */ static unsigned int is_icru; static DEFINE_SPINLOCK(rom_lock); static void *cru_rom_addr; static struct cmn_registers cmn_regs; Loading Loading @@ -476,19 +490,22 @@ static int hpwdt_pretimeout(struct notifier_block *nb, unsigned long ulReason, goto out; spin_lock_irqsave(&rom_lock, rom_pl); if (!die_nmi_called) if (!die_nmi_called && !is_icru) asminline_call(&cmn_regs, cru_rom_addr); die_nmi_called = 1; spin_unlock_irqrestore(&rom_lock, rom_pl); if (!is_icru) { 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"); } out: return NOTIFY_OK; } Loading Loading @@ -659,10 +676,42 @@ static void __devinit hpwdt_check_nmi_decoding(struct pci_dev *dev) } #endif /* CONFIG_X86_LOCAL_APIC */ /* * dmi_find_icru * * Routine Description: * This function checks whether or not we are on an iCRU-based server. * This check is independent of architecture and needs to be made for * any ProLiant system. */ static void __devinit dmi_find_icru(const struct dmi_header *dm, void *dummy) { struct smbios_proliant_info *smbios_proliant_ptr; if (dm->type == SMBIOS_ICRU_INFORMATION) { smbios_proliant_ptr = (struct smbios_proliant_info *) dm; if (smbios_proliant_ptr->misc_features & 0x01) is_icru = 1; } } static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) { int retval; /* * On typical CRU-based systems we need to map that service in * the BIOS. For 32 bit Operating Systems we need to go through * the 32 Bit BIOS Service Directory. For 64 bit Operating * Systems we get that service through SMBIOS. * * On systems that support the new iCRU service all we need to * do is call dmi_walk to get the supported flag value and skip * the old cru detect code. */ dmi_walk(dmi_find_icru, NULL); if (!is_icru) { /* * We need to map the ROM to get the CRU service. * For 32 bit Operating Systems we need to go through the 32 Bit Loading @@ -683,6 +732,7 @@ static int __devinit hpwdt_init_nmi_decoding(struct pci_dev *dev) */ cmn_regs.u1.rah = 0x0D; cmn_regs.u1.ral = 0x02; } /* * If the priority is set to 1, then we will be put first on the Loading