1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34#include <linux/config.h>
35#include <linux/module.h>
36#include <linux/ipmi.h>
37#include <linux/ipmi_smi.h>
38#include <linux/watchdog.h>
39#include <linux/miscdevice.h>
40#include <linux/init.h>
41#include <linux/rwsem.h>
42#include <linux/errno.h>
43#include <asm/uaccess.h>
44#include <linux/notifier.h>
45#include <linux/nmi.h>
46#include <linux/reboot.h>
47#include <linux/wait.h>
48#include <linux/poll.h>
49#ifdef CONFIG_X86_LOCAL_APIC
50#include <asm/apic.h>
51#endif
52
53
54
55
56
57
58#define WDOG_DONT_LOG (1 << 7)
59#define WDOG_DONT_STOP_ON_SET (1 << 6)
60#define WDOG_SET_TIMER_USE(byte, use) \
61 byte = ((byte) & 0xf8) | ((use) & 0x7)
62#define WDOG_GET_TIMER_USE(byte) ((byte) & 0x7)
63#define WDOG_TIMER_USE_BIOS_FRB2 1
64#define WDOG_TIMER_USE_BIOS_POST 2
65#define WDOG_TIMER_USE_OS_LOAD 3
66#define WDOG_TIMER_USE_SMS_OS 4
67#define WDOG_TIMER_USE_OEM 5
68
69
70#define WDOG_SET_PRETIMEOUT_ACT(byte, use) \
71 byte = ((byte) & 0x8f) | (((use) & 0x7) << 4)
72#define WDOG_GET_PRETIMEOUT_ACT(byte) (((byte) >> 4) & 0x7)
73#define WDOG_PRETIMEOUT_NONE 0
74#define WDOG_PRETIMEOUT_SMI 1
75#define WDOG_PRETIMEOUT_NMI 2
76#define WDOG_PRETIMEOUT_MSG_INT 3
77
78
79#define WDOG_PREOP_NONE 0
80#define WDOG_PREOP_PANIC 1
81#define WDOG_PREOP_GIVE_DATA 2
82
83
84
85
86#define WDOG_SET_TIMEOUT_ACT(byte, use) \
87 byte = ((byte) & 0xf8) | ((use) & 0x7)
88#define WDOG_GET_TIMEOUT_ACT(byte) ((byte) & 0x7)
89#define WDOG_TIMEOUT_NONE 0
90#define WDOG_TIMEOUT_RESET 1
91#define WDOG_TIMEOUT_POWER_DOWN 2
92#define WDOG_TIMEOUT_POWER_CYCLE 3
93
94
95
96
97
98#define WDOG_EXPIRE_CLEAR_BIOS_FRB2 (1 << 1)
99#define WDOG_EXPIRE_CLEAR_BIOS_POST (1 << 2)
100#define WDOG_EXPIRE_CLEAR_OS_LOAD (1 << 3)
101#define WDOG_EXPIRE_CLEAR_SMS_OS (1 << 4)
102#define WDOG_EXPIRE_CLEAR_OEM (1 << 5)
103
104
105
106
107
108
109#define WDOG_SET_TIMEOUT(byte1, byte2, val) \
110 (byte1) = (((val) * 10) & 0xff), (byte2) = (((val) * 10) >> 8)
111#define WDOG_GET_TIMEOUT(byte1, byte2) \
112 (((byte1) | ((byte2) << 8)) / 10)
113
114#define IPMI_WDOG_RESET_TIMER 0x22
115#define IPMI_WDOG_SET_TIMER 0x24
116#define IPMI_WDOG_GET_TIMER 0x25
117
118
119#ifndef WDIOC_GETTIMEOUT
120#define WDIOC_GETTIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 20, int)
121#endif
122#ifndef WDIOC_SET_PRETIMEOUT
123#define WDIOC_SET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 21, int)
124#endif
125#ifndef WDIOC_GET_PRETIMEOUT
126#define WDIOC_GET_PRETIMEOUT _IOW(WATCHDOG_IOCTL_BASE, 22, int)
127#endif
128
129static ipmi_user_t watchdog_user = NULL;
130
131
132static int timeout = 10;
133
134
135static int pretimeout = 0;
136
137
138static unsigned char action_val = WDOG_TIMEOUT_RESET;
139
140static char *action = "reset";
141
142static unsigned char preaction_val = WDOG_PRETIMEOUT_NONE;
143
144static char *preaction = "pre_none";
145
146static unsigned char preop_val = WDOG_PREOP_NONE;
147
148static char *preop = "preop_none";
149static spinlock_t ipmi_read_lock = SPIN_LOCK_UNLOCKED;
150static char data_to_read = 0;
151static DECLARE_WAIT_QUEUE_HEAD(read_q);
152static struct fasync_struct *fasync_q = NULL;
153static char pretimeout_since_last_heartbeat = 0;
154
155MODULE_PARM(timeout, "i");
156MODULE_PARM(pretimeout, "i");
157MODULE_PARM(action, "s");
158MODULE_PARM(preaction, "s");
159MODULE_PARM(preop, "s");
160
161
162static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
163
164
165static int ipmi_ignore_heartbeat = 0;
166
167
168static int ipmi_wdog_open = 0;
169
170
171
172static int start_now = 0;
173
174
175
176
177
178static int ipmi_start_timer_on_heartbeat = 0;
179
180
181static unsigned char ipmi_version_major;
182static unsigned char ipmi_version_minor;
183
184
185static int ipmi_heartbeat(void);
186static void panic_halt_ipmi_heartbeat(void);
187
188
189
190
191
192
193static atomic_t set_timeout_tofree = ATOMIC_INIT(0);
194static DECLARE_MUTEX(set_timeout_lock);
195static void set_timeout_free_smi(struct ipmi_smi_msg *msg)
196{
197 if (atomic_dec_and_test(&set_timeout_tofree))
198 up(&set_timeout_lock);
199}
200static void set_timeout_free_recv(struct ipmi_recv_msg *msg)
201{
202 if (atomic_dec_and_test(&set_timeout_tofree))
203 up(&set_timeout_lock);
204}
205static struct ipmi_smi_msg set_timeout_smi_msg =
206{
207 .done = set_timeout_free_smi
208};
209static struct ipmi_recv_msg set_timeout_recv_msg =
210{
211 .done = set_timeout_free_recv
212};
213
214static int i_ipmi_set_timeout(struct ipmi_smi_msg *smi_msg,
215 struct ipmi_recv_msg *recv_msg,
216 int *send_heartbeat_now)
217{
218 struct ipmi_msg msg;
219 unsigned char data[6];
220 int rv;
221 struct ipmi_system_interface_addr addr;
222 int hbnow = 0;
223
224
225 data[0] = 0;
226 WDOG_SET_TIMER_USE(data[0], WDOG_TIMER_USE_SMS_OS);
227
228 if ((ipmi_version_major > 1)
229 || ((ipmi_version_major == 1) && (ipmi_version_minor >= 5)))
230 {
231
232 data[0] |= WDOG_DONT_STOP_ON_SET;
233 } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
234
235
236 hbnow = 1;
237 }
238
239 data[1] = 0;
240 WDOG_SET_TIMEOUT_ACT(data[1], ipmi_watchdog_state);
241 if (pretimeout > 0) {
242 WDOG_SET_PRETIMEOUT_ACT(data[1], preaction_val);
243 data[2] = pretimeout;
244 } else {
245 WDOG_SET_PRETIMEOUT_ACT(data[1], WDOG_PRETIMEOUT_NONE);
246 data[2] = 0;
247 }
248 data[3] = 0;
249 WDOG_SET_TIMEOUT(data[4], data[5], timeout);
250
251 addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
252 addr.channel = IPMI_BMC_CHANNEL;
253 addr.lun = 0;
254
255 msg.netfn = 0x06;
256 msg.cmd = IPMI_WDOG_SET_TIMER;
257 msg.data = data;
258 msg.data_len = sizeof(data);
259 rv = ipmi_request_supply_msgs(watchdog_user,
260 (struct ipmi_addr *) &addr,
261 0,
262 &msg,
263 smi_msg,
264 recv_msg,
265 1);
266 if (rv) {
267 printk(KERN_WARNING "IPMI Watchdog, set timeout error: %d\n",
268 rv);
269 }
270
271 if (send_heartbeat_now)
272 *send_heartbeat_now = hbnow;
273
274 return rv;
275}
276
277
278#define IPMI_SET_TIMEOUT_NO_HB 0
279#define IPMI_SET_TIMEOUT_HB_IF_NECESSARY 1
280#define IPMI_SET_TIMEOUT_FORCE_HB 2
281
282static int ipmi_set_timeout(int do_heartbeat)
283{
284 int send_heartbeat_now;
285 int rv;
286
287
288
289 down(&set_timeout_lock);
290
291 atomic_set(&set_timeout_tofree, 2);
292
293 rv = i_ipmi_set_timeout(&set_timeout_smi_msg,
294 &set_timeout_recv_msg,
295 &send_heartbeat_now);
296 if (rv) {
297 up(&set_timeout_lock);
298 } else {
299 if ((do_heartbeat == IPMI_SET_TIMEOUT_FORCE_HB)
300 || ((send_heartbeat_now)
301 && (do_heartbeat == IPMI_SET_TIMEOUT_HB_IF_NECESSARY)))
302 {
303 rv = ipmi_heartbeat();
304 }
305 }
306
307 return rv;
308}
309
310static void dummy_smi_free(struct ipmi_smi_msg *msg)
311{
312}
313static void dummy_recv_free(struct ipmi_recv_msg *msg)
314{
315}
316static struct ipmi_smi_msg panic_halt_smi_msg =
317{
318 .done = dummy_smi_free
319};
320static struct ipmi_recv_msg panic_halt_recv_msg =
321{
322 .done = dummy_recv_free
323};
324
325
326
327
328
329static void panic_halt_ipmi_set_timeout(void)
330{
331 int send_heartbeat_now;
332 int rv;
333
334 rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
335 &panic_halt_recv_msg,
336 &send_heartbeat_now);
337 if (!rv) {
338 if (send_heartbeat_now)
339 panic_halt_ipmi_heartbeat();
340 }
341}
342
343
344
345
346void ipmi_delayed_shutdown(long delay, int power_off)
347{
348 ipmi_ignore_heartbeat = 1;
349 if (power_off)
350 ipmi_watchdog_state = WDOG_TIMEOUT_POWER_DOWN;
351 else
352 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
353 timeout = delay;
354 ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
355}
356
357
358
359
360
361static atomic_t heartbeat_tofree = ATOMIC_INIT(0);
362static DECLARE_MUTEX(heartbeat_lock);
363static DECLARE_MUTEX_LOCKED(heartbeat_wait_lock);
364static void heartbeat_free_smi(struct ipmi_smi_msg *msg)
365{
366 if (atomic_dec_and_test(&heartbeat_tofree))
367 up(&heartbeat_wait_lock);
368}
369static void heartbeat_free_recv(struct ipmi_recv_msg *msg)
370{
371 if (atomic_dec_and_test(&heartbeat_tofree))
372 up(&heartbeat_wait_lock);
373}
374static struct ipmi_smi_msg heartbeat_smi_msg =
375{
376 .done = heartbeat_free_smi
377};
378static struct ipmi_recv_msg heartbeat_recv_msg =
379{
380 .done = heartbeat_free_recv
381};
382
383static struct ipmi_smi_msg panic_halt_heartbeat_smi_msg =
384{
385 .done = dummy_smi_free
386};
387static struct ipmi_recv_msg panic_halt_heartbeat_recv_msg =
388{
389 .done = dummy_recv_free
390};
391
392static int ipmi_heartbeat(void)
393{
394 struct ipmi_msg msg;
395 int rv;
396 struct ipmi_system_interface_addr addr;
397
398 if (ipmi_ignore_heartbeat) {
399 return 0;
400 }
401
402 if (ipmi_start_timer_on_heartbeat) {
403 ipmi_start_timer_on_heartbeat = 0;
404 ipmi_watchdog_state = action_val;
405 return ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
406 } else if (pretimeout_since_last_heartbeat) {
407
408
409
410
411 pretimeout_since_last_heartbeat = 0;
412 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
413 }
414
415 down(&heartbeat_lock);
416
417 atomic_set(&heartbeat_tofree, 2);
418
419
420
421 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE) {
422 up(&heartbeat_lock);
423 return 0;
424 }
425
426 addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
427 addr.channel = IPMI_BMC_CHANNEL;
428 addr.lun = 0;
429
430 msg.netfn = 0x06;
431 msg.cmd = IPMI_WDOG_RESET_TIMER;
432 msg.data = NULL;
433 msg.data_len = 0;
434 rv = ipmi_request_supply_msgs(watchdog_user,
435 (struct ipmi_addr *) &addr,
436 0,
437 &msg,
438 &heartbeat_smi_msg,
439 &heartbeat_recv_msg,
440 1);
441 if (rv) {
442 up(&heartbeat_lock);
443 printk(KERN_WARNING "IPMI Watchdog, heartbeat failure: %d\n",
444 rv);
445 return rv;
446 }
447
448
449 down(&heartbeat_wait_lock);
450
451 if (heartbeat_recv_msg.msg.data[0] != 0) {
452
453
454
455 rv = -EINVAL;
456 }
457
458 up(&heartbeat_lock);
459
460 return rv;
461}
462
463static void panic_halt_ipmi_heartbeat(void)
464{
465 struct ipmi_msg msg;
466 struct ipmi_system_interface_addr addr;
467
468
469
470
471 if (ipmi_watchdog_state == WDOG_TIMEOUT_NONE)
472 return;
473
474 addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
475 addr.channel = IPMI_BMC_CHANNEL;
476 addr.lun = 0;
477
478 msg.netfn = 0x06;
479 msg.cmd = IPMI_WDOG_RESET_TIMER;
480 msg.data = NULL;
481 msg.data_len = 0;
482 ipmi_request_supply_msgs(watchdog_user,
483 (struct ipmi_addr *) &addr,
484 0,
485 &msg,
486 &panic_halt_heartbeat_smi_msg,
487 &panic_halt_heartbeat_recv_msg,
488 1);
489}
490
491static struct watchdog_info ident=
492{
493 0,
494 1,
495 "IPMI"
496};
497
498static int ipmi_ioctl(struct inode *inode, struct file *file,
499 unsigned int cmd, unsigned long arg)
500{
501 int i;
502 int val;
503
504 switch(cmd) {
505 case WDIOC_GETSUPPORT:
506 i = copy_to_user((void*)arg, &ident, sizeof(ident));
507 return i ? -EFAULT : 0;
508
509 case WDIOC_SETTIMEOUT:
510 i = copy_from_user(&val, (void *) arg, sizeof(int));
511 if (i)
512 return -EFAULT;
513 timeout = val;
514 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
515
516 case WDIOC_GETTIMEOUT:
517 i = copy_to_user((void *) arg,
518 &timeout,
519 sizeof(timeout));
520 if (i)
521 return -EFAULT;
522 return 0;
523
524 case WDIOC_SET_PRETIMEOUT:
525 i = copy_from_user(&val, (void *) arg, sizeof(int));
526 if (i)
527 return -EFAULT;
528 pretimeout = val;
529 return ipmi_set_timeout(IPMI_SET_TIMEOUT_HB_IF_NECESSARY);
530
531 case WDIOC_GET_PRETIMEOUT:
532 i = copy_to_user((void *) arg,
533 &pretimeout,
534 sizeof(pretimeout));
535 if (i)
536 return -EFAULT;
537 return 0;
538
539 case WDIOC_KEEPALIVE:
540 return ipmi_heartbeat();
541
542 case WDIOC_SETOPTIONS:
543 i = copy_from_user(&val, (void *) arg, sizeof(int));
544 if (i)
545 return -EFAULT;
546 if (val & WDIOS_DISABLECARD)
547 {
548 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
549 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
550 ipmi_start_timer_on_heartbeat = 0;
551 }
552
553 if (val & WDIOS_ENABLECARD)
554 {
555 ipmi_watchdog_state = action_val;
556 ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
557 }
558 return 0;
559
560 case WDIOC_GETSTATUS:
561 val = 0;
562 return copy_to_user((void *) arg, &val, sizeof(val));
563
564 default:
565 return -ENOIOCTLCMD;
566 }
567}
568
569static ssize_t ipmi_write(struct file *file,
570 const char *buf,
571 size_t len,
572 loff_t *ppos)
573{
574 int rv;
575
576
577 if (ppos != &file->f_pos)
578 return -ESPIPE;
579
580 if (len) {
581 rv = ipmi_heartbeat();
582 if (rv)
583 return rv;
584 return 1;
585 }
586 return 0;
587}
588
589static ssize_t ipmi_read(struct file *file,
590 char *buf,
591 size_t count,
592 loff_t *ppos)
593{
594 int rv = 0;
595 wait_queue_t wait;
596
597
598 if (ppos != &file->f_pos)
599 return -ESPIPE;
600
601 if (count <= 0)
602 return 0;
603
604
605
606 spin_lock(&ipmi_read_lock);
607 if (!data_to_read) {
608 if (file->f_flags & O_NONBLOCK) {
609 rv = -EAGAIN;
610 goto out;
611 }
612
613 init_waitqueue_entry(&wait, current);
614 add_wait_queue(&read_q, &wait);
615 while (!data_to_read) {
616 set_current_state(TASK_INTERRUPTIBLE);
617 spin_unlock(&ipmi_read_lock);
618 schedule();
619 spin_lock(&ipmi_read_lock);
620 }
621 remove_wait_queue(&read_q, &wait);
622
623 if (signal_pending(current)) {
624 rv = -ERESTARTSYS;
625 goto out;
626 }
627 }
628 data_to_read = 0;
629
630 out:
631 spin_unlock(&ipmi_read_lock);
632
633 if (rv == 0) {
634 if (copy_to_user(buf, &data_to_read, 1))
635 rv = -EFAULT;
636 else
637 rv = 1;
638 }
639
640 return rv;
641}
642
643static int ipmi_open(struct inode *ino, struct file *filep)
644{
645 switch (minor(ino->i_rdev))
646 {
647 case WATCHDOG_MINOR:
648 if (ipmi_wdog_open)
649 return -EBUSY;
650
651 ipmi_wdog_open = 1;
652
653
654
655 ipmi_start_timer_on_heartbeat = 1;
656 return(0);
657
658 default:
659 return (-ENODEV);
660 }
661}
662
663static unsigned int ipmi_poll(struct file *file, poll_table *wait)
664{
665 unsigned int mask = 0;
666
667 poll_wait(file, &read_q, wait);
668
669 spin_lock(&ipmi_read_lock);
670 if (data_to_read)
671 mask |= (POLLIN | POLLRDNORM);
672 spin_unlock(&ipmi_read_lock);
673
674 return mask;
675}
676
677static int ipmi_fasync(int fd, struct file *file, int on)
678{
679 int result;
680
681 result = fasync_helper(fd, file, on, &fasync_q);
682
683 return (result);
684}
685
686static int ipmi_close(struct inode *ino, struct file *filep)
687{
688 if (minor(ino->i_rdev)==WATCHDOG_MINOR)
689 {
690#ifndef CONFIG_WATCHDOG_NOWAYOUT
691 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
692 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
693#endif
694 ipmi_wdog_open = 0;
695 }
696
697 ipmi_fasync (-1, filep, 0);
698
699 return 0;
700}
701
702static struct file_operations ipmi_wdog_fops = {
703 .owner = THIS_MODULE,
704 .read = ipmi_read,
705 .poll = ipmi_poll,
706 .write = ipmi_write,
707 .ioctl = ipmi_ioctl,
708 .open = ipmi_open,
709 .release = ipmi_close,
710 .fasync = ipmi_fasync,
711};
712
713static struct miscdevice ipmi_wdog_miscdev = {
714 WATCHDOG_MINOR,
715 "watchdog",
716 &ipmi_wdog_fops
717};
718
719static DECLARE_RWSEM(register_sem);
720
721static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
722 void *handler_data)
723{
724 if (msg->msg.data[0] != 0) {
725 printk(KERN_ERR "IPMI Watchdog response: Error %x on cmd %x\n",
726 msg->msg.data[0],
727 msg->msg.cmd);
728 }
729
730 ipmi_free_recv_msg(msg);
731}
732
733static void ipmi_wdog_pretimeout_handler(void *handler_data)
734{
735 if (preaction_val != WDOG_PRETIMEOUT_NONE) {
736 if (preop_val == WDOG_PREOP_PANIC)
737 panic("Watchdog pre-timeout");
738 else if (preop_val == WDOG_PREOP_GIVE_DATA) {
739 spin_lock(&ipmi_read_lock);
740 data_to_read = 1;
741 wake_up_interruptible(&read_q);
742 kill_fasync(&fasync_q, SIGIO, POLL_IN);
743
744 spin_unlock(&ipmi_read_lock);
745 }
746 }
747
748
749
750
751 pretimeout_since_last_heartbeat = 1;
752}
753
754static struct ipmi_user_hndl ipmi_hndlrs =
755{
756 .ipmi_recv_hndl = ipmi_wdog_msg_handler,
757 .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler
758};
759
760static void ipmi_register_watchdog(int ipmi_intf)
761{
762 int rv = -EBUSY;
763
764 down_write(®ister_sem);
765 if (watchdog_user)
766 goto out;
767
768 rv = ipmi_create_user(ipmi_intf, &ipmi_hndlrs, NULL, &watchdog_user);
769 if (rv < 0) {
770 printk("IPMI watchdog: Unable to register with ipmi\n");
771 goto out;
772 }
773
774 ipmi_get_version(watchdog_user,
775 &ipmi_version_major,
776 &ipmi_version_minor);
777
778 rv = misc_register(&ipmi_wdog_miscdev);
779 if (rv < 0) {
780 ipmi_destroy_user(watchdog_user);
781 watchdog_user = NULL;
782 printk("IPMI watchdog: Unable to register misc device\n");
783 }
784
785 out:
786 up_write(®ister_sem);
787
788 if ((start_now) && (rv == 0)) {
789
790 start_now = 0;
791 ipmi_watchdog_state = action_val;
792 ipmi_set_timeout(IPMI_SET_TIMEOUT_FORCE_HB);
793 printk("Starting IPMI Watchdog now!\n");
794 }
795}
796
797#ifdef HAVE_NMI_HANDLER
798static int
799ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
800{
801
802
803 if ((!handled) && (preop_val == WDOG_PREOP_PANIC))
804 panic("IPMI watchdog pre-timeout");
805
806
807
808
809 pretimeout_since_last_heartbeat = 1;
810
811 return NOTIFY_DONE;
812}
813
814static struct nmi_handler ipmi_nmi_handler =
815{
816 .dev_name = "ipmi_watchdog",
817 .dev_id = NULL,
818 .handler = ipmi_nmi,
819 .priority = 0,
820};
821#endif
822
823static int wdog_reboot_handler(struct notifier_block *this,
824 unsigned long code,
825 void *unused)
826{
827 static int reboot_event_handled = 0;
828
829 if ((watchdog_user) && (!reboot_event_handled)) {
830
831 reboot_event_handled = 1;
832
833 if (code == SYS_DOWN || code == SYS_HALT) {
834
835 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
836 panic_halt_ipmi_set_timeout();
837 } else {
838
839
840 timeout = 120;
841 pretimeout = 0;
842 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
843 panic_halt_ipmi_set_timeout();
844 }
845 }
846 return NOTIFY_OK;
847}
848
849static struct notifier_block wdog_reboot_notifier = {
850 wdog_reboot_handler,
851 NULL,
852 0
853};
854
855extern int panic_timeout;
856
857static int wdog_panic_handler(struct notifier_block *this,
858 unsigned long event,
859 void *unused)
860{
861 static int panic_event_handled = 0;
862
863
864
865 if (watchdog_user && !panic_event_handled && (panic_timeout > 0)) {
866
867
868 panic_event_handled = 1;
869
870 timeout = panic_timeout + 120;
871 if (timeout > 255)
872 timeout = 255;
873 pretimeout = 0;
874 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
875 panic_halt_ipmi_set_timeout();
876 }
877
878 return NOTIFY_OK;
879}
880
881static struct notifier_block wdog_panic_notifier = {
882 wdog_panic_handler,
883 NULL,
884 150
885};
886
887
888static void ipmi_new_smi(int if_num)
889{
890 ipmi_register_watchdog(if_num);
891}
892
893static void ipmi_smi_gone(int if_num)
894{
895
896
897
898}
899
900static struct ipmi_smi_watcher smi_watcher =
901{
902 .new_smi = ipmi_new_smi,
903 .smi_gone = ipmi_smi_gone
904};
905
906static int __init ipmi_wdog_init(void)
907{
908 int rv;
909
910 if (strcmp(action, "reset") == 0) {
911 action_val = WDOG_TIMEOUT_RESET;
912 } else if (strcmp(action, "none") == 0) {
913 action_val = WDOG_TIMEOUT_NONE;
914 } else if (strcmp(action, "power_cycle") == 0) {
915 action_val = WDOG_TIMEOUT_POWER_CYCLE;
916 } else if (strcmp(action, "power_off") == 0) {
917 action_val = WDOG_TIMEOUT_POWER_DOWN;
918 } else {
919 action_val = WDOG_TIMEOUT_RESET;
920 printk("ipmi_watchdog: Unknown action '%s', defaulting to"
921 " reset\n", action);
922 }
923
924 if (strcmp(preaction, "pre_none") == 0) {
925 preaction_val = WDOG_PRETIMEOUT_NONE;
926 } else if (strcmp(preaction, "pre_smi") == 0) {
927 preaction_val = WDOG_PRETIMEOUT_SMI;
928#ifdef HAVE_NMI_HANDLER
929 } else if (strcmp(preaction, "pre_nmi") == 0) {
930 preaction_val = WDOG_PRETIMEOUT_NMI;
931#endif
932 } else if (strcmp(preaction, "pre_int") == 0) {
933 preaction_val = WDOG_PRETIMEOUT_MSG_INT;
934 } else {
935 preaction_val = WDOG_PRETIMEOUT_NONE;
936 printk("ipmi_watchdog: Unknown preaction '%s', defaulting to"
937 " none\n", preaction);
938 }
939
940 if (strcmp(preop, "preop_none") == 0) {
941 preop_val = WDOG_PREOP_NONE;
942 } else if (strcmp(preop, "preop_panic") == 0) {
943 preop_val = WDOG_PREOP_PANIC;
944 } else if (strcmp(preop, "preop_give_data") == 0) {
945 preop_val = WDOG_PREOP_GIVE_DATA;
946 } else {
947 preop_val = WDOG_PREOP_NONE;
948 printk("ipmi_watchdog: Unknown preop '%s', defaulting to"
949 " none\n", preop);
950 }
951
952#ifdef HAVE_NMI_HANDLER
953 if (preaction_val == WDOG_PRETIMEOUT_NMI) {
954 if (preop_val == WDOG_PREOP_GIVE_DATA) {
955 printk(KERN_WARNING
956 "ipmi_watchdog: Pretimeout op is to give data"
957 " but NMI pretimeout is enabled, setting"
958 " pretimeout op to none\n");
959 preop_val = WDOG_PREOP_NONE;
960 }
961#ifdef CONFIG_X86_LOCAL_APIC
962 if (nmi_watchdog == NMI_IO_APIC) {
963 printk(KERN_WARNING
964 "ipmi_watchdog: nmi_watchdog is set to IO APIC"
965 " mode (value is %d), that is incompatible"
966 " with using NMI in the IPMI watchdog."
967 " Disabling IPMI nmi pretimeout.\n",
968 nmi_watchdog);
969 preaction_val = WDOG_PRETIMEOUT_NONE;
970 } else {
971#endif
972 rv = request_nmi(&ipmi_nmi_handler);
973 if (rv) {
974 printk(KERN_WARNING
975 "ipmi_watchdog: Can't register nmi handler\n");
976 return rv;
977 }
978#ifdef CONFIG_X86_LOCAL_APIC
979 }
980#endif
981 }
982#endif
983
984 rv = ipmi_smi_watcher_register(&smi_watcher);
985 if (rv) {
986#ifdef HAVE_NMI_HANDLER
987 if (preaction_val == WDOG_PRETIMEOUT_NMI)
988 release_nmi(&ipmi_nmi_handler);
989#endif
990 printk(KERN_WARNING
991 "ipmi_watchdog: can't register smi watcher\n");
992 return rv;
993 }
994
995 register_reboot_notifier(&wdog_reboot_notifier);
996 notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier);
997
998 printk(KERN_INFO "IPMI watchdog by "
999 "Corey Minyard (minyard@mvista.com)\n");
1000
1001 return 0;
1002}
1003
1004#ifdef MODULE
1005static void ipmi_unregister_watchdog(void)
1006{
1007 int rv;
1008
1009 down_write(®ister_sem);
1010
1011#ifdef HAVE_NMI_HANDLER
1012 if (preaction_val == WDOG_PRETIMEOUT_NMI)
1013 release_nmi(&ipmi_nmi_handler);
1014#endif
1015
1016 notifier_chain_unregister(&panic_notifier_list, &wdog_panic_notifier);
1017 unregister_reboot_notifier(&wdog_reboot_notifier);
1018
1019 if (! watchdog_user)
1020 goto out;
1021
1022
1023 misc_deregister(&ipmi_wdog_miscdev);
1024
1025
1026 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
1027 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
1028
1029
1030
1031
1032 while (atomic_read(&set_timeout_tofree)) {
1033 schedule_timeout(1);
1034 }
1035
1036
1037 rv = ipmi_destroy_user(watchdog_user);
1038 if (rv) {
1039 printk(KERN_WARNING
1040 "IPMI Watchdog, error unlinking from IPMI: %d\n",
1041 rv);
1042 }
1043 watchdog_user = NULL;
1044
1045 out:
1046 up_write(®ister_sem);
1047}
1048
1049static void __exit ipmi_wdog_exit(void)
1050{
1051 ipmi_smi_watcher_unregister(&smi_watcher);
1052 ipmi_unregister_watchdog();
1053}
1054module_exit(ipmi_wdog_exit);
1055#else
1056static int __init ipmi_wdog_setup(char *str)
1057{
1058 int val;
1059 int rv;
1060 char *option;
1061
1062 rv = get_option(&str, &val);
1063 if (rv == 0)
1064 return 1;
1065 if (val > 0)
1066 timeout = val;
1067 if (rv == 1)
1068 return 1;
1069
1070 rv = get_option(&str, &val);
1071 if (rv == 0)
1072 return 1;
1073 if (val >= 0)
1074 pretimeout = val;
1075 if (rv == 1)
1076 return 1;
1077
1078 while ((option = strsep(&str, ",")) != NULL) {
1079 if (strcmp(option, "reset") == 0) {
1080 action = "reset";
1081 }
1082 else if (strcmp(option, "none") == 0) {
1083 action = "none";
1084 }
1085 else if (strcmp(option, "power_cycle") == 0) {
1086 action = "power_cycle";
1087 }
1088 else if (strcmp(option, "power_off") == 0) {
1089 action = "power_off";
1090 }
1091 else if (strcmp(option, "pre_none") == 0) {
1092 preaction = "pre_none";
1093 }
1094 else if (strcmp(option, "pre_smi") == 0) {
1095 preaction = "pre_smi";
1096 }
1097#ifdef HAVE_NMI_HANDLER
1098 else if (strcmp(option, "pre_nmi") == 0) {
1099 preaction = "pre_nmi";
1100 }
1101#endif
1102 else if (strcmp(option, "pre_int") == 0) {
1103 preaction = "pre_int";
1104 }
1105 else if (strcmp(option, "start_now") == 0) {
1106 start_now = 1;
1107 }
1108 else if (strcmp(option, "preop_none") == 0) {
1109 preop = "preop_none";
1110 }
1111 else if (strcmp(option, "preop_panic") == 0) {
1112 preop = "preop_panic";
1113 }
1114 else if (strcmp(option, "preop_give_data") == 0) {
1115 preop = "preop_give_data";
1116 } else {
1117 printk("Unknown IPMI watchdog option: '%s'\n", option);
1118 }
1119 }
1120
1121 return 1;
1122}
1123__setup("ipmi_wdog=", ipmi_wdog_setup);
1124#endif
1125
1126EXPORT_SYMBOL(ipmi_delayed_shutdown);
1127
1128module_init(ipmi_wdog_init);
1129MODULE_LICENSE("GPL");
1130