Path: blob/master/drivers/misc/ibmasm/r_heartbeat.c
17590 views
1/*2* This program is free software; you can redistribute it and/or modify3* it under the terms of the GNU General Public License as published by4* the Free Software Foundation; either version 2 of the License, or5* (at your option) any later version.6*7* This program is distributed in the hope that it will be useful,8* but WITHOUT ANY WARRANTY; without even the implied warranty of9* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the10* GNU General Public License for more details.11*12* You should have received a copy of the GNU General Public License13* along with this program; if not, write to the Free Software14* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.15*16* Copyright (C) IBM Corporation, 200417*18* Author: Max Asb�ck <[email protected]>19*20*/2122#include <linux/sched.h>23#include "ibmasm.h"24#include "dot_command.h"2526/*27* Reverse Heartbeat, i.e. heartbeats sent from the driver to the28* service processor.29* These heartbeats are initiated by user level programs.30*/3132/* the reverse heartbeat dot command */33#pragma pack(1)34static struct {35struct dot_command_header header;36unsigned char command[3];37} rhb_dot_cmd = {38.header = {39.type = sp_read,40.command_size = 3,41.data_size = 0,42.status = 043},44.command = { 4, 3, 6 }45};46#pragma pack()4748void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)49{50init_waitqueue_head(&rhb->wait);51rhb->stopped = 0;52}5354/**55* start_reverse_heartbeat56* Loop forever, sending a reverse heartbeat dot command to the service57* processor, then sleeping. The loop comes to an end if the service58* processor fails to respond 3 times or we were interrupted.59*/60int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)61{62struct command *cmd;63int times_failed = 0;64int result = 1;6566cmd = ibmasm_new_command(sp, sizeof rhb_dot_cmd);67if (!cmd)68return -ENOMEM;6970while (times_failed < 3) {71memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);72cmd->status = IBMASM_CMD_PENDING;73ibmasm_exec_command(sp, cmd);74ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);7576if (cmd->status != IBMASM_CMD_COMPLETE)77times_failed++;7879wait_event_interruptible_timeout(rhb->wait,80rhb->stopped,81REVERSE_HEARTBEAT_TIMEOUT * HZ);8283if (signal_pending(current) || rhb->stopped) {84result = -EINTR;85break;86}87}88command_put(cmd);89rhb->stopped = 0;9091return result;92}9394void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)95{96rhb->stopped = 1;97wake_up_interruptible(&rhb->wait);98}99100101