root/drivers/misc/ibmasm/r_heartbeat.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ibmasm_init_reverse_heartbeat
  2. ibmasm_start_reverse_heartbeat
  3. ibmasm_stop_reverse_heartbeat

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 
   3 /*
   4  *
   5  * Copyright (C) IBM Corporation, 2004
   6  *
   7  * Author: Max Asböck <amax@us.ibm.com>
   8  */
   9 
  10 #include <linux/sched/signal.h>
  11 #include "ibmasm.h"
  12 #include "dot_command.h"
  13 
  14 /*
  15  * Reverse Heartbeat, i.e. heartbeats sent from the driver to the
  16  * service processor.
  17  * These heartbeats are initiated by user level programs.
  18  */
  19 
  20 /* the reverse heartbeat dot command */
  21 #pragma pack(1)
  22 static struct {
  23         struct dot_command_header       header;
  24         unsigned char                   command[3];
  25 } rhb_dot_cmd = {
  26         .header = {
  27                 .type =         sp_read,
  28                 .command_size = 3,
  29                 .data_size =    0,
  30                 .status =       0
  31         },
  32         .command = { 4, 3, 6 }
  33 };
  34 #pragma pack()
  35 
  36 void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
  37 {
  38         init_waitqueue_head(&rhb->wait);
  39         rhb->stopped = 0;
  40 }
  41 
  42 /**
  43  * start_reverse_heartbeat
  44  * Loop forever, sending a reverse heartbeat dot command to the service
  45  * processor, then sleeping. The loop comes to an end if the service
  46  * processor fails to respond 3 times or we were interrupted.
  47  */
  48 int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
  49 {
  50         struct command *cmd;
  51         int times_failed = 0;
  52         int result = 1;
  53 
  54         cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);
  55         if (!cmd)
  56                 return -ENOMEM;
  57 
  58         while (times_failed < 3) {
  59                 memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
  60                 cmd->status = IBMASM_CMD_PENDING;
  61                 ibmasm_exec_command(sp, cmd);
  62                 ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
  63 
  64                 if (cmd->status != IBMASM_CMD_COMPLETE)
  65                         times_failed++;
  66 
  67                 wait_event_interruptible_timeout(rhb->wait,
  68                         rhb->stopped,
  69                         REVERSE_HEARTBEAT_TIMEOUT * HZ);
  70 
  71                 if (signal_pending(current) || rhb->stopped) {
  72                         result = -EINTR;
  73                         break;
  74                 }
  75         }
  76         command_put(cmd);
  77         rhb->stopped = 0;
  78 
  79         return result;
  80 }
  81 
  82 void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
  83 {
  84         rhb->stopped = 1;
  85         wake_up_interruptible(&rhb->wait);
  86 }

/* [<][>][^][v][top][bottom][index][help] */