0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/notifier.h>
0012 #include <linux/panic_notifier.h>
0013 #include "ibmasm.h"
0014 #include "dot_command.h"
0015 #include "lowlevel.h"
0016
0017 static int suspend_heartbeats = 0;
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 static int panic_happened(struct notifier_block *n, unsigned long val, void *v)
0033 {
0034 suspend_heartbeats = 1;
0035 return 0;
0036 }
0037
0038 static struct notifier_block panic_notifier = { panic_happened, NULL, 1 };
0039
0040 void ibmasm_register_panic_notifier(void)
0041 {
0042 atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
0043 }
0044
0045 void ibmasm_unregister_panic_notifier(void)
0046 {
0047 atomic_notifier_chain_unregister(&panic_notifier_list,
0048 &panic_notifier);
0049 }
0050
0051
0052 int ibmasm_heartbeat_init(struct service_processor *sp)
0053 {
0054 sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE);
0055 if (sp->heartbeat == NULL)
0056 return -ENOMEM;
0057
0058 return 0;
0059 }
0060
0061 void ibmasm_heartbeat_exit(struct service_processor *sp)
0062 {
0063 char tsbuf[32];
0064
0065 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
0066 ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL);
0067 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
0068 suspend_heartbeats = 1;
0069 command_put(sp->heartbeat);
0070 }
0071
0072 void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size)
0073 {
0074 struct command *cmd = sp->heartbeat;
0075 struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
0076 char tsbuf[32];
0077
0078 dbg("%s:%d at %s\n", __func__, __LINE__, get_timestamp(tsbuf));
0079 if (suspend_heartbeats)
0080 return;
0081
0082
0083 cmd->status = IBMASM_CMD_PENDING;
0084 size = min(size, cmd->buffer_size);
0085 memcpy_fromio(cmd->buffer, message, size);
0086 header->type = sp_write;
0087 ibmasm_exec_command(sp, cmd);
0088 }