/*
 * 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/slab.h>
#include <linux/module.h>
#include "osd.h"
#include "logging.h"
#include "vmbus_private.h"

/* Internal routines */
static int VmbusChannelCreateGpadlHeader(
	void *Kbuffer,	/* must be phys and virt contiguous */
	u32 Size,	/* page-size multiple */
	struct vmbus_channel_msginfo **msgInfo,
	u32 *MessageCount);
static void DumpVmbusChannel(struct vmbus_channel *channel);
static void VmbusChannelSetEvent(struct vmbus_channel *channel);


#if 0
static void DumpMonitorPage(struct hv_monitor_page *MonitorPage)
{
	int i = 0;
	int j = 0;

	DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d",
		   MonitorPage, MonitorPage->TriggerState);

	for (i = 0; i < 4; i++)
		DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i,
			   MonitorPage->TriggerGroup[i].AsUINT64);

	for (i = 0; i < 4; i++) {
		for (j = 0; j < 32; j++) {
			DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j,
				   MonitorPage->Latency[i][j]);
		}
	}
	for (i = 0; i < 4; i++) {
		for (j = 0; j < 32; j++) {
			DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j,
			       MonitorPage->Parameter[i][j].ConnectionId.Asu32);
			DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j,
				MonitorPage->Parameter[i][j].FlagNumber);
		}
	}
}
#endif

/*
 * VmbusChannelSetEvent - Trigger an event notification on the specified
 * channel.
 */
static void VmbusChannelSetEvent(struct vmbus_channel *Channel)
{
	struct hv_monitor_page *monitorPage;

	DPRINT_ENTER(VMBUS);

	if (Channel->OfferMsg.MonitorAllocated) {
		/* Each u32 represents 32 channels */
		set_bit(Channel->OfferMsg.ChildRelId & 31,
			(unsigned long *) gVmbusConnection.SendInterruptPage +
			(Channel->OfferMsg.ChildRelId >> 5));

		monitorPage = gVmbusConnection.MonitorPages;
		monitorPage++; /* Get the child to parent monitor page */

		set_bit(Channel->MonitorBit,
			(unsigned long *)&monitorPage->TriggerGroup
					[Channel->MonitorGroup].Pending);

	} else {
		VmbusSetEvent(Channel->OfferMsg.ChildRelId);
	}

	DPRINT_EXIT(VMBUS);
}

#if 0
static void VmbusChannelClearEvent(struct vmbus_channel *channel)
{
	struct hv_monitor_page *monitorPage;

	DPRINT_ENTER(VMBUS);

	if (Channel->OfferMsg.MonitorAllocated) {
		/* Each u32 represents 32 channels */
		clear_bit(Channel->OfferMsg.ChildRelId & 31,
			  (unsigned long *)gVmbusConnection.SendInterruptPage +
			  (Channel->OfferMsg.ChildRelId >> 5));

		monitorPage =
			(struct hv_monitor_page *)gVmbusConnection.MonitorPages;
		monitorPage++; /* Get the child to parent monitor page */

		clear_bit(Channel->MonitorBit,
			  (unsigned long *)&monitorPage->TriggerGroup
					[Channel->MonitorGroup].Pending);
	}

	DPRINT_EXIT(VMBUS);
}

#endif
/*
 * VmbusChannelGetDebugInfo -Retrieve various channel debug info
 */
void VmbusChannelGetDebugInfo(struct vmbus_channel *Channel,
			      struct vmbus_channel_debug_info *DebugInfo)
{
	struct hv_monitor_page *monitorPage;
	u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32;
	u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32;
	/* u32 monitorBit	= 1 << monitorOffset; */

	DebugInfo->RelId = Channel->OfferMsg.ChildRelId;
	DebugInfo->State = Channel->State;
	memcpy(&DebugInfo->InterfaceType,
	       &Channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid));
	memcpy(&DebugInfo->InterfaceInstance,
	       &Channel->OfferMsg.Offer.InterfaceInstance,
	       sizeof(struct hv_guid));

	monitorPage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages;

	DebugInfo->MonitorId = Channel->OfferMsg.MonitorId;

	DebugInfo->ServerMonitorPending =
			monitorPage->TriggerGroup[monitorGroup].Pending;
	DebugInfo->ServerMonitorLatency =
			monitorPage->Latency[monitorGroup][monitorOffset];
	DebugInfo->ServerMonitorConnectionId =
			monitorPage->Parameter[monitorGroup]
					      [monitorOffset].ConnectionId.u.Id;

	monitorPage++;

	DebugInfo->ClientMonitorPending =
			monitorPage->TriggerGroup[monitorGroup].Pending;
	DebugInfo->ClientMonitorLatency =
			monitorPage->Latency[monitorGroup][monitorOffset];
	DebugInfo->ClientMonitorConnectionId =
			monitorPage->Parameter[monitorGroup]
					      [monitorOffset].ConnectionId.u.Id;

	RingBufferGetDebugInfo(&Channel->Inbound, &DebugInfo->Inbound);
	RingBufferGetDebugInfo(&Channel->Outbound, &DebugInfo->Outbound);
}

/*
 * VmbusChannelOpen - Open the specified channel.
 */
int VmbusChannelOpen(struct vmbus_channel *NewChannel, u32 SendRingBufferSize,
		     u32 RecvRingBufferSize, void *UserData, u32 UserDataLen,
		     void (*OnChannelCallback)(void *context), void *Context)
{
	struct vmbus_channel_open_channel *openMsg;
	struct vmbus_channel_msginfo *openInfo = NULL;
	void *in, *out;
	unsigned long flags;
	int ret, err = 0;

	DPRINT_ENTER(VMBUS);

	/* Aligned to page size */
	/* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */
	/* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */

	NewChannel->OnChannelCallback = OnChannelCallback;
	NewChannel->ChannelCallbackContext = Context;

	/* Allocate the ring buffer */
	out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize)
			     >> PAGE_SHIFT);
	if (!out)
		return -ENOMEM;

	/* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */

	in = (void *)((unsigned long)out + SendRingBufferSize);

	NewChannel->RingBufferPages = out;
	NewChannel->RingBufferPageCount = (SendRingBufferSize +
					   RecvRingBufferSize) >> PAGE_SHIFT;

	ret = RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize);
	if (ret != 0) {
		err = ret;
		goto errorout;
	}

	ret = RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize);
	if (ret != 0) {
		err = ret;
		goto errorout;
	}


	/* Establish the gpadl for the ring buffer */
	DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...",
		   NewChannel);

	NewChannel->RingBufferGpadlHandle = 0;

	ret = VmbusChannelEstablishGpadl(NewChannel,
					 NewChannel->Outbound.RingBuffer,
					 SendRingBufferSize +
					 RecvRingBufferSize,
					 &NewChannel->RingBufferGpadlHandle);

	if (ret != 0) {
		err = ret;
		goto errorout;
	}

	DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p "
		   "size %d recv ring %p size %d, downstreamoffset %d>",
		   NewChannel, NewChannel->OfferMsg.ChildRelId,
		   NewChannel->RingBufferGpadlHandle,
		   NewChannel->Outbound.RingBuffer,
		   NewChannel->Outbound.RingSize,
		   NewChannel->Inbound.RingBuffer,
		   NewChannel->Inbound.RingSize,
		   SendRingBufferSize);

	/* Create and init the channel open message */
	openInfo = kmalloc(sizeof(*openInfo) +
			   sizeof(struct vmbus_channel_open_channel),
			   GFP_KERNEL);
	if (!openInfo) {
		err = -ENOMEM;
		goto errorout;
	}

	openInfo->WaitEvent = osd_WaitEventCreate();
	if (!openInfo->WaitEvent) {
		err = -ENOMEM;
		goto errorout;
	}

	openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg;
	openMsg->Header.MessageType = ChannelMessageOpenChannel;
	openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; /* FIXME */
	openMsg->ChildRelId = NewChannel->OfferMsg.ChildRelId;
	openMsg->RingBufferGpadlHandle = NewChannel->RingBufferGpadlHandle;
	openMsg->DownstreamRingBufferPageOffset = SendRingBufferSize >>
						  PAGE_SHIFT;
	openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */

	if (UserDataLen > MAX_USER_DEFINED_BYTES) {
		err = -EINVAL;
		goto errorout;
	}

	if (UserDataLen)
		memcpy(openMsg->UserData, UserData, UserDataLen);

	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_add_tail(&openInfo->MsgListEntry,
		      &gVmbusConnection.ChannelMsgList);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	DPRINT_DBG(VMBUS, "Sending channel open msg...");

	ret = VmbusPostMessage(openMsg,
			       sizeof(struct vmbus_channel_open_channel));
	if (ret != 0) {
		DPRINT_ERR(VMBUS, "unable to open channel - %d", ret);
		goto Cleanup;
	}

	/* FIXME: Need to time-out here */
	osd_WaitEventWait(openInfo->WaitEvent);

	if (openInfo->Response.OpenResult.Status == 0)
		DPRINT_INFO(VMBUS, "channel <%p> open success!!", NewChannel);
	else
		DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!",
			    NewChannel, openInfo->Response.OpenResult.Status);

Cleanup:
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_del(&openInfo->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	kfree(openInfo->WaitEvent);
	kfree(openInfo);

	DPRINT_EXIT(VMBUS);

	return 0;

errorout:
	RingBufferCleanup(&NewChannel->Outbound);
	RingBufferCleanup(&NewChannel->Inbound);
	osd_PageFree(out, (SendRingBufferSize + RecvRingBufferSize)
		     >> PAGE_SHIFT);
	kfree(openInfo);
	return err;
}

/*
 * DumpGpadlBody - Dump the gpadl body message to the console for
 * debugging purposes.
 */
static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len)
{
	int i;
	int pfnCount;

	pfnCount = (Len - sizeof(struct vmbus_channel_gpadl_body)) /
		   sizeof(u64);
	DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", Len, pfnCount);

	for (i = 0; i < pfnCount; i++)
		DPRINT_DBG(VMBUS, "gpadl body  - %d) pfn %llu",
			   i, Gpadl->Pfn[i]);
}

/*
 * DumpGpadlHeader - Dump the gpadl header message to the console for
 * debugging purposes.
 */
static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl)
{
	int i, j;
	int pageCount;

	DPRINT_DBG(VMBUS,
		   "gpadl header - relid %d, range count %d, range buflen %d",
		   Gpadl->ChildRelId, Gpadl->RangeCount, Gpadl->RangeBufLen);
	for (i = 0; i < Gpadl->RangeCount; i++) {
		pageCount = Gpadl->Range[i].ByteCount >> PAGE_SHIFT;
		pageCount = (pageCount > 26) ? 26 : pageCount;

		DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d "
			   "page count %d", i, Gpadl->Range[i].ByteCount,
			   Gpadl->Range[i].ByteOffset, pageCount);

		for (j = 0; j < pageCount; j++)
			DPRINT_DBG(VMBUS, "%d) pfn %llu", j,
				   Gpadl->Range[i].PfnArray[j]);
	}
}

/*
 * VmbusChannelCreateGpadlHeader - Creates a gpadl for the specified buffer
 */
static int VmbusChannelCreateGpadlHeader(void *Kbuffer, u32 Size,
					 struct vmbus_channel_msginfo **MsgInfo,
					 u32 *MessageCount)
{
	int i;
	int pageCount;
	unsigned long long pfn;
	struct vmbus_channel_gpadl_header *gpaHeader;
	struct vmbus_channel_gpadl_body *gpadlBody;
	struct vmbus_channel_msginfo *msgHeader;
	struct vmbus_channel_msginfo *msgBody = NULL;
	u32 msgSize;

	int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize;

	/* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */
	/* ASSERT((Size & (PAGE_SIZE-1)) == 0); */

	pageCount = Size >> PAGE_SHIFT;
	pfn = virt_to_phys(Kbuffer) >> PAGE_SHIFT;

	/* do we need a gpadl body msg */
	pfnSize = MAX_SIZE_CHANNEL_MESSAGE -
		  sizeof(struct vmbus_channel_gpadl_header) -
		  sizeof(struct gpa_range);
	pfnCount = pfnSize / sizeof(u64);

	if (pageCount > pfnCount) {
		/* we need a gpadl body */
		/* fill in the header */
		msgSize = sizeof(struct vmbus_channel_msginfo) +
			  sizeof(struct vmbus_channel_gpadl_header) +
			  sizeof(struct gpa_range) + pfnCount * sizeof(u64);
		msgHeader =  kzalloc(msgSize, GFP_KERNEL);
		if (!msgHeader)
			goto nomem;

		INIT_LIST_HEAD(&msgHeader->SubMsgList);
		msgHeader->MessageSize = msgSize;

		gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg;
		gpaHeader->RangeCount = 1;
		gpaHeader->RangeBufLen = sizeof(struct gpa_range) +
					 pageCount * sizeof(u64);
		gpaHeader->Range[0].ByteOffset = 0;
		gpaHeader->Range[0].ByteCount = Size;
		for (i = 0; i < pfnCount; i++)
			gpaHeader->Range[0].PfnArray[i] = pfn+i;
		*MsgInfo = msgHeader;
		*MessageCount = 1;

		pfnSum = pfnCount;
		pfnLeft = pageCount - pfnCount;

		/* how many pfns can we fit */
		pfnSize = MAX_SIZE_CHANNEL_MESSAGE -
			  sizeof(struct vmbus_channel_gpadl_body);
		pfnCount = pfnSize / sizeof(u64);

		/* fill in the body */
		while (pfnLeft) {
			if (pfnLeft > pfnCount)
				pfnCurr = pfnCount;
			else
				pfnCurr = pfnLeft;

			msgSize = sizeof(struct vmbus_channel_msginfo) +
				  sizeof(struct vmbus_channel_gpadl_body) +
				  pfnCurr * sizeof(u64);
			msgBody = kzalloc(msgSize, GFP_KERNEL);
			/* FIXME: we probably need to more if this fails */
			if (!msgBody)
				goto nomem;
			msgBody->MessageSize = msgSize;
			(*MessageCount)++;
			gpadlBody =
				(struct vmbus_channel_gpadl_body *)msgBody->Msg;

			/*
			 * FIXME:
			 * Gpadl is u32 and we are using a pointer which could
			 * be 64-bit
			 */
			/* gpadlBody->Gpadl = kbuffer; */
			for (i = 0; i < pfnCurr; i++)
				gpadlBody->Pfn[i] = pfn + pfnSum + i;

			/* add to msg header */
			list_add_tail(&msgBody->MsgListEntry,
				      &msgHeader->SubMsgList);
			pfnSum += pfnCurr;
			pfnLeft -= pfnCurr;
		}
	} else {
		/* everything fits in a header */
		msgSize = sizeof(struct vmbus_channel_msginfo) +
			  sizeof(struct vmbus_channel_gpadl_header) +
			  sizeof(struct gpa_range) + pageCount * sizeof(u64);
		msgHeader = kzalloc(msgSize, GFP_KERNEL);
		msgHeader->MessageSize = msgSize;

		gpaHeader = (struct vmbus_channel_gpadl_header *)msgHeader->Msg;
		gpaHeader->RangeCount = 1;
		gpaHeader->RangeBufLen = sizeof(struct gpa_range) +
					 pageCount * sizeof(u64);
		gpaHeader->Range[0].ByteOffset = 0;
		gpaHeader->Range[0].ByteCount = Size;
		for (i = 0; i < pageCount; i++)
			gpaHeader->Range[0].PfnArray[i] = pfn+i;

		*MsgInfo = msgHeader;
		*MessageCount = 1;
	}

	return 0;
nomem:
	kfree(msgHeader);
	kfree(msgBody);
	return -ENOMEM;
}

/*
 * VmbusChannelEstablishGpadl - Estabish a GPADL for the specified buffer
 *
 * @Channel: a channel
 * @Kbuffer: from kmalloc
 * @Size: page-size multiple
 * @GpadlHandle: some funky thing
 */
int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel, void *Kbuffer,
			       u32 Size, u32 *GpadlHandle)
{
	struct vmbus_channel_gpadl_header *gpadlMsg;
	struct vmbus_channel_gpadl_body *gpadlBody;
	/* struct vmbus_channel_gpadl_created *gpadlCreated; */
	struct vmbus_channel_msginfo *msgInfo = NULL;
	struct vmbus_channel_msginfo *subMsgInfo;
	u32 msgCount;
	struct list_head *curr;
	u32 nextGpadlHandle;
	unsigned long flags;
	int ret = 0;

	DPRINT_ENTER(VMBUS);

	nextGpadlHandle = atomic_read(&gVmbusConnection.NextGpadlHandle);
	atomic_inc(&gVmbusConnection.NextGpadlHandle);

	ret = VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount);
	if (ret)
		return ret;

	msgInfo->WaitEvent = osd_WaitEventCreate();
	if (!msgInfo->WaitEvent) {
		ret = -ENOMEM;
		goto Cleanup;
	}

	gpadlMsg = (struct vmbus_channel_gpadl_header *)msgInfo->Msg;
	gpadlMsg->Header.MessageType = ChannelMessageGpadlHeader;
	gpadlMsg->ChildRelId = Channel->OfferMsg.ChildRelId;
	gpadlMsg->Gpadl = nextGpadlHandle;

	DumpGpadlHeader(gpadlMsg);

	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_add_tail(&msgInfo->MsgListEntry,
		      &gVmbusConnection.ChannelMsgList);

	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
	DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d",
		   Kbuffer, Size, msgCount);

	DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd",
		   msgInfo->MessageSize - sizeof(*msgInfo));

	ret = VmbusPostMessage(gpadlMsg, msgInfo->MessageSize -
			       sizeof(*msgInfo));
	if (ret != 0) {
		DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret);
		goto Cleanup;
	}

	if (msgCount > 1) {
		list_for_each(curr, &msgInfo->SubMsgList) {

			/* FIXME: should this use list_entry() instead ? */
			subMsgInfo = (struct vmbus_channel_msginfo *)curr;
			gpadlBody =
			     (struct vmbus_channel_gpadl_body *)subMsgInfo->Msg;

			gpadlBody->Header.MessageType = ChannelMessageGpadlBody;
			gpadlBody->Gpadl = nextGpadlHandle;

			DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd",
				   subMsgInfo->MessageSize -
				   sizeof(*subMsgInfo));

			DumpGpadlBody(gpadlBody, subMsgInfo->MessageSize -
				      sizeof(*subMsgInfo));
			ret = VmbusPostMessage(gpadlBody,
					       subMsgInfo->MessageSize -
					       sizeof(*subMsgInfo));
			if (ret != 0)
				goto Cleanup;

		}
	}
	osd_WaitEventWait(msgInfo->WaitEvent);

	/* At this point, we received the gpadl created msg */
	DPRINT_DBG(VMBUS, "Received GPADL created "
		   "(relid %d, status %d handle %x)",
		   Channel->OfferMsg.ChildRelId,
		   msgInfo->Response.GpadlCreated.CreationStatus,
		   gpadlMsg->Gpadl);

	*GpadlHandle = gpadlMsg->Gpadl;

Cleanup:
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_del(&msgInfo->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	kfree(msgInfo->WaitEvent);
	kfree(msgInfo);

	DPRINT_EXIT(VMBUS);

	return ret;
}

/*
 * VmbusChannelTeardownGpadl -Teardown the specified GPADL handle
 */
int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle)
{
	struct vmbus_channel_gpadl_teardown *msg;
	struct vmbus_channel_msginfo *info;
	unsigned long flags;
	int ret;

	DPRINT_ENTER(VMBUS);

	/* ASSERT(GpadlHandle != 0); */

	info = kmalloc(sizeof(*info) +
		       sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->WaitEvent = osd_WaitEventCreate();
	if (!info->WaitEvent) {
		kfree(info);
		return -ENOMEM;
	}

	msg = (struct vmbus_channel_gpadl_teardown *)info->Msg;

	msg->Header.MessageType = ChannelMessageGpadlTeardown;
	msg->ChildRelId = Channel->OfferMsg.ChildRelId;
	msg->Gpadl = GpadlHandle;

	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_add_tail(&info->MsgListEntry,
		      &gVmbusConnection.ChannelMsgList);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	ret = VmbusPostMessage(msg,
			       sizeof(struct vmbus_channel_gpadl_teardown));
	if (ret != 0) {
		/* TODO: */
		/* something... */
	}

	osd_WaitEventWait(info->WaitEvent);

	/* Received a torndown response */
	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	list_del(&info->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

	kfree(info->WaitEvent);
	kfree(info);

	DPRINT_EXIT(VMBUS);

	return ret;
}

/*
 * VmbusChannelClose - Close the specified channel
 */
void VmbusChannelClose(struct vmbus_channel *Channel)
{
	struct vmbus_channel_close_channel *msg;
	struct vmbus_channel_msginfo *info;
	unsigned long flags;
	int ret;

	DPRINT_ENTER(VMBUS);

	/* Stop callback and cancel the timer asap */
	Channel->OnChannelCallback = NULL;
	del_timer_sync(&Channel->poll_timer);

	/* Send a closing message */
	info = kmalloc(sizeof(*info) +
		       sizeof(struct vmbus_channel_close_channel), GFP_KERNEL);
        /* FIXME: can't do anything other than return here because the
	 *        function is void */
	if (!info)
		return;

	/* info->waitEvent = osd_WaitEventCreate(); */

	msg = (struct vmbus_channel_close_channel *)info->Msg;
	msg->Header.MessageType = ChannelMessageCloseChannel;
	msg->ChildRelId = Channel->OfferMsg.ChildRelId;

	ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel));
	if (ret != 0) {
		/* TODO: */
		/* something... */
	}

	/* Tear down the gpadl for the channel's ring buffer */
	if (Channel->RingBufferGpadlHandle)
		VmbusChannelTeardownGpadl(Channel,
					  Channel->RingBufferGpadlHandle);

	/* TODO: Send a msg to release the childRelId */

	/* Cleanup the ring buffers for this channel */
	RingBufferCleanup(&Channel->Outbound);
	RingBufferCleanup(&Channel->Inbound);

	osd_PageFree(Channel->RingBufferPages, Channel->RingBufferPageCount);

	kfree(info);

	/*
	 * If we are closing the channel during an error path in
	 * opening the channel, don't free the channel since the
	 * caller will free the channel
	 */

	if (Channel->State == CHANNEL_OPEN_STATE) {
		spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
		list_del(&Channel->ListEntry);
		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);

		FreeVmbusChannel(Channel);
	}

	DPRINT_EXIT(VMBUS);
}

/**
 * VmbusChannelSendPacket() - Send the specified buffer on the given channel
 * @Channel: Pointer to vmbus_channel structure.
 * @Buffer: Pointer to the buffer you want to receive the data into.
 * @BufferLen: Maximum size of what the the buffer will hold
 * @RequestId: Identifier of the request
 * @vmbus_packet_type: Type of packet that is being send e.g. negotiate, time
 * packet etc.
 *
 * Sends data in @Buffer directly to hyper-v via the vmbus
 * This will send the data unparsed to hyper-v.
 *
 * Mainly used by Hyper-V drivers.
 */
int VmbusChannelSendPacket(struct vmbus_channel *Channel, const void *Buffer,
			   u32 BufferLen, u64 RequestId,
			   enum vmbus_packet_type Type, u32 Flags)
{
	struct vmpacket_descriptor desc;
	u32 packetLen = sizeof(struct vmpacket_descriptor) + BufferLen;
	u32 packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
	struct scatterlist bufferList[3];
	u64 alignedData = 0;
	int ret;

	DPRINT_ENTER(VMBUS);
	DPRINT_DBG(VMBUS, "channel %p buffer %p len %d",
		   Channel, Buffer, BufferLen);

	DumpVmbusChannel(Channel);

	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */

	/* Setup the descriptor */
	desc.Type = Type; /* VmbusPacketTypeDataInBand; */
	desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
	/* in 8-bytes granularity */
	desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3;
	desc.Length8 = (u16)(packetLenAligned >> 3);
	desc.TransactionId = RequestId;

	sg_init_table(bufferList, 3);
	sg_set_buf(&bufferList[0], &desc, sizeof(struct vmpacket_descriptor));
	sg_set_buf(&bufferList[1], Buffer, BufferLen);
	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);

	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);

	/* TODO: We should determine if this is optional */
	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
		VmbusChannelSetEvent(Channel);

	DPRINT_EXIT(VMBUS);

	return ret;
}
EXPORT_SYMBOL(VmbusChannelSendPacket);

/*
 * VmbusChannelSendPacketPageBuffer - Send a range of single-page buffer
 * packets using a GPADL Direct packet type.
 */
int VmbusChannelSendPacketPageBuffer(struct vmbus_channel *Channel,
				     struct hv_page_buffer PageBuffers[],
				     u32 PageCount, void *Buffer, u32 BufferLen,
				     u64 RequestId)
{
	int ret;
	int i;
	struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc;
	u32 descSize;
	u32 packetLen;
	u32 packetLenAligned;
	struct scatterlist bufferList[3];
	u64 alignedData = 0;

	DPRINT_ENTER(VMBUS);

	if (PageCount > MAX_PAGE_BUFFER_COUNT)
		return -EINVAL;

	DumpVmbusChannel(Channel);

	/*
	 * Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the
	 * largest size we support
	 */
	descSize = sizeof(struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER) -
			  ((MAX_PAGE_BUFFER_COUNT - PageCount) *
			  sizeof(struct hv_page_buffer));
	packetLen = descSize + BufferLen;
	packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));

	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */

	/* Setup the descriptor */
	desc.Type = VmbusPacketTypeDataUsingGpaDirect;
	desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
	desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
	desc.Length8 = (u16)(packetLenAligned >> 3);
	desc.TransactionId = RequestId;
	desc.RangeCount = PageCount;

	for (i = 0; i < PageCount; i++) {
		desc.Range[i].Length = PageBuffers[i].Length;
		desc.Range[i].Offset = PageBuffers[i].Offset;
		desc.Range[i].Pfn	 = PageBuffers[i].Pfn;
	}

	sg_init_table(bufferList, 3);
	sg_set_buf(&bufferList[0], &desc, descSize);
	sg_set_buf(&bufferList[1], Buffer, BufferLen);
	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);

	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);

	/* TODO: We should determine if this is optional */
	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
		VmbusChannelSetEvent(Channel);

	DPRINT_EXIT(VMBUS);

	return ret;
}

/*
 * VmbusChannelSendPacketMultiPageBuffer - Send a multi-page buffer packet
 * using a GPADL Direct packet type.
 */
int VmbusChannelSendPacketMultiPageBuffer(struct vmbus_channel *Channel,
				struct hv_multipage_buffer *MultiPageBuffer,
				void *Buffer, u32 BufferLen, u64 RequestId)
{
	int ret;
	struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER desc;
	u32 descSize;
	u32 packetLen;
	u32 packetLenAligned;
	struct scatterlist bufferList[3];
	u64 alignedData = 0;
	u32 PfnCount = NUM_PAGES_SPANNED(MultiPageBuffer->Offset,
					 MultiPageBuffer->Length);

	DPRINT_ENTER(VMBUS);

	DumpVmbusChannel(Channel);

	DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u",
		   MultiPageBuffer->Offset, MultiPageBuffer->Length, PfnCount);

	if ((PfnCount < 0) || (PfnCount > MAX_MULTIPAGE_BUFFER_COUNT))
		return -EINVAL;

	/*
	 * Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is
	 * the largest size we support
	 */
	descSize = sizeof(struct VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER) -
			  ((MAX_MULTIPAGE_BUFFER_COUNT - PfnCount) *
			  sizeof(u64));
	packetLen = descSize + BufferLen;
	packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));

	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */

	/* Setup the descriptor */
	desc.Type = VmbusPacketTypeDataUsingGpaDirect;
	desc.Flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
	desc.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
	desc.Length8 = (u16)(packetLenAligned >> 3);
	desc.TransactionId = RequestId;
	desc.RangeCount = 1;

	desc.Range.Length = MultiPageBuffer->Length;
	desc.Range.Offset = MultiPageBuffer->Offset;

	memcpy(desc.Range.PfnArray, MultiPageBuffer->PfnArray,
	       PfnCount * sizeof(u64));

	sg_init_table(bufferList, 3);
	sg_set_buf(&bufferList[0], &desc, descSize);
	sg_set_buf(&bufferList[1], Buffer, BufferLen);
	sg_set_buf(&bufferList[2], &alignedData, packetLenAligned - packetLen);

	ret = RingBufferWrite(&Channel->Outbound, bufferList, 3);

	/* TODO: We should determine if this is optional */
	if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
		VmbusChannelSetEvent(Channel);

	DPRINT_EXIT(VMBUS);

	return ret;
}


/**
 * VmbusChannelRecvPacket() - Retrieve the user packet on the specified channel
 * @Channel: Pointer to vmbus_channel structure.
 * @Buffer: Pointer to the buffer you want to receive the data into.
 * @BufferLen: Maximum size of what the the buffer will hold
 * @BufferActualLen: The actual size of the data after it was received
 * @RequestId: Identifier of the request
 *
 * Receives directly from the hyper-v vmbus and puts the data it received
 * into Buffer. This will receive the data unparsed from hyper-v.
 *
 * Mainly used by Hyper-V drivers.
 */
int VmbusChannelRecvPacket(struct vmbus_channel *Channel, void *Buffer,
			   u32 BufferLen, u32 *BufferActualLen, u64 *RequestId)
{
	struct vmpacket_descriptor desc;
	u32 packetLen;
	u32 userLen;
	int ret;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	*BufferActualLen = 0;
	*RequestId = 0;

	spin_lock_irqsave(&Channel->inbound_lock, flags);

	ret = RingBufferPeek(&Channel->Inbound, &desc,
			     sizeof(struct vmpacket_descriptor));
	if (ret != 0) {
		spin_unlock_irqrestore(&Channel->inbound_lock, flags);

		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
		DPRINT_EXIT(VMBUS);
		return 0;
	}

	/* VmbusChannelClearEvent(Channel); */

	packetLen = desc.Length8 << 3;
	userLen = packetLen - (desc.DataOffset8 << 3);
	/* ASSERT(userLen > 0); */

	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
		   "flag %d tid %llx pktlen %d datalen %d> ",
		   Channel, Channel->OfferMsg.ChildRelId, desc.Type,
		   desc.Flags, desc.TransactionId, packetLen, userLen);

	*BufferActualLen = userLen;

	if (userLen > BufferLen) {
		spin_unlock_irqrestore(&Channel->inbound_lock, flags);

		DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d",
			   BufferLen, userLen);
		DPRINT_EXIT(VMBUS);

		return -1;
	}

	*RequestId = desc.TransactionId;

	/* Copy over the packet to the user buffer */
	ret = RingBufferRead(&Channel->Inbound, Buffer, userLen,
			     (desc.DataOffset8 << 3));

	spin_unlock_irqrestore(&Channel->inbound_lock, flags);

	DPRINT_EXIT(VMBUS);

	return 0;
}
EXPORT_SYMBOL(VmbusChannelRecvPacket);

/*
 * VmbusChannelRecvPacketRaw - Retrieve the raw packet on the specified channel
 */
int VmbusChannelRecvPacketRaw(struct vmbus_channel *Channel, void *Buffer,
			      u32 BufferLen, u32 *BufferActualLen,
			      u64 *RequestId)
{
	struct vmpacket_descriptor desc;
	u32 packetLen;
	u32 userLen;
	int ret;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	*BufferActualLen = 0;
	*RequestId = 0;

	spin_lock_irqsave(&Channel->inbound_lock, flags);

	ret = RingBufferPeek(&Channel->Inbound, &desc,
			     sizeof(struct vmpacket_descriptor));
	if (ret != 0) {
		spin_unlock_irqrestore(&Channel->inbound_lock, flags);

		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
		DPRINT_EXIT(VMBUS);
		return 0;
	}

	/* VmbusChannelClearEvent(Channel); */

	packetLen = desc.Length8 << 3;
	userLen = packetLen - (desc.DataOffset8 << 3);

	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
		   "flag %d tid %llx pktlen %d datalen %d> ",
		   Channel, Channel->OfferMsg.ChildRelId, desc.Type,
		   desc.Flags, desc.TransactionId, packetLen, userLen);

	*BufferActualLen = packetLen;

	if (packetLen > BufferLen) {
		spin_unlock_irqrestore(&Channel->inbound_lock, flags);

		DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but "
			   "got space for only %d bytes", packetLen, BufferLen);
		DPRINT_EXIT(VMBUS);
		return -2;
	}

	*RequestId = desc.TransactionId;

	/* Copy over the entire packet to the user buffer */
	ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0);

	spin_unlock_irqrestore(&Channel->inbound_lock, flags);

	DPRINT_EXIT(VMBUS);

	return 0;
}

/*
 * VmbusChannelOnChannelEvent - Channel event callback
 */
void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel)
{
	DumpVmbusChannel(Channel);
	/* ASSERT(Channel->OnChannelCallback); */

	Channel->OnChannelCallback(Channel->ChannelCallbackContext);

	mod_timer(&Channel->poll_timer, jiffies + usecs_to_jiffies(100));
}

/*
 * VmbusChannelOnTimer - Timer event callback
 */
void VmbusChannelOnTimer(unsigned long data)
{
	struct vmbus_channel *channel = (struct vmbus_channel *)data;

	if (channel->OnChannelCallback)
		channel->OnChannelCallback(channel->ChannelCallbackContext);
}

/*
 * DumpVmbusChannel - Dump vmbus channel info to the console
 */
static void DumpVmbusChannel(struct vmbus_channel *Channel)
{
	DPRINT_DBG(VMBUS, "Channel (%d)", Channel->OfferMsg.ChildRelId);
	DumpRingInfo(&Channel->Outbound, "Outbound ");
	DumpRingInfo(&Channel->Inbound, "Inbound ");
}
