summaryrefslogtreecommitdiffstats
path: root/drivers/hv
diff options
context:
space:
mode:
authorVitaly Kuznetsov <vkuznets@redhat.com>2015-04-11 21:07:52 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-24 15:17:41 -0400
commit6472f80a2eeb34b442542bccd4d600e9251d9c36 (patch)
treeafab8c5e127db58891ccba29c50e6a98533a7325 /drivers/hv
parent14b50f80c32dd4e84b6baeaa8bf4049cc5ecf56d (diff)
Drivers: hv: vss: convert to hv_utils_transport
Convert to hv_utils_transport to support both netlink and /dev/vmbus/hv_vss communication methods. Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> Tested-by: Alex Ng <alexng@microsoft.com> Signed-off-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/hv')
-rw-r--r--drivers/hv/hv_snapshot.c52
1 files changed, 27 insertions, 25 deletions
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c
index ddb1cda4b2fc..2c8c246d09eb 100644
--- a/drivers/hv/hv_snapshot.c
+++ b/drivers/hv/hv_snapshot.c
@@ -25,6 +25,7 @@
25#include <linux/hyperv.h> 25#include <linux/hyperv.h>
26 26
27#include "hyperv_vmbus.h" 27#include "hyperv_vmbus.h"
28#include "hv_utils_transport.h"
28 29
29#define VSS_MAJOR 5 30#define VSS_MAJOR 5
30#define VSS_MINOR 0 31#define VSS_MINOR 0
@@ -58,9 +59,9 @@ static struct {
58 59
59static void vss_respond_to_host(int error); 60static void vss_respond_to_host(int error);
60 61
61static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL }; 62static const char vss_devname[] = "vmbus/hv_vss";
62static const char vss_name[] = "vss_kernel_module";
63static __u8 *recv_buffer; 63static __u8 *recv_buffer;
64static struct hvutil_transport *hvt;
64 65
65static void vss_send_op(struct work_struct *dummy); 66static void vss_send_op(struct work_struct *dummy);
66static void vss_timeout_func(struct work_struct *dummy); 67static void vss_timeout_func(struct work_struct *dummy);
@@ -88,12 +89,12 @@ static void vss_timeout_func(struct work_struct *dummy)
88 hv_vss_onchannelcallback); 89 hv_vss_onchannelcallback);
89} 90}
90 91
91static void 92static int vss_on_msg(void *msg, int len)
92vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
93{ 93{
94 struct hv_vss_msg *vss_msg; 94 struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;
95 95
96 vss_msg = (struct hv_vss_msg *)msg->data; 96 if (len != sizeof(*vss_msg))
97 return -EINVAL;
97 98
98 /* 99 /*
99 * Don't process registration messages if we're in the middle of 100 * Don't process registration messages if we're in the middle of
@@ -101,7 +102,7 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
101 */ 102 */
102 if (vss_transaction.state > HVUTIL_READY && 103 if (vss_transaction.state > HVUTIL_READY &&
103 vss_msg->vss_hdr.operation == VSS_OP_REGISTER) 104 vss_msg->vss_hdr.operation == VSS_OP_REGISTER)
104 return; 105 return -EINVAL;
105 106
106 if (vss_transaction.state == HVUTIL_DEVICE_INIT && 107 if (vss_transaction.state == HVUTIL_DEVICE_INIT &&
107 vss_msg->vss_hdr.operation == VSS_OP_REGISTER) { 108 vss_msg->vss_hdr.operation == VSS_OP_REGISTER) {
@@ -119,8 +120,9 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
119 } else { 120 } else {
120 /* This is a spurious call! */ 121 /* This is a spurious call! */
121 pr_warn("VSS: Transaction not active\n"); 122 pr_warn("VSS: Transaction not active\n");
122 return; 123 return -EINVAL;
123 } 124 }
125 return 0;
124} 126}
125 127
126 128
@@ -128,27 +130,20 @@ static void vss_send_op(struct work_struct *dummy)
128{ 130{
129 int op = vss_transaction.msg->vss_hdr.operation; 131 int op = vss_transaction.msg->vss_hdr.operation;
130 int rc; 132 int rc;
131 struct cn_msg *msg;
132 struct hv_vss_msg *vss_msg; 133 struct hv_vss_msg *vss_msg;
133 134
134 /* The transaction state is wrong. */ 135 /* The transaction state is wrong. */
135 if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED) 136 if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
136 return; 137 return;
137 138
138 msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC); 139 vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
139 if (!msg) 140 if (!vss_msg)
140 return; 141 return;
141 142
142 vss_msg = (struct hv_vss_msg *)msg->data;
143
144 msg->id.idx = CN_VSS_IDX;
145 msg->id.val = CN_VSS_VAL;
146
147 vss_msg->vss_hdr.operation = op; 143 vss_msg->vss_hdr.operation = op;
148 msg->len = sizeof(struct hv_vss_msg);
149 144
150 vss_transaction.state = HVUTIL_USERSPACE_REQ; 145 vss_transaction.state = HVUTIL_USERSPACE_REQ;
151 rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC); 146 rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg));
152 if (rc) { 147 if (rc) {
153 pr_warn("VSS: failed to communicate to the daemon: %d\n", rc); 148 pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
154 if (cancel_delayed_work_sync(&vss_timeout_work)) { 149 if (cancel_delayed_work_sync(&vss_timeout_work)) {
@@ -157,7 +152,7 @@ static void vss_send_op(struct work_struct *dummy)
157 } 152 }
158 } 153 }
159 154
160 kfree(msg); 155 kfree(vss_msg);
161 156
162 return; 157 return;
163} 158}
@@ -308,14 +303,16 @@ void hv_vss_onchannelcallback(void *context)
308 303
309} 304}
310 305
306static void vss_on_reset(void)
307{
308 if (cancel_delayed_work_sync(&vss_timeout_work))
309 vss_respond_to_host(HV_E_FAIL);
310 vss_transaction.state = HVUTIL_DEVICE_INIT;
311}
312
311int 313int
312hv_vss_init(struct hv_util_service *srv) 314hv_vss_init(struct hv_util_service *srv)
313{ 315{
314 int err;
315
316 err = cn_add_callback(&vss_id, vss_name, vss_cn_callback);
317 if (err)
318 return err;
319 recv_buffer = srv->recv_buffer; 316 recv_buffer = srv->recv_buffer;
320 317
321 /* 318 /*
@@ -326,13 +323,18 @@ hv_vss_init(struct hv_util_service *srv)
326 */ 323 */
327 vss_transaction.state = HVUTIL_DEVICE_INIT; 324 vss_transaction.state = HVUTIL_DEVICE_INIT;
328 325
326 hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
327 vss_on_msg, vss_on_reset);
328 if (!hvt)
329 return -EFAULT;
330
329 return 0; 331 return 0;
330} 332}
331 333
332void hv_vss_deinit(void) 334void hv_vss_deinit(void)
333{ 335{
334 vss_transaction.state = HVUTIL_DEVICE_DYING; 336 vss_transaction.state = HVUTIL_DEVICE_DYING;
335 cn_del_callback(&vss_id);
336 cancel_delayed_work_sync(&vss_timeout_work); 337 cancel_delayed_work_sync(&vss_timeout_work);
337 cancel_work_sync(&vss_send_op_work); 338 cancel_work_sync(&vss_send_op_work);
339 hvutil_transport_destroy(hvt);
338} 340}