3 * IBM ASM Service Processor Device Driver
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * Copyright (C) IBM Corporation, 2004
21 * Author: Max Asböck <amax@us.ibm.com>
25 #include <linux/notifier.h>
27 #include "dot_command.h"
29 static int suspend_heartbeats
= 0;
32 * Once the driver indicates to the service processor that it is running
33 * - see send_os_state() - the service processor sends periodic heartbeats
34 * to the driver. The driver must respond to the heartbeats or else the OS
36 * In the case of a panic the interrupt handler continues to work and thus
37 * continues to respond to heartbeats, making the service processor believe
38 * the OS is still running and thus preventing a reboot.
39 * To prevent this from happening a callback is added the panic_notifier_list.
40 * Before responding to a heartbeat the driver checks if a panic has happened,
41 * if yes it suspends heartbeat, causing the service processor to reboot as
44 static int panic_happened(struct notifier_block
*n
, unsigned long val
, void *v
)
46 suspend_heartbeats
= 1;
50 static struct notifier_block panic_notifier
= { panic_happened
, NULL
, 1 };
52 void ibmasm_register_panic_notifier(void)
54 notifier_chain_register(&panic_notifier_list
, &panic_notifier
);
57 void ibmasm_unregister_panic_notifier(void)
59 notifier_chain_unregister(&panic_notifier_list
, &panic_notifier
);
63 int ibmasm_heartbeat_init(struct service_processor
*sp
)
65 sp
->heartbeat
= ibmasm_new_command(HEARTBEAT_BUFFER_SIZE
);
66 if (sp
->heartbeat
== NULL
)
72 void ibmasm_heartbeat_exit(struct service_processor
*sp
)
74 command_put(sp
->heartbeat
);
77 void ibmasm_receive_heartbeat(struct service_processor
*sp
, void *message
, size_t size
)
79 struct command
*cmd
= sp
->heartbeat
;
80 struct dot_command_header
*header
= (struct dot_command_header
*)cmd
->buffer
;
82 if (suspend_heartbeats
)
85 /* return the received dot command to sender */
86 cmd
->status
= IBMASM_CMD_PENDING
;
87 size
= min(size
, cmd
->buffer_size
);
88 memcpy(cmd
->buffer
, message
, size
);
89 header
->type
= sp_write
;
90 ibmasm_exec_command(sp
, cmd
);