Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6472f80a authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Greg Kroah-Hartman
Browse files

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: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Tested-by: default avatarAlex Ng <alexng@microsoft.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 14b50f80
Loading
Loading
Loading
Loading
+27 −25
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <linux/hyperv.h>

#include "hyperv_vmbus.h"
#include "hv_utils_transport.h"

#define VSS_MAJOR  5
#define VSS_MINOR  0
@@ -58,9 +59,9 @@ static struct {

static void vss_respond_to_host(int error);

static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL };
static const char vss_name[] = "vss_kernel_module";
static const char vss_devname[] = "vmbus/hv_vss";
static __u8 *recv_buffer;
static struct hvutil_transport *hvt;

static void vss_send_op(struct work_struct *dummy);
static void vss_timeout_func(struct work_struct *dummy);
@@ -88,12 +89,12 @@ static void vss_timeout_func(struct work_struct *dummy)
			hv_vss_onchannelcallback);
}

static void
vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
static int vss_on_msg(void *msg, int len)
{
	struct hv_vss_msg *vss_msg;
	struct hv_vss_msg *vss_msg = (struct hv_vss_msg *)msg;

	vss_msg = (struct hv_vss_msg *)msg->data;
	if (len != sizeof(*vss_msg))
		return -EINVAL;

	/*
	 * 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)
	 */
	if (vss_transaction.state > HVUTIL_READY &&
	    vss_msg->vss_hdr.operation == VSS_OP_REGISTER)
		return;
		return -EINVAL;

	if (vss_transaction.state == HVUTIL_DEVICE_INIT &&
	    vss_msg->vss_hdr.operation == VSS_OP_REGISTER) {
@@ -119,8 +120,9 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
	} else {
		/* This is a spurious call! */
		pr_warn("VSS: Transaction not active\n");
		return;
		return -EINVAL;
	}
	return 0;
}


@@ -128,27 +130,20 @@ static void vss_send_op(struct work_struct *dummy)
{
	int op = vss_transaction.msg->vss_hdr.operation;
	int rc;
	struct cn_msg *msg;
	struct hv_vss_msg *vss_msg;

	/* The transaction state is wrong. */
	if (vss_transaction.state != HVUTIL_HOSTMSG_RECEIVED)
		return;

	msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC);
	if (!msg)
	vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
	if (!vss_msg)
		return;

	vss_msg = (struct hv_vss_msg *)msg->data;

	msg->id.idx =  CN_VSS_IDX;
	msg->id.val = CN_VSS_VAL;

	vss_msg->vss_hdr.operation = op;
	msg->len = sizeof(struct hv_vss_msg);

	vss_transaction.state = HVUTIL_USERSPACE_REQ;
	rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
	rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg));
	if (rc) {
		pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
		if (cancel_delayed_work_sync(&vss_timeout_work)) {
@@ -157,7 +152,7 @@ static void vss_send_op(struct work_struct *dummy)
		}
	}

	kfree(msg);
	kfree(vss_msg);

	return;
}
@@ -308,14 +303,16 @@ void hv_vss_onchannelcallback(void *context)

}

static void vss_on_reset(void)
{
	if (cancel_delayed_work_sync(&vss_timeout_work))
		vss_respond_to_host(HV_E_FAIL);
	vss_transaction.state = HVUTIL_DEVICE_INIT;
}

int
hv_vss_init(struct hv_util_service *srv)
{
	int err;

	err = cn_add_callback(&vss_id, vss_name, vss_cn_callback);
	if (err)
		return err;
	recv_buffer = srv->recv_buffer;

	/*
@@ -326,13 +323,18 @@ hv_vss_init(struct hv_util_service *srv)
	 */
	vss_transaction.state = HVUTIL_DEVICE_INIT;

	hvt = hvutil_transport_init(vss_devname, CN_VSS_IDX, CN_VSS_VAL,
				    vss_on_msg, vss_on_reset);
	if (!hvt)
		return -EFAULT;

	return 0;
}

void hv_vss_deinit(void)
{
	vss_transaction.state = HVUTIL_DEVICE_DYING;
	cn_del_callback(&vss_id);
	cancel_delayed_work_sync(&vss_timeout_work);
	cancel_work_sync(&vss_send_op_work);
	hvutil_transport_destroy(hvt);
}