/*
 *
 * 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 "osd.h"
#include "logging.h"
#include "VmbusPrivate.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

/*++

Name:
	VmbusChannelSetEvent()

Description:
	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 = (struct hv_monitor_page *)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
/*++;

Name:
	VmbusChannelGetDebugInfo()

Description:
	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);
}


/*++;

Name:
	VmbusChannelOpen()

Description:
	Open the specified channel.

--*/
int VmbusChannelOpen(struct vmbus_channel *NewChannel,
	u32					SendRingBufferSize,
	u32					RecvRingBufferSize,
	void *					UserData,
	u32					UserDataLen,
	PFN_CHANNEL_CALLBACK	pfnOnChannelCallback,
	void *					Context
	)
{
	int ret=0;
	struct vmbus_channel_open_channel *openMsg;
	struct vmbus_channel_msginfo *openInfo;
	void *in, *out;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

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

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

	/* Allocate the ring buffer */
	out = osd_PageAlloc((SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT);
	/* out = kzalloc(sendRingBufferSize + recvRingBufferSize, GFP_KERNEL); */
	ASSERT(out);
	ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0);

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

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

	RingBufferInit(&NewChannel->Outbound, out, SendRingBufferSize);

	RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize);

	/* 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);

	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);
	ASSERT(openInfo != NULL);

	openInfo->WaitEvent = osd_WaitEventCreate();

	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;
    ASSERT(openMsg->RingBufferGpadlHandle);
    openMsg->DownstreamRingBufferPageOffset		= SendRingBufferSize >> PAGE_SHIFT;
    openMsg->ServerContextAreaGpadlHandle	= 0; /* TODO */

	ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES);
	if (UserDataLen)
	{
		memcpy(openMsg->UserData, UserData, UserDataLen);
	}

	spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
	INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &openInfo->MsgListEntry);
	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);
	REMOVE_ENTRY_LIST(&openInfo->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

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

	DPRINT_EXIT(VMBUS);

	return 0;
}

/*++;

Name:
	DumpGpadlBody()

Description:
	Dump the gpadl body message to the console for debugging purposes.

--*/
static void DumpGpadlBody(struct vmbus_channel_gpadl_body *Gpadl, u32 Len)
{
	int i=0;
	int pfnCount=0;

	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]);
	}
}


/*++;

Name:
	DumpGpadlHeader()

Description:
	Dump the gpadl header message to the console for debugging purposes.

--*/
static void DumpGpadlHeader(struct vmbus_channel_gpadl_header *Gpadl)
{
	int i=0,j=0;
	int pageCount=0;


	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]);
		}
	}
}

/*++;

Name:
	VmbusChannelCreateGpadlHeader()

Description:
	Creates a gpadl for the specified buffer

--*/
static int
VmbusChannelCreateGpadlHeader(
	void *					Kbuffer,	/* from kmalloc() */
	u32					Size,		/* page-size multiple */
	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;
	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);

		INITIALIZE_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);
			ASSERT(msgBody);
			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 */
			INSERT_TAIL_LIST(&msgHeader->SubMsgList, &msgBody->MsgListEntry);
			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;
}


/*++;

Name:
	VmbusChannelEstablishGpadl()

Description:
	Estabish a GPADL for the specified buffer

--*/
int VmbusChannelEstablishGpadl(struct vmbus_channel *Channel,
	void *			Kbuffer,	/* from kmalloc() */
	u32			Size,		/* page-size multiple */
	u32			*GpadlHandle
	)
{
	int ret=0;
	struct vmbus_channel_gpadl_header *gpadlMsg;
	struct vmbus_channel_gpadl_body *gpadlBody;
	/* struct vmbus_channel_gpadl_created *gpadlCreated; */

	struct vmbus_channel_msginfo *msgInfo;
	struct vmbus_channel_msginfo *subMsgInfo;

	u32 msgCount;
	LIST_ENTRY* anchor;
	LIST_ENTRY* curr;
	u32 nextGpadlHandle;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

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

	VmbusChannelCreateGpadlHeader(Kbuffer, Size, &msgInfo, &msgCount);
	ASSERT(msgInfo != NULL);
	ASSERT(msgCount >0);

	msgInfo->WaitEvent = osd_WaitEventCreate();
	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);
	INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &msgInfo->MsgListEntry);
	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)
	{
		ITERATE_LIST_ENTRIES(anchor, curr, &msgInfo->SubMsgList)
		{
			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));
			ASSERT(ret == 0);
		}
	}
	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);
	REMOVE_ENTRY_LIST(&msgInfo->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

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

	DPRINT_EXIT(VMBUS);

	return ret;
}



/*++;

Name:
	VmbusChannelTeardownGpadl()

Description:
	Teardown the specified GPADL handle

--*/
int VmbusChannelTeardownGpadl(struct vmbus_channel *Channel, u32 GpadlHandle)
{
	int ret=0;
	struct vmbus_channel_gpadl_teardown *msg;
	struct vmbus_channel_msginfo *info;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

	ASSERT(GpadlHandle != 0);

	info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL);
	ASSERT(info != NULL);

	info->WaitEvent = osd_WaitEventCreate();

	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);
	INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &info->MsgListEntry);
	spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);

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

	osd_WaitEventWait(info->WaitEvent);

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

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

	DPRINT_EXIT(VMBUS);

	return ret;
}


/*++

Name:
	VmbusChannelClose()

Description:
	Close the specified channel

--*/
void VmbusChannelClose(struct vmbus_channel *Channel)
{
	int ret=0;
	struct vmbus_channel_close_channel *msg;
	struct vmbus_channel_msginfo *info;
	unsigned long flags;

	DPRINT_ENTER(VMBUS);

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

	/* Send a closing message */
	info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_close_channel), GFP_KERNEL);
	ASSERT(info != NULL);

	/* 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: */
	}

	/* 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);
		REMOVE_ENTRY_LIST(&Channel->ListEntry);
		spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);

		FreeVmbusChannel(Channel);
	}

	DPRINT_EXIT(VMBUS);
}


/*++

Name:
	VmbusChannelSendPacket()

Description:
	Send the specified buffer on the given channel

--*/
int VmbusChannelSendPacket(struct vmbus_channel *Channel,
	const void *			Buffer,
	u32				BufferLen,
	u64				RequestId,
	enum vmbus_packet_type Type,
	u32				Flags
)
{
	int ret=0;
	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;

	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; */
	desc.DataOffset8 = sizeof(struct vmpacket_descriptor) >> 3; /* in 8-bytes granularity */
	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;
}


/*++

Name:
	VmbusChannelSendPacketPageBuffer()

Description:
	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=0;
	int i=0;
	struct VMBUS_CHANNEL_PACKET_PAGE_BUFFER desc;
	u32 descSize;
	u32 packetLen;
	u32 packetLenAligned;
	struct scatterlist bufferList[3];
	u64 alignedData=0;

	DPRINT_ENTER(VMBUS);

	ASSERT(PageCount <= MAX_PAGE_BUFFER_COUNT);

	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;
}



/*++

Name:
	VmbusChannelSendPacketMultiPageBuffer()

Description:
	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=0;
	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);

	ASSERT(PfnCount > 0);
	ASSERT(PfnCount <= MAX_MULTIPAGE_BUFFER_COUNT);

	/* 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;
}


/*++

Name:
	VmbusChannelRecvPacket()

Description:
	Retrieve the user packet on the specified channel

--*/
/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */
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;
}

/*++

Name:
	VmbusChannelRecvPacketRaw()

Description:
	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;
}


/*++

Name:
	VmbusChannelOnChannelEvent()

Description:
	Channel event callback

--*/
void VmbusChannelOnChannelEvent(struct vmbus_channel *Channel)
{
	DumpVmbusChannel(Channel);
	ASSERT(Channel->OnChannelCallback);
#ifdef ENABLE_POLLING
	del_timer(&Channel->poll_timer);
	Channel->OnChannelCallback(Channel->ChannelCallbackContext);
	channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
	add_timer(&channel->poll_timer);
#else
	Channel->OnChannelCallback(Channel->ChannelCallbackContext);
#endif
}

/*++

Name:
	VmbusChannelOnTimer()

Description:
	Timer event callback

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

	if (channel->OnChannelCallback)
	{
		channel->OnChannelCallback(channel->ChannelCallbackContext);
#ifdef ENABLE_POLLING
		channel->poll_timer.expires(jiffies + usecs_to_jiffies(100);
		add_timer(&channel->poll_timer);
#endif
	}
}


/*++

Name:
	DumpVmbusChannel()

Description:
	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 ");
}


/* eof */
