From: Hank Janssen Date: Sat, 15 May 2010 21:39:58 +0000 (-0700) Subject: staging: hv: Added heartbeat functionality to hv_utils X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=9153f7b997aef3fcfd0bf1eededfd76595c7dc0b;p=linux-beck.git staging: hv: Added heartbeat functionality to hv_utils Add heartbeat functionality to hv_utils/Hyper-V Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 6877e8e7f71e..3f53b4d1e4cf 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -33,8 +33,8 @@ struct vmbus_channel_message_table_entry { void (*messageHandler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 2 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 6 +#define MAX_MSG_TYPES 3 +#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 7 static const struct hv_guid gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { @@ -89,6 +89,14 @@ static const struct hv_guid 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .data = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + } + }, }; @@ -211,6 +219,17 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { .callback = chn_cb_negotiate, .log_msg = "Timesync channel functionality initialized" }, + /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ + /* Heartbeat */ + { + .msg_type = HV_HEARTBEAT_MSG, + .data = { + 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d + }, + .callback = chn_cb_negotiate, + .log_msg = "Heartbeat channel functionality initialized" + }, }; EXPORT_SYMBOL(hv_cb_utils); 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); diff --git a/drivers/staging/hv/utils.h b/drivers/staging/hv/utils.h index a4b9fd06e270..7c0749999a6f 100644 --- a/drivers/staging/hv/utils.h +++ b/drivers/staging/hv/utils.h @@ -75,6 +75,10 @@ struct shutdown_msg_data { u8 display_message[2048]; } __attribute__((packed)); +struct heartbeat_msg_data { + u64 seq_num; + u32 reserved[8]; +} __attribute__((packed)); /* Time Sync IC defs */ #define ICTIMESYNCFLAG_PROBE 0 @@ -97,6 +101,7 @@ struct ictimesync_data{ /* Index for each IC struct in array hv_cb_utils[] */ #define HV_SHUTDOWN_MSG 0 #define HV_TIMESYNC_MSG 1 +#define HV_HEARTBEAT_MSG 2 struct hyperv_service_callback { u8 msg_type; diff --git a/drivers/staging/hv/version_info.h b/drivers/staging/hv/version_info.h index 82e74b1ab150..35178f2c7967 100644 --- a/drivers/staging/hv/version_info.h +++ b/drivers/staging/hv/version_info.h @@ -40,8 +40,9 @@ * Minor Number Changes when new functionality is added * to the Linux IC's that is not a bug fix. * + * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync */ -#define HV_DRV_VERSION "3.0" +#define HV_DRV_VERSION "3.1" #endif