aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/channel_mgmt.c73
-rw-r--r--drivers/hv/hv.c2
-rw-r--r--drivers/hv/hv_kvp.c3
-rw-r--r--drivers/hv/hv_util.c9
-rw-r--r--drivers/hv/hyperv_vmbus.h2
5 files changed, 57 insertions, 32 deletions
diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
index 9ffbfc575a0c..2b8b8d4558d2 100644
--- a/drivers/hv/channel_mgmt.c
+++ b/drivers/hv/channel_mgmt.c
@@ -46,40 +46,61 @@ 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{
59 if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { 63 int icframe_vercnt;
60 icmsghdrp->icmsgsize = 0x10; 64 int icmsg_vercnt;
61 65 int i;
62 negop = (struct icmsg_negotiate *)&buf[ 66
63 sizeof(struct vmbuspipe_hdr) + 67 icmsghdrp->icmsgsize = 0x10;
64 sizeof(struct icmsg_hdr)]; 68
65 69 negop = (struct icmsg_negotiate *)&buf[
66 if (negop->icframe_vercnt == 2 && 70 sizeof(struct vmbuspipe_hdr) +
67 negop->icversion_data[1].major == 3) { 71 sizeof(struct icmsg_hdr)];
68 negop->icversion_data[0].major = 3; 72
69 negop->icversion_data[0].minor = 0; 73 icframe_vercnt = negop->icframe_vercnt;
70 negop->icversion_data[1].major = 3; 74 icmsg_vercnt = negop->icmsg_vercnt;
71 negop->icversion_data[1].minor = 0; 75
72 } else { 76 /*
73 negop->icversion_data[0].major = 1; 77 * Select the framework version number we will
74 negop->icversion_data[0].minor = 0; 78 * support.
75 negop->icversion_data[1].major = 1; 79 */
76 negop->icversion_data[1].minor = 0; 80
77 } 81 for (i = 0; i < negop->icframe_vercnt; i++) {
82 if (negop->icversion_data[i].major <= max_fw_version)
83 icframe_vercnt = negop->icversion_data[i].major;
84 }
78 85
79 negop->icframe_vercnt = 1; 86 for (i = negop->icframe_vercnt;
80 negop->icmsg_vercnt = 1; 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;
81 } 90 }
91
92 /*
93 * Respond with the maximum framework and service
94 * version numbers we can support.
95 */
96 negop->icframe_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;
82} 102}
103
83EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp); 104EXPORT_SYMBOL_GPL(vmbus_prep_negotiate_resp);
84 105
85/* 106/*
diff --git a/drivers/hv/hv.c b/drivers/hv/hv.c
index 15956bd48b48..86f8885aeb45 100644
--- a/drivers/hv/hv.c
+++ b/drivers/hv/hv.c
@@ -252,7 +252,7 @@ void hv_cleanup(void)
252 * 252 *
253 * This involves a hypercall. 253 * This involves a hypercall.
254 */ 254 */
255u16 hv_post_message(union hv_connection_id connection_id, 255int hv_post_message(union hv_connection_id connection_id,
256 enum hv_message_type message_type, 256 enum hv_message_type message_type,
257 void *payload, size_t payload_size) 257 void *payload, size_t payload_size)
258{ 258{
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[
diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h
index 699f0d8e59ed..b9426a6592ee 100644
--- a/drivers/hv/hyperv_vmbus.h
+++ b/drivers/hv/hyperv_vmbus.h
@@ -495,7 +495,7 @@ extern int hv_init(void);
495 495
496extern void hv_cleanup(void); 496extern void hv_cleanup(void);
497 497
498extern u16 hv_post_message(union hv_connection_id connection_id, 498extern int hv_post_message(union hv_connection_id connection_id,
499 enum hv_message_type message_type, 499 enum hv_message_type message_type,
500 void *payload, size_t payload_size); 500 void *payload, size_t payload_size);
501 501