diff options
author | Hank Janssen | 2010-05-15 23:39:58 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2010-05-18 01:32:30 +0200 |
commit | 9153f7b997aef3fcfd0bf1eededfd76595c7dc0b (patch) | |
tree | 5122ab51d6b722b34e93f3a11e608fa168151ff6 /drivers/staging/hv/hv_utils.c | |
parent | Staging: Use kmemdup (diff) | |
download | kernel-qcow2-linux-9153f7b997aef3fcfd0bf1eededfd76595c7dc0b.tar.gz kernel-qcow2-linux-9153f7b997aef3fcfd0bf1eededfd76595c7dc0b.tar.xz kernel-qcow2-linux-9153f7b997aef3fcfd0bf1eededfd76595c7dc0b.zip |
staging: hv: Added heartbeat functionality to hv_utils
Add heartbeat functionality to hv_utils/Hyper-V
Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/hv/hv_utils.c')
-rw-r--r-- | drivers/staging/hv/hv_utils.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index db45d97a3a7c..8a49aafea37a 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -194,6 +194,62 @@ static void timesync_onchannelcallback(void *context) DPRINT_EXIT(VMBUS); } +/* + * Heartbeat functionality. + * Every two seconds, Hyper-V send us a heartbeat request message. + * we respond to this message, and Hyper-V knows we are alive. + */ +static void heartbeat_onchannelcallback(void *context) +{ + struct vmbus_channel *channel = context; + u8 *buf; + u32 buflen, recvlen; + u64 requestid; + struct icmsg_hdr *icmsghdrp; + struct heartbeat_msg_data *heartbeat_msg; + + DPRINT_ENTER(VMBUS); + + buflen = PAGE_SIZE; + buf = kmalloc(buflen, GFP_ATOMIC); + + VmbusChannelRecvPacket(channel, buf, buflen, &recvlen, &requestid); + + if (recvlen > 0) { + DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", + recvlen, requestid); + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + icmsghdrp = (struct icmsg_hdr *)&buf[ + sizeof(struct vmbuspipe_hdr)]; + + if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { + prep_negotiate_resp(icmsghdrp, NULL, buf); + } else { + heartbeat_msg = (struct heartbeat_msg_data *)&buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; + + DPRINT_DBG(VMBUS, "heartbeat seq = %lld", + heartbeat_msg->seq_num); + + heartbeat_msg->seq_num += 1; + } + + icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION + | ICMSGHDRFLAG_RESPONSE; + + VmbusChannelSendPacket(channel, buf, + recvlen, requestid, + VmbusPacketTypeDataInBand, 0); + } + + kfree(buf); + + DPRINT_EXIT(VMBUS); +} static int __init init_hyperv_utils(void) { @@ -207,6 +263,10 @@ static int __init init_hyperv_utils(void) ×ync_onchannelcallback; hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &heartbeat_onchannelcallback; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; + return 0; } @@ -221,6 +281,10 @@ static void exit_hyperv_utils(void) hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = &chn_cb_negotiate; hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; + + hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + &chn_cb_negotiate; + hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; } module_init(init_hyperv_utils); |