1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#include "ibmasm.h"
24#include "dot_command.h"
25
26
27
28
29
30
31
32
33#pragma pack(1)
34static struct {
35 struct dot_command_header header;
36 unsigned char command[3];
37} rhb_dot_cmd = {
38 .header = {
39 .type = sp_read,
40 .command_size = 3,
41 .data_size = 0,
42 .status = 0
43 },
44 .command = { 4, 3, 6 }
45};
46#pragma pack()
47
48void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
49{
50 init_waitqueue_head(&rhb->wait);
51 rhb->stopped = 0;
52}
53
54
55
56
57
58
59
60int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
61{
62 struct command *cmd;
63 int times_failed = 0;
64 int result = 1;
65
66 cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
67 if (!cmd)
68 return -ENOMEM;
69
70 while (times_failed < 3) {
71 memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
72 cmd->status = IBMASM_CMD_PENDING;
73 ibmasm_exec_command(sp, cmd);
74 ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
75
76 if (cmd->status != IBMASM_CMD_COMPLETE)
77 times_failed++;
78
79 wait_event_interruptible_timeout(rhb->wait,
80 rhb->stopped,
81 REVERSE_HEARTBEAT_TIMEOUT * HZ);
82
83 if (signal_pending(current) || rhb->stopped) {
84 result = -EINTR;
85 break;
86 }
87 }
88 command_put(cmd);
89 rhb->stopped = 0;
90
91 return result;
92}
93
94void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
95{
96 rhb->stopped = 1;
97 wake_up_interruptible(&rhb->wait);
98}
99