/*
 * Copyright (c) 2009, Microsoft Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place - Suite 330, Boston, MA 02111-1307 USA.
 *
 * Authors:
 *   Haiyang Zhang <haiyangz@microsoft.com>
 *   Hank Janssen  <hjanssen@microsoft.com>
 */
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/list.h>
#include "osd.h"
#include "logging.h"
#include "VmbusPrivate.h"

struct vmbus_channel_message_table_entry {
	enum vmbus_channel_message_type messageType;
	void (*messageHandler)(struct vmbus_channel_message_header *msg);
};

#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 4
static const struct hv_guid
		gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
	/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
	/* Storage - SCSI */
	{
		.data  = {
			0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
			0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
		}
	},

	/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
	/* Network */
	{
		.data = {
			0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46,
			0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E
		}
	},

	/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
	/* Input */
	{
		.data = {
			0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c,
			0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A
		}
	},

	/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
	/* IDE */
	{
		.data = {
			0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
			0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
		}
	},
};

/**
 * AllocVmbusChannel - Allocate and initialize a vmbus channel object
 */
struct vmbus_channel *AllocVmbusChannel(void)
{
	struct vmbus_channel *channel;

	channel = kzalloc(sizeof(*channel), GFP_ATOMIC);
	if (!channel)
		return NULL;

	spin_lock_init(&channel->inbound_lock);

	init_timer(&channel->poll_timer);
	channel->poll_timer.data = (unsigned long)channel;
	channel->poll_timer.function = VmbusChannelOnTimer;

	channel->ControlWQ = create_workqueue("hv_vmbus_ctl");
	if (!channel->ControlWQ) {
		kfree(channel);
		return NULL;
	}

	return channel;
}

/**
 * ReleaseVmbusChannel - Release the vmbus channel object itself
 */
static inline void ReleaseVmbusChannel(void *context)
{
	struct vmbus_channel *channel = context;

	DPRINT_ENTER(VMBUS);

	DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
	destroy_workqueue(channel->ControlWQ);
	DPRINT_DBG(VMBUS, "channel released (%p)", channel);

	kfree(channel);

	DPRINT_EXIT(VMBUS);
}

/**
 * FreeVmbusChannel - Release the resources used by the vmbus channel object
 */
void FreeVmbusChannel(struct vmbus_channel *Channel)
{
	del_timer_sync(&Channel->poll_timer);

	/*
	 * We have to release the channel's workqueue/thread in the vmbus's
	 * workqueue/thread context
	 * ie we can't destroy ourselves.
	 */
	osd_schedule_callback(gVmbusConnection.WorkQueue, ReleaseVmbusChannel,
			      Channel);
}

/**
 * VmbusChannelProcessOffer - Process the offer by creating a channel/device associated with this offer
 */
static void VmbusChannelProcessOffer(void *context)
{
	struct vmbus_channel *newChannel = context;
	struct vmbus_channel *channel;
	bool fNew = true;
	int ret;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	/* Make sure this is a new offer */
	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);

	list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) {
		if (!memcmp(&channel->OfferMsg.Offer.InterfaceType,
			    &newChannel->OfferMsg.Offer.InterfaceType,
			    sizeof(struct hv_guid)) &&
		    !memcmp(&channel->OfferMsg.Offer.InterfaceInstance,
			    &newChannel->OfferMsg.Offer.InterfaceInstance,
			    sizeof(struct hv_guid))) {
			fNew = false;
			break;
		}
	}

	if (fNew)
		list_add_tail(&newChannel->ListEntry,
			      &gVmbusConnection.ChannelList);

	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);

	if (!fNew) {
		DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
			   newChannel->OfferMsg.ChildRelId);
		FreeVmbusChannel(newChannel);
		DPRINT_EXIT(VMBUS);
		return;
	}

	/*
	 * Start the process of binding this offer to the driver
	 * We need to set the DeviceObject field before calling
	 * VmbusChildDeviceAdd()
	 */
	newChannel->DeviceObject = VmbusChildDeviceCreate(
		&newChannel->OfferMsg.Offer.InterfaceType,
		&newChannel->OfferMsg.Offer.InterfaceInstance,
		newChannel);

	DPRINT_DBG(VMBUS, "child device object allocated - %p",
		   newChannel->DeviceObject);

	/*
	 * Add the new device to the bus. This will kick off device-driver
	 * binding which eventually invokes the device driver's AddDevice()
	 * method.
	 */
	ret = VmbusChildDeviceAdd(newChannel->DeviceObject);
	if (ret != 0) {
		DPRINT_ERR(VMBUS,
			   "unable to add child device object (relid %d)",
			   newChannel->OfferMsg.ChildRelId);

		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
		list_del(&newChannel->ListEntry);
		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);

		FreeVmbusChannel(newChannel);
	} else {
		/*
		 * This state is used to indicate a successful open
		 * so that when we do close the channel normally, we
		 * can cleanup properly
		 */
		newChannel->State = CHANNEL_OPEN_STATE;
	}
	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelProcessRescindOffer - Rescind the offer by initiating a device removal
 */
static void VmbusChannelProcessRescindOffer(void *context)
{
	struct vmbus_channel *channel = context;

	DPRINT_ENTER(VMBUS);
	VmbusChildDeviceRemove(channel->DeviceObject);
	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnOffer - Handler for channel offers from vmbus in parent partition.
 *
 * We ignore all offers except network and storage offers. For each network and
 * storage offers, we create a channel object and queue a work item to the
 * channel object to process the offer synchronously
 */
static void VmbusChannelOnOffer(struct vmbus_channel_message_header *hdr)
{
	struct vmbus_channel_offer_channel *offer;
	struct vmbus_channel *newChannel;
	struct hv_guid *guidType;
	struct hv_guid *guidInstance;
	int i;
	int fSupported = 0;

	DPRINT_ENTER(VMBUS);

	offer = (struct vmbus_channel_offer_channel *)hdr;
	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
		if (memcmp(&offer->Offer.InterfaceType,
		    &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) {
			fSupported = 1;
			break;
		}
	}

	if (!fSupported) {
		DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
			   "child relid %d", offer->ChildRelId);
		DPRINT_EXIT(VMBUS);
		return;
	}

	guidType = &offer->Offer.InterfaceType;
	guidInstance = &offer->Offer.InterfaceInstance;

	DPRINT_INFO(VMBUS, "Channel offer notification - "
		    "child relid %d monitor id %d allocated %d, "
		    "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
		    "%02x%02x%02x%02x%02x%02x%02x%02x} "
		    "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
		    offer->ChildRelId, offer->MonitorId,
		    offer->MonitorAllocated,
		    guidType->data[3], guidType->data[2],
		    guidType->data[1], guidType->data[0],
		    guidType->data[5], guidType->data[4],
		    guidType->data[7], guidType->data[6],
		    guidType->data[8], guidType->data[9],
		    guidType->data[10], guidType->data[11],
		    guidType->data[12], guidType->data[13],
		    guidType->data[14], guidType->data[15],
		    guidInstance->data[3], guidInstance->data[2],
		    guidInstance->data[1], guidInstance->data[0],
		    guidInstance->data[5], guidInstance->data[4],
		    guidInstance->data[7], guidInstance->data[6],
		    guidInstance->data[8], guidInstance->data[9],
		    guidInstance->data[10], guidInstance->data[11],
		    guidInstance->data[12], guidInstance->data[13],
		    guidInstance->data[14], guidInstance->data[15]);

	/* Allocate the channel object and save this offer. */
	newChannel = AllocVmbusChannel();
	if (!newChannel) {
		DPRINT_ERR(VMBUS, "unable to allocate channel object");
		return;
	}

	DPRINT_DBG(VMBUS, "channel object allocated - %p", newChannel);

	memcpy(&newChannel->OfferMsg, offer,
	       sizeof(struct vmbus_channel_offer_channel));
	newChannel->MonitorGroup = (u8)offer->MonitorId / 32;
	newChannel->MonitorBit = (u8)offer->MonitorId % 32;

	/* TODO: Make sure the offer comes from our parent partition */
	osd_schedule_callback(newChannel->ControlWQ, VmbusChannelProcessOffer,
			      newChannel);

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnOfferRescind - Rescind offer handler.
 *
 * We queue a work item to process this offer synchronously
 */
static void VmbusChannelOnOfferRescind(struct vmbus_channel_message_header *hdr)
{
	struct vmbus_channel_rescind_offer *rescind;
	struct vmbus_channel *channel;

	DPRINT_ENTER(VMBUS);

	rescind = (struct vmbus_channel_rescind_offer *)hdr;
	channel = GetChannelFromRelId(rescind->ChildRelId);
	if (channel == NULL) {
		DPRINT_DBG(VMBUS, "channel not found for relId %d",
			   rescind->ChildRelId);
		return;
	}

	osd_schedule_callback(channel->ControlWQ,
			      VmbusChannelProcessRescindOffer,
			      channel);

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnOffersDelivered - This is invoked when all offers have been delivered.
 *
 * Nothing to do here.
 */
static void VmbusChannelOnOffersDelivered(
			struct vmbus_channel_message_header *hdr)
{
	DPRINT_ENTER(VMBUS);
	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnOpenResult - Open result handler.
 *
 * This is invoked when we received a response to our channel open request.
 * Find the matching request, copy the response and signal the requesting
 * thread.
 */
static void VmbusChannelOnOpenResult(struct vmbus_channel_message_header *hdr)
{
	struct vmbus_channel_open_result *result;
	struct list_head *curr;
	struct vmbus_channel_msginfo *msgInfo;
	struct vmbus_channel_message_header *requestHeader;
	struct vmbus_channel_open_channel *openMsg;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	result = (struct vmbus_channel_open_result *)hdr;
	DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);

	/*
	 * Find the open msg, copy the result and signal/unblock the wait event
	 */
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);

	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
/* FIXME: this should probably use list_entry() instead */
		msgInfo = (struct vmbus_channel_msginfo *)curr;
		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;

		if (requestHeader->MessageType == ChannelMessageOpenChannel) {
			openMsg = (struct vmbus_channel_open_channel *)msgInfo->Msg;
			if (openMsg->ChildRelId == result->ChildRelId &&
			    openMsg->OpenId == result->OpenId) {
				memcpy(&msgInfo->Response.OpenResult,
				       result,
				       sizeof(struct vmbus_channel_open_result));
				osd_WaitEventSet(msgInfo->WaitEvent);
				break;
			}
		}
	}
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnGpadlCreated - GPADL created handler.
 *
 * This is invoked when we received a response to our gpadl create request.
 * Find the matching request, copy the response and signal the requesting
 * thread.
 */
static void VmbusChannelOnGpadlCreated(struct vmbus_channel_message_header *hdr)
{
	struct vmbus_channel_gpadl_created *gpadlCreated;
	struct list_head *curr;
	struct vmbus_channel_msginfo *msgInfo;
	struct vmbus_channel_message_header *requestHeader;
	struct vmbus_channel_gpadl_header *gpadlHeader;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	gpadlCreated = (struct vmbus_channel_gpadl_created *)hdr;
	DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
		   gpadlCreated->CreationStatus);

	/*
	 * Find the establish msg, copy the result and signal/unblock the wait
	 * event
	 */
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);

	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
/* FIXME: this should probably use list_entry() instead */
		msgInfo = (struct vmbus_channel_msginfo *)curr;
		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;

		if (requestHeader->MessageType == ChannelMessageGpadlHeader) {
			gpadlHeader = (struct vmbus_channel_gpadl_header *)requestHeader;

			if ((gpadlCreated->ChildRelId ==
			     gpadlHeader->ChildRelId) &&
			    (gpadlCreated->Gpadl == gpadlHeader->Gpadl)) {
				memcpy(&msgInfo->Response.GpadlCreated,
				       gpadlCreated,
				       sizeof(struct vmbus_channel_gpadl_created));
				osd_WaitEventSet(msgInfo->WaitEvent);
				break;
			}
		}
	}
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnGpadlTorndown - GPADL torndown handler.
 *
 * This is invoked when we received a response to our gpadl teardown request.
 * Find the matching request, copy the response and signal the requesting
 * thread.
 */
static void VmbusChannelOnGpadlTorndown(
			struct vmbus_channel_message_header *hdr)
{
	struct vmbus_channel_gpadl_torndown *gpadlTorndown;
	struct list_head *curr;
	struct vmbus_channel_msginfo *msgInfo;
	struct vmbus_channel_message_header *requestHeader;
	struct vmbus_channel_gpadl_teardown *gpadlTeardown;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	gpadlTorndown = (struct vmbus_channel_gpadl_torndown *)hdr;

	/*
	 * Find the open msg, copy the result and signal/unblock the wait event
	 */
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);

	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
/* FIXME: this should probably use list_entry() instead */
		msgInfo = (struct vmbus_channel_msginfo *)curr;
		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;

		if (requestHeader->MessageType == ChannelMessageGpadlTeardown) {
			gpadlTeardown = (struct vmbus_channel_gpadl_teardown *)requestHeader;

			if (gpadlTorndown->Gpadl == gpadlTeardown->Gpadl) {
				memcpy(&msgInfo->Response.GpadlTorndown,
				       gpadlTorndown,
				       sizeof(struct vmbus_channel_gpadl_torndown));
				osd_WaitEventSet(msgInfo->WaitEvent);
				break;
			}
		}
	}
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelOnVersionResponse - Version response handler
 *
 * This is invoked when we received a response to our initiate contact request.
 * Find the matching request, copy the response and signal the requesting
 * thread.
 */
static void VmbusChannelOnVersionResponse(
		struct vmbus_channel_message_header *hdr)
{
	struct list_head *curr;
	struct vmbus_channel_msginfo *msgInfo;
	struct vmbus_channel_message_header *requestHeader;
	struct vmbus_channel_initiate_contact *initiate;
	struct vmbus_channel_version_response *versionResponse;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	versionResponse = (struct vmbus_channel_version_response *)hdr;
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);

	list_for_each(curr, &gVmbusConnection.ChannelMsgList) {
/* FIXME: this should probably use list_entry() instead */
		msgInfo = (struct vmbus_channel_msginfo *)curr;
		requestHeader = (struct vmbus_channel_message_header *)msgInfo->Msg;

		if (requestHeader->MessageType ==
		    ChannelMessageInitiateContact) {
			initiate = (struct vmbus_channel_initiate_contact *)requestHeader;
			memcpy(&msgInfo->Response.VersionResponse,
			      versionResponse,
			      sizeof(struct vmbus_channel_version_response));
			osd_WaitEventSet(msgInfo->WaitEvent);
		}
	}
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	DPRINT_EXIT(VMBUS);
}

/* Channel message dispatch table */
static struct vmbus_channel_message_table_entry
	gChannelMessageTable[ChannelMessageCount] = {
	{ChannelMessageInvalid,			NULL},
	{ChannelMessageOfferChannel,		VmbusChannelOnOffer},
	{ChannelMessageRescindChannelOffer,	VmbusChannelOnOfferRescind},
	{ChannelMessageRequestOffers,		NULL},
	{ChannelMessageAllOffersDelivered,	VmbusChannelOnOffersDelivered},
	{ChannelMessageOpenChannel,		NULL},
	{ChannelMessageOpenChannelResult,	VmbusChannelOnOpenResult},
	{ChannelMessageCloseChannel,		NULL},
	{ChannelMessageGpadlHeader,		NULL},
	{ChannelMessageGpadlBody,		NULL},
	{ChannelMessageGpadlCreated,		VmbusChannelOnGpadlCreated},
	{ChannelMessageGpadlTeardown,		NULL},
	{ChannelMessageGpadlTorndown,		VmbusChannelOnGpadlTorndown},
	{ChannelMessageRelIdReleased,		NULL},
	{ChannelMessageInitiateContact,		NULL},
	{ChannelMessageVersionResponse,		VmbusChannelOnVersionResponse},
	{ChannelMessageUnload,			NULL},
};

/**
 * VmbusOnChannelMessage - Handler for channel protocol messages.
 *
 * This is invoked in the vmbus worker thread context.
 */
void VmbusOnChannelMessage(void *Context)
{
	struct hv_message *msg = Context;
	struct vmbus_channel_message_header *hdr;
	int size;

	DPRINT_ENTER(VMBUS);

	hdr = (struct vmbus_channel_message_header *)msg->u.Payload;
	size = msg->Header.PayloadSize;

	DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size);

	if (hdr->MessageType >= ChannelMessageCount) {
		DPRINT_ERR(VMBUS,
			   "Received invalid channel message type %d size %d",
			   hdr->MessageType, size);
		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
				     (unsigned char *)msg->u.Payload, size);
		kfree(msg);
		return;
	}

	if (gChannelMessageTable[hdr->MessageType].messageHandler)
		gChannelMessageTable[hdr->MessageType].messageHandler(hdr);
	else
		DPRINT_ERR(VMBUS, "Unhandled channel message type %d",
			   hdr->MessageType);

	/* Free the msg that was allocated in VmbusOnMsgDPC() */
	kfree(msg);
	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelRequestOffers - Send a request to get all our pending offers.
 */
int VmbusChannelRequestOffers(void)
{
	struct vmbus_channel_message_header *msg;
	struct vmbus_channel_msginfo *msgInfo;
	int ret;

	DPRINT_ENTER(VMBUS);

	msgInfo = kmalloc(sizeof(*msgInfo) +
			  sizeof(struct vmbus_channel_message_header),
			  GFP_KERNEL);
	ASSERT(msgInfo != NULL);

	msgInfo->WaitEvent = osd_WaitEventCreate();
	msg = (struct vmbus_channel_message_header *)msgInfo->Msg;

	msg->MessageType = ChannelMessageRequestOffers;

	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
	INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList,
			 &msgInfo->msgListEntry);
	SpinlockRelease(gVmbusConnection.channelMsgLock);*/

	ret = VmbusPostMessage(msg,
			       sizeof(struct vmbus_channel_message_header));
	if (ret != 0) {
		DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret);

		/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
		REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
		SpinlockRelease(gVmbusConnection.channelMsgLock);*/

		goto Cleanup;
	}
	/* osd_WaitEventWait(msgInfo->waitEvent); */

	/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
	REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
	SpinlockRelease(gVmbusConnection.channelMsgLock);*/


Cleanup:
	if (msgInfo) {
		kfree(msgInfo->WaitEvent);
		kfree(msgInfo);
	}

	DPRINT_EXIT(VMBUS);
	return ret;
}

/**
 * VmbusChannelReleaseUnattachedChannels - Release channels that are unattached/unconnected ie (no drivers associated)
 */
void VmbusChannelReleaseUnattachedChannels(void)
{
	struct vmbus_channel *channel, *pos;
	struct vmbus_channel *start = NULL;
	unsigned long flags;

	spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);

	list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList,
				 ListEntry) {
		if (channel == start)
			break;

		if (!channel->DeviceObject->Driver) {
			list_del(&channel->ListEntry);
			DPRINT_INFO(VMBUS,
				    "Releasing unattached device object %p",
				    channel->DeviceObject);

			VmbusChildDeviceRemove(channel->DeviceObject);
			FreeVmbusChannel(channel);
		} else {
			if (!start)
				start = channel;
		}
	}

	spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
}

/* eof */
