aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/ibmasm/heartbeat.c
diff options
context:
space:
mode:
authorMax Asbock <masbock@us.ibm.com>2005-06-21 17:16:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 19:07:35 -0700
commit8818760512424f60ad9fafb7a087b007a9274eb3 (patch)
treefb49ce398750f42803d4631a24e4a2ffe35d79d7 /drivers/misc/ibmasm/heartbeat.c
parent278d72ae8803ffcd16070c95fe1d53f4466dc741 (diff)
[PATCH] ibmasm driver: fix race in command refcount logic
This patch fixes a race in the command reference counting logic by putting spinlocks around kobject_put() in the command_put function. - Also added debug messages. - Changed a memcpy to memcpy_fromio since we are reading from io space. Signed-off-by: Max Asbock <masbock@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/misc/ibmasm/heartbeat.c')
-rw-r--r--drivers/misc/ibmasm/heartbeat.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c
index ce09309174d..f295401fac2 100644
--- a/drivers/misc/ibmasm/heartbeat.c
+++ b/drivers/misc/ibmasm/heartbeat.c
@@ -25,6 +25,7 @@
#include <linux/notifier.h>
#include "ibmasm.h"
#include "dot_command.h"
+#include "lowlevel.h"
static int suspend_heartbeats = 0;
@@ -62,7 +63,7 @@ void ibmasm_unregister_panic_notifier(void)
int ibmasm_heartbeat_init(struct service_processor *sp)
{
- sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE);
+ sp->heartbeat = ibmasm_new_command(sp, HEARTBEAT_BUFFER_SIZE);
if (sp->heartbeat == NULL)
return -ENOMEM;
@@ -71,6 +72,12 @@ int ibmasm_heartbeat_init(struct service_processor *sp)
void ibmasm_heartbeat_exit(struct service_processor *sp)
{
+ char tsbuf[32];
+
+ dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
+ ibmasm_wait_for_response(sp->heartbeat, IBMASM_CMD_TIMEOUT_NORMAL);
+ dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
+ suspend_heartbeats = 1;
command_put(sp->heartbeat);
}
@@ -78,14 +85,16 @@ void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size
{
struct command *cmd = sp->heartbeat;
struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
+ char tsbuf[32];
+ dbg("%s:%d at %s\n", __FUNCTION__, __LINE__, get_timestamp(tsbuf));
if (suspend_heartbeats)
return;
/* return the received dot command to sender */
cmd->status = IBMASM_CMD_PENDING;
size = min(size, cmd->buffer_size);
- memcpy(cmd->buffer, message, size);
+ memcpy_fromio(cmd->buffer, message, size);
header->type = sp_write;
ibmasm_exec_command(sp, cmd);
}