0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/sched/signal.h>
0011 #include "ibmasm.h"
0012 #include "dot_command.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021 #pragma pack(1)
0022 static struct {
0023 struct dot_command_header header;
0024 unsigned char command[3];
0025 } rhb_dot_cmd = {
0026 .header = {
0027 .type = sp_read,
0028 .command_size = 3,
0029 .data_size = 0,
0030 .status = 0
0031 },
0032 .command = { 4, 3, 6 }
0033 };
0034 #pragma pack()
0035
0036 void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
0037 {
0038 init_waitqueue_head(&rhb->wait);
0039 rhb->stopped = 0;
0040 }
0041
0042
0043
0044
0045
0046
0047
0048 int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
0049 {
0050 struct command *cmd;
0051 int times_failed = 0;
0052 int result = 1;
0053
0054 cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
0055 if (!cmd)
0056 return -ENOMEM;
0057
0058 while (times_failed < 3) {
0059 memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
0060 cmd->status = IBMASM_CMD_PENDING;
0061 ibmasm_exec_command(sp, cmd);
0062 ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
0063
0064 if (cmd->status != IBMASM_CMD_COMPLETE)
0065 times_failed++;
0066
0067 wait_event_interruptible_timeout(rhb->wait,
0068 rhb->stopped,
0069 REVERSE_HEARTBEAT_TIMEOUT * HZ);
0070
0071 if (signal_pending(current) || rhb->stopped) {
0072 result = -EINTR;
0073 break;
0074 }
0075 }
0076 command_put(cmd);
0077 rhb->stopped = 0;
0078
0079 return result;
0080 }
0081
0082 void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
0083 {
0084 rhb->stopped = 1;
0085 wake_up_interruptible(&rhb->wait);
0086 }