aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/channel_mgmt.c54
-rw-r--r--drivers/hv/hv_kvp.c3
-rw-r--r--drivers/hv/hv_util.c9
3 files changed, 46 insertions, 20 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 6c8c4d340930..2b8b8d4558d2 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -46,37 +46,59 @@ struct vmbus_channel_message_table_entry {
46 * 46 *
47 * @icmsghdrp is of type &struct icmsg_hdr. 47 * @icmsghdrp is of type &struct icmsg_hdr.
48 * @negop is of type &struct icmsg_negotiate. 48 * @negop is of type &struct icmsg_negotiate.
49 * Set up and fill in default negotiate response message. This response can 49 * Set up and fill in default negotiate response message.
50 * come from both the vmbus driver and the hv_utils driver. The current api 50 *
51 * will respond properly to both Windows 2008 and Windows 2008-R2 operating 51 * The max_fw_version specifies the maximum framework version that
52 * systems. 52 * we can support and max _srv_version specifies the maximum service
53 * version we can support. A special value MAX_SRV_VER can be
54 * specified to indicate that we can handle the maximum version
55 * exposed by the host.
53 * 56 *
54 * Mainly used by Hyper-V drivers. 57 * Mainly used by Hyper-V drivers.
55 */ 58 */
56void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp, 59void vmbus_prep_negotiate_resp(struct icmsg_hdr *icmsghdrp,
57 struct icmsg_negotiate *negop, u8 *buf) 60 struct icmsg_negotiate *negop, u8 *buf,
61 int max_fw_version, int max_srv_version)
58{ 62{
63 int icframe_vercnt;
64 int icmsg_vercnt;
65 int i;
66
59 icmsghdrp->icmsgsize = 0x10; 67 icmsghdrp->icmsgsize = 0x10;
60 68
61 negop = (struct icmsg_negotiate *)&buf[ 69 negop = (struct icmsg_negotiate *)&buf[
62 sizeof(struct vmbuspipe_hdr) + 70 sizeof(struct vmbuspipe_hdr) +
63 sizeof(struct icmsg_hdr)]; 71 sizeof(struct icmsg_hdr)];
64 72
65 if (negop->icframe_vercnt == 2 && 73 icframe_vercnt = negop->icframe_vercnt;
66 negop->icversion_data[1].major == 3) { 74 icmsg_vercnt = negop->icmsg_vercnt;
67 negop->icversion_data[0].major = 3; 75
68 negop->icversion_data[0].minor = 0; 76 /*
69 negop->icversion_data[1].major = 3; 77 * Select the framework version number we will
70 negop->icversion_data[1].minor = 0; 78 * support.
71 } else { 79 */
72 negop->icversion_data[0].major = 1; 80
73 negop->icversion_data[0].minor = 0; 81 for (i = 0; i < negop->icframe_vercnt; i++) {
74 negop->icversion_data[1].major = 1; 82 if (negop->icversion_data[i].major <= max_fw_version)
75 negop->icversion_data[1].minor = 0; 83 icframe_vercnt = negop->icversion_data[i].major;
84 }
85
86 for (i = negop->icframe_vercnt;
87 (i < negop->icframe_vercnt + negop->icmsg_vercnt); i++) {
88 if (negop->icversion_data[i].major <= max_srv_version)
89 icmsg_vercnt = negop->icversion_data[i].major;
76 } 90 }
77 91
92 /*
93 * Respond with the maximum framework and service
94 * version numbers we can support.
95 */
78 negop->icframe_vercnt = 1; 96 negop->icframe_vercnt = 1;
79 negop->icmsg_vercnt = 1; 97 negop->icmsg_vercnt = 1;
98 negop->icversion_data[0].major = icframe_vercnt;
99 negop->icversion_data[0].minor = 0;
100 negop->icversion_data[1].major = icmsg_vercnt;
101 negop->icversion_data[1].minor = 0;
80} 102}
81 103
82EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp); 104EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c
index 6186025209ce..0012eed6d872 100644
--- a/drivers/hv/hv_kvp.c
+++ b/drivers/hv/hv_kvp.c
@@ -394,7 +394,8 @@ void hv_kvp_onchannelcallback(void *context)
394 sizeof(struct vmbuspipe_hdr)]; 394 sizeof(struct vmbuspipe_hdr)];
395 395
396 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 396 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
397 vmbus_prep_negotiate_resp(icmsghdrp, negop, recv_buffer); 397 vmbus_prep_negotiate_resp(icmsghdrp, negop,
398 recv_buffer, MAX_SRV_VER, MAX_SRV_VER);
398 } else { 399 } else {
399 kvp_msg = (struct hv_kvp_msg *)&recv_buffer[ 400 kvp_msg = (struct hv_kvp_msg *)&recv_buffer[
400 sizeof(struct vmbuspipe_hdr) + 401 sizeof(struct vmbuspipe_hdr) +
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index dbb8b8eec210..d3ac6a40118b 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -70,7 +70,8 @@ static void shutdown_onchannelcallback(void *context)
70 sizeof(struct vmbuspipe_hdr)]; 70 sizeof(struct vmbuspipe_hdr)];
71 71
72 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 72 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
73 vmbus_prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); 73 vmbus_prep_negotiate_resp(icmsghdrp, negop,
74 shut_txf_buf, MAX_SRV_VER, MAX_SRV_VER);
74 } else { 75 } else {
75 shutdown_msg = 76 shutdown_msg =
76 (struct shutdown_msg_data *)&shut_txf_buf[ 77 (struct shutdown_msg_data *)&shut_txf_buf[
@@ -195,7 +196,8 @@ static void timesync_onchannelcallback(void *context)
195 sizeof(struct vmbuspipe_hdr)]; 196 sizeof(struct vmbuspipe_hdr)];
196 197
197 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 198 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
198 vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); 199 vmbus_prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf,
200 MAX_SRV_VER, MAX_SRV_VER);
199 } else { 201 } else {
200 timedatap = (struct ictimesync_data *)&time_txf_buf[ 202 timedatap = (struct ictimesync_data *)&time_txf_buf[
201 sizeof(struct vmbuspipe_hdr) + 203 sizeof(struct vmbuspipe_hdr) +
@@ -234,7 +236,8 @@ static void heartbeat_onchannelcallback(void *context)
234 sizeof(struct vmbuspipe_hdr)]; 236 sizeof(struct vmbuspipe_hdr)];
235 237
236 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 238 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
237 vmbus_prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); 239 vmbus_prep_negotiate_resp(icmsghdrp, NULL,
240 hbeat_txf_buf, MAX_SRV_VER, MAX_SRV_VER);
238 } else { 241 } else {
239 heartbeat_msg = 242 heartbeat_msg =
240 (struct heartbeat_msg_data *)&hbeat_txf_buf[ 243 (struct heartbeat_msg_data *)&hbeat_txf_buf[