Staging: hv: Remove C99 comments
Remove C99 // comments with traditional /* */ comments Signed-off-by: Bill Pemberton <wfp5p@virginia.edu> Cc: Hank Janssen <hjanssen@microsoft.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
226408a499
commit
454f18a963
|
@ -26,12 +26,12 @@
|
|||
|
||||
static const char* gBlkDriverName="blkvsc";
|
||||
|
||||
//{32412632-86cb-44a2-9b5c-50d1417354f5}
|
||||
/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
|
||||
static const GUID gBlkVscDeviceType={
|
||||
.Data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}
|
||||
};
|
||||
|
||||
// Static routines
|
||||
/* Static routines */
|
||||
static int
|
||||
BlkVscOnDeviceAdd(
|
||||
DEVICE_OBJECT *Device,
|
||||
|
@ -49,21 +49,21 @@ BlkVscInitialize(
|
|||
|
||||
DPRINT_ENTER(BLKVSC);
|
||||
|
||||
// Make sure we are at least 2 pages since 1 page is used for control
|
||||
/* Make sure we are at least 2 pages since 1 page is used for control */
|
||||
ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1));
|
||||
|
||||
Driver->name = gBlkDriverName;
|
||||
memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(GUID));
|
||||
|
||||
storDriver->RequestExtSize = sizeof(STORVSC_REQUEST_EXTENSION);
|
||||
// Divide the ring buffer data size (which is 1 page less than the ring buffer size since that page is reserved for the ring buffer indices)
|
||||
// by the max request size (which is VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + VSTOR_PACKET + u64)
|
||||
/* Divide the ring buffer data size (which is 1 page less than the ring buffer size since that page is reserved for the ring buffer indices) */
|
||||
/* by the max request size (which is VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + VSTOR_PACKET + u64) */
|
||||
storDriver->MaxOutstandingRequestsPerChannel =
|
||||
((storDriver->RingBufferSize - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(VSTOR_PACKET) + sizeof(u64),sizeof(u64)));
|
||||
|
||||
DPRINT_INFO(BLKVSC, "max io outstd %u", storDriver->MaxOutstandingRequestsPerChannel);
|
||||
|
||||
// Setup the dispatch table
|
||||
/* Setup the dispatch table */
|
||||
storDriver->Base.OnDeviceAdd = BlkVscOnDeviceAdd;
|
||||
storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove;
|
||||
storDriver->Base.OnCleanup = StorVscOnCleanup;
|
||||
|
@ -95,8 +95,8 @@ BlkVscOnDeviceAdd(
|
|||
return ret;
|
||||
}
|
||||
|
||||
// We need to use the device instance guid to set the path and target id. For IDE devices, the
|
||||
// device instance id is formatted as <bus id> - <device id> - 8899 - 000000000000.
|
||||
/* We need to use the device instance guid to set the path and target id. For IDE devices, the */
|
||||
/* device instance id is formatted as <bus id> - <device id> - 8899 - 000000000000. */
|
||||
deviceInfo->PathId = Device->deviceInstance.Data[3] << 24 | Device->deviceInstance.Data[2] << 16 |
|
||||
Device->deviceInstance.Data[1] << 8 |Device->deviceInstance.Data[0];
|
||||
|
||||
|
|
|
@ -27,13 +27,11 @@
|
|||
|
||||
#include "VmbusPrivate.h"
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
/* Internal routines */
|
||||
static int
|
||||
VmbusChannelCreateGpadlHeader(
|
||||
void * Kbuffer, // must be phys and virt contiguous
|
||||
u32 Size, // page-size multiple
|
||||
void * Kbuffer, /* must be phys and virt contiguous */
|
||||
u32 Size, /* page-size multiple */
|
||||
VMBUS_CHANNEL_MSGINFO **msgInfo,
|
||||
u32 *MessageCount
|
||||
);
|
||||
|
@ -105,11 +103,11 @@ VmbusChannelSetEvent(
|
|||
|
||||
if (Channel->OfferMsg.MonitorAllocated)
|
||||
{
|
||||
// Each u32 represents 32 channels
|
||||
/* Each u32 represents 32 channels */
|
||||
BitSet((u32*)gVmbusConnection.SendInterruptPage + (Channel->OfferMsg.ChildRelId >> 5), Channel->OfferMsg.ChildRelId & 31);
|
||||
|
||||
monitorPage = (HV_MONITOR_PAGE*)gVmbusConnection.MonitorPages;
|
||||
monitorPage++; // Get the child to parent monitor page
|
||||
monitorPage++; /* Get the child to parent monitor page */
|
||||
|
||||
BitSet((u32*) &monitorPage->TriggerGroup[Channel->MonitorGroup].Pending, Channel->MonitorBit);
|
||||
}
|
||||
|
@ -133,11 +131,11 @@ VmbusChannelClearEvent(
|
|||
|
||||
if (Channel->OfferMsg.MonitorAllocated)
|
||||
{
|
||||
// Each u32 represents 32 channels
|
||||
/* Each u32 represents 32 channels */
|
||||
BitClear((u32*)gVmbusConnection.SendInterruptPage + (Channel->OfferMsg.ChildRelId >> 5), Channel->OfferMsg.ChildRelId & 31);
|
||||
|
||||
monitorPage = (HV_MONITOR_PAGE*)gVmbusConnection.MonitorPages;
|
||||
monitorPage++; // Get the child to parent monitor page
|
||||
monitorPage++; /* Get the child to parent monitor page */
|
||||
|
||||
BitClear((u32*) &monitorPage->TriggerGroup[Channel->MonitorGroup].Pending, Channel->MonitorBit);
|
||||
}
|
||||
|
@ -164,7 +162,7 @@ VmbusChannelGetDebugInfo(
|
|||
HV_MONITOR_PAGE *monitorPage;
|
||||
u8 monitorGroup = (u8)Channel->OfferMsg.MonitorId / 32;
|
||||
u8 monitorOffset = (u8)Channel->OfferMsg.MonitorId % 32;
|
||||
//u32 monitorBit = 1 << monitorOffset;
|
||||
/* u32 monitorBit = 1 << monitorOffset; */
|
||||
|
||||
DebugInfo->RelId = Channel->OfferMsg.ChildRelId;
|
||||
DebugInfo->State = Channel->State;
|
||||
|
@ -218,16 +216,16 @@ VmbusChannelOpen(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Aligned to page size
|
||||
/* Aligned to page size */
|
||||
ASSERT(!(SendRingBufferSize & (PAGE_SIZE -1)));
|
||||
ASSERT(!(RecvRingBufferSize & (PAGE_SIZE -1)));
|
||||
|
||||
NewChannel->OnChannelCallback = pfnOnChannelCallback;
|
||||
NewChannel->ChannelCallbackContext = Context;
|
||||
|
||||
// Allocate the ring buffer
|
||||
/* Allocate the ring buffer */
|
||||
out = PageAlloc((SendRingBufferSize + RecvRingBufferSize) >> PAGE_SHIFT);
|
||||
//out = kzalloc(sendRingBufferSize + recvRingBufferSize, GFP_KERNEL);
|
||||
/* out = kzalloc(sendRingBufferSize + recvRingBufferSize, GFP_KERNEL); */
|
||||
ASSERT(out);
|
||||
ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0);
|
||||
|
||||
|
@ -240,7 +238,7 @@ VmbusChannelOpen(
|
|||
|
||||
RingBufferInit(&NewChannel->Inbound, in, RecvRingBufferSize);
|
||||
|
||||
// Establish the gpadl for the ring buffer
|
||||
/* Establish the gpadl for the ring buffer */
|
||||
DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", NewChannel);
|
||||
|
||||
NewChannel->RingBufferGpadlHandle = 0;
|
||||
|
@ -260,7 +258,7 @@ VmbusChannelOpen(
|
|||
NewChannel->Inbound.RingSize,
|
||||
SendRingBufferSize);
|
||||
|
||||
// Create and init the channel open message
|
||||
/* Create and init the channel open message */
|
||||
openInfo = kmalloc(sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_OPEN_CHANNEL), GFP_KERNEL);
|
||||
ASSERT(openInfo != NULL);
|
||||
|
||||
|
@ -268,12 +266,12 @@ VmbusChannelOpen(
|
|||
|
||||
openMsg = (VMBUS_CHANNEL_OPEN_CHANNEL*)openInfo->Msg;
|
||||
openMsg->Header.MessageType = ChannelMessageOpenChannel;
|
||||
openMsg->OpenId = NewChannel->OfferMsg.ChildRelId; // FIXME
|
||||
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
|
||||
openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */
|
||||
|
||||
ASSERT(UserDataLen <= MAX_USER_DEFINED_BYTES);
|
||||
if (UserDataLen)
|
||||
|
@ -294,7 +292,7 @@ VmbusChannelOpen(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// FIXME: Need to time-out here
|
||||
/* FIXME: Need to time-out here */
|
||||
WaitEventWait(openInfo->WaitEvent);
|
||||
|
||||
if (openInfo->Response.OpenResult.Status == 0)
|
||||
|
@ -392,8 +390,8 @@ Description:
|
|||
--*/
|
||||
static int
|
||||
VmbusChannelCreateGpadlHeader(
|
||||
void * Kbuffer, // from kmalloc()
|
||||
u32 Size, // page-size multiple
|
||||
void * Kbuffer, /* from kmalloc() */
|
||||
u32 Size, /* page-size multiple */
|
||||
VMBUS_CHANNEL_MSGINFO **MsgInfo,
|
||||
u32 *MessageCount)
|
||||
{
|
||||
|
@ -408,19 +406,19 @@ VmbusChannelCreateGpadlHeader(
|
|||
|
||||
int pfnSum, pfnCount, pfnLeft, pfnCurr, pfnSize;
|
||||
|
||||
//ASSERT( (kbuffer & (PAGE_SIZE-1)) == 0);
|
||||
/* ASSERT( (kbuffer & (PAGE_SIZE-1)) == 0); */
|
||||
ASSERT( (Size & (PAGE_SIZE-1)) == 0);
|
||||
|
||||
pageCount = Size >> PAGE_SHIFT;
|
||||
pfn = GetPhysicalAddress(Kbuffer) >> PAGE_SHIFT;
|
||||
|
||||
// do we need a gpadl body msg
|
||||
/* do we need a gpadl body msg */
|
||||
pfnSize = MAX_SIZE_CHANNEL_MESSAGE - sizeof(VMBUS_CHANNEL_GPADL_HEADER) - sizeof(GPA_RANGE);
|
||||
pfnCount = pfnSize / sizeof(u64);
|
||||
|
||||
if (pageCount > pfnCount) // we need a gpadl body
|
||||
if (pageCount > pfnCount) /* we need a gpadl body */
|
||||
{
|
||||
// fill in the header
|
||||
/* fill in the header */
|
||||
msgSize = sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_HEADER) + sizeof(GPA_RANGE) + pfnCount*sizeof(u64);
|
||||
msgHeader = kzalloc(msgSize, GFP_KERNEL);
|
||||
|
||||
|
@ -442,11 +440,11 @@ VmbusChannelCreateGpadlHeader(
|
|||
pfnSum = pfnCount;
|
||||
pfnLeft = pageCount - pfnCount;
|
||||
|
||||
// how many pfns can we fit
|
||||
/* how many pfns can we fit */
|
||||
pfnSize = MAX_SIZE_CHANNEL_MESSAGE - sizeof(VMBUS_CHANNEL_GPADL_BODY);
|
||||
pfnCount = pfnSize / sizeof(u64);
|
||||
|
||||
// fill in the body
|
||||
/* fill in the body */
|
||||
while (pfnLeft)
|
||||
{
|
||||
if (pfnLeft > pfnCount)
|
||||
|
@ -465,14 +463,14 @@ VmbusChannelCreateGpadlHeader(
|
|||
(*MessageCount)++;
|
||||
gpadlBody = (VMBUS_CHANNEL_GPADL_BODY*)msgBody->Msg;
|
||||
|
||||
// FIXME: Gpadl is u32 and we are using a pointer which could be 64-bit
|
||||
//gpadlBody->Gpadl = kbuffer;
|
||||
/* 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
|
||||
/* add to msg header */
|
||||
INSERT_TAIL_LIST(&msgHeader->SubMsgList, &msgBody->MsgListEntry);
|
||||
pfnSum += pfnCurr;
|
||||
pfnLeft -= pfnCurr;
|
||||
|
@ -480,7 +478,7 @@ VmbusChannelCreateGpadlHeader(
|
|||
}
|
||||
else
|
||||
{
|
||||
// everything fits in a header
|
||||
/* everything fits in a header */
|
||||
msgSize = sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_GPADL_HEADER) + sizeof(GPA_RANGE) + pageCount*sizeof(u64);
|
||||
msgHeader = kzalloc(msgSize, GFP_KERNEL);
|
||||
msgHeader->MessageSize=msgSize;
|
||||
|
@ -515,15 +513,15 @@ Description:
|
|||
int
|
||||
VmbusChannelEstablishGpadl(
|
||||
VMBUS_CHANNEL *Channel,
|
||||
void * Kbuffer, // from kmalloc()
|
||||
u32 Size, // page-size multiple
|
||||
void * Kbuffer, /* from kmalloc() */
|
||||
u32 Size, /* page-size multiple */
|
||||
u32 *GpadlHandle
|
||||
)
|
||||
{
|
||||
int ret=0;
|
||||
VMBUS_CHANNEL_GPADL_HEADER* gpadlMsg;
|
||||
VMBUS_CHANNEL_GPADL_BODY* gpadlBody;
|
||||
//VMBUS_CHANNEL_GPADL_CREATED* gpadlCreated;
|
||||
/* VMBUS_CHANNEL_GPADL_CREATED* gpadlCreated; */
|
||||
|
||||
VMBUS_CHANNEL_MSGINFO *msgInfo;
|
||||
VMBUS_CHANNEL_MSGINFO *subMsgInfo;
|
||||
|
@ -585,7 +583,7 @@ VmbusChannelEstablishGpadl(
|
|||
}
|
||||
WaitEventWait(msgInfo->WaitEvent);
|
||||
|
||||
// At this point, we received the gpadl created msg
|
||||
/* 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,
|
||||
|
@ -650,12 +648,12 @@ VmbusChannelTeardownGpadl(
|
|||
ret = VmbusPostMessage(msg, sizeof(VMBUS_CHANNEL_GPADL_TEARDOWN));
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
}
|
||||
|
||||
WaitEventWait(info->WaitEvent);
|
||||
|
||||
// Received a torndown response
|
||||
/* Received a torndown response */
|
||||
spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
|
||||
REMOVE_ENTRY_LIST(&info->MsgListEntry);
|
||||
spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
|
||||
|
@ -690,15 +688,15 @@ VmbusChannelClose(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Stop callback and cancel the timer asap
|
||||
/* Stop callback and cancel the timer asap */
|
||||
Channel->OnChannelCallback = NULL;
|
||||
TimerStop(Channel->PollTimer);
|
||||
|
||||
// Send a closing message
|
||||
/* Send a closing message */
|
||||
info = kmalloc(sizeof(VMBUS_CHANNEL_MSGINFO) + sizeof(VMBUS_CHANNEL_CLOSE_CHANNEL), GFP_KERNEL);
|
||||
ASSERT(info != NULL);
|
||||
|
||||
//info->waitEvent = WaitEventCreate();
|
||||
/* info->waitEvent = WaitEventCreate(); */
|
||||
|
||||
msg = (VMBUS_CHANNEL_CLOSE_CHANNEL*)info->Msg;
|
||||
msg->Header.MessageType = ChannelMessageCloseChannel;
|
||||
|
@ -707,18 +705,18 @@ VmbusChannelClose(
|
|||
ret = VmbusPostMessage(msg, sizeof(VMBUS_CHANNEL_CLOSE_CHANNEL));
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
}
|
||||
|
||||
// Tear down the gpadl for the channel's ring buffer
|
||||
/* 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
|
||||
/* TODO: Send a msg to release the childRelId */
|
||||
|
||||
// Cleanup the ring buffers for this channel
|
||||
/* Cleanup the ring buffers for this channel */
|
||||
RingBufferCleanup(&Channel->Outbound);
|
||||
RingBufferCleanup(&Channel->Inbound);
|
||||
|
||||
|
@ -726,8 +724,13 @@ VmbusChannelClose(
|
|||
|
||||
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 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);
|
||||
|
@ -774,12 +777,12 @@ VmbusChannelSendPacket(
|
|||
|
||||
ASSERT((packetLenAligned - packetLen) < sizeof(u64));
|
||||
|
||||
// Setup the descriptor
|
||||
desc.Type = Type;//VmbusPacketTypeDataInBand;
|
||||
desc.Flags = Flags;//VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
|
||||
desc.DataOffset8 = sizeof(VMPACKET_DESCRIPTOR) >> 3; // in 8-bytes granularity
|
||||
desc.Length8 = (u16)(packetLenAligned >> 3);
|
||||
desc.TransactionId = RequestId;
|
||||
/* Setup the descriptor */
|
||||
desc.Type = Type; /* VmbusPacketTypeDataInBand; */
|
||||
desc.Flags = Flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
|
||||
desc.DataOffset8 = sizeof(VMPACKET_DESCRIPTOR) >> 3; /* in 8-bytes granularity */
|
||||
desc.Length8 = (u16)(packetLenAligned >> 3);
|
||||
desc.TransactionId = RequestId;
|
||||
|
||||
bufferList[0].Data = &desc;
|
||||
bufferList[0].Length = sizeof(VMPACKET_DESCRIPTOR);
|
||||
|
@ -795,7 +798,7 @@ VmbusChannelSendPacket(
|
|||
bufferList,
|
||||
3);
|
||||
|
||||
// TODO: We should determine if this is optional
|
||||
/* TODO: We should determine if this is optional */
|
||||
if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
|
||||
{
|
||||
VmbusChannelSetEvent(Channel);
|
||||
|
@ -841,19 +844,19 @@ VmbusChannelSendPacketPageBuffer(
|
|||
|
||||
DumpVmbusChannel(Channel);
|
||||
|
||||
// Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the largest size we support
|
||||
/* Adjust the size down since VMBUS_CHANNEL_PACKET_PAGE_BUFFER is the largest size we support */
|
||||
descSize = sizeof(VMBUS_CHANNEL_PACKET_PAGE_BUFFER) - ((MAX_PAGE_BUFFER_COUNT - PageCount)*sizeof(PAGE_BUFFER));
|
||||
packetLen = descSize + BufferLen;
|
||||
packetLenAligned = ALIGN_UP(packetLen, sizeof(u64));
|
||||
|
||||
ASSERT((packetLenAligned - packetLen) < sizeof(u64));
|
||||
|
||||
// Setup the descriptor
|
||||
/* 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.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
|
||||
desc.Length8 = (u16)(packetLenAligned >> 3);
|
||||
desc.TransactionId = RequestId;
|
||||
desc.RangeCount = PageCount;
|
||||
|
||||
for (i=0; i<PageCount; i++)
|
||||
|
@ -877,7 +880,7 @@ VmbusChannelSendPacketPageBuffer(
|
|||
bufferList,
|
||||
3);
|
||||
|
||||
// TODO: We should determine if this is optional
|
||||
/* TODO: We should determine if this is optional */
|
||||
if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
|
||||
{
|
||||
VmbusChannelSetEvent(Channel);
|
||||
|
@ -926,19 +929,19 @@ VmbusChannelSendPacketMultiPageBuffer(
|
|||
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
|
||||
/* Adjust the size down since VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER is the largest size we support */
|
||||
descSize = sizeof(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
|
||||
/* 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.DataOffset8 = descSize >> 3; /* in 8-bytes grandularity */
|
||||
desc.Length8 = (u16)(packetLenAligned >> 3);
|
||||
desc.TransactionId = RequestId;
|
||||
desc.RangeCount = 1;
|
||||
|
||||
desc.Range.Length = MultiPageBuffer->Length;
|
||||
|
@ -960,7 +963,7 @@ VmbusChannelSendPacketMultiPageBuffer(
|
|||
bufferList,
|
||||
3);
|
||||
|
||||
// TODO: We should determine if this is optional
|
||||
/* TODO: We should determine if this is optional */
|
||||
if (ret == 0 && !GetRingBufferInterruptMask(&Channel->Outbound))
|
||||
{
|
||||
VmbusChannelSetEvent(Channel);
|
||||
|
@ -981,7 +984,7 @@ Description:
|
|||
Retrieve the user packet on the specified channel
|
||||
|
||||
--*/
|
||||
// TODO: Do we ever receive a gpa direct packet other than the ones we send ?
|
||||
/* TODO: Do we ever receive a gpa direct packet other than the ones we send ? */
|
||||
int
|
||||
VmbusChannelRecvPacket(
|
||||
VMBUS_CHANNEL *Channel,
|
||||
|
@ -1009,16 +1012,16 @@ VmbusChannelRecvPacket(
|
|||
{
|
||||
spin_unlock_irqrestore(&Channel->inbound_lock, flags);
|
||||
|
||||
//DPRINT_DBG(VMBUS, "nothing to read!!");
|
||||
/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
|
||||
DPRINT_EXIT(VMBUS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//VmbusChannelClearEvent(Channel);
|
||||
/* VmbusChannelClearEvent(Channel); */
|
||||
|
||||
packetLen = desc.Length8 << 3;
|
||||
userLen = packetLen - (desc.DataOffset8 << 3);
|
||||
//ASSERT(userLen > 0);
|
||||
/* ASSERT(userLen > 0); */
|
||||
|
||||
DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d flag %d tid %llx pktlen %d datalen %d> ",
|
||||
Channel,
|
||||
|
@ -1041,7 +1044,7 @@ VmbusChannelRecvPacket(
|
|||
|
||||
*RequestId = desc.TransactionId;
|
||||
|
||||
// Copy over the packet to the user buffer
|
||||
/* Copy over the packet to the user buffer */
|
||||
ret = RingBufferRead(&Channel->Inbound, Buffer, userLen, (desc.DataOffset8 << 3));
|
||||
|
||||
spin_unlock_irqrestore(&Channel->inbound_lock, flags);
|
||||
|
@ -1087,12 +1090,12 @@ VmbusChannelRecvPacketRaw(
|
|||
{
|
||||
spin_unlock_irqrestore(&Channel->inbound_lock, flags);
|
||||
|
||||
//DPRINT_DBG(VMBUS, "nothing to read!!");
|
||||
/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
|
||||
DPRINT_EXIT(VMBUS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//VmbusChannelClearEvent(Channel);
|
||||
/* VmbusChannelClearEvent(Channel); */
|
||||
|
||||
packetLen = desc.Length8 << 3;
|
||||
userLen = packetLen - (desc.DataOffset8 << 3);
|
||||
|
@ -1117,7 +1120,7 @@ VmbusChannelRecvPacketRaw(
|
|||
|
||||
*RequestId = desc.TransactionId;
|
||||
|
||||
// Copy over the entire packet to the user buffer
|
||||
/* Copy over the entire packet to the user buffer */
|
||||
ret = RingBufferRead(&Channel->Inbound, Buffer, packetLen, 0);
|
||||
|
||||
spin_unlock_irqrestore(&Channel->inbound_lock, flags);
|
||||
|
@ -1199,4 +1202,4 @@ DumpVmbusChannel(
|
|||
}
|
||||
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#pragma pack(push,1)
|
||||
|
||||
|
||||
// The format must be the same as VMDATA_GPA_DIRECT
|
||||
/* The format must be the same as VMDATA_GPA_DIRECT */
|
||||
typedef struct _VMBUS_CHANNEL_PACKET_PAGE_BUFFER {
|
||||
u16 Type;
|
||||
u16 DataOffset8;
|
||||
|
@ -44,7 +44,7 @@ typedef struct _VMBUS_CHANNEL_PACKET_PAGE_BUFFER {
|
|||
} VMBUS_CHANNEL_PACKET_PAGE_BUFFER;
|
||||
|
||||
|
||||
// The format must be the same as VMDATA_GPA_DIRECT
|
||||
/* The format must be the same as VMDATA_GPA_DIRECT */
|
||||
typedef struct _VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER {
|
||||
u16 Type;
|
||||
u16 DataOffset8;
|
||||
|
@ -52,15 +52,15 @@ typedef struct _VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER {
|
|||
u16 Flags;
|
||||
u64 TransactionId;
|
||||
u32 Reserved;
|
||||
u32 RangeCount; // Always 1 in this case
|
||||
u32 RangeCount; /* Always 1 in this case */
|
||||
MULTIPAGE_BUFFER Range;
|
||||
} VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//
|
||||
// Routines
|
||||
//
|
||||
|
||||
/* Routines */
|
||||
|
||||
|
||||
static int
|
||||
VmbusChannelOpen(
|
||||
|
@ -110,8 +110,8 @@ VmbusChannelSendPacketMultiPageBuffer(
|
|||
static int
|
||||
VmbusChannelEstablishGpadl(
|
||||
VMBUS_CHANNEL *Channel,
|
||||
void * Kbuffer, // from kmalloc()
|
||||
u32 Size, // page-size multiple
|
||||
void * Kbuffer, /* from kmalloc() */
|
||||
u32 Size, /* page-size multiple */
|
||||
u32 *GpadlHandle
|
||||
);
|
||||
|
||||
|
@ -154,4 +154,4 @@ static void
|
|||
VmbusChannelOnTimer(
|
||||
void *Context
|
||||
);
|
||||
#endif //_CHANNEL_H_
|
||||
#endif /* _CHANNEL_H_ */
|
||||
|
|
|
@ -38,4 +38,4 @@ GetChannelInfo(
|
|||
DEVICE_INFO *DeviceInfo
|
||||
);
|
||||
|
||||
#endif // _CHANNEL_INTERFACE_H_
|
||||
#endif /* _CHANNEL_INTERFACE_H_ */
|
||||
|
|
|
@ -27,13 +27,7 @@
|
|||
|
||||
#include "VmbusPrivate.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
/* Data types */
|
||||
|
||||
typedef void (*PFN_CHANNEL_MESSAGE_HANDLER)(VMBUS_CHANNEL_MESSAGE_HEADER* msg);
|
||||
|
||||
|
@ -42,9 +36,7 @@ typedef struct _VMBUS_CHANNEL_MESSAGE_TABLE_ENTRY {
|
|||
PFN_CHANNEL_MESSAGE_HANDLER messageHandler;
|
||||
} VMBUS_CHANNEL_MESSAGE_TABLE_ENTRY;
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
/* Internal routines */
|
||||
|
||||
static void
|
||||
VmbusChannelOnOffer(
|
||||
|
@ -91,25 +83,23 @@ VmbusChannelProcessRescindOffer(
|
|||
);
|
||||
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
/* Globals */
|
||||
|
||||
#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 4
|
||||
|
||||
const GUID gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED]= {
|
||||
//{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
|
||||
{.Data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}},// Storage - SCSI
|
||||
//{F8615163-DF3E-46c5-913F-F2D2F965ED0E}
|
||||
{.Data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}}, // Network
|
||||
//{CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A}
|
||||
{.Data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}}, // Input
|
||||
//{32412632-86cb-44a2-9b5c-50d1417354f5}
|
||||
{.Data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}}, // IDE
|
||||
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
|
||||
{.Data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}},/* Storage - SCSI */
|
||||
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
|
||||
{.Data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}}, /* Network */
|
||||
/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */
|
||||
{.Data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A}}, /* Input */
|
||||
/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
|
||||
{.Data = {0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5}}, /* IDE */
|
||||
|
||||
};
|
||||
|
||||
// Channel message dispatch table
|
||||
/* Channel message dispatch table */
|
||||
VMBUS_CHANNEL_MESSAGE_TABLE_ENTRY gChannelMessageTable[ChannelMessageCount]= {
|
||||
{ChannelMessageInvalid, NULL},
|
||||
{ChannelMessageOfferChannel, VmbusChannelOnOffer},
|
||||
|
@ -158,7 +148,7 @@ VMBUS_CHANNEL* AllocVmbusChannel(void)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
//channel->dataWorkQueue = WorkQueueCreate("data");
|
||||
/* channel->dataWorkQueue = WorkQueueCreate("data"); */
|
||||
channel->ControlWQ = WorkQueueCreate("control");
|
||||
if (!channel->ControlWQ)
|
||||
{
|
||||
|
@ -207,8 +197,8 @@ void FreeVmbusChannel(VMBUS_CHANNEL* Channel)
|
|||
{
|
||||
TimerClose(Channel->PollTimer);
|
||||
|
||||
// We have to release the channel's workqueue/thread in the vmbus's workqueue/thread context
|
||||
// ie we can't destroy ourselves.
|
||||
/* We have to release the channel's workqueue/thread in the vmbus's workqueue/thread context */
|
||||
/* ie we can't destroy ourselves. */
|
||||
WorkQueueQueueWorkItem(gVmbusConnection.WorkQueue, ReleaseVmbusChannel, (void*)Channel);
|
||||
}
|
||||
|
||||
|
@ -237,7 +227,7 @@ VmbusChannelProcessOffer(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Make sure this is a new offer
|
||||
/* Make sure this is a new offer */
|
||||
spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
|
||||
|
||||
ITERATE_LIST_ENTRIES(anchor, curr, &gVmbusConnection.ChannelList)
|
||||
|
@ -266,8 +256,8 @@ VmbusChannelProcessOffer(
|
|||
return;
|
||||
}
|
||||
|
||||
// Start the process of binding this offer to the driver
|
||||
// We need to set the DeviceObject field before calling VmbusChildDeviceAdd()
|
||||
/* 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,
|
||||
|
@ -275,8 +265,12 @@ VmbusChannelProcessOffer(
|
|||
|
||||
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.
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
|
@ -291,8 +285,11 @@ VmbusChannelProcessOffer(
|
|||
}
|
||||
else
|
||||
{
|
||||
// This state is used to indicate a successful open so that when we do close the channel normally,
|
||||
// we can cleanup properly
|
||||
/*
|
||||
* 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);
|
||||
|
@ -377,7 +374,7 @@ VmbusChannelOnOffer(
|
|||
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.
|
||||
/* Allocate the channel object and save this offer. */
|
||||
newChannel = AllocVmbusChannel();
|
||||
if (!newChannel)
|
||||
{
|
||||
|
@ -391,7 +388,7 @@ VmbusChannelOnOffer(
|
|||
newChannel->MonitorGroup = (u8)offer->MonitorId / 32;
|
||||
newChannel->MonitorBit = (u8)offer->MonitorId % 32;
|
||||
|
||||
// TODO: Make sure the offer comes from our parent partition
|
||||
/* TODO: Make sure the offer comes from our parent partition */
|
||||
WorkQueueQueueWorkItem(newChannel->ControlWQ, VmbusChannelProcessOffer, newChannel);
|
||||
|
||||
DPRINT_EXIT(VMBUS);
|
||||
|
@ -479,7 +476,7 @@ VmbusChannelOnOpenResult(
|
|||
|
||||
DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status);
|
||||
|
||||
// Find the open msg, copy the result and signal/unblock the wait event
|
||||
/* Find the open msg, copy the result and signal/unblock the wait event */
|
||||
spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
|
||||
|
||||
ITERATE_LIST_ENTRIES(anchor, curr, &gVmbusConnection.ChannelMsgList)
|
||||
|
@ -533,7 +530,7 @@ VmbusChannelOnGpadlCreated(
|
|||
|
||||
DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d", gpadlCreated->CreationStatus);
|
||||
|
||||
// Find the establish msg, copy the result and signal/unblock the wait event
|
||||
/* Find the establish msg, copy the result and signal/unblock the wait event */
|
||||
spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
|
||||
|
||||
ITERATE_LIST_ENTRIES(anchor, curr, &gVmbusConnection.ChannelMsgList)
|
||||
|
@ -586,7 +583,7 @@ VmbusChannelOnGpadlTorndown(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Find the open msg, copy the result and signal/unblock the wait event
|
||||
/* Find the open msg, copy the result and signal/unblock the wait event */
|
||||
spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
|
||||
|
||||
ITERATE_LIST_ENTRIES(anchor, curr, &gVmbusConnection.ChannelMsgList)
|
||||
|
@ -702,7 +699,7 @@ VmbusOnChannelMessage(
|
|||
DPRINT_ERR(VMBUS, "Unhandled channel message type %d", hdr->MessageType);
|
||||
}
|
||||
|
||||
// Free the msg that was allocated in VmbusOnMsgDPC()
|
||||
/* Free the msg that was allocated in VmbusOnMsgDPC() */
|
||||
kfree(msg);
|
||||
DPRINT_EXIT(VMBUS);
|
||||
}
|
||||
|
@ -751,7 +748,7 @@ VmbusChannelRequestOffers(
|
|||
|
||||
goto Cleanup;
|
||||
}
|
||||
//WaitEventWait(msgInfo->waitEvent);
|
||||
/* WaitEventWait(msgInfo->waitEvent); */
|
||||
|
||||
/*SpinlockAcquire(gVmbusConnection.channelMsgLock);
|
||||
REMOVE_ENTRY_LIST(&msgInfo->msgListEntry);
|
||||
|
@ -819,5 +816,4 @@ VmbusChannelReleaseUnattachedChannels(
|
|||
spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
|
||||
}
|
||||
|
||||
// eof
|
||||
|
||||
/* eof */
|
||||
|
|
|
@ -47,27 +47,27 @@ typedef struct _VMBUS_CHANNEL {
|
|||
|
||||
DEVICE_OBJECT* DeviceObject;
|
||||
|
||||
HANDLE PollTimer; // SA-111 workaround
|
||||
HANDLE PollTimer; /* SA-111 workaround */
|
||||
|
||||
VMBUS_CHANNEL_STATE State;
|
||||
|
||||
VMBUS_CHANNEL_OFFER_CHANNEL OfferMsg;
|
||||
// These are based on the OfferMsg.MonitorId. Save it here for easy access.
|
||||
/* These are based on the OfferMsg.MonitorId. Save it here for easy access. */
|
||||
u8 MonitorGroup;
|
||||
u8 MonitorBit;
|
||||
|
||||
u32 RingBufferGpadlHandle;
|
||||
|
||||
// Allocated memory for ring buffer
|
||||
/* Allocated memory for ring buffer */
|
||||
void * RingBufferPages;
|
||||
u32 RingBufferPageCount;
|
||||
RING_BUFFER_INFO Outbound; // send to parent
|
||||
RING_BUFFER_INFO Inbound; // receive from parent
|
||||
RING_BUFFER_INFO Outbound; /* send to parent */
|
||||
RING_BUFFER_INFO Inbound; /* receive from parent */
|
||||
spinlock_t inbound_lock;
|
||||
HANDLE ControlWQ;
|
||||
|
||||
// Channel callback are invoked in this workqueue context
|
||||
//HANDLE dataWorkQueue;
|
||||
/* Channel callback are invoked in this workqueue context */
|
||||
/* HANDLE dataWorkQueue; */
|
||||
|
||||
PFN_CHANNEL_CALLBACK OnChannelCallback;
|
||||
void * ChannelCallbackContext;
|
||||
|
@ -102,31 +102,31 @@ typedef union {
|
|||
} VMBUS_CHANNEL_MESSAGE_RESPONSE;
|
||||
|
||||
|
||||
// Represents each channel msg on the vmbus connection
|
||||
// This is a variable-size data structure depending on
|
||||
// the msg type itself
|
||||
/*
|
||||
* Represents each channel msg on the vmbus connection This is a
|
||||
* variable-size data structure depending on the msg type itself
|
||||
*/
|
||||
|
||||
typedef struct _VMBUS_CHANNEL_MSGINFO {
|
||||
// Bookkeeping stuff
|
||||
/* Bookkeeping stuff */
|
||||
LIST_ENTRY MsgListEntry;
|
||||
|
||||
// So far, this is only used to handle gpadl body message
|
||||
/* So far, this is only used to handle gpadl body message */
|
||||
LIST_ENTRY SubMsgList;
|
||||
|
||||
// Synchronize the request/response if needed
|
||||
/* Synchronize the request/response if needed */
|
||||
HANDLE WaitEvent;
|
||||
|
||||
VMBUS_CHANNEL_MESSAGE_RESPONSE Response;
|
||||
|
||||
u32 MessageSize;
|
||||
// The channel message that goes out on the "wire".
|
||||
// It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
|
||||
/* The channel message that goes out on the "wire". */
|
||||
/* It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header */
|
||||
unsigned char Msg[0];
|
||||
} VMBUS_CHANNEL_MSGINFO;
|
||||
|
||||
|
||||
//
|
||||
// Routines
|
||||
//
|
||||
/* Routines */
|
||||
|
||||
static VMBUS_CHANNEL*
|
||||
AllocVmbusChannel(
|
||||
|
@ -153,4 +153,4 @@ VmbusChannelReleaseUnattachedChannels(
|
|||
void
|
||||
);
|
||||
|
||||
#endif //_CHANNEL_MGMT_H_
|
||||
#endif /* _CHANNEL_MGMT_H_ */
|
||||
|
|
|
@ -26,9 +26,7 @@
|
|||
|
||||
#include "VmbusPrivate.h"
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
/* Globals */
|
||||
|
||||
|
||||
VMBUS_CONNECTION gVmbusConnection = {
|
||||
|
@ -57,11 +55,11 @@ VmbusConnect(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Make sure we are not connecting or connected
|
||||
/* Make sure we are not connecting or connected */
|
||||
if (gVmbusConnection.ConnectState != Disconnected)
|
||||
return -1;
|
||||
|
||||
// Initialize the vmbus connection
|
||||
/* Initialize the vmbus connection */
|
||||
gVmbusConnection.ConnectState = Connecting;
|
||||
gVmbusConnection.WorkQueue = WorkQueueCreate("vmbusQ");
|
||||
|
||||
|
@ -71,7 +69,10 @@ VmbusConnect(
|
|||
INITIALIZE_LIST_HEAD(&gVmbusConnection.ChannelList);
|
||||
spin_lock_init(&gVmbusConnection.channel_lock);
|
||||
|
||||
// Setup the vmbus event connection for channel interrupt abstraction stuff
|
||||
/*
|
||||
* Setup the vmbus event connection for channel interrupt
|
||||
* abstraction stuff
|
||||
*/
|
||||
gVmbusConnection.InterruptPage = PageAlloc(1);
|
||||
if (gVmbusConnection.InterruptPage == NULL)
|
||||
{
|
||||
|
@ -82,7 +83,10 @@ VmbusConnect(
|
|||
gVmbusConnection.RecvInterruptPage = gVmbusConnection.InterruptPage;
|
||||
gVmbusConnection.SendInterruptPage = (void*)((unsigned long)gVmbusConnection.InterruptPage + (PAGE_SIZE >> 1));
|
||||
|
||||
// Setup the monitor notification facility. The 1st page for parent->child and the 2nd page for child->parent
|
||||
/* Setup the monitor
|
||||
* notification facility. The 1st page for parent->child and
|
||||
* the 2nd page for child->parent
|
||||
*/
|
||||
gVmbusConnection.MonitorPages = PageAlloc(2);
|
||||
if (gVmbusConnection.MonitorPages == NULL)
|
||||
{
|
||||
|
@ -106,8 +110,10 @@ VmbusConnect(
|
|||
msg->MonitorPage1 = GetPhysicalAddress(gVmbusConnection.MonitorPages);
|
||||
msg->MonitorPage2 = GetPhysicalAddress((void *)((unsigned long)gVmbusConnection.MonitorPages + PAGE_SIZE));
|
||||
|
||||
// Add to list before we send the request since we may receive the response
|
||||
// before returning from this routine
|
||||
/*
|
||||
* Add to list before we send the request since we may
|
||||
* receive the response before returning from this routine
|
||||
*/
|
||||
spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags);
|
||||
INSERT_TAIL_LIST(&gVmbusConnection.ChannelMsgList, &msgInfo->MsgListEntry);
|
||||
spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags);
|
||||
|
@ -124,12 +130,12 @@ VmbusConnect(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Wait for the connection response
|
||||
/* Wait for the connection response */
|
||||
WaitEventWait(msgInfo->WaitEvent);
|
||||
|
||||
REMOVE_ENTRY_LIST(&msgInfo->MsgListEntry);
|
||||
|
||||
// Check if successful
|
||||
/* Check if successful */
|
||||
if (msgInfo->Response.VersionResponse.VersionSupported)
|
||||
{
|
||||
DPRINT_INFO(VMBUS, "Vmbus connected!!");
|
||||
|
@ -202,7 +208,7 @@ VmbusDisconnect(
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Make sure we are connected
|
||||
/* Make sure we are connected */
|
||||
if (gVmbusConnection.ConnectState != Connected)
|
||||
return -1;
|
||||
|
||||
|
@ -219,7 +225,7 @@ VmbusDisconnect(
|
|||
|
||||
PageFree(gVmbusConnection.InterruptPage, 1);
|
||||
|
||||
// TODO: iterate thru the msg list and free up
|
||||
/* TODO: iterate thru the msg list and free up */
|
||||
|
||||
WorkQueueClose(gVmbusConnection.WorkQueue);
|
||||
|
||||
|
@ -296,18 +302,20 @@ VmbusProcessChannelEvent(
|
|||
|
||||
ASSERT(relId > 0);
|
||||
|
||||
// Find the channel based on this relid and invokes
|
||||
// the channel callback to process the event
|
||||
/*
|
||||
* Find the channel based on this relid and invokes the
|
||||
* channel callback to process the event
|
||||
*/
|
||||
channel = GetChannelFromRelId(relId);
|
||||
|
||||
if (channel)
|
||||
{
|
||||
VmbusChannelOnChannelEvent(channel);
|
||||
//WorkQueueQueueWorkItem(channel->dataWorkQueue, VmbusChannelOnChannelEvent, (void*)channel);
|
||||
/* WorkQueueQueueWorkItem(channel->dataWorkQueue, VmbusChannelOnChannelEvent, (void*)channel); */
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId);
|
||||
DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,16 +335,16 @@ VmbusOnEvents(
|
|||
)
|
||||
{
|
||||
int dword;
|
||||
//int maxdword = PAGE_SIZE >> 3; // receive size is 1/2 page and divide that by 4 bytes
|
||||
/* int maxdword = PAGE_SIZE >> 3; // receive size is 1/2 page and divide that by 4 bytes */
|
||||
int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
|
||||
int bit;
|
||||
int relid;
|
||||
u32* recvInterruptPage = gVmbusConnection.RecvInterruptPage;
|
||||
//VMBUS_CHANNEL_MESSAGE* receiveMsg;
|
||||
/* VMBUS_CHANNEL_MESSAGE* receiveMsg; */
|
||||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Check events
|
||||
/* Check events */
|
||||
if (recvInterruptPage)
|
||||
{
|
||||
for (dword = 0; dword < maxdword; dword++)
|
||||
|
@ -351,15 +359,15 @@ VmbusOnEvents(
|
|||
|
||||
DPRINT_DBG(VMBUS, "event detected for relid - %d", relid);
|
||||
|
||||
if (relid == 0) // special case - vmbus channel protocol msg
|
||||
if (relid == 0) /* special case - vmbus channel protocol msg */
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "invalid relid - %d", relid);
|
||||
|
||||
continue; }
|
||||
else
|
||||
{
|
||||
//QueueWorkItem(VmbusProcessEvent, (void*)relid);
|
||||
//ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid);
|
||||
/* QueueWorkItem(VmbusProcessEvent, (void*)relid); */
|
||||
/* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */
|
||||
VmbusProcessChannelEvent((void*)(unsigned long)relid);
|
||||
}
|
||||
}
|
||||
|
@ -418,7 +426,7 @@ VmbusSetEvent(u32 childRelId)
|
|||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Each u32 represents 32 channels
|
||||
/* Each u32 represents 32 channels */
|
||||
BitSet((u32*)gVmbusConnection.SendInterruptPage + (childRelId >> 5), childRelId & 31);
|
||||
ret = HvSignalEvent();
|
||||
|
||||
|
@ -427,4 +435,4 @@ VmbusSetEvent(u32 childRelId)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// EOF
|
||||
/* EOF */
|
||||
|
|
|
@ -25,11 +25,9 @@
|
|||
#include "include/logging.h"
|
||||
#include "VmbusPrivate.h"
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
/* Globals */
|
||||
|
||||
// The one and only
|
||||
/* The one and only */
|
||||
HV_CONTEXT gHvContext={
|
||||
.SynICInitialized = false,
|
||||
.HypercallPage = NULL,
|
||||
|
@ -90,10 +88,11 @@ HvQueryHypervisorInfo (
|
|||
unsigned int maxLeaf;
|
||||
unsigned int op;
|
||||
|
||||
//
|
||||
// Its assumed that this is called after confirming that Viridian is present.
|
||||
// Query id and revision.
|
||||
//
|
||||
/*
|
||||
* Its assumed that this is called after confirming that Viridian
|
||||
* is present. Query id and revision.
|
||||
*/
|
||||
|
||||
|
||||
eax = 0;
|
||||
ebx = 0;
|
||||
|
@ -103,18 +102,18 @@ HvQueryHypervisorInfo (
|
|||
do_cpuid(op, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
|
||||
(ebx & 0xFF),
|
||||
((ebx >> 8) & 0xFF),
|
||||
((ebx >> 16) & 0xFF),
|
||||
((ebx >> 24) & 0xFF),
|
||||
(ecx & 0xFF),
|
||||
((ecx >> 8) & 0xFF),
|
||||
((ecx >> 16) & 0xFF),
|
||||
((ecx >> 24) & 0xFF),
|
||||
(edx & 0xFF),
|
||||
((edx >> 8) & 0xFF),
|
||||
((edx >> 16) & 0xFF),
|
||||
((edx >> 24) & 0xFF));
|
||||
(ebx & 0xFF),
|
||||
((ebx >> 8) & 0xFF),
|
||||
((ebx >> 16) & 0xFF),
|
||||
((ebx >> 24) & 0xFF),
|
||||
(ecx & 0xFF),
|
||||
((ecx >> 8) & 0xFF),
|
||||
((ecx >> 16) & 0xFF),
|
||||
((ecx >> 24) & 0xFF),
|
||||
(edx & 0xFF),
|
||||
((edx >> 8) & 0xFF),
|
||||
((edx >> 16) & 0xFF),
|
||||
((edx >> 24) & 0xFF));
|
||||
|
||||
maxLeaf = eax;
|
||||
eax = 0;
|
||||
|
@ -125,25 +124,25 @@ HvQueryHypervisorInfo (
|
|||
do_cpuid(op, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
|
||||
(eax & 0xFF),
|
||||
((eax >> 8) & 0xFF),
|
||||
((eax >> 16) & 0xFF),
|
||||
((eax >> 24) & 0xFF));
|
||||
(eax & 0xFF),
|
||||
((eax >> 8) & 0xFF),
|
||||
((eax >> 16) & 0xFF),
|
||||
((eax >> 24) & 0xFF));
|
||||
|
||||
if (maxLeaf >= HvCpuIdFunctionMsHvVersion) {
|
||||
eax = 0;
|
||||
ebx = 0;
|
||||
ecx = 0;
|
||||
edx = 0;
|
||||
op = HvCpuIdFunctionMsHvVersion;
|
||||
do_cpuid(op, &eax, &ebx, &ecx, &edx);
|
||||
DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",
|
||||
eax,
|
||||
ebx >> 16,
|
||||
ebx & 0xFFFF,
|
||||
ecx,
|
||||
edx >> 24,
|
||||
edx & 0xFFFFFF);
|
||||
eax = 0;
|
||||
ebx = 0;
|
||||
ecx = 0;
|
||||
edx = 0;
|
||||
op = HvCpuIdFunctionMsHvVersion;
|
||||
do_cpuid(op, &eax, &ebx, &ecx, &edx);
|
||||
DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",
|
||||
eax,
|
||||
ebx >> 16,
|
||||
ebx & 0xFFFF,
|
||||
ecx,
|
||||
edx >> 24,
|
||||
edx & 0xFFFFFF);
|
||||
}
|
||||
return maxLeaf;
|
||||
}
|
||||
|
@ -211,7 +210,7 @@ HvDoHypercall (
|
|||
DPRINT_DBG(VMBUS, "Hypercall <return %llx>", hvStatusLo | ((u64)hvStatusHi << 32));
|
||||
|
||||
return (hvStatusLo | ((u64)hvStatusHi << 32));
|
||||
#endif // x86_64
|
||||
#endif /* x86_64 */
|
||||
}
|
||||
|
||||
/*++
|
||||
|
@ -249,26 +248,26 @@ HvInit (
|
|||
DPRINT_INFO(VMBUS, "Windows hypervisor detected! Retrieving more info...");
|
||||
|
||||
maxLeaf = HvQueryHypervisorInfo();
|
||||
//HvQueryHypervisorFeatures(maxLeaf);
|
||||
/* HvQueryHypervisorFeatures(maxLeaf); */
|
||||
|
||||
// Determine if we are running on xenlinux (ie x2v shim) or native linux
|
||||
/* Determine if we are running on xenlinux (ie x2v shim) or native linux */
|
||||
gHvContext.GuestId = ReadMsr(HV_X64_MSR_GUEST_OS_ID);
|
||||
|
||||
if (gHvContext.GuestId == 0)
|
||||
{
|
||||
// Write our OS info
|
||||
/* Write our OS info */
|
||||
WriteMsr(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
|
||||
|
||||
gHvContext.GuestId = HV_LINUX_GUEST_ID;
|
||||
}
|
||||
|
||||
// See if the hypercall page is already set
|
||||
/* See if the hypercall page is already set */
|
||||
hypercallMsr.AsUINT64 = ReadMsr(HV_X64_MSR_HYPERCALL);
|
||||
|
||||
if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
|
||||
{
|
||||
// Allocate the hypercall page memory
|
||||
//virtAddr = PageAlloc(1);
|
||||
/* Allocate the hypercall page memory */
|
||||
/* virtAddr = PageAlloc(1); */
|
||||
virtAddr = VirtualAllocExec(PAGE_SIZE);
|
||||
|
||||
if (!virtAddr)
|
||||
|
@ -278,11 +277,11 @@ HvInit (
|
|||
}
|
||||
|
||||
hypercallMsr.Enable = 1;
|
||||
//hypercallMsr.GuestPhysicalAddress = Logical2PhysicalAddr(virtAddr) >> PAGE_SHIFT;
|
||||
/* hypercallMsr.GuestPhysicalAddress = Logical2PhysicalAddr(virtAddr) >> PAGE_SHIFT; */
|
||||
hypercallMsr.GuestPhysicalAddress = Virtual2Physical(virtAddr) >> PAGE_SHIFT;
|
||||
WriteMsr(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64);
|
||||
|
||||
// Confirm that hypercall page did get setup.
|
||||
/* Confirm that hypercall page did get setup. */
|
||||
hypercallMsr.AsUINT64 = 0;
|
||||
hypercallMsr.AsUINT64 = ReadMsr(HV_X64_MSR_HYPERCALL);
|
||||
|
||||
|
@ -304,7 +303,7 @@ HvInit (
|
|||
gHvContext.HypercallPage,
|
||||
(u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT);
|
||||
|
||||
// Setup the global signal event param for the signal event hypercall
|
||||
/* Setup the global signal event param for the signal event hypercall */
|
||||
gHvContext.SignalEventBuffer = kmalloc(sizeof(HV_INPUT_SIGNAL_EVENT_BUFFER), GFP_KERNEL);
|
||||
if (!gHvContext.SignalEventBuffer)
|
||||
{
|
||||
|
@ -317,7 +316,7 @@ HvInit (
|
|||
gHvContext.SignalEventParam->FlagNumber = 0;
|
||||
gHvContext.SignalEventParam->RsvdZ = 0;
|
||||
|
||||
//DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId());
|
||||
/* DPRINT_DBG(VMBUS, "My id %llu", HvGetCurrentPartitionId()); */
|
||||
|
||||
DPRINT_EXIT(VMBUS);
|
||||
|
||||
|
@ -490,12 +489,12 @@ HvSynicInit (
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Check the version
|
||||
/* Check the version */
|
||||
version = ReadMsr(HV_X64_MSR_SVERSION);
|
||||
|
||||
DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
|
||||
|
||||
// TODO: Handle SMP
|
||||
/* TODO: Handle SMP */
|
||||
if (gHvContext.GuestId == HV_XENLINUX_GUEST_ID)
|
||||
{
|
||||
DPRINT_INFO(VMBUS, "Skipping SIMP and SIEFP setup since it is already set.");
|
||||
|
@ -505,7 +504,7 @@ HvSynicInit (
|
|||
|
||||
DPRINT_DBG(VMBUS, "Simp: %llx, Sifep: %llx", simp.AsUINT64, siefp.AsUINT64);
|
||||
|
||||
// Determine if we are running on xenlinux (ie x2v shim) or native linux
|
||||
/* Determine if we are running on xenlinux (ie x2v shim) or native linux */
|
||||
guestID = ReadMsr(HV_X64_MSR_GUEST_OS_ID);
|
||||
|
||||
if (guestID == HV_LINUX_GUEST_ID)
|
||||
|
@ -536,9 +535,7 @@ HvSynicInit (
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
//
|
||||
// Setup the Synic's message page
|
||||
//
|
||||
/* Setup the Synic's message page */
|
||||
simp.AsUINT64 = ReadMsr(HV_X64_MSR_SIMP);
|
||||
simp.SimpEnabled = 1;
|
||||
simp.BaseSimpGpa = GetPhysicalAddress(gHvContext.synICMessagePage[0]) >> PAGE_SHIFT;
|
||||
|
@ -547,9 +544,7 @@ HvSynicInit (
|
|||
|
||||
WriteMsr(HV_X64_MSR_SIMP, simp.AsUINT64);
|
||||
|
||||
//
|
||||
// Setup the Synic's event page
|
||||
//
|
||||
/* Setup the Synic's event page */
|
||||
siefp.AsUINT64 = ReadMsr(HV_X64_MSR_SIEFP);
|
||||
siefp.SiefpEnabled = 1;
|
||||
siefp.BaseSiefpGpa = GetPhysicalAddress(gHvContext.synICEventPage[0]) >> PAGE_SHIFT;
|
||||
|
@ -558,31 +553,27 @@ HvSynicInit (
|
|||
|
||||
WriteMsr(HV_X64_MSR_SIEFP, siefp.AsUINT64);
|
||||
}
|
||||
//
|
||||
// Setup the interception SINT.
|
||||
//
|
||||
//WriteMsr((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX),
|
||||
// interceptionSint.AsUINT64);
|
||||
/* Setup the interception SINT. */
|
||||
/* WriteMsr((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
|
||||
/* interceptionSint.AsUINT64); */
|
||||
|
||||
//
|
||||
// Setup the shared SINT.
|
||||
//
|
||||
/* Setup the shared SINT. */
|
||||
sharedSint.AsUINT64 = ReadMsr(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT);
|
||||
|
||||
sharedSint.AsUINT64 = 0;
|
||||
sharedSint.Vector = irqVector; //HV_SHARED_SINT_IDT_VECTOR + 0x20;
|
||||
sharedSint.Masked = false;
|
||||
sharedSint.AutoEoi = true;
|
||||
sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */
|
||||
sharedSint.Masked = false;
|
||||
sharedSint.AutoEoi = true;
|
||||
|
||||
DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", sharedSint.AsUINT64);
|
||||
|
||||
WriteMsr(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
|
||||
|
||||
// Enable the global synic bit
|
||||
/* Enable the global synic bit */
|
||||
sctrl.AsUINT64 = ReadMsr(HV_X64_MSR_SCONTROL);
|
||||
sctrl.Enable = 1;
|
||||
|
||||
WriteMsr(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
|
||||
WriteMsr(HV_X64_MSR_SCONTROL, sctrl.AsUINT64);
|
||||
|
||||
gHvContext.SynICInitialized = true;
|
||||
|
||||
|
@ -642,11 +633,14 @@ HvSynicCleanup(
|
|||
|
||||
sharedSint.Masked = 1;
|
||||
|
||||
// Disable the interrupt
|
||||
/* Disable the interrupt */
|
||||
WriteMsr(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
|
||||
|
||||
// Disable and free the resources only if we are running as native linux
|
||||
// since in xenlinux, we are sharing the resources with the x2v shim
|
||||
/*
|
||||
* Disable and free the resources only if we are running as
|
||||
* native linux since in xenlinux, we are sharing the
|
||||
* resources with the x2v shim
|
||||
*/
|
||||
if (gHvContext.GuestId == HV_LINUX_GUEST_ID)
|
||||
{
|
||||
simp.AsUINT64 = ReadMsr(HV_X64_MSR_SIMP);
|
||||
|
@ -669,4 +663,4 @@ HvSynicCleanup(
|
|||
}
|
||||
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -29,17 +29,17 @@
|
|||
|
||||
#include "include/HvTypes.h"
|
||||
#include "include/HvStatus.h"
|
||||
//#include "HvVmApi.h"
|
||||
//#include "HvKeApi.h"
|
||||
//#include "HvMmApi.h"
|
||||
//#include "HvCpuApi.h"
|
||||
/* #include "HvVmApi.h" */
|
||||
/* #include "HvKeApi.h" */
|
||||
/* #include "HvMmApi.h" */
|
||||
/* #include "HvCpuApi.h" */
|
||||
#include "include/HvHalApi.h"
|
||||
#include "include/HvVpApi.h"
|
||||
//#include "HvTrApi.h"
|
||||
/* #include "HvTrApi.h" */
|
||||
#include "include/HvSynicApi.h"
|
||||
//#include "HvAmApi.h"
|
||||
//#include "HvHkApi.h"
|
||||
//#include "HvValApi.h"
|
||||
/* #include "HvAmApi.h" */
|
||||
/* #include "HvHkApi.h" */
|
||||
/* #include "HvValApi.h" */
|
||||
#include "include/HvHcApi.h"
|
||||
#include "include/HvPtApi.h"
|
||||
|
||||
|
@ -53,9 +53,9 @@ enum
|
|||
VMBUS_MONITOR_PORT_ID = 3,
|
||||
VMBUS_MESSAGE_SINT = 2
|
||||
};
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
|
||||
/* #defines */
|
||||
|
||||
#define HV_PRESENT_BIT 0x80000000
|
||||
|
||||
#define HV_XENLINUX_GUEST_ID_LO 0x00000000
|
||||
|
@ -75,9 +75,9 @@ enum
|
|||
|
||||
#define HV_HYPERCALL_PARAM_ALIGN sizeof(u64)
|
||||
|
||||
//
|
||||
// Service definitions
|
||||
//
|
||||
|
||||
/* Service definitions */
|
||||
|
||||
#define HV_SERVICE_PARENT_PORT (0)
|
||||
#define HV_SERVICE_PARENT_CONNECTION (0)
|
||||
|
||||
|
@ -95,10 +95,10 @@ enum
|
|||
#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
|
||||
#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
|
||||
|
||||
//#define VMBUS_REVISION_NUMBER 6
|
||||
//#define VMBUS_PORT_ID 11 // Our local vmbus's port and connection id. Anything >0 is fine
|
||||
/* #define VMBUS_REVISION_NUMBER 6 */
|
||||
/* #define VMBUS_PORT_ID 11 // Our local vmbus's port and connection id. Anything >0 is fine */
|
||||
|
||||
// 628180B8-308D-4c5e-B7DB-1BEB62E62EF4
|
||||
/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
|
||||
static const GUID VMBUS_SERVICE_ID = {.Data = {0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4} };
|
||||
|
||||
#define MAX_NUM_CPUS 1
|
||||
|
@ -110,14 +110,14 @@ typedef struct {
|
|||
} HV_INPUT_SIGNAL_EVENT_BUFFER;
|
||||
|
||||
typedef struct {
|
||||
u64 GuestId; // XenLinux or native Linux. If XenLinux, the hypercall and synic pages has already been initialized
|
||||
u64 GuestId; /* XenLinux or native Linux. If XenLinux, the hypercall and synic pages has already been initialized */
|
||||
void* HypercallPage;
|
||||
|
||||
bool SynICInitialized;
|
||||
// This is used as an input param to HvCallSignalEvent hypercall. The input param is immutable
|
||||
// in our usage and must be dynamic mem (vs stack or global).
|
||||
/* This is used as an input param to HvCallSignalEvent hypercall. The input param is immutable */
|
||||
/* in our usage and must be dynamic mem (vs stack or global). */
|
||||
HV_INPUT_SIGNAL_EVENT_BUFFER *SignalEventBuffer;
|
||||
HV_INPUT_SIGNAL_EVENT *SignalEventParam; // 8-bytes aligned of the buffer above
|
||||
HV_INPUT_SIGNAL_EVENT *SignalEventParam; /* 8-bytes aligned of the buffer above */
|
||||
|
||||
HANDLE synICMessagePage[MAX_NUM_CPUS];
|
||||
HANDLE synICEventPage[MAX_NUM_CPUS];
|
||||
|
@ -126,9 +126,9 @@ typedef struct {
|
|||
extern HV_CONTEXT gHvContext;
|
||||
|
||||
|
||||
//
|
||||
// Inline routines
|
||||
//
|
||||
|
||||
/* Inline routines */
|
||||
|
||||
static inline unsigned long long ReadMsr(int msr)
|
||||
{
|
||||
unsigned long long val;
|
||||
|
@ -145,9 +145,9 @@ static inline void WriteMsr(int msr, u64 val)
|
|||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Hv Interface
|
||||
//
|
||||
|
||||
/* Hv Interface */
|
||||
|
||||
static int
|
||||
HvInit(
|
||||
void
|
||||
|
@ -181,4 +181,4 @@ HvSynicCleanup(
|
|||
void
|
||||
);
|
||||
|
||||
#endif // __HV_H__
|
||||
#endif /* __HV_H__ */
|
||||
|
|
|
@ -28,20 +28,16 @@
|
|||
#include "RndisFilter.h"
|
||||
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
/* Globals */
|
||||
static const char* gDriverName="netvsc";
|
||||
|
||||
// {F8615163-DF3E-46c5-913F-F2D2F965ED0E}
|
||||
/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */
|
||||
static const GUID gNetVscDeviceType={
|
||||
.Data = {0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
/* Internal routines */
|
||||
static int
|
||||
NetVscOnDeviceAdd(
|
||||
DEVICE_OBJECT *Device,
|
||||
|
@ -125,7 +121,7 @@ static inline NETVSC_DEVICE* AllocNetDevice(DEVICE_OBJECT *Device)
|
|||
if (!netDevice)
|
||||
return NULL;
|
||||
|
||||
// Set to 2 to allow both inbound and outbound traffic
|
||||
/* Set to 2 to allow both inbound and outbound traffic */
|
||||
InterlockedCompareExchange(&netDevice->RefCount, 2, 0);
|
||||
|
||||
netDevice->Device = Device;
|
||||
|
@ -142,7 +138,7 @@ static inline void FreeNetDevice(NETVSC_DEVICE *Device)
|
|||
}
|
||||
|
||||
|
||||
// Get the net device object iff exists and its refcount > 1
|
||||
/* Get the net device object iff exists and its refcount > 1 */
|
||||
static inline NETVSC_DEVICE* GetOutboundNetDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
NETVSC_DEVICE *netDevice;
|
||||
|
@ -160,7 +156,7 @@ static inline NETVSC_DEVICE* GetOutboundNetDevice(DEVICE_OBJECT *Device)
|
|||
return netDevice;
|
||||
}
|
||||
|
||||
// Get the net device object iff exists and its refcount > 0
|
||||
/* Get the net device object iff exists and its refcount > 0 */
|
||||
static inline NETVSC_DEVICE* GetInboundNetDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
NETVSC_DEVICE *netDevice;
|
||||
|
@ -196,7 +192,7 @@ static inline NETVSC_DEVICE* ReleaseOutboundNetDevice(DEVICE_OBJECT *Device)
|
|||
if (netDevice == NULL)
|
||||
return NULL;
|
||||
|
||||
// Busy wait until the ref drop to 2, then set it to 1
|
||||
/* Busy wait until the ref drop to 2, then set it to 1 */
|
||||
while (InterlockedCompareExchange(&netDevice->RefCount, 1, 2) != 2)
|
||||
{
|
||||
udelay(100);
|
||||
|
@ -213,7 +209,7 @@ static inline NETVSC_DEVICE* ReleaseInboundNetDevice(DEVICE_OBJECT *Device)
|
|||
if (netDevice == NULL)
|
||||
return NULL;
|
||||
|
||||
// Busy wait until the ref drop to 1, then set it to 0
|
||||
/* Busy wait until the ref drop to 1, then set it to 0 */
|
||||
while (InterlockedCompareExchange(&netDevice->RefCount, 0, 1) != 1)
|
||||
{
|
||||
udelay(100);
|
||||
|
@ -246,17 +242,17 @@ NetVscInitialize(
|
|||
DPRINT_DBG(NETVSC, "sizeof(NETVSC_PACKET)=%d, sizeof(NVSP_MESSAGE)=%d, sizeof(VMTRANSFER_PAGE_PACKET_HEADER)=%d",
|
||||
sizeof(NETVSC_PACKET), sizeof(NVSP_MESSAGE), sizeof(VMTRANSFER_PAGE_PACKET_HEADER));
|
||||
|
||||
// Make sure we are at least 2 pages since 1 page is used for control
|
||||
/* Make sure we are at least 2 pages since 1 page is used for control */
|
||||
ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1));
|
||||
|
||||
drv->name = gDriverName;
|
||||
memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(GUID));
|
||||
|
||||
// Make sure it is set by the caller
|
||||
/* Make sure it is set by the caller */
|
||||
ASSERT(driver->OnReceiveCallback);
|
||||
ASSERT(driver->OnLinkStatusChanged);
|
||||
|
||||
// Setup the dispatch table
|
||||
/* Setup the dispatch table */
|
||||
driver->Base.OnDeviceAdd = NetVscOnDeviceAdd;
|
||||
driver->Base.OnDeviceRemove = NetVscOnDeviceRemove;
|
||||
driver->Base.OnCleanup = NetVscOnCleanup;
|
||||
|
@ -289,7 +285,7 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
return -1;
|
||||
}
|
||||
ASSERT(netDevice->ReceiveBufferSize > 0);
|
||||
ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE-1)) == 0); // page-size grandularity
|
||||
ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE-1)) == 0); /* page-size grandularity */
|
||||
|
||||
netDevice->ReceiveBuffer = PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT);
|
||||
if (!netDevice->ReceiveBuffer)
|
||||
|
@ -298,13 +294,15 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
ret = -1;
|
||||
goto Cleanup;
|
||||
}
|
||||
ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE-1)) == 0); // page-aligned buffer
|
||||
ASSERT(((unsigned long)netDevice->ReceiveBuffer & (PAGE_SIZE-1)) == 0); /* page-aligned buffer */
|
||||
|
||||
DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL...");
|
||||
|
||||
// Establish the gpadl handle for this buffer on this channel.
|
||||
// Note: This call uses the vmbus connection rather than the channel to establish
|
||||
// the gpadl handle.
|
||||
/*
|
||||
* Establish the gpadl handle for this buffer on this
|
||||
* channel. Note: This call uses the vmbus connection rather
|
||||
* than the channel to establish the gpadl handle.
|
||||
*/
|
||||
ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
|
||||
netDevice->ReceiveBuffer,
|
||||
netDevice->ReceiveBufferSize,
|
||||
|
@ -316,9 +314,9 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
//WaitEventWait(ext->ChannelInitEvent);
|
||||
/* WaitEventWait(ext->ChannelInitEvent); */
|
||||
|
||||
// Notify the NetVsp of the gpadl handle
|
||||
/* Notify the NetVsp of the gpadl handle */
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer...");
|
||||
|
||||
initPacket = &netDevice->ChannelInitPacket;
|
||||
|
@ -329,7 +327,7 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle;
|
||||
initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID;
|
||||
|
||||
// Send the gpadl notification request
|
||||
/* Send the gpadl notification request */
|
||||
ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
|
||||
initPacket,
|
||||
sizeof(NVSP_MESSAGE),
|
||||
|
@ -344,7 +342,7 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
|
||||
WaitEventWait(netDevice->ChannelInitEvent);
|
||||
|
||||
// Check the response
|
||||
/* Check the response */
|
||||
if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess)
|
||||
{
|
||||
DPRINT_ERR(NETVSC,
|
||||
|
@ -354,7 +352,7 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Parse the response
|
||||
/* Parse the response */
|
||||
ASSERT(netDevice->ReceiveSectionCount == 0);
|
||||
ASSERT(netDevice->ReceiveSections == NULL);
|
||||
|
||||
|
@ -377,7 +375,7 @@ NetVscInitializeReceiveBufferWithNetVsp(
|
|||
netDevice->ReceiveSections[0].SubAllocationSize, netDevice->ReceiveSections[0].NumSubAllocations);
|
||||
|
||||
|
||||
//For 1st release, there should only be 1 section that represents the entire receive buffer
|
||||
/* For 1st release, there should only be 1 section that represents the entire receive buffer */
|
||||
if (netDevice->ReceiveSectionCount != 1 ||
|
||||
netDevice->ReceiveSections->Offset != 0 )
|
||||
{
|
||||
|
@ -416,7 +414,7 @@ NetVscInitializeSendBufferWithNetVsp(
|
|||
return -1;
|
||||
}
|
||||
ASSERT(netDevice->SendBufferSize > 0);
|
||||
ASSERT((netDevice->SendBufferSize & (PAGE_SIZE-1)) == 0); // page-size grandularity
|
||||
ASSERT((netDevice->SendBufferSize & (PAGE_SIZE-1)) == 0); /* page-size grandularity */
|
||||
|
||||
netDevice->SendBuffer = PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT);
|
||||
if (!netDevice->SendBuffer)
|
||||
|
@ -425,17 +423,19 @@ NetVscInitializeSendBufferWithNetVsp(
|
|||
ret = -1;
|
||||
goto Cleanup;
|
||||
}
|
||||
ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE-1)) == 0); // page-aligned buffer
|
||||
ASSERT(((unsigned long)netDevice->SendBuffer & (PAGE_SIZE-1)) == 0); /* page-aligned buffer */
|
||||
|
||||
DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL...");
|
||||
|
||||
// Establish the gpadl handle for this buffer on this channel.
|
||||
// Note: This call uses the vmbus connection rather than the channel to establish
|
||||
// the gpadl handle.
|
||||
/*
|
||||
* Establish the gpadl handle for this buffer on this
|
||||
* channel. Note: This call uses the vmbus connection rather
|
||||
* than the channel to establish the gpadl handle.
|
||||
*/
|
||||
ret = Device->Driver->VmbusChannelInterface.EstablishGpadl(Device,
|
||||
netDevice->SendBuffer,
|
||||
netDevice->SendBufferSize,
|
||||
&netDevice->SendBufferGpadlHandle);
|
||||
netDevice->SendBuffer,
|
||||
netDevice->SendBufferSize,
|
||||
&netDevice->SendBufferGpadlHandle);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -443,9 +443,9 @@ NetVscInitializeSendBufferWithNetVsp(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
//WaitEventWait(ext->ChannelInitEvent);
|
||||
/* WaitEventWait(ext->ChannelInitEvent); */
|
||||
|
||||
// Notify the NetVsp of the gpadl handle
|
||||
/* Notify the NetVsp of the gpadl handle */
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer...");
|
||||
|
||||
initPacket = &netDevice->ChannelInitPacket;
|
||||
|
@ -456,7 +456,7 @@ NetVscInitializeSendBufferWithNetVsp(
|
|||
initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle;
|
||||
initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID;
|
||||
|
||||
// Send the gpadl notification request
|
||||
/* Send the gpadl notification request */
|
||||
ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
|
||||
initPacket,
|
||||
sizeof(NVSP_MESSAGE),
|
||||
|
@ -471,7 +471,7 @@ NetVscInitializeSendBufferWithNetVsp(
|
|||
|
||||
WaitEventWait(netDevice->ChannelInitEvent);
|
||||
|
||||
// Check the response
|
||||
/* Check the response */
|
||||
if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess)
|
||||
{
|
||||
DPRINT_ERR(NETVSC,
|
||||
|
@ -505,13 +505,17 @@ NetVscDestroyReceiveBuffer(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// If we got a section count, it means we received a SendReceiveBufferComplete msg
|
||||
// (ie sent NvspMessage1TypeSendReceiveBuffer msg) therefore, we need to send a revoke msg here
|
||||
/*
|
||||
* If we got a section count, it means we received a
|
||||
* SendReceiveBufferComplete msg (ie sent
|
||||
* NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
|
||||
* to send a revoke msg here
|
||||
*/
|
||||
if (NetDevice->ReceiveSectionCount)
|
||||
{
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeReceiveBuffer...");
|
||||
|
||||
// Send the revoke receive buffer
|
||||
/* Send the revoke receive buffer */
|
||||
revokePacket = &NetDevice->RevokePacket;
|
||||
memset(revokePacket, 0, sizeof(NVSP_MESSAGE));
|
||||
|
||||
|
@ -524,7 +528,10 @@ NetVscDestroyReceiveBuffer(
|
|||
(unsigned long)revokePacket,
|
||||
VmbusPacketTypeDataInBand,
|
||||
0);
|
||||
// If we failed here, we might as well return and have a leak rather than continue and a bugchk
|
||||
/*
|
||||
* If we failed here, we might as well return and
|
||||
* have a leak rather than continue and a bugchk
|
||||
*/
|
||||
if (ret != 0)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "unable to send revoke receive buffer to netvsp");
|
||||
|
@ -533,7 +540,7 @@ NetVscDestroyReceiveBuffer(
|
|||
}
|
||||
}
|
||||
|
||||
// Teardown the gpadl on the vsp end
|
||||
/* Teardown the gpadl on the vsp end */
|
||||
if (NetDevice->ReceiveBufferGpadlHandle)
|
||||
{
|
||||
DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL...");
|
||||
|
@ -541,7 +548,7 @@ NetVscDestroyReceiveBuffer(
|
|||
ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device,
|
||||
NetDevice->ReceiveBufferGpadlHandle);
|
||||
|
||||
// If we failed here, we might as well return and have a leak rather than continue and a bugchk
|
||||
/* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
|
||||
if (ret != 0)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "unable to teardown receive buffer's gpadl");
|
||||
|
@ -555,7 +562,7 @@ NetVscDestroyReceiveBuffer(
|
|||
{
|
||||
DPRINT_INFO(NETVSC, "Freeing up receive buffer...");
|
||||
|
||||
// Free up the receive buffer
|
||||
/* Free up the receive buffer */
|
||||
PageFree(NetDevice->ReceiveBuffer, NetDevice->ReceiveBufferSize >> PAGE_SHIFT);
|
||||
NetDevice->ReceiveBuffer = NULL;
|
||||
}
|
||||
|
@ -586,13 +593,17 @@ NetVscDestroySendBuffer(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// If we got a section count, it means we received a SendReceiveBufferComplete msg
|
||||
// (ie sent NvspMessage1TypeSendReceiveBuffer msg) therefore, we need to send a revoke msg here
|
||||
/*
|
||||
* If we got a section count, it means we received a
|
||||
* SendReceiveBufferComplete msg (ie sent
|
||||
* NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
|
||||
* to send a revoke msg here
|
||||
*/
|
||||
if (NetDevice->SendSectionSize)
|
||||
{
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeSendBuffer...");
|
||||
|
||||
// Send the revoke send buffer
|
||||
/* Send the revoke send buffer */
|
||||
revokePacket = &NetDevice->RevokePacket;
|
||||
memset(revokePacket, 0, sizeof(NVSP_MESSAGE));
|
||||
|
||||
|
@ -605,7 +616,7 @@ NetVscDestroySendBuffer(
|
|||
(unsigned long)revokePacket,
|
||||
VmbusPacketTypeDataInBand,
|
||||
0);
|
||||
// If we failed here, we might as well return and have a leak rather than continue and a bugchk
|
||||
/* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
|
||||
if (ret != 0)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "unable to send revoke send buffer to netvsp");
|
||||
|
@ -614,7 +625,7 @@ NetVscDestroySendBuffer(
|
|||
}
|
||||
}
|
||||
|
||||
// Teardown the gpadl on the vsp end
|
||||
/* Teardown the gpadl on the vsp end */
|
||||
if (NetDevice->SendBufferGpadlHandle)
|
||||
{
|
||||
DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL...");
|
||||
|
@ -622,7 +633,7 @@ NetVscDestroySendBuffer(
|
|||
ret = NetDevice->Device->Driver->VmbusChannelInterface.TeardownGpadl(NetDevice->Device,
|
||||
NetDevice->SendBufferGpadlHandle);
|
||||
|
||||
// If we failed here, we might as well return and have a leak rather than continue and a bugchk
|
||||
/* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
|
||||
if (ret != 0)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "unable to teardown send buffer's gpadl");
|
||||
|
@ -636,7 +647,7 @@ NetVscDestroySendBuffer(
|
|||
{
|
||||
DPRINT_INFO(NETVSC, "Freeing up send buffer...");
|
||||
|
||||
// Free up the receive buffer
|
||||
/* Free up the receive buffer */
|
||||
PageFree(NetDevice->SendBuffer, NetDevice->SendBufferSize >> PAGE_SHIFT);
|
||||
NetDevice->SendBuffer = NULL;
|
||||
}
|
||||
|
@ -677,7 +688,7 @@ NetVscConnectToVsp(
|
|||
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit...");
|
||||
|
||||
// Send the init request
|
||||
/* Send the init request */
|
||||
ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
|
||||
initPacket,
|
||||
sizeof(NVSP_MESSAGE),
|
||||
|
@ -693,8 +704,8 @@ NetVscConnectToVsp(
|
|||
|
||||
WaitEventWait(netDevice->ChannelInitEvent);
|
||||
|
||||
// Now, check the response
|
||||
//ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT);
|
||||
/* Now, check the response */
|
||||
/* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */
|
||||
DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)",
|
||||
initPacket->Messages.InitMessages.InitComplete.Status,
|
||||
initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength);
|
||||
|
@ -715,7 +726,7 @@ NetVscConnectToVsp(
|
|||
}
|
||||
DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion...");
|
||||
|
||||
// Send the ndis version
|
||||
/* Send the ndis version */
|
||||
memset(initPacket, 0, sizeof(NVSP_MESSAGE));
|
||||
|
||||
ndisVersion = 0x00050000;
|
||||
|
@ -724,7 +735,7 @@ NetVscConnectToVsp(
|
|||
initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion = (ndisVersion & 0xFFFF0000) >> 16;
|
||||
initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion = ndisVersion & 0xFFFF;
|
||||
|
||||
// Send the init request
|
||||
/* Send the init request */
|
||||
ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
|
||||
initPacket,
|
||||
sizeof(NVSP_MESSAGE),
|
||||
|
@ -737,12 +748,15 @@ NetVscConnectToVsp(
|
|||
ret = -1;
|
||||
goto Cleanup;
|
||||
}
|
||||
//
|
||||
// BUGBUG - We have to wait for the above msg since the netvsp uses KMCL which acknowledges packet (completion packet)
|
||||
// since our Vmbus always set the VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
|
||||
//WaitEventWait(NetVscChannel->ChannelInitEvent);
|
||||
/*
|
||||
* BUGBUG - We have to wait for the above msg since the
|
||||
* netvsp uses KMCL which acknowledges packet (completion
|
||||
* packet) since our Vmbus always set the
|
||||
* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag
|
||||
*/
|
||||
/* WaitEventWait(NetVscChannel->ChannelInitEvent); */
|
||||
|
||||
// Post the big receive buffer to NetVSP
|
||||
/* Post the big receive buffer to NetVSP */
|
||||
ret = NetVscInitializeReceiveBufferWithNetVsp(Device);
|
||||
if (ret == 0)
|
||||
{
|
||||
|
@ -804,7 +818,7 @@ NetVscOnDeviceAdd(
|
|||
|
||||
DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice);
|
||||
|
||||
// Initialize the NetVSC channel extension
|
||||
/* Initialize the NetVSC channel extension */
|
||||
netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE;
|
||||
spin_lock_init(&netDevice->receive_packet_list_lock);
|
||||
|
||||
|
@ -825,14 +839,14 @@ NetVscOnDeviceAdd(
|
|||
}
|
||||
netDevice->ChannelInitEvent = WaitEventCreate();
|
||||
|
||||
// Open the channel
|
||||
/* Open the channel */
|
||||
ret = Device->Driver->VmbusChannelInterface.Open(Device,
|
||||
netDriver->RingBufferSize,
|
||||
netDriver->RingBufferSize,
|
||||
NULL, 0,
|
||||
NetVscOnChannelCallback,
|
||||
Device
|
||||
);
|
||||
netDriver->RingBufferSize,
|
||||
netDriver->RingBufferSize,
|
||||
NULL, 0,
|
||||
NetVscOnChannelCallback,
|
||||
Device
|
||||
);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -841,10 +855,10 @@ NetVscOnDeviceAdd(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Channel is opened
|
||||
/* Channel is opened */
|
||||
DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***");
|
||||
|
||||
// Connect with the NetVsp
|
||||
/* Connect with the NetVsp */
|
||||
ret = NetVscConnectToVsp(Device);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -859,7 +873,7 @@ NetVscOnDeviceAdd(
|
|||
return ret;
|
||||
|
||||
Close:
|
||||
// Now, we can close the channel safely
|
||||
/* Now, we can close the channel safely */
|
||||
Device->Driver->VmbusChannelInterface.Close(Device);
|
||||
|
||||
Cleanup:
|
||||
|
@ -909,7 +923,7 @@ NetVscOnDeviceRemove(
|
|||
|
||||
DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", Device->Extension);
|
||||
|
||||
// Stop outbound traffic ie sends and receives completions
|
||||
/* Stop outbound traffic ie sends and receives completions */
|
||||
netDevice = ReleaseOutboundNetDevice(Device);
|
||||
if (!netDevice)
|
||||
{
|
||||
|
@ -917,7 +931,7 @@ NetVscOnDeviceRemove(
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Wait for all send completions
|
||||
/* Wait for all send completions */
|
||||
while (netDevice->NumOutstandingSends)
|
||||
{
|
||||
DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", netDevice->NumOutstandingSends);
|
||||
|
@ -931,16 +945,16 @@ NetVscOnDeviceRemove(
|
|||
|
||||
DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", Device->Extension);
|
||||
|
||||
// Stop inbound traffic ie receives and sends completions
|
||||
/* Stop inbound traffic ie receives and sends completions */
|
||||
netDevice = ReleaseInboundNetDevice(Device);
|
||||
|
||||
// At this point, no one should be accessing netDevice except in here
|
||||
/* At this point, no one should be accessing netDevice except in here */
|
||||
DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice);
|
||||
|
||||
// Now, we can close the channel safely
|
||||
/* Now, we can close the channel safely */
|
||||
Device->Driver->VmbusChannelInterface.Close(Device);
|
||||
|
||||
// Release all resources
|
||||
/* Release all resources */
|
||||
while (!IsListEmpty(&netDevice->ReceivePacketList))
|
||||
{
|
||||
entry = REMOVE_HEAD_LIST(&netDevice->ReceivePacketList);
|
||||
|
@ -1005,17 +1019,17 @@ NetVscOnSendCompletion(
|
|||
nvspPacket->Header.MessageType == NvspMessage1TypeSendReceiveBufferComplete ||
|
||||
nvspPacket->Header.MessageType == NvspMessage1TypeSendSendBufferComplete)
|
||||
{
|
||||
// Copy the response back
|
||||
/* Copy the response back */
|
||||
memcpy(&netDevice->ChannelInitPacket, nvspPacket, sizeof(NVSP_MESSAGE));
|
||||
WaitEventSet(netDevice->ChannelInitEvent);
|
||||
}
|
||||
else if (nvspPacket->Header.MessageType == NvspMessage1TypeSendRNDISPacketComplete)
|
||||
{
|
||||
// Get the send context
|
||||
/* Get the send context */
|
||||
nvscPacket = (NETVSC_PACKET *)(unsigned long)Packet->TransactionId;
|
||||
ASSERT(nvscPacket);
|
||||
|
||||
// Notify the layer above us
|
||||
/* Notify the layer above us */
|
||||
nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext);
|
||||
|
||||
InterlockedDecrement(&netDevice->NumOutstandingSends);
|
||||
|
@ -1054,11 +1068,11 @@ NetVscOnSend(
|
|||
|
||||
sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket;
|
||||
if (Packet->IsDataPacket)
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0;// 0 is RMC_DATA;
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0;/* 0 is RMC_DATA; */
|
||||
else
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1;// 1 is RMC_CONTROL;
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1;/* 1 is RMC_CONTROL; */
|
||||
|
||||
// Not using send buffer section
|
||||
/* Not using send buffer section */
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF;
|
||||
sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0;
|
||||
|
||||
|
@ -1108,7 +1122,7 @@ NetVscOnReceive(
|
|||
LIST_ENTRY* entry;
|
||||
unsigned long start;
|
||||
unsigned long end, endVirtual;
|
||||
//NETVSC_DRIVER_OBJECT *netvscDriver;
|
||||
/* NETVSC_DRIVER_OBJECT *netvscDriver; */
|
||||
XFERPAGE_PACKET *xferpagePacket=NULL;
|
||||
LIST_ENTRY listHead;
|
||||
|
||||
|
@ -1126,7 +1140,7 @@ NetVscOnReceive(
|
|||
return;
|
||||
}
|
||||
|
||||
// All inbound packets other than send completion should be xfer page packet
|
||||
/* All inbound packets other than send completion should be xfer page packet */
|
||||
if (Packet->Type != VmbusPacketTypeDataUsingTransferPages)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "Unknown packet type received - %d", Packet->Type);
|
||||
|
@ -1136,7 +1150,7 @@ NetVscOnReceive(
|
|||
|
||||
nvspPacket = (NVSP_MESSAGE*)((unsigned long)Packet + (Packet->DataOffset8 << 3));
|
||||
|
||||
// Make sure this is a valid nvsp packet
|
||||
/* Make sure this is a valid nvsp packet */
|
||||
if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket )
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", nvspPacket->Header.MessageType);
|
||||
|
@ -1159,8 +1173,12 @@ NetVscOnReceive(
|
|||
|
||||
INITIALIZE_LIST_HEAD(&listHead);
|
||||
|
||||
// Grab free packets (range count + 1) to represent this xfer page packet. +1 to represent
|
||||
// the xfer page packet itself. We grab it here so that we know exactly how many we can fulfil
|
||||
/*
|
||||
* Grab free packets (range count + 1) to represent this xfer
|
||||
* page packet. +1 to represent the xfer page packet itself.
|
||||
* We grab it here so that we know exactly how many we can
|
||||
* fulfil
|
||||
*/
|
||||
spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
|
||||
while (!IsListEmpty(&netDevice->ReceivePacketList))
|
||||
{
|
||||
|
@ -1174,13 +1192,16 @@ NetVscOnReceive(
|
|||
}
|
||||
spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
|
||||
|
||||
// We need at least 2 netvsc pkts (1 to represent the xfer page and at least 1 for the range)
|
||||
// i.e. we can handled some of the xfer page packet ranges...
|
||||
/*
|
||||
* We need at least 2 netvsc pkts (1 to represent the xfer
|
||||
* page and at least 1 for the range) i.e. we can handled
|
||||
* some of the xfer page packet ranges...
|
||||
*/
|
||||
if (count < 2)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. Dropping this xfer page packet completely!", count, vmxferpagePacket->RangeCount+1);
|
||||
|
||||
// Return it to the freelist
|
||||
/* Return it to the freelist */
|
||||
spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
|
||||
for (i=count; i != 0; i--)
|
||||
{
|
||||
|
@ -1197,10 +1218,10 @@ NetVscOnReceive(
|
|||
return;
|
||||
}
|
||||
|
||||
// Remove the 1st packet to represent the xfer page packet itself
|
||||
/* Remove the 1st packet to represent the xfer page packet itself */
|
||||
entry = REMOVE_HEAD_LIST(&listHead);
|
||||
xferpagePacket = CONTAINING_RECORD(entry, XFERPAGE_PACKET, ListEntry);
|
||||
xferpagePacket->Count = count - 1; // This is how much we can satisfy
|
||||
xferpagePacket->Count = count - 1; /* This is how much we can satisfy */
|
||||
ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= vmxferpagePacket->RangeCount);
|
||||
|
||||
if (xferpagePacket->Count != vmxferpagePacket->RangeCount)
|
||||
|
@ -1208,18 +1229,18 @@ NetVscOnReceive(
|
|||
DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer page...got %d", vmxferpagePacket->RangeCount, xferpagePacket->Count);
|
||||
}
|
||||
|
||||
// Each range represents 1 RNDIS pkt that contains 1 ethernet frame
|
||||
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
|
||||
for (i=0; i < (count - 1); i++)
|
||||
{
|
||||
entry = REMOVE_HEAD_LIST(&listHead);
|
||||
netvscPacket = CONTAINING_RECORD(entry, NETVSC_PACKET, ListEntry);
|
||||
|
||||
// Initialize the netvsc packet
|
||||
/* Initialize the netvsc packet */
|
||||
netvscPacket->XferPagePacket = xferpagePacket;
|
||||
netvscPacket->Completion.Recv.OnReceiveCompletion = NetVscOnReceiveCompletion;
|
||||
netvscPacket->Completion.Recv.ReceiveCompletionContext = netvscPacket;
|
||||
netvscPacket->Device = Device;
|
||||
netvscPacket->Completion.Recv.ReceiveCompletionTid = vmxferpagePacket->d.TransactionId; // Save this so that we can send it back
|
||||
netvscPacket->Completion.Recv.ReceiveCompletionTid = vmxferpagePacket->d.TransactionId; /* Save this so that we can send it back */
|
||||
|
||||
netvscPacket->TotalDataBufferLength = vmxferpagePacket->Ranges[i].ByteCount;
|
||||
netvscPacket->PageBufferCount = 1;
|
||||
|
@ -1236,10 +1257,10 @@ NetVscOnReceive(
|
|||
+ vmxferpagePacket->Ranges[i].ByteCount -1;
|
||||
end = GetPhysicalAddress((void*)endVirtual);
|
||||
|
||||
// Calculate the page relative offset
|
||||
/* Calculate the page relative offset */
|
||||
netvscPacket->PageBuffers[0].Offset = vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE -1);
|
||||
if ((end >> PAGE_SHIFT) != (start>>PAGE_SHIFT)) {
|
||||
//Handle frame across multiple pages:
|
||||
/* Handle frame across multiple pages: */
|
||||
netvscPacket->PageBuffers[0].Length =
|
||||
(netvscPacket->PageBuffers[0].Pfn <<PAGE_SHIFT) + PAGE_SIZE - start;
|
||||
bytesRemain = netvscPacket->TotalDataBufferLength - netvscPacket->PageBuffers[0].Length;
|
||||
|
@ -1268,7 +1289,7 @@ NetVscOnReceive(
|
|||
netvscPacket->PageBuffers[0].Offset,
|
||||
netvscPacket->PageBuffers[0].Length);
|
||||
|
||||
// Pass it to the upper layer
|
||||
/* Pass it to the upper layer */
|
||||
((NETVSC_DRIVER_OBJECT*)Device->Driver)->OnReceiveCallback(Device, netvscPacket);
|
||||
|
||||
NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext);
|
||||
|
@ -1295,22 +1316,22 @@ NetVscSendReceiveCompletion(
|
|||
|
||||
recvcompMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacketComplete;
|
||||
|
||||
// FIXME: Pass in the status
|
||||
/* FIXME: Pass in the status */
|
||||
recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess;
|
||||
|
||||
retry_send_cmplt:
|
||||
// Send the completion
|
||||
/* Send the completion */
|
||||
ret = Device->Driver->VmbusChannelInterface.SendPacket(Device,
|
||||
&recvcompMessage,
|
||||
sizeof(NVSP_MESSAGE),
|
||||
TransactionId,
|
||||
VmbusPacketTypeCompletion,
|
||||
0);
|
||||
if (ret == 0) // success
|
||||
if (ret == 0) /* success */
|
||||
{
|
||||
// no-op
|
||||
/* no-op */
|
||||
}
|
||||
else if (ret == -1) // no more room...wait a bit and attempt to retry 3 times
|
||||
else if (ret == -1) /* no more room...wait a bit and attempt to retry 3 times */
|
||||
{
|
||||
retries++;
|
||||
DPRINT_ERR(NETVSC, "unable to send receive completion pkt (tid %llx)...retrying %d", TransactionId, retries);
|
||||
|
@ -1331,9 +1352,7 @@ retry_send_cmplt:
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Send a receive completion packet to RNDIS device (ie NetVsp)
|
||||
//
|
||||
/* Send a receive completion packet to RNDIS device (ie NetVsp) */
|
||||
static void
|
||||
NetVscOnReceiveCompletion(
|
||||
void * Context)
|
||||
|
@ -1349,8 +1368,8 @@ NetVscOnReceiveCompletion(
|
|||
|
||||
ASSERT(packet->XferPagePacket);
|
||||
|
||||
// Even though it seems logical to do a GetOutboundNetDevice() here to send out receive completion,
|
||||
// we are using GetInboundNetDevice() since we may have disable outbound traffic already.
|
||||
/* Even though it seems logical to do a GetOutboundNetDevice() here to send out receive completion, */
|
||||
/* we are using GetInboundNetDevice() since we may have disable outbound traffic already. */
|
||||
netDevice = GetInboundNetDevice(device);
|
||||
if (!netDevice)
|
||||
{
|
||||
|
@ -1359,14 +1378,14 @@ NetVscOnReceiveCompletion(
|
|||
return;
|
||||
}
|
||||
|
||||
// Overloading use of the lock.
|
||||
/* Overloading use of the lock. */
|
||||
spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags);
|
||||
|
||||
ASSERT(packet->XferPagePacket->Count > 0);
|
||||
packet->XferPagePacket->Count--;
|
||||
|
||||
// Last one in the line that represent 1 xfer page packet.
|
||||
// Return the xfer page packet itself to the freelist
|
||||
/* Last one in the line that represent 1 xfer page packet. */
|
||||
/* Return the xfer page packet itself to the freelist */
|
||||
if (packet->XferPagePacket->Count == 0)
|
||||
{
|
||||
fSendReceiveComp = true;
|
||||
|
@ -1375,11 +1394,11 @@ NetVscOnReceiveCompletion(
|
|||
INSERT_TAIL_LIST(&netDevice->ReceivePacketList, &packet->XferPagePacket->ListEntry);
|
||||
}
|
||||
|
||||
// Put the packet back
|
||||
/* Put the packet back */
|
||||
INSERT_TAIL_LIST(&netDevice->ReceivePacketList, &packet->ListEntry);
|
||||
spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags);
|
||||
|
||||
// Send a receive completion for the xfer page packet
|
||||
/* Send a receive completion for the xfer page packet */
|
||||
if (fSendReceiveComp)
|
||||
{
|
||||
NetVscSendReceiveCompletion(device, transactionId);
|
||||
|
@ -1451,7 +1470,7 @@ NetVscOnChannelCallback(
|
|||
break;
|
||||
}
|
||||
|
||||
// reset
|
||||
/* reset */
|
||||
if (bufferlen > netPacketSize)
|
||||
{
|
||||
kfree(buffer);
|
||||
|
@ -1462,9 +1481,9 @@ NetVscOnChannelCallback(
|
|||
}
|
||||
else
|
||||
{
|
||||
//DPRINT_DBG(NETVSC, "nothing else to read...");
|
||||
/* DPRINT_DBG(NETVSC, "nothing else to read..."); */
|
||||
|
||||
// reset
|
||||
/* reset */
|
||||
if (bufferlen > netPacketSize)
|
||||
{
|
||||
kfree(buffer);
|
||||
|
@ -1476,12 +1495,12 @@ NetVscOnChannelCallback(
|
|||
break;
|
||||
}
|
||||
}
|
||||
else if (ret == -2) // Handle large packet
|
||||
else if (ret == -2) /* Handle large packet */
|
||||
{
|
||||
buffer = kmalloc(bytesRecvd, GFP_ATOMIC);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
// Try again next time around
|
||||
/* Try again next time around */
|
||||
DPRINT_ERR(NETVSC, "unable to allocate buffer of size (%d)!!", bytesRecvd);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -30,62 +30,62 @@
|
|||
#include "include/List.h"
|
||||
|
||||
#include "include/NetVscApi.h"
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
//#define NVSC_MIN_PROTOCOL_VERSION 1
|
||||
//#define NVSC_MAX_PROTOCOL_VERSION 1
|
||||
|
||||
#define NETVSC_SEND_BUFFER_SIZE 64*1024 // 64K
|
||||
/* #defines */
|
||||
|
||||
/* #define NVSC_MIN_PROTOCOL_VERSION 1 */
|
||||
/* #define NVSC_MAX_PROTOCOL_VERSION 1 */
|
||||
|
||||
#define NETVSC_SEND_BUFFER_SIZE 64*1024 /* 64K */
|
||||
#define NETVSC_SEND_BUFFER_ID 0xface
|
||||
|
||||
|
||||
#define NETVSC_RECEIVE_BUFFER_SIZE 1024*1024 // 1MB
|
||||
#define NETVSC_RECEIVE_BUFFER_SIZE 1024*1024 /* 1MB */
|
||||
|
||||
#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
|
||||
|
||||
#define NETVSC_RECEIVE_SG_COUNT 1
|
||||
|
||||
// Preallocated receive packets
|
||||
/* Preallocated receive packets */
|
||||
#define NETVSC_RECEIVE_PACKETLIST_COUNT 256
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
// Per netvsc channel-specific
|
||||
/* Data types */
|
||||
|
||||
|
||||
/* Per netvsc channel-specific */
|
||||
typedef struct _NETVSC_DEVICE {
|
||||
DEVICE_OBJECT *Device;
|
||||
|
||||
int RefCount;
|
||||
|
||||
int NumOutstandingSends;
|
||||
// List of free preallocated NETVSC_PACKET to represent receive packet
|
||||
/* List of free preallocated NETVSC_PACKET to represent receive packet */
|
||||
LIST_ENTRY ReceivePacketList;
|
||||
spinlock_t receive_packet_list_lock;
|
||||
|
||||
// Send buffer allocated by us but manages by NetVSP
|
||||
/* Send buffer allocated by us but manages by NetVSP */
|
||||
void * SendBuffer;
|
||||
u32 SendBufferSize;
|
||||
u32 SendBufferGpadlHandle;
|
||||
u32 SendSectionSize;
|
||||
|
||||
// Receive buffer allocated by us but manages by NetVSP
|
||||
/* Receive buffer allocated by us but manages by NetVSP */
|
||||
void * ReceiveBuffer;
|
||||
u32 ReceiveBufferSize;
|
||||
u32 ReceiveBufferGpadlHandle;
|
||||
u32 ReceiveSectionCount;
|
||||
PNVSP_1_RECEIVE_BUFFER_SECTION ReceiveSections;
|
||||
|
||||
// Used for NetVSP initialization protocol
|
||||
/* Used for NetVSP initialization protocol */
|
||||
HANDLE ChannelInitEvent;
|
||||
NVSP_MESSAGE ChannelInitPacket;
|
||||
|
||||
NVSP_MESSAGE RevokePacket;
|
||||
//unsigned char HwMacAddr[HW_MACADDR_LEN];
|
||||
/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
|
||||
|
||||
// Holds rndis device info
|
||||
/* Holds rndis device info */
|
||||
void *Extension;
|
||||
} NETVSC_DEVICE;
|
||||
|
||||
#endif // _NETVSC_H_
|
||||
#endif /* _NETVSC_H_ */
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
#include "include/logging.h"
|
||||
#include "RingBuffer.h"
|
||||
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
|
||||
// Amount of space to write to
|
||||
/* #defines */
|
||||
|
||||
|
||||
/* Amount of space to write to */
|
||||
#define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r))?((z) - ((w) - (r))):((r) - (w))
|
||||
|
||||
|
||||
|
@ -48,7 +48,7 @@ GetRingBufferAvailBytes(RING_BUFFER_INFO *rbi, u32 *read, u32 *write)
|
|||
{
|
||||
u32 read_loc,write_loc;
|
||||
|
||||
// Capture the read/write indices before they changed
|
||||
/* Capture the read/write indices before they changed */
|
||||
read_loc = rbi->RingBuffer->ReadIndex;
|
||||
write_loc = rbi->RingBuffer->WriteIndex;
|
||||
|
||||
|
@ -221,9 +221,9 @@ DumpRingInfo(RING_BUFFER_INFO* RingInfo, char *Prefix)
|
|||
RingInfo->RingBuffer->WriteIndex);
|
||||
}
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
|
||||
/* Internal routines */
|
||||
|
||||
static u32
|
||||
CopyToRingBuffer(
|
||||
RING_BUFFER_INFO *RingInfo,
|
||||
|
@ -376,10 +376,10 @@ RingBufferWrite(
|
|||
|
||||
DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite);
|
||||
|
||||
//DumpRingInfo(OutRingInfo, "BEFORE ");
|
||||
/* DumpRingInfo(OutRingInfo, "BEFORE "); */
|
||||
|
||||
// If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer
|
||||
// is empty since the read index == write index
|
||||
/* If there is only room for the packet, assume it is full. Otherwise, the next time around, we think the ring buffer */
|
||||
/* is empty since the read index == write index */
|
||||
if (byteAvailToWrite <= totalBytesToWrite)
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer (needed %u, avail %u)", totalBytesToWrite, byteAvailToWrite);
|
||||
|
@ -391,7 +391,7 @@ RingBufferWrite(
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Write to the ring buffer
|
||||
/* Write to the ring buffer */
|
||||
nextWriteLocation = GetNextWriteLocation(OutRingInfo);
|
||||
|
||||
for (i=0; i < SgBufferCount; i++)
|
||||
|
@ -402,7 +402,7 @@ RingBufferWrite(
|
|||
SgBuffers[i].Length);
|
||||
}
|
||||
|
||||
// Set previous packet start
|
||||
/* Set previous packet start */
|
||||
prevIndices = GetRingBufferIndices(OutRingInfo);
|
||||
|
||||
nextWriteLocation = CopyToRingBuffer(OutRingInfo,
|
||||
|
@ -410,13 +410,13 @@ RingBufferWrite(
|
|||
&prevIndices,
|
||||
sizeof(u64));
|
||||
|
||||
// Make sure we flush all writes before updating the writeIndex
|
||||
/* Make sure we flush all writes before updating the writeIndex */
|
||||
mb();
|
||||
|
||||
// Now, update the write location
|
||||
/* Now, update the write location */
|
||||
SetNextWriteLocation(OutRingInfo, nextWriteLocation);
|
||||
|
||||
//DumpRingInfo(OutRingInfo, "AFTER ");
|
||||
/* DumpRingInfo(OutRingInfo, "AFTER "); */
|
||||
|
||||
spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags);
|
||||
|
||||
|
@ -451,17 +451,17 @@ RingBufferPeek(
|
|||
|
||||
GetRingBufferAvailBytes(InRingInfo, &bytesAvailToRead, &bytesAvailToWrite);
|
||||
|
||||
// Make sure there is something to read
|
||||
/* Make sure there is something to read */
|
||||
if (bytesAvailToRead < BufferLen )
|
||||
{
|
||||
//DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen);
|
||||
/* DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen); */
|
||||
|
||||
spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Convert to byte offset
|
||||
/* Convert to byte offset */
|
||||
nextReadLocation = GetNextReadLocation(InRingInfo);
|
||||
|
||||
nextReadLocation = CopyFromRingBuffer(InRingInfo,
|
||||
|
@ -506,9 +506,9 @@ RingBufferRead(
|
|||
|
||||
DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen);
|
||||
|
||||
//DumpRingInfo(InRingInfo, "BEFORE ");
|
||||
/* DumpRingInfo(InRingInfo, "BEFORE "); */
|
||||
|
||||
// Make sure there is something to read
|
||||
/* Make sure there is something to read */
|
||||
if (bytesAvailToRead < BufferLen )
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "got callback but not enough to read <avail to read %d read size %d>!!", bytesAvailToRead, BufferLen);
|
||||
|
@ -530,14 +530,14 @@ RingBufferRead(
|
|||
sizeof(u64),
|
||||
nextReadLocation);
|
||||
|
||||
// Make sure all reads are done before we update the read index since
|
||||
// the writer may start writing to the read area once the read index is updated
|
||||
/* Make sure all reads are done before we update the read index since */
|
||||
/* the writer may start writing to the read area once the read index is updated */
|
||||
mb();
|
||||
|
||||
// Update the read index
|
||||
/* Update the read index */
|
||||
SetNextReadLocation(InRingInfo, nextReadLocation);
|
||||
|
||||
//DumpRingInfo(InRingInfo, "AFTER ");
|
||||
/* DumpRingInfo(InRingInfo, "AFTER "); */
|
||||
|
||||
spin_unlock_irqrestore(&InRingInfo->ring_lock, flags);
|
||||
|
||||
|
@ -566,7 +566,7 @@ CopyToRingBuffer(
|
|||
u32 ringBufferSize=GetRingBufferSize(RingInfo);
|
||||
u32 fragLen;
|
||||
|
||||
if (SrcLen > ringBufferSize - StartWriteOffset) // wrap-around detected!
|
||||
if (SrcLen > ringBufferSize - StartWriteOffset) /* wrap-around detected! */
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "wrap-around detected!");
|
||||
|
||||
|
@ -608,7 +608,7 @@ CopyFromRingBuffer(
|
|||
|
||||
u32 fragLen;
|
||||
|
||||
if (DestLen > ringBufferSize - StartReadOffset) // wrap-around detected at the src
|
||||
if (DestLen > ringBufferSize - StartReadOffset) /* wrap-around detected at the src */
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "src wrap-around detected!");
|
||||
|
||||
|
@ -629,4 +629,4 @@ CopyFromRingBuffer(
|
|||
}
|
||||
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -33,24 +33,24 @@ typedef struct _SG_BUFFER_LIST {
|
|||
} SG_BUFFER_LIST;
|
||||
|
||||
typedef struct _RING_BUFFER {
|
||||
volatile u32 WriteIndex; // Offset in bytes from the start of ring data below
|
||||
volatile u32 ReadIndex; // Offset in bytes from the start of ring data below
|
||||
volatile u32 WriteIndex; /* Offset in bytes from the start of ring data below */
|
||||
volatile u32 ReadIndex; /* Offset in bytes from the start of ring data below */
|
||||
|
||||
volatile u32 InterruptMask;
|
||||
u8 Reserved[4084]; // Pad it to PAGE_SIZE so that data starts on page boundary
|
||||
// NOTE: The InterruptMask field is used only for channels but since our vmbus connection
|
||||
// also uses this data structure and its data starts here, we commented out this field.
|
||||
// volatile u32 InterruptMask;
|
||||
// Ring data starts here + RingDataStartOffset !!! DO NOT place any fields below this !!!
|
||||
u8 Reserved[4084]; /* Pad it to PAGE_SIZE so that data starts on page boundary */
|
||||
/* NOTE: The InterruptMask field is used only for channels but since our vmbus connection */
|
||||
/* also uses this data structure and its data starts here, we commented out this field. */
|
||||
/* volatile u32 InterruptMask; */
|
||||
/* Ring data starts here + RingDataStartOffset !!! DO NOT place any fields below this !!! */
|
||||
u8 Buffer[0];
|
||||
} __attribute__((packed)) RING_BUFFER;
|
||||
|
||||
typedef struct _RING_BUFFER_INFO {
|
||||
RING_BUFFER* RingBuffer;
|
||||
u32 RingSize; // Include the shared header
|
||||
u32 RingSize; /* Include the shared header */
|
||||
spinlock_t ring_lock;
|
||||
|
||||
u32 RingDataSize; // < ringSize
|
||||
u32 RingDataSize; /* < ringSize */
|
||||
u32 RingDataStartOffset;
|
||||
|
||||
} RING_BUFFER_INFO;
|
||||
|
@ -65,9 +65,9 @@ typedef struct _RING_BUFFER_DEBUG_INFO {
|
|||
}RING_BUFFER_DEBUG_INFO;
|
||||
|
||||
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
|
||||
/* Interface */
|
||||
|
||||
|
||||
static int
|
||||
RingBufferInit(
|
||||
|
@ -120,4 +120,4 @@ RingBufferGetDebugInfo(
|
|||
RING_BUFFER_DEBUG_INFO *DebugInfo
|
||||
);
|
||||
|
||||
#endif // _RING_BUFFER_H_
|
||||
#endif /* _RING_BUFFER_H_ */
|
||||
|
|
|
@ -28,12 +28,12 @@
|
|||
#include "include/NetVscApi.h"
|
||||
#include "RndisFilter.h"
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
typedef struct _RNDIS_FILTER_DRIVER_OBJECT {
|
||||
// The original driver
|
||||
/* The original driver */
|
||||
NETVSC_DRIVER_OBJECT InnerDriver;
|
||||
|
||||
} RNDIS_FILTER_DRIVER_OBJECT;
|
||||
|
@ -63,14 +63,14 @@ typedef struct _RNDIS_REQUEST {
|
|||
LIST_ENTRY ListEntry;
|
||||
HANDLE WaitEvent;
|
||||
|
||||
// FIXME: We assumed a fixed size response here. If we do ever need to handle a bigger response,
|
||||
// we can either define a max response message or add a response buffer variable above this field
|
||||
/* FIXME: We assumed a fixed size response here. If we do ever need to handle a bigger response, */
|
||||
/* we can either define a max response message or add a response buffer variable above this field */
|
||||
RNDIS_MESSAGE ResponseMessage;
|
||||
|
||||
// Simplify allocation by having a netvsc packet inline
|
||||
/* Simplify allocation by having a netvsc packet inline */
|
||||
NETVSC_PACKET Packet;
|
||||
PAGE_BUFFER Buffer;
|
||||
// FIXME: We assumed a fixed size request here.
|
||||
/* FIXME: We assumed a fixed size request here. */
|
||||
RNDIS_MESSAGE RequestMessage;
|
||||
} RNDIS_REQUEST;
|
||||
|
||||
|
@ -82,9 +82,9 @@ typedef struct _RNDIS_FILTER_PACKET {
|
|||
RNDIS_MESSAGE Message;
|
||||
} RNDIS_FILTER_PACKET;
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
|
||||
/* Internal routines */
|
||||
|
||||
static int
|
||||
RndisFilterSendRequest(
|
||||
RNDIS_DEVICE *Device,
|
||||
|
@ -197,11 +197,11 @@ RndisFilterOnSendRequestCompletion(
|
|||
void *Context
|
||||
);
|
||||
|
||||
//
|
||||
// Global var
|
||||
//
|
||||
|
||||
// The one and only
|
||||
/* Global var */
|
||||
|
||||
|
||||
/* The one and only */
|
||||
RNDIS_FILTER_DRIVER_OBJECT gRndisFilter;
|
||||
|
||||
static inline RNDIS_DEVICE* GetRndisDevice(void)
|
||||
|
@ -252,12 +252,12 @@ static inline RNDIS_REQUEST* GetRndisRequest(RNDIS_DEVICE *Device, u32 MessageTy
|
|||
rndisMessage->NdisMessageType = MessageType;
|
||||
rndisMessage->MessageLength = MessageLength;
|
||||
|
||||
// Set the request id. This field is always after the rndis header for request/response packet types so
|
||||
// we just used the SetRequest as a template
|
||||
/* Set the request id. This field is always after the rndis header for request/response packet types so */
|
||||
/* we just used the SetRequest as a template */
|
||||
set = &rndisMessage->Message.SetRequest;
|
||||
set->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
|
||||
|
||||
// Add to the request list
|
||||
/* Add to the request list */
|
||||
spin_lock_irqsave(&Device->request_lock, flags);
|
||||
INSERT_TAIL_LIST(&Device->RequestList, &request->ListEntry);
|
||||
spin_unlock_irqrestore(&Device->request_lock, flags);
|
||||
|
@ -349,7 +349,7 @@ RndisFilterSendRequest(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Setup the packet to send it
|
||||
/* Setup the packet to send it */
|
||||
packet = &Request->Packet;
|
||||
|
||||
packet->IsDataPacket = false;
|
||||
|
@ -360,7 +360,7 @@ RndisFilterSendRequest(
|
|||
packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength;
|
||||
packet->PageBuffers[0].Offset = (unsigned long)&Request->RequestMessage & (PAGE_SIZE -1);
|
||||
|
||||
packet->Completion.Send.SendCompletionContext = Request;//packet;
|
||||
packet->Completion.Send.SendCompletionContext = Request;/* packet; */
|
||||
packet->Completion.Send.OnSendCompletion = RndisFilterOnSendRequestCompletion;
|
||||
packet->Completion.Send.SendCompletionTid = (unsigned long)Device;
|
||||
|
||||
|
@ -389,7 +389,7 @@ RndisFilterReceiveResponse(
|
|||
{
|
||||
request = CONTAINING_RECORD(curr, RNDIS_REQUEST, ListEntry);
|
||||
|
||||
// All request/response message contains RequestId as the 1st field
|
||||
/* All request/response message contains RequestId as the 1st field */
|
||||
if (request->RequestMessage.Message.InitializeRequest.RequestId == Response->Message.InitializeComplete.RequestId)
|
||||
{
|
||||
DPRINT_DBG(NETVSC, "found rndis request for this response (id 0x%x req type 0x%x res type 0x%x)",
|
||||
|
@ -411,7 +411,7 @@ RndisFilterReceiveResponse(
|
|||
{
|
||||
DPRINT_ERR(NETVSC, "rndis response buffer overflow detected (size %u max %u)", Response->MessageLength, sizeof(RNDIS_FILTER_PACKET));
|
||||
|
||||
if (Response->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) // does not have a request id field
|
||||
if (Response->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) /* does not have a request id field */
|
||||
{
|
||||
request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ RndisFilterReceiveIndicateStatus(
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,15 +466,15 @@ RndisFilterReceiveData(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// empty ethernet frame ??
|
||||
/* empty ethernet frame ?? */
|
||||
ASSERT(Packet->PageBuffers[0].Length > RNDIS_MESSAGE_SIZE(RNDIS_PACKET));
|
||||
|
||||
rndisPacket = &Message->Message.Packet;
|
||||
|
||||
// FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this
|
||||
// netvsc packet (ie TotalDataBufferLength != MessageLength)
|
||||
/* FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this */
|
||||
/* netvsc packet (ie TotalDataBufferLength != MessageLength) */
|
||||
|
||||
// Remove the rndis header and pass it back up the stack
|
||||
/* Remove the rndis header and pass it back up the stack */
|
||||
dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset;
|
||||
|
||||
Packet->TotalDataBufferLength -= dataOffset;
|
||||
|
@ -502,7 +502,7 @@ RndisFilterOnReceive(
|
|||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
ASSERT(netDevice);
|
||||
//Make sure the rndis device state is initialized
|
||||
/* Make sure the rndis device state is initialized */
|
||||
if (!netDevice->Extension)
|
||||
{
|
||||
DPRINT_ERR(NETVSC, "got rndis message but no rndis device...dropping this message!");
|
||||
|
@ -522,9 +522,9 @@ RndisFilterOnReceive(
|
|||
|
||||
rndisHeader = (void*)((unsigned long)rndisHeader + Packet->PageBuffers[0].Offset);
|
||||
|
||||
// Make sure we got a valid rndis message
|
||||
// FIXME: There seems to be a bug in set completion msg where its MessageLength is 16 bytes but
|
||||
// the ByteCount field in the xfer page range shows 52 bytes
|
||||
/* Make sure we got a valid rndis message */
|
||||
/* FIXME: There seems to be a bug in set completion msg where its MessageLength is 16 bytes but */
|
||||
/* the ByteCount field in the xfer page range shows 52 bytes */
|
||||
#if 0
|
||||
if ( Packet->TotalDataBufferLength != rndisHeader->MessageLength )
|
||||
{
|
||||
|
@ -551,21 +551,21 @@ RndisFilterOnReceive(
|
|||
|
||||
switch (rndisMessage.NdisMessageType)
|
||||
{
|
||||
// data msg
|
||||
/* data msg */
|
||||
case REMOTE_NDIS_PACKET_MSG:
|
||||
RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet);
|
||||
break;
|
||||
|
||||
// completion msgs
|
||||
/* completion msgs */
|
||||
case REMOTE_NDIS_INITIALIZE_CMPLT:
|
||||
case REMOTE_NDIS_QUERY_CMPLT:
|
||||
case REMOTE_NDIS_SET_CMPLT:
|
||||
//case REMOTE_NDIS_RESET_CMPLT:
|
||||
//case REMOTE_NDIS_KEEPALIVE_CMPLT:
|
||||
/* case REMOTE_NDIS_RESET_CMPLT: */
|
||||
/* case REMOTE_NDIS_KEEPALIVE_CMPLT: */
|
||||
RndisFilterReceiveResponse(rndisDevice, &rndisMessage);
|
||||
break;
|
||||
|
||||
// notification msgs
|
||||
/* notification msgs */
|
||||
case REMOTE_NDIS_INDICATE_STATUS_MSG:
|
||||
RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage);
|
||||
break;
|
||||
|
@ -605,7 +605,7 @@ RndisFilterQueryDevice(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Setup the rndis query
|
||||
/* Setup the rndis query */
|
||||
query = &request->RequestMessage.Message.QueryRequest;
|
||||
query->Oid = Oid;
|
||||
query->InformationBufferOffset = sizeof(RNDIS_QUERY_REQUEST);
|
||||
|
@ -620,7 +620,7 @@ RndisFilterQueryDevice(
|
|||
|
||||
WaitEventWait(request->WaitEvent);
|
||||
|
||||
// Copy the response back
|
||||
/* Copy the response back */
|
||||
queryComplete = &request->ResponseMessage.Message.QueryComplete;
|
||||
|
||||
if (queryComplete->InformationBufferLength > inresultSize)
|
||||
|
@ -694,7 +694,7 @@ RndisFilterSetPacketFilter(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Setup the rndis set
|
||||
/* Setup the rndis set */
|
||||
set = &request->RequestMessage.Message.SetRequest;
|
||||
set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER;
|
||||
set->InformationBufferLength = sizeof(u32);
|
||||
|
@ -713,7 +713,7 @@ RndisFilterSetPacketFilter(
|
|||
{
|
||||
ret = -1;
|
||||
DPRINT_ERR(NETVSC, "timeout before we got a set response...");
|
||||
// We cant deallocate the request since we may still receive a send completion for it.
|
||||
/* We cant deallocate the request since we may still receive a send completion for it. */
|
||||
goto Exit;
|
||||
}
|
||||
else
|
||||
|
@ -747,9 +747,9 @@ RndisFilterInit(
|
|||
DPRINT_DBG(NETVSC, "sizeof(RNDIS_FILTER_PACKET) == %d", sizeof(RNDIS_FILTER_PACKET));
|
||||
|
||||
Driver->RequestExtSize = sizeof(RNDIS_FILTER_PACKET);
|
||||
Driver->AdditionalRequestPageBufferCount = 1; // For rndis header
|
||||
Driver->AdditionalRequestPageBufferCount = 1; /* For rndis header */
|
||||
|
||||
//Driver->Context = rndisDriver;
|
||||
/* Driver->Context = rndisDriver; */
|
||||
|
||||
memset(&gRndisFilter, 0, sizeof(RNDIS_FILTER_DRIVER_OBJECT));
|
||||
|
||||
|
@ -758,7 +758,7 @@ RndisFilterInit(
|
|||
ASSERT(Driver->OnLinkStatusChanged);
|
||||
rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
|
||||
|
||||
// Save the original dispatch handlers before we override it
|
||||
/* Save the original dispatch handlers before we override it */
|
||||
gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd;
|
||||
gRndisFilter.InnerDriver.Base.OnDeviceRemove = Driver->Base.OnDeviceRemove;
|
||||
gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup;
|
||||
|
@ -769,14 +769,14 @@ RndisFilterInit(
|
|||
gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback;
|
||||
gRndisFilter.InnerDriver.OnLinkStatusChanged = Driver->OnLinkStatusChanged;
|
||||
|
||||
// Override
|
||||
/* Override */
|
||||
Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd;
|
||||
Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove;
|
||||
Driver->Base.OnCleanup = RndisFilterOnCleanup;
|
||||
Driver->OnSend = RndisFilterOnSend;
|
||||
Driver->OnOpen = RndisFilterOnOpen;
|
||||
Driver->OnClose = RndisFilterOnClose;
|
||||
//Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus;
|
||||
/* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */
|
||||
Driver->OnReceiveCallback = RndisFilterOnReceive;
|
||||
|
||||
DPRINT_EXIT(NETVSC);
|
||||
|
@ -804,11 +804,11 @@ RndisFilterInitDevice(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Setup the rndis set
|
||||
/* Setup the rndis set */
|
||||
init = &request->RequestMessage.Message.InitializeRequest;
|
||||
init->MajorVersion = RNDIS_MAJOR_VERSION;
|
||||
init->MinorVersion = RNDIS_MINOR_VERSION;
|
||||
init->MaxTransferSize = 2048; // FIXME: Use 1536 - rounded ethernet frame size
|
||||
init->MaxTransferSize = 2048; /* FIXME: Use 1536 - rounded ethernet frame size */
|
||||
|
||||
Device->State = RNDIS_DEV_INITIALIZING;
|
||||
|
||||
|
@ -854,18 +854,18 @@ RndisFilterHaltDevice(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Attempt to do a rndis device halt
|
||||
/* Attempt to do a rndis device halt */
|
||||
request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(RNDIS_HALT_REQUEST));
|
||||
if (!request)
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Setup the rndis set
|
||||
/* Setup the rndis set */
|
||||
halt = &request->RequestMessage.Message.HaltRequest;
|
||||
halt->RequestId = InterlockedIncrement((int*)&Device->NewRequestId);
|
||||
|
||||
// Ignore return since this msg is optional.
|
||||
/* Ignore return since this msg is optional. */
|
||||
RndisFilterSendRequest(Device, request);
|
||||
|
||||
Device->State = RNDIS_DEV_UNINITIALIZED;
|
||||
|
@ -948,9 +948,9 @@ RndisFilterOnDeviceAdd(
|
|||
|
||||
DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
|
||||
|
||||
// Let the inner driver handle this first to create the netvsc channel
|
||||
// NOTE! Once the channel is created, we may get a receive callback
|
||||
// (RndisFilterOnReceive()) before this call is completed
|
||||
/* Let the inner driver handle this first to create the netvsc channel */
|
||||
/* NOTE! Once the channel is created, we may get a receive callback */
|
||||
/* (RndisFilterOnReceive()) before this call is completed */
|
||||
ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -959,9 +959,9 @@ RndisFilterOnDeviceAdd(
|
|||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// Initialize the rndis device
|
||||
//
|
||||
|
||||
/* Initialize the rndis device */
|
||||
|
||||
netDevice = (NETVSC_DEVICE*)Device->Extension;
|
||||
ASSERT(netDevice);
|
||||
ASSERT(netDevice->Device);
|
||||
|
@ -969,18 +969,18 @@ RndisFilterOnDeviceAdd(
|
|||
netDevice->Extension = rndisDevice;
|
||||
rndisDevice->NetDevice = netDevice;
|
||||
|
||||
// Send the rndis initialization message
|
||||
/* Send the rndis initialization message */
|
||||
ret = RndisFilterInitDevice(rndisDevice);
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO: If rndis init failed, we will need to shut down the channel
|
||||
/* TODO: If rndis init failed, we will need to shut down the channel */
|
||||
}
|
||||
|
||||
// Get the mac address
|
||||
/* Get the mac address */
|
||||
ret = RndisFilterQueryDeviceMac(rndisDevice);
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO: shutdown rndis device and the channel
|
||||
/* TODO: shutdown rndis device and the channel */
|
||||
}
|
||||
|
||||
DPRINT_INFO(NETVSC, "Device 0x%p mac addr %02x%02x%02x%02x%02x%02x",
|
||||
|
@ -1015,13 +1015,13 @@ RndisFilterOnDeviceRemove(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Halt and release the rndis device
|
||||
/* Halt and release the rndis device */
|
||||
RndisFilterHaltDevice(rndisDevice);
|
||||
|
||||
PutRndisDevice(rndisDevice);
|
||||
netDevice->Extension = NULL;
|
||||
|
||||
// Pass control to inner driver to remove the device
|
||||
/* Pass control to inner driver to remove the device */
|
||||
gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device);
|
||||
|
||||
DPRINT_EXIT(NETVSC);
|
||||
|
@ -1091,7 +1091,7 @@ RndisFilterOnSend(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Add the rndis header
|
||||
/* Add the rndis header */
|
||||
filterPacket = (RNDIS_FILTER_PACKET*)Packet->Extension;
|
||||
ASSERT(filterPacket);
|
||||
|
||||
|
@ -1112,18 +1112,18 @@ RndisFilterOnSend(
|
|||
Packet->PageBuffers[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1);
|
||||
Packet->PageBuffers[0].Length = rndisMessageSize;
|
||||
|
||||
// Save the packet send completion and context
|
||||
/* Save the packet send completion and context */
|
||||
filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion;
|
||||
filterPacket->CompletionContext = Packet->Completion.Send.SendCompletionContext;
|
||||
|
||||
// Use ours
|
||||
/* Use ours */
|
||||
Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion;
|
||||
Packet->Completion.Send.SendCompletionContext = filterPacket;
|
||||
|
||||
ret = gRndisFilter.InnerDriver.OnSend(Device, Packet);
|
||||
if (ret != 0)
|
||||
{
|
||||
// Reset the completion to originals to allow retries from above
|
||||
/* Reset the completion to originals to allow retries from above */
|
||||
Packet->Completion.Send.OnSendCompletion = filterPacket->OnCompletion;
|
||||
Packet->Completion.Send.SendCompletionContext = filterPacket->CompletionContext;
|
||||
}
|
||||
|
@ -1141,7 +1141,7 @@ RndisFilterOnSendCompletion(
|
|||
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Pass it back to the original handler
|
||||
/* Pass it back to the original handler */
|
||||
filterPacket->OnCompletion(filterPacket->CompletionContext);
|
||||
|
||||
DPRINT_EXIT(NETVSC);
|
||||
|
@ -1155,6 +1155,6 @@ RndisFilterOnSendRequestCompletion(
|
|||
{
|
||||
DPRINT_ENTER(NETVSC);
|
||||
|
||||
// Noop
|
||||
/* Noop */
|
||||
DPRINT_EXIT(NETVSC);
|
||||
}
|
||||
|
|
|
@ -49,13 +49,13 @@
|
|||
|
||||
|
||||
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
|
||||
/* Interface */
|
||||
|
||||
int
|
||||
RndisFilterInit(
|
||||
NETVSC_DRIVER_OBJECT *Driver
|
||||
);
|
||||
|
||||
|
||||
#endif // _RNDISFILTER_H_
|
||||
#endif /* _RNDISFILTER_H_ */
|
||||
|
|
|
@ -32,45 +32,48 @@
|
|||
#include "include/vstorage.h"
|
||||
|
||||
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
/* #defines */
|
||||
|
||||
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
typedef struct _STORVSC_REQUEST_EXTENSION {
|
||||
//LIST_ENTRY ListEntry;
|
||||
/* LIST_ENTRY ListEntry; */
|
||||
|
||||
STORVSC_REQUEST *Request;
|
||||
DEVICE_OBJECT *Device;
|
||||
|
||||
// Synchronize the request/response if needed
|
||||
/* Synchronize the request/response if needed */
|
||||
HANDLE WaitEvent;
|
||||
|
||||
VSTOR_PACKET VStorPacket;
|
||||
} STORVSC_REQUEST_EXTENSION;
|
||||
|
||||
|
||||
// A storvsc device is a device object that contains a vmbus channel
|
||||
/* A storvsc device is a device object that contains a vmbus channel */
|
||||
typedef struct _STORVSC_DEVICE{
|
||||
DEVICE_OBJECT *Device;
|
||||
|
||||
int RefCount; // 0 indicates the device is being destroyed
|
||||
int RefCount; /* 0 indicates the device is being destroyed */
|
||||
|
||||
int NumOutstandingRequests;
|
||||
|
||||
// Each unique Port/Path/Target represents 1 channel ie scsi controller. In reality, the pathid, targetid is always 0
|
||||
// and the port is set by us
|
||||
/*
|
||||
* Each unique Port/Path/Target represents 1 channel ie scsi
|
||||
* controller. In reality, the pathid, targetid is always 0
|
||||
* and the port is set by us
|
||||
*/
|
||||
unsigned int PortNumber;
|
||||
unsigned char PathId;
|
||||
unsigned char TargetId;
|
||||
|
||||
//LIST_ENTRY OutstandingRequestList;
|
||||
//HANDLE OutstandingRequestLock;
|
||||
/* LIST_ENTRY OutstandingRequestList; */
|
||||
/* HANDLE OutstandingRequestLock; */
|
||||
|
||||
// Used for vsc/vsp channel reset process
|
||||
/* Used for vsc/vsp channel reset process */
|
||||
STORVSC_REQUEST_EXTENSION InitRequest;
|
||||
|
||||
STORVSC_REQUEST_EXTENSION ResetRequest;
|
||||
|
@ -78,19 +81,19 @@ typedef struct _STORVSC_DEVICE{
|
|||
} STORVSC_DEVICE;
|
||||
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
/* Globals */
|
||||
|
||||
static const char* gDriverName="storvsc";
|
||||
|
||||
//{ba6163d9-04a1-4d29-b605-72e2ffb1dc7f}
|
||||
/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
|
||||
static const GUID gStorVscDeviceType={
|
||||
.Data = {0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f}
|
||||
};
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
|
||||
/* Internal routines */
|
||||
|
||||
static int
|
||||
StorVscOnDeviceAdd(
|
||||
DEVICE_OBJECT *Device,
|
||||
|
@ -150,8 +153,8 @@ static inline STORVSC_DEVICE* AllocStorDevice(DEVICE_OBJECT *Device)
|
|||
if (!storDevice)
|
||||
return NULL;
|
||||
|
||||
// Set to 2 to allow both inbound and outbound traffics
|
||||
// (ie GetStorDevice() and MustGetStorDevice()) to proceed.
|
||||
/* Set to 2 to allow both inbound and outbound traffics */
|
||||
/* (ie GetStorDevice() and MustGetStorDevice()) to proceed. */
|
||||
InterlockedCompareExchange(&storDevice->RefCount, 2, 0);
|
||||
|
||||
storDevice->Device = Device;
|
||||
|
@ -166,7 +169,7 @@ static inline void FreeStorDevice(STORVSC_DEVICE *Device)
|
|||
kfree(Device);
|
||||
}
|
||||
|
||||
// Get the stordevice object iff exists and its refcount > 1
|
||||
/* Get the stordevice object iff exists and its refcount > 1 */
|
||||
static inline STORVSC_DEVICE* GetStorDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
STORVSC_DEVICE *storDevice;
|
||||
|
@ -184,7 +187,7 @@ static inline STORVSC_DEVICE* GetStorDevice(DEVICE_OBJECT *Device)
|
|||
return storDevice;
|
||||
}
|
||||
|
||||
// Get the stordevice object iff exists and its refcount > 0
|
||||
/* Get the stordevice object iff exists and its refcount > 0 */
|
||||
static inline STORVSC_DEVICE* MustGetStorDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
STORVSC_DEVICE *storDevice;
|
||||
|
@ -213,7 +216,7 @@ static inline void PutStorDevice(DEVICE_OBJECT *Device)
|
|||
ASSERT(storDevice->RefCount);
|
||||
}
|
||||
|
||||
// Drop ref count to 1 to effectively disable GetStorDevice()
|
||||
/* Drop ref count to 1 to effectively disable GetStorDevice() */
|
||||
static inline STORVSC_DEVICE* ReleaseStorDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
STORVSC_DEVICE *storDevice;
|
||||
|
@ -221,7 +224,7 @@ static inline STORVSC_DEVICE* ReleaseStorDevice(DEVICE_OBJECT *Device)
|
|||
storDevice = (STORVSC_DEVICE*)Device->Extension;
|
||||
ASSERT(storDevice);
|
||||
|
||||
// Busy wait until the ref drop to 2, then set it to 1
|
||||
/* Busy wait until the ref drop to 2, then set it to 1 */
|
||||
while (InterlockedCompareExchange(&storDevice->RefCount, 1, 2) != 2)
|
||||
{
|
||||
udelay(100);
|
||||
|
@ -230,7 +233,7 @@ static inline STORVSC_DEVICE* ReleaseStorDevice(DEVICE_OBJECT *Device)
|
|||
return storDevice;
|
||||
}
|
||||
|
||||
// Drop ref count to 0. No one can use StorDevice object.
|
||||
/* Drop ref count to 0. No one can use StorDevice object. */
|
||||
static inline STORVSC_DEVICE* FinalReleaseStorDevice(DEVICE_OBJECT *Device)
|
||||
{
|
||||
STORVSC_DEVICE *storDevice;
|
||||
|
@ -238,7 +241,7 @@ static inline STORVSC_DEVICE* FinalReleaseStorDevice(DEVICE_OBJECT *Device)
|
|||
storDevice = (STORVSC_DEVICE*)Device->Extension;
|
||||
ASSERT(storDevice);
|
||||
|
||||
// Busy wait until the ref drop to 1, then set it to 0
|
||||
/* Busy wait until the ref drop to 1, then set it to 0 */
|
||||
while (InterlockedCompareExchange(&storDevice->RefCount, 0, 1) != 1)
|
||||
{
|
||||
udelay(100);
|
||||
|
@ -271,7 +274,7 @@ StorVscInitialize(
|
|||
DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%d sizeof(STORVSC_REQUEST_EXTENSION)=%d sizeof(VSTOR_PACKET)=%d, sizeof(VMSCSI_REQUEST)=%d",
|
||||
sizeof(STORVSC_REQUEST), sizeof(STORVSC_REQUEST_EXTENSION), sizeof(VSTOR_PACKET), sizeof(VMSCSI_REQUEST));
|
||||
|
||||
// Make sure we are at least 2 pages since 1 page is used for control
|
||||
/* Make sure we are at least 2 pages since 1 page is used for control */
|
||||
ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1));
|
||||
|
||||
Driver->name = gDriverName;
|
||||
|
@ -279,14 +282,18 @@ StorVscInitialize(
|
|||
|
||||
storDriver->RequestExtSize = sizeof(STORVSC_REQUEST_EXTENSION);
|
||||
|
||||
// Divide the ring buffer data size (which is 1 page less than the ring buffer size since that page is reserved for the ring buffer indices)
|
||||
// by the max request size (which is VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + VSTOR_PACKET + u64)
|
||||
/*
|
||||
* Divide the ring buffer data size (which is 1 page less
|
||||
* than the ring buffer size since that page is reserved for
|
||||
* the ring buffer indices) by the max request size (which is
|
||||
* VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER + VSTOR_PACKET + u64)
|
||||
*/
|
||||
storDriver->MaxOutstandingRequestsPerChannel =
|
||||
((storDriver->RingBufferSize - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(VSTOR_PACKET) + sizeof(u64),sizeof(u64)));
|
||||
|
||||
DPRINT_INFO(STORVSC, "max io %u, currently %u\n", storDriver->MaxOutstandingRequestsPerChannel, STORVSC_MAX_IO_REQUESTS);
|
||||
|
||||
// Setup the dispatch table
|
||||
/* Setup the dispatch table */
|
||||
storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd;
|
||||
storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove;
|
||||
storDriver->Base.OnCleanup = StorVscOnCleanup;
|
||||
|
@ -316,7 +323,7 @@ StorVscOnDeviceAdd(
|
|||
{
|
||||
int ret=0;
|
||||
STORVSC_DEVICE *storDevice;
|
||||
//VMSTORAGE_CHANNEL_PROPERTIES *props;
|
||||
/* VMSTORAGE_CHANNEL_PROPERTIES *props; */
|
||||
STORVSC_DEVICE_INFO *deviceInfo = (STORVSC_DEVICE_INFO*)AdditionalInfo;
|
||||
|
||||
DPRINT_ENTER(STORVSC);
|
||||
|
@ -328,21 +335,25 @@ StorVscOnDeviceAdd(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Save the channel properties to our storvsc channel
|
||||
//props = (VMSTORAGE_CHANNEL_PROPERTIES*) channel->offerMsg.Offer.u.Standard.UserDefined;
|
||||
/* Save the channel properties to our storvsc channel */
|
||||
/* props = (VMSTORAGE_CHANNEL_PROPERTIES*) channel->offerMsg.Offer.u.Standard.UserDefined; */
|
||||
|
||||
// FIXME:
|
||||
// If we support more than 1 scsi channel, we need to set the port number here
|
||||
// to the scsi channel but how do we get the scsi channel prior to the bus scan
|
||||
/*storChannel->PortNumber = 0;
|
||||
/* FIXME: */
|
||||
/*
|
||||
* If we support more than 1 scsi channel, we need to set the
|
||||
* port number here to the scsi channel but how do we get the
|
||||
* scsi channel prior to the bus scan
|
||||
*/
|
||||
|
||||
/* storChannel->PortNumber = 0;
|
||||
storChannel->PathId = props->PathId;
|
||||
storChannel->TargetId = props->TargetId;*/
|
||||
storChannel->TargetId = props->TargetId; */
|
||||
|
||||
storDevice->PortNumber = deviceInfo->PortNumber;
|
||||
// Send it back up
|
||||
/* Send it back up */
|
||||
ret = StorVscConnectToVsp(Device);
|
||||
|
||||
//deviceInfo->PortNumber = storDevice->PortNumber;
|
||||
/* deviceInfo->PortNumber = storDevice->PortNumber; */
|
||||
deviceInfo->PathId = storDevice->PathId;
|
||||
deviceInfo->TargetId = storDevice->TargetId;
|
||||
|
||||
|
@ -372,7 +383,7 @@ static int StorVscChannelInit(DEVICE_OBJECT *Device)
|
|||
request = &storDevice->InitRequest;
|
||||
vstorPacket = &request->VStorPacket;
|
||||
|
||||
// Now, initiate the vsc/vsp initialization protocol on the open channel
|
||||
/* Now, initiate the vsc/vsp initialization protocol on the open channel */
|
||||
|
||||
memset(request, sizeof(STORVSC_REQUEST_EXTENSION), 0);
|
||||
request->WaitEvent = WaitEventCreate();
|
||||
|
@ -408,7 +419,7 @@ static int StorVscChannelInit(DEVICE_OBJECT *Device)
|
|||
|
||||
DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
|
||||
|
||||
// reuse the packet for version range supported
|
||||
/* reuse the packet for version range supported */
|
||||
memset(vstorPacket, sizeof(VSTOR_PACKET), 0);
|
||||
vstorPacket->Operation = VStorOperationQueryProtocolVersion;
|
||||
vstorPacket->Flags = REQUEST_COMPLETION_FLAG;
|
||||
|
@ -430,14 +441,14 @@ static int StorVscChannelInit(DEVICE_OBJECT *Device)
|
|||
|
||||
WaitEventWait(request->WaitEvent);
|
||||
|
||||
// TODO: Check returned version
|
||||
/* TODO: Check returned version */
|
||||
if (vstorPacket->Operation != VStorOperationCompleteIo || vstorPacket->Status != 0)
|
||||
{
|
||||
DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed (op %d status 0x%lx)", vstorPacket->Operation, vstorPacket->Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Query channel properties
|
||||
/* Query channel properties */
|
||||
DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
|
||||
|
||||
memset(vstorPacket, sizeof(VSTOR_PACKET), 0);
|
||||
|
@ -460,14 +471,14 @@ static int StorVscChannelInit(DEVICE_OBJECT *Device)
|
|||
|
||||
WaitEventWait(request->WaitEvent);
|
||||
|
||||
// TODO: Check returned version
|
||||
/* TODO: Check returned version */
|
||||
if (vstorPacket->Operation != VStorOperationCompleteIo || vstorPacket->Status != 0)
|
||||
{
|
||||
DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed (op %d status 0x%lx)", vstorPacket->Operation, vstorPacket->Status);
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
//storDevice->PortNumber = vstorPacket->StorageChannelProperties.PortNumber;
|
||||
/* storDevice->PortNumber = vstorPacket->StorageChannelProperties.PortNumber; */
|
||||
storDevice->PathId = vstorPacket->StorageChannelProperties.PathId;
|
||||
storDevice->TargetId = vstorPacket->StorageChannelProperties.TargetId;
|
||||
|
||||
|
@ -528,7 +539,7 @@ StorVscConnectToVsp(
|
|||
|
||||
memset(&props, sizeof(VMSTORAGE_CHANNEL_PROPERTIES), 0);
|
||||
|
||||
// Open the channel
|
||||
/* Open the channel */
|
||||
ret = Device->Driver->VmbusChannelInterface.Open(Device,
|
||||
storDriver->RingBufferSize,
|
||||
storDriver->RingBufferSize,
|
||||
|
@ -575,8 +586,11 @@ StorVscOnDeviceRemove(
|
|||
|
||||
storDevice = ReleaseStorDevice(Device);
|
||||
|
||||
// At this point, all outbound traffic should be disable. We only allow inbound traffic (responses) to proceed
|
||||
// so that outstanding requests can be completed.
|
||||
/*
|
||||
* At this point, all outbound traffic should be disable. We
|
||||
* only allow inbound traffic (responses) to proceed so that
|
||||
* outstanding requests can be completed.
|
||||
*/
|
||||
while (storDevice->NumOutstandingRequests)
|
||||
{
|
||||
DPRINT_INFO(STORVSC, "waiting for %d requests to complete...", storDevice->NumOutstandingRequests);
|
||||
|
@ -590,7 +604,7 @@ StorVscOnDeviceRemove(
|
|||
|
||||
DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice);
|
||||
|
||||
// Close the channel
|
||||
/* Close the channel */
|
||||
Device->Driver->VmbusChannelInterface.Close(Device);
|
||||
|
||||
FreeStorDevice(storDevice);
|
||||
|
@ -599,22 +613,23 @@ StorVscOnDeviceRemove(
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* ***************
|
||||
static void
|
||||
StorVscOnTargetRescan(
|
||||
void *Context
|
||||
)
|
||||
{
|
||||
DEVICE_OBJECT *device=(DEVICE_OBJECT*)Context;
|
||||
STORVSC_DRIVER_OBJECT *storDriver;
|
||||
|
||||
//static void
|
||||
//StorVscOnTargetRescan(
|
||||
// void *Context
|
||||
// )
|
||||
//{
|
||||
// DEVICE_OBJECT *device=(DEVICE_OBJECT*)Context;
|
||||
// STORVSC_DRIVER_OBJECT *storDriver;
|
||||
//
|
||||
// DPRINT_ENTER(STORVSC);
|
||||
//
|
||||
// storDriver = (STORVSC_DRIVER_OBJECT*) device->Driver;
|
||||
// storDriver->OnHostRescan(device);
|
||||
//
|
||||
// DPRINT_EXIT(STORVSC);
|
||||
//}
|
||||
DPRINT_ENTER(STORVSC);
|
||||
|
||||
storDriver = (STORVSC_DRIVER_OBJECT*) device->Driver;
|
||||
storDriver->OnHostRescan(device);
|
||||
|
||||
DPRINT_EXIT(STORVSC);
|
||||
}
|
||||
*********** */
|
||||
|
||||
int
|
||||
StorVscOnHostReset(
|
||||
|
@ -660,13 +675,16 @@ StorVscOnHostReset(
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// FIXME: Add a timeout
|
||||
/* FIXME: Add a timeout */
|
||||
WaitEventWait(request->WaitEvent);
|
||||
|
||||
WaitEventClose(request->WaitEvent);
|
||||
DPRINT_INFO(STORVSC, "host adapter reset completed");
|
||||
|
||||
// At this point, all outstanding requests in the adapter should have been flushed out and return to us
|
||||
/*
|
||||
* At this point, all outstanding requests in the adapter
|
||||
* should have been flushed out and return to us
|
||||
*/
|
||||
|
||||
Cleanup:
|
||||
PutStorDevice(Device);
|
||||
|
@ -729,7 +747,7 @@ StorVscOnIORequest(
|
|||
|
||||
vstorPacket->VmSrb.SenseInfoLength = SENSE_BUFFER_SIZE;
|
||||
|
||||
// Copy over the scsi command descriptor block
|
||||
/* Copy over the scsi command descriptor block */
|
||||
vstorPacket->VmSrb.CdbLength = Request->CdbLen;
|
||||
memcpy(&vstorPacket->VmSrb.Cdb, Request->Cdb, Request->CdbLen);
|
||||
|
||||
|
@ -827,7 +845,7 @@ StorVscOnIOCompletion(
|
|||
|
||||
ASSERT(request->OnIOCompletion != NULL);
|
||||
|
||||
// Copy over the status...etc
|
||||
/* Copy over the status...etc */
|
||||
request->Status = VStorPacket->VmSrb.ScsiStatus;
|
||||
|
||||
if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1)
|
||||
|
@ -838,9 +856,9 @@ StorVscOnIOCompletion(
|
|||
VStorPacket->VmSrb.SrbStatus);
|
||||
}
|
||||
|
||||
if ((request->Status & 0xFF) == 0x02) // CHECK_CONDITION
|
||||
if ((request->Status & 0xFF) == 0x02) /* CHECK_CONDITION */
|
||||
{
|
||||
if (VStorPacket->VmSrb.SrbStatus & 0x80) // autosense data available
|
||||
if (VStorPacket->VmSrb.SrbStatus & 0x80) /* autosense data available */
|
||||
{
|
||||
DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data valid - len %d\n",
|
||||
RequestExt, VStorPacket->VmSrb.SenseInfoLength);
|
||||
|
@ -854,7 +872,7 @@ StorVscOnIOCompletion(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
request->BytesXfer = VStorPacket->VmSrb.DataTransferLength;
|
||||
|
||||
request->OnIOCompletion(request);
|
||||
|
@ -882,17 +900,17 @@ StorVscOnReceive(
|
|||
StorVscOnIOCompletion(Device, VStorPacket, RequestExt);
|
||||
break;
|
||||
|
||||
//case ENUMERATE_DEVICE_OPERATION:
|
||||
/* case ENUMERATE_DEVICE_OPERATION: */
|
||||
|
||||
// DPRINT_INFO(STORVSC, "ENUMERATE_DEVICE_OPERATION");
|
||||
/* DPRINT_INFO(STORVSC, "ENUMERATE_DEVICE_OPERATION"); */
|
||||
|
||||
// StorVscOnTargetRescan(Device);
|
||||
// break;
|
||||
/* StorVscOnTargetRescan(Device); */
|
||||
/* break; */
|
||||
|
||||
case VStorOperationRemoveDevice:
|
||||
case VStorOperationRemoveDevice:
|
||||
|
||||
DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION");
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -937,15 +955,15 @@ StorVscOnChannelCallback(
|
|||
{
|
||||
DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", bytesRecvd, requestId);
|
||||
|
||||
//ASSERT(bytesRecvd == sizeof(VSTOR_PACKET));
|
||||
/* ASSERT(bytesRecvd == sizeof(VSTOR_PACKET)); */
|
||||
|
||||
request = (STORVSC_REQUEST_EXTENSION*)(unsigned long)requestId;
|
||||
ASSERT(request);
|
||||
|
||||
//if (vstorPacket.Flags & SYNTHETIC_FLAG)
|
||||
/* if (vstorPacket.Flags & SYNTHETIC_FLAG) */
|
||||
if ((request == &storDevice->InitRequest) || (request == &storDevice->ResetRequest))
|
||||
{
|
||||
//DPRINT_INFO(STORVSC, "reset completion - operation %u status %u", vstorPacket.Operation, vstorPacket.Status);
|
||||
/* DPRINT_INFO(STORVSC, "reset completion - operation %u status %u", vstorPacket.Operation, vstorPacket.Status); */
|
||||
|
||||
memcpy(&request->VStorPacket, packet, sizeof(VSTOR_PACKET));
|
||||
|
||||
|
@ -958,7 +976,7 @@ StorVscOnChannelCallback(
|
|||
}
|
||||
else
|
||||
{
|
||||
//DPRINT_DBG(STORVSC, "nothing else to read...");
|
||||
/* DPRINT_DBG(STORVSC, "nothing else to read..."); */
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
|
|
@ -27,29 +27,31 @@
|
|||
#include "VersionInfo.h"
|
||||
#include "VmbusPrivate.h"
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
/* Globals */
|
||||
|
||||
static const char* gDriverName="vmbus";
|
||||
|
||||
// Windows vmbus does not defined this. We defined this to be consistent with other devices
|
||||
//{c5295816-f63a-4d5f-8d1a-4daf999ca185}
|
||||
/* Windows vmbus does not defined this.
|
||||
* We defined this to be consistent with other devices
|
||||
*/
|
||||
/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */
|
||||
static const GUID gVmbusDeviceType={
|
||||
.Data = {0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85}
|
||||
};
|
||||
|
||||
//{ac3760fc-9adf-40aa-9427-a70ed6de95c5}
|
||||
/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */
|
||||
static const GUID gVmbusDeviceId={
|
||||
.Data = {0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5}
|
||||
};
|
||||
|
||||
static DRIVER_OBJECT* gDriver; // vmbus driver object
|
||||
static DEVICE_OBJECT* gDevice; // vmbus root device
|
||||
static DRIVER_OBJECT* gDriver; /* vmbus driver object */
|
||||
static DEVICE_OBJECT* gDevice; /* vmbus root device */
|
||||
|
||||
|
||||
//
|
||||
// Internal routines
|
||||
//
|
||||
|
||||
/* Internal routines */
|
||||
|
||||
|
||||
static void
|
||||
VmbusGetChannelInterface(
|
||||
|
@ -129,7 +131,7 @@ VmbusInitialize(
|
|||
drv->name = gDriverName;
|
||||
memcpy(&drv->deviceType, &gVmbusDeviceType, sizeof(GUID));
|
||||
|
||||
// Setup dispatch table
|
||||
/* Setup dispatch table */
|
||||
driver->Base.OnDeviceAdd = VmbusOnDeviceAdd;
|
||||
driver->Base.OnDeviceRemove = VmbusOnDeviceRemove;
|
||||
driver->Base.OnCleanup = VmbusOnCleanup;
|
||||
|
@ -140,7 +142,7 @@ VmbusInitialize(
|
|||
driver->GetChannelInterface = VmbusGetChannelInterface;
|
||||
driver->GetChannelInfo = VmbusGetChannelInfo;
|
||||
|
||||
// Hypervisor initialization...setup hypercall page..etc
|
||||
/* Hypervisor initialization...setup hypercall page..etc */
|
||||
ret = HvInit();
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -283,15 +285,18 @@ Description:
|
|||
Release the child device from the vmbus
|
||||
|
||||
--*/
|
||||
//void
|
||||
//VmbusChildDeviceDestroy(
|
||||
// DEVICE_OBJECT* ChildDevice
|
||||
// )
|
||||
//{
|
||||
// VMBUS_DRIVER_OBJECT* vmbusDriver = (VMBUS_DRIVER_OBJECT*)gDriver;
|
||||
//
|
||||
// vmbusDriver->OnChildDeviceDestroy(ChildDevice);
|
||||
//}
|
||||
|
||||
/* **************
|
||||
void
|
||||
VmbusChildDeviceDestroy(
|
||||
DEVICE_OBJECT* ChildDevice
|
||||
)
|
||||
{
|
||||
VMBUS_DRIVER_OBJECT* vmbusDriver = (VMBUS_DRIVER_OBJECT*)gDriver;
|
||||
|
||||
vmbusDriver->OnChildDeviceDestroy(ChildDevice);
|
||||
}
|
||||
************* */
|
||||
|
||||
/*++
|
||||
|
||||
|
@ -318,14 +323,14 @@ VmbusOnDeviceAdd(
|
|||
memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(GUID));
|
||||
memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, sizeof(GUID));
|
||||
|
||||
//strcpy(dev->name, "vmbus");
|
||||
// SynIC setup...
|
||||
/* strcpy(dev->name, "vmbus"); */
|
||||
/* SynIC setup... */
|
||||
ret = HvSynicInit(*irqvector);
|
||||
|
||||
// Connect to VMBus in the root partition
|
||||
/* Connect to VMBus in the root partition */
|
||||
ret = VmbusConnect();
|
||||
|
||||
//VmbusSendEvent(device->localPortId+1);
|
||||
/* VmbusSendEvent(device->localPortId+1); */
|
||||
DPRINT_EXIT(VMBUS);
|
||||
|
||||
return ret;
|
||||
|
@ -375,7 +380,7 @@ VmbusOnCleanup(
|
|||
DRIVER_OBJECT* drv
|
||||
)
|
||||
{
|
||||
//VMBUS_DRIVER_OBJECT* driver = (VMBUS_DRIVER_OBJECT*)drv;
|
||||
/* VMBUS_DRIVER_OBJECT* driver = (VMBUS_DRIVER_OBJECT*)drv; */
|
||||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
|
@ -405,7 +410,7 @@ VmbusOnMsgDPC(
|
|||
HV_MESSAGE *copied;
|
||||
while (1)
|
||||
{
|
||||
if (msg->Header.MessageType == HvMessageTypeNone) // no msg
|
||||
if (msg->Header.MessageType == HvMessageTypeNone) /* no msg */
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -423,14 +428,22 @@ VmbusOnMsgDPC(
|
|||
|
||||
msg->Header.MessageType = HvMessageTypeNone;
|
||||
|
||||
// Make sure the write to MessageType (ie set to HvMessageTypeNone) happens
|
||||
// before we read the MessagePending and EOMing. Otherwise, the EOMing will not deliver
|
||||
// any more messages since there is no empty slot
|
||||
/*
|
||||
* Make sure the write to MessageType (ie set to
|
||||
* HvMessageTypeNone) happens before we read the
|
||||
* MessagePending and EOMing. Otherwise, the EOMing
|
||||
* will not deliver any more messages since there is
|
||||
* no empty slot
|
||||
*/
|
||||
mb();
|
||||
|
||||
if (msg->Header.MessageFlags.MessagePending)
|
||||
{
|
||||
// This will cause message queue rescan to possibly deliver another msg from the hypervisor
|
||||
/*
|
||||
* This will cause message queue rescan to
|
||||
* possibly deliver another msg from the
|
||||
* hypervisor
|
||||
*/
|
||||
WriteMsr(HV_X64_MSR_EOM, 0);
|
||||
}
|
||||
}
|
||||
|
@ -450,7 +463,7 @@ VmbusOnEventDPC(
|
|||
DRIVER_OBJECT* drv
|
||||
)
|
||||
{
|
||||
// TODO: Process any events
|
||||
/* TODO: Process any events */
|
||||
VmbusOnEvents();
|
||||
}
|
||||
|
||||
|
@ -469,33 +482,33 @@ VmbusOnISR(
|
|||
DRIVER_OBJECT* drv
|
||||
)
|
||||
{
|
||||
//VMBUS_DRIVER_OBJECT* driver = (VMBUS_DRIVER_OBJECT*)drv;
|
||||
/* VMBUS_DRIVER_OBJECT* driver = (VMBUS_DRIVER_OBJECT*)drv; */
|
||||
|
||||
int ret=0;
|
||||
//struct page* page;
|
||||
/* struct page* page; */
|
||||
void *page_addr;
|
||||
HV_MESSAGE* msg;
|
||||
HV_SYNIC_EVENT_FLAGS* event;
|
||||
|
||||
//page = SynICMessagePage[0];
|
||||
//page_addr = page_address(page);
|
||||
/* page = SynICMessagePage[0]; */
|
||||
/* page_addr = page_address(page); */
|
||||
page_addr = gHvContext.synICMessagePage[0];
|
||||
msg = (HV_MESSAGE*)page_addr + VMBUS_MESSAGE_SINT;
|
||||
|
||||
DPRINT_ENTER(VMBUS);
|
||||
|
||||
// Check if there are actual msgs to be process
|
||||
/* Check if there are actual msgs to be process */
|
||||
if (msg->Header.MessageType != HvMessageTypeNone)
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "received msg type %d size %d", msg->Header.MessageType, msg->Header.PayloadSize);
|
||||
ret |= 0x1;
|
||||
}
|
||||
|
||||
// TODO: Check if there are events to be process
|
||||
/* TODO: Check if there are events to be process */
|
||||
page_addr = gHvContext.synICEventPage[0];
|
||||
event = (HV_SYNIC_EVENT_FLAGS*)page_addr + VMBUS_MESSAGE_SINT;
|
||||
|
||||
// Since we are a child, we only need to check bit 0
|
||||
/* Since we are a child, we only need to check bit 0 */
|
||||
if (BitTestAndClear(&event->Flags32[0], 0))
|
||||
{
|
||||
DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]);
|
||||
|
@ -506,4 +519,4 @@ VmbusOnISR(
|
|||
return ret;
|
||||
}
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -30,26 +30,29 @@
|
|||
#include "Channel.h"
|
||||
#include "ChannelMgmt.h"
|
||||
#include "ChannelInterface.h"
|
||||
//#include "ChannelMessages.h"
|
||||
/* #include "ChannelMessages.h" */
|
||||
#include "RingBuffer.h"
|
||||
//#include "Packet.h"
|
||||
/* #include "Packet.h" */
|
||||
#include "include/List.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
// Maximum channels is determined by the size of the interrupt page which is PAGE_SIZE. 1/2 of PAGE_SIZE is for
|
||||
// send endpoint interrupt and the other is receive endpoint interrupt
|
||||
#define MAX_NUM_CHANNELS (PAGE_SIZE >> 1) << 3 // 16348 channels
|
||||
/* Defines */
|
||||
|
||||
// The value here must be in multiple of 32
|
||||
// TODO: Need to make this configurable
|
||||
|
||||
/*
|
||||
* Maximum channels is determined by the size of the interrupt page
|
||||
* which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
|
||||
* and the other is receive endpoint interrupt
|
||||
*/
|
||||
#define MAX_NUM_CHANNELS (PAGE_SIZE >> 1) << 3 /* 16348 channels */
|
||||
|
||||
/* The value here must be in multiple of 32 */
|
||||
/* TODO: Need to make this configurable */
|
||||
#define MAX_NUM_CHANNELS_SUPPORTED 256
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
typedef enum {
|
||||
Disconnected,
|
||||
|
@ -66,23 +69,27 @@ typedef struct _VMBUS_CONNECTION {
|
|||
|
||||
u32 NextGpadlHandle;
|
||||
|
||||
// Represents channel interrupts. Each bit position
|
||||
// represents a channel.
|
||||
// When a channel sends an interrupt via VMBUS, it
|
||||
// finds its bit in the sendInterruptPage, set it and
|
||||
// calls Hv to generate a port event. The other end
|
||||
// receives the port event and parse the recvInterruptPage
|
||||
// to see which bit is set
|
||||
/*
|
||||
* Represents channel interrupts. Each bit position represents
|
||||
* a channel. When a channel sends an interrupt via VMBUS, it
|
||||
* finds its bit in the sendInterruptPage, set it and calls Hv
|
||||
* to generate a port event. The other end receives the port
|
||||
* event and parse the recvInterruptPage to see which bit is
|
||||
* set
|
||||
*/
|
||||
void * InterruptPage;
|
||||
void * SendInterruptPage;
|
||||
void * RecvInterruptPage;
|
||||
|
||||
// 2 pages - 1st page for parent->child notification and 2nd is child->parent notification
|
||||
/*
|
||||
* 2 pages - 1st page for parent->child notification and 2nd
|
||||
* is child->parent notification
|
||||
*/
|
||||
void * MonitorPages;
|
||||
LIST_ENTRY ChannelMsgList;
|
||||
spinlock_t channelmsg_lock;
|
||||
|
||||
// List of channels
|
||||
/* List of channels */
|
||||
LIST_ENTRY ChannelList;
|
||||
spinlock_t channel_lock;
|
||||
|
||||
|
@ -91,25 +98,25 @@ typedef struct _VMBUS_CONNECTION {
|
|||
|
||||
|
||||
typedef struct _VMBUS_MSGINFO {
|
||||
// Bookkeeping stuff
|
||||
/* Bookkeeping stuff */
|
||||
LIST_ENTRY MsgListEntry;
|
||||
|
||||
// Synchronize the request/response if needed
|
||||
/* Synchronize the request/response if needed */
|
||||
HANDLE WaitEvent;
|
||||
|
||||
// The message itself
|
||||
/* The message itself */
|
||||
unsigned char Msg[0];
|
||||
} VMBUS_MSGINFO;
|
||||
|
||||
|
||||
//
|
||||
// Externs
|
||||
//
|
||||
|
||||
/* Externs */
|
||||
|
||||
extern VMBUS_CONNECTION gVmbusConnection;
|
||||
|
||||
//
|
||||
// General vmbus interface
|
||||
//
|
||||
|
||||
/* General vmbus interface */
|
||||
|
||||
static DEVICE_OBJECT*
|
||||
VmbusChildDeviceCreate(
|
||||
GUID deviceType,
|
||||
|
@ -124,18 +131,18 @@ static void
|
|||
VmbusChildDeviceRemove(
|
||||
DEVICE_OBJECT* Device);
|
||||
|
||||
//static void
|
||||
//VmbusChildDeviceDestroy(
|
||||
// DEVICE_OBJECT*);
|
||||
/* static void */
|
||||
/* VmbusChildDeviceDestroy( */
|
||||
/* DEVICE_OBJECT*); */
|
||||
|
||||
static VMBUS_CHANNEL*
|
||||
GetChannelFromRelId(
|
||||
u32 relId
|
||||
);
|
||||
|
||||
//
|
||||
// Connection interface
|
||||
//
|
||||
|
||||
/* Connection interface */
|
||||
|
||||
static int
|
||||
VmbusConnect(
|
||||
void
|
||||
|
@ -163,4 +170,4 @@ VmbusOnEvents(
|
|||
);
|
||||
|
||||
|
||||
#endif // _VMBUS_PRIVATE_H_
|
||||
#endif /* _VMBUS_PRIVATE_H_ */
|
||||
|
|
|
@ -38,38 +38,41 @@
|
|||
|
||||
#include "include/StorVscApi.h"
|
||||
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
|
||||
/* #defines */
|
||||
|
||||
#define BLKVSC_MINORS 64
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
enum blkvsc_device_type {
|
||||
UNKNOWN_DEV_TYPE,
|
||||
HARDDISK_TYPE,
|
||||
DVD_TYPE,
|
||||
};
|
||||
|
||||
// This request ties the struct request and struct blkvsc_request/STORVSC_REQUEST together
|
||||
// A struct request may be represented by 1 or more struct blkvsc_request
|
||||
/*
|
||||
* This request ties the struct request and struct
|
||||
* blkvsc_request/STORVSC_REQUEST together A struct request may be
|
||||
* represented by 1 or more struct blkvsc_request
|
||||
*/
|
||||
struct blkvsc_request_group {
|
||||
int outstanding;
|
||||
int status;
|
||||
|
||||
struct list_head blkvsc_req_list; // list of blkvsc_requests
|
||||
struct list_head blkvsc_req_list; /* list of blkvsc_requests */
|
||||
};
|
||||
|
||||
|
||||
struct blkvsc_request {
|
||||
struct list_head req_entry; // blkvsc_request_group.blkvsc_req_list
|
||||
struct list_head req_entry; /* blkvsc_request_group.blkvsc_req_list */
|
||||
|
||||
struct list_head pend_entry; // block_device_context.pending_list
|
||||
struct list_head pend_entry; /* block_device_context.pending_list */
|
||||
|
||||
struct request *req; // This may be null if we generate a request internally
|
||||
struct request *req; /* This may be null if we generate a request internally */
|
||||
struct block_device_context *dev;
|
||||
struct blkvsc_request_group *group; // The group this request is part of. Maybe null
|
||||
struct blkvsc_request_group *group; /* The group this request is part of. Maybe null */
|
||||
|
||||
wait_queue_head_t wevent;
|
||||
int cond;
|
||||
|
@ -83,13 +86,13 @@ struct blkvsc_request {
|
|||
unsigned char cmnd[MAX_COMMAND_SIZE];
|
||||
|
||||
STORVSC_REQUEST request;
|
||||
// !!!DO NOT ADD ANYTHING BELOW HERE!!! Otherwise, memory can overlap, because -
|
||||
// The extension buffer falls right here and is pointed to by request.Extension;
|
||||
/* !!!DO NOT ADD ANYTHING BELOW HERE!!! Otherwise, memory can overlap, because - */
|
||||
/* The extension buffer falls right here and is pointed to by request.Extension; */
|
||||
};
|
||||
|
||||
// Per device structure
|
||||
/* Per device structure */
|
||||
struct block_device_context {
|
||||
struct device_context *device_ctx; // point back to our device context
|
||||
struct device_context *device_ctx; /* point back to our device context */
|
||||
struct kmem_cache *request_pool;
|
||||
spinlock_t lock;
|
||||
struct gendisk *gd;
|
||||
|
@ -109,14 +112,14 @@ struct block_device_context {
|
|||
int users;
|
||||
};
|
||||
|
||||
// Per driver
|
||||
/* Per driver */
|
||||
struct blkvsc_driver_context {
|
||||
// !! These must be the first 2 fields !!
|
||||
/* !! These must be the first 2 fields !! */
|
||||
struct driver_context drv_ctx;
|
||||
STORVSC_DRIVER_OBJECT drv_obj;
|
||||
};
|
||||
|
||||
// Static decl
|
||||
/* Static decl */
|
||||
static int blkvsc_probe(struct device *dev);
|
||||
static int blkvsc_remove(struct device *device);
|
||||
static void blkvsc_shutdown(struct device *device);
|
||||
|
@ -144,7 +147,7 @@ static int blkvsc_do_pending_reqs(struct block_device_context *blkdev);
|
|||
|
||||
static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE;
|
||||
|
||||
// The one and only one
|
||||
/* The one and only one */
|
||||
static struct blkvsc_driver_context g_blkvsc_drv;
|
||||
|
||||
|
||||
|
@ -178,7 +181,7 @@ int blkvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
|
||||
storvsc_drv_obj->RingBufferSize = blkvsc_ringbuffer_size;
|
||||
|
||||
// Callback to client driver to complete the initialization
|
||||
/* Callback to client driver to complete the initialization */
|
||||
pfn_drv_init(&storvsc_drv_obj->Base);
|
||||
|
||||
drv_ctx->driver.name = storvsc_drv_obj->Base.name;
|
||||
|
@ -188,7 +191,7 @@ int blkvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
drv_ctx->remove = blkvsc_remove;
|
||||
drv_ctx->shutdown = blkvsc_shutdown;
|
||||
|
||||
// The driver belongs to vmbus
|
||||
/* The driver belongs to vmbus */
|
||||
vmbus_child_driver_register(drv_ctx);
|
||||
|
||||
DPRINT_EXIT(BLKVSC_DRV);
|
||||
|
@ -201,7 +204,7 @@ static int blkvsc_drv_exit_cb(struct device *dev, void *data)
|
|||
{
|
||||
struct device **curr = (struct device **)data;
|
||||
*curr = dev;
|
||||
return 1; // stop iterating
|
||||
return 1; /* stop iterating */
|
||||
}
|
||||
|
||||
/*++
|
||||
|
@ -224,13 +227,13 @@ void blkvsc_drv_exit(void)
|
|||
{
|
||||
current_dev = NULL;
|
||||
|
||||
// Get the device
|
||||
/* Get the device */
|
||||
driver_for_each_device(&drv_ctx->driver, NULL, (void*)¤t_dev, blkvsc_drv_exit_cb);
|
||||
|
||||
if (current_dev == NULL)
|
||||
break;
|
||||
|
||||
// Initiate removal from the top-down
|
||||
/* Initiate removal from the top-down */
|
||||
device_unregister(current_dev);
|
||||
}
|
||||
|
||||
|
@ -291,14 +294,14 @@ static int blkvsc_probe(struct device *device)
|
|||
|
||||
INIT_LIST_HEAD(&blkdev->pending_list);
|
||||
|
||||
// Initialize what we can here
|
||||
/* Initialize what we can here */
|
||||
spin_lock_init(&blkdev->lock);
|
||||
|
||||
ASSERT(sizeof(struct blkvsc_request_group) <= sizeof(struct blkvsc_request));
|
||||
|
||||
blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device),
|
||||
sizeof(struct blkvsc_request) + storvsc_drv_obj->RequestExtSize, 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device),
|
||||
sizeof(struct blkvsc_request) + storvsc_drv_obj->RequestExtSize, 0,
|
||||
SLAB_HWCACHE_ALIGN, NULL);
|
||||
if (!blkdev->request_pool)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
|
@ -306,7 +309,7 @@ static int blkvsc_probe(struct device *device)
|
|||
}
|
||||
|
||||
|
||||
// Call to the vsc driver to add the device
|
||||
/* Call to the vsc driver to add the device */
|
||||
ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj, &device_info);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -315,16 +318,16 @@ static int blkvsc_probe(struct device *device)
|
|||
}
|
||||
|
||||
blkdev->device_ctx = device_ctx;
|
||||
blkdev->target = device_info.TargetId; // this identified the device 0 or 1
|
||||
blkdev->path = device_info.PathId; // this identified the ide ctrl 0 or 1
|
||||
blkdev->target = device_info.TargetId; /* this identified the device 0 or 1 */
|
||||
blkdev->path = device_info.PathId; /* this identified the ide ctrl 0 or 1 */
|
||||
|
||||
dev_set_drvdata(device, blkdev);
|
||||
|
||||
// Calculate the major and device num
|
||||
/* Calculate the major and device num */
|
||||
if (blkdev->path == 0)
|
||||
{
|
||||
major = IDE0_MAJOR;
|
||||
devnum = blkdev->path + blkdev->target; // 0 or 1
|
||||
devnum = blkdev->path + blkdev->target; /* 0 or 1 */
|
||||
|
||||
if (!ide0_registered)
|
||||
{
|
||||
|
@ -341,7 +344,7 @@ static int blkvsc_probe(struct device *device)
|
|||
else if (blkdev->path == 1)
|
||||
{
|
||||
major = IDE1_MAJOR;
|
||||
devnum = blkdev->path + blkdev->target + 1; // 2 or 3
|
||||
devnum = blkdev->path + blkdev->target + 1; /* 2 or 3 */
|
||||
|
||||
if (!ide1_registered)
|
||||
{
|
||||
|
@ -405,7 +408,7 @@ static int blkvsc_probe(struct device *device)
|
|||
|
||||
set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
|
||||
blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
|
||||
// go!
|
||||
/* go! */
|
||||
add_disk(blkdev->gd);
|
||||
|
||||
DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %llu sector_size %d", blkdev->gd->disk_name, blkdev->capacity, blkdev->sector_size);
|
||||
|
@ -494,7 +497,7 @@ static int blkvsc_do_flush(struct block_device_context *blkdev)
|
|||
blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
|
||||
blkvsc_req->cmd_len = 10;
|
||||
|
||||
// Set this here since the completion routine may be invoked and completed before we return
|
||||
/* Set this here since the completion routine may be invoked and completed before we return */
|
||||
blkvsc_req->cond =0;
|
||||
blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
|
||||
|
||||
|
@ -505,7 +508,7 @@ static int blkvsc_do_flush(struct block_device_context *blkdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Do a scsi INQUIRY cmd here to get the device type (ie disk or dvd)
|
||||
/* Do a scsi INQUIRY cmd here to get the device type (ie disk or dvd) */
|
||||
static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
||||
{
|
||||
struct blkvsc_request *blkvsc_req=NULL;
|
||||
|
@ -539,12 +542,12 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
|||
blkvsc_req->request.DataBuffer.Length = 64;
|
||||
|
||||
blkvsc_req->cmnd[0] = INQUIRY;
|
||||
blkvsc_req->cmnd[1] = 0x1; // Get product data
|
||||
blkvsc_req->cmnd[2] = 0x83; // mode page 83
|
||||
blkvsc_req->cmnd[1] = 0x1; /* Get product data */
|
||||
blkvsc_req->cmnd[2] = 0x83; /* mode page 83 */
|
||||
blkvsc_req->cmnd[4] = 64;
|
||||
blkvsc_req->cmd_len = 6;
|
||||
|
||||
// Set this here since the completion routine may be invoked and completed before we return
|
||||
/* Set this here since the completion routine may be invoked and completed before we return */
|
||||
blkvsc_req->cond =0;
|
||||
|
||||
blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
|
||||
|
@ -556,7 +559,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
|||
buf = kmap(page_buf);
|
||||
|
||||
/* print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, 64); */
|
||||
// be to le
|
||||
/* be to le */
|
||||
device_type = buf[0] & 0x1F;
|
||||
|
||||
if (device_type == 0x0)
|
||||
|
@ -569,7 +572,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
|||
}
|
||||
else
|
||||
{
|
||||
// TODO: this is currently unsupported device type
|
||||
/* TODO: this is currently unsupported device type */
|
||||
blkdev->device_type = UNKNOWN_DEV_TYPE;
|
||||
}
|
||||
|
||||
|
@ -581,7 +584,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
|||
|
||||
memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
|
||||
/* printk_hex_dump_bytes("", DUMP_PREFIX_NONE, blkdev->device_id,
|
||||
* blkdev->device_id_len); */
|
||||
* blkdev->device_id_len); */
|
||||
|
||||
kunmap(page_buf);
|
||||
|
||||
|
@ -592,7 +595,7 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Do a scsi READ_CAPACITY cmd here to get the size of the disk
|
||||
/* Do a scsi READ_CAPACITY cmd here to get the size of the disk */
|
||||
static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
|
||||
{
|
||||
struct blkvsc_request *blkvsc_req=NULL;
|
||||
|
@ -604,7 +607,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
|
|||
|
||||
blkdev->sector_size = 0;
|
||||
blkdev->capacity = 0;
|
||||
blkdev->media_not_present = 0; // assume a disk is present
|
||||
blkdev->media_not_present = 0; /* assume a disk is present */
|
||||
|
||||
blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
|
||||
if (!blkvsc_req)
|
||||
|
@ -632,7 +635,10 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
|
|||
blkvsc_req->cmnd[0] = READ_CAPACITY;
|
||||
blkvsc_req->cmd_len = 16;
|
||||
|
||||
// Set this here since the completion routine may be invoked and completed before we return
|
||||
/*
|
||||
* Set this here since the completion routine may be invoked
|
||||
* and completed before we return
|
||||
*/
|
||||
blkvsc_req->cond =0;
|
||||
|
||||
blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
|
||||
|
@ -641,12 +647,12 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
|
|||
|
||||
wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
|
||||
|
||||
// check error
|
||||
/* check error */
|
||||
if (blkvsc_req->request.Status)
|
||||
{
|
||||
scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
|
||||
|
||||
if (sense_hdr.asc == 0x3A) // Medium not present
|
||||
if (sense_hdr.asc == 0x3A) /* Medium not present */
|
||||
{
|
||||
blkdev->media_not_present = 1;
|
||||
}
|
||||
|
@ -655,7 +661,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
|
|||
}
|
||||
buf = kmap(page_buf);
|
||||
|
||||
// be to le
|
||||
/* be to le */
|
||||
blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) + 1;
|
||||
blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
||||
|
||||
|
@ -680,7 +686,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
|
|||
|
||||
blkdev->sector_size = 0;
|
||||
blkdev->capacity = 0;
|
||||
blkdev->media_not_present = 0; // assume a disk is present
|
||||
blkdev->media_not_present = 0; /* assume a disk is present */
|
||||
|
||||
blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
|
||||
if (!blkvsc_req)
|
||||
|
@ -705,10 +711,13 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
|
|||
blkvsc_req->request.DataBuffer.Offset = 0;
|
||||
blkvsc_req->request.DataBuffer.Length = 12;
|
||||
|
||||
blkvsc_req->cmnd[0] = 0x9E; //READ_CAPACITY16;
|
||||
blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */
|
||||
blkvsc_req->cmd_len = 16;
|
||||
|
||||
// Set this here since the completion routine may be invoked and completed before we return
|
||||
/*
|
||||
* Set this here since the completion routine may be invoked
|
||||
* and completed before we return
|
||||
*/
|
||||
blkvsc_req->cond =0;
|
||||
|
||||
blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
|
||||
|
@ -717,12 +726,12 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
|
|||
|
||||
wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
|
||||
|
||||
// check error
|
||||
/* check error */
|
||||
if (blkvsc_req->request.Status)
|
||||
{
|
||||
scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr);
|
||||
|
||||
if (sense_hdr.asc == 0x3A) // Medium not present
|
||||
if (sense_hdr.asc == 0x3A) /* Medium not present */
|
||||
{
|
||||
blkdev->media_not_present = 1;
|
||||
}
|
||||
|
@ -731,12 +740,12 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
|
|||
}
|
||||
buf = kmap(page_buf);
|
||||
|
||||
// be to le
|
||||
/* be to le */
|
||||
blkdev->capacity = be64_to_cpu(*(unsigned long long*) &buf[0]) + 1;
|
||||
blkdev->sector_size = be32_to_cpu(*(unsigned int*)&buf[8]);
|
||||
|
||||
//blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) + 1;
|
||||
//blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
|
||||
/* blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]) + 1; */
|
||||
/* blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; */
|
||||
|
||||
kunmap(page_buf);
|
||||
|
||||
|
@ -777,15 +786,15 @@ static int blkvsc_remove(struct device *device)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Call to the vsc driver to let it know that the device is being removed
|
||||
/* Call to the vsc driver to let it know that the device is being removed */
|
||||
ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
DPRINT_ERR(BLKVSC_DRV, "unable to remove blkvsc device (ret %d)", ret);
|
||||
}
|
||||
|
||||
// Get to a known state
|
||||
/* Get to a known state */
|
||||
spin_lock_irqsave(&blkdev->lock, flags);
|
||||
|
||||
blkdev->shutting_down = 1;
|
||||
|
@ -922,7 +931,7 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, void (*reque
|
|||
storvsc_req->Host = blkdev->port;
|
||||
storvsc_req->Bus = blkdev->path;
|
||||
storvsc_req->TargetId = blkdev->target;
|
||||
storvsc_req->LunId = 0; // this is not really used at all
|
||||
storvsc_req->LunId = 0; /* this is not really used at all */
|
||||
|
||||
storvsc_req->CdbLen = blkvsc_req->cmd_len;
|
||||
storvsc_req->Cdb = blkvsc_req->cmnd;
|
||||
|
@ -939,11 +948,13 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, void (*reque
|
|||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
// We break the request into 1 or more blkvsc_requests and submit them.
|
||||
// If we cant submit them all, we put them on the pending_list. The
|
||||
// blkvsc_request() will work on the pending_list.
|
||||
//
|
||||
|
||||
/*
|
||||
* We break the request into 1 or more blkvsc_requests and submit
|
||||
* them. If we cant submit them all, we put them on the
|
||||
* pending_list. The blkvsc_request() will work on the pending_list.
|
||||
*/
|
||||
|
||||
static int blkvsc_do_request(struct block_device_context *blkdev, struct request *req)
|
||||
{
|
||||
struct bio *bio=NULL;
|
||||
|
@ -963,7 +974,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
|
||||
DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %llu \n", blkdev, req, blk_rq_pos(req));
|
||||
|
||||
// Create a group to tie req to list of blkvsc_reqs
|
||||
/* Create a group to tie req to list of blkvsc_reqs */
|
||||
group = (struct blkvsc_request_group*)kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
|
||||
if (!group)
|
||||
{
|
||||
|
@ -975,23 +986,23 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
|
||||
start_sector = blk_rq_pos(req);
|
||||
|
||||
// foreach bio in the request
|
||||
/* foreach bio in the request */
|
||||
if (req->bio)
|
||||
for (bio = req->bio; bio; bio = bio->bi_next)
|
||||
{
|
||||
// Map this bio into an existing or new storvsc request
|
||||
/* Map this bio into an existing or new storvsc request */
|
||||
bio_for_each_segment (bvec, bio, seg_idx)
|
||||
{
|
||||
DPRINT_DBG(BLKVSC_DRV, "bio_for_each_segment() - req %p bio %p bvec %p seg_idx %d databuf_idx %d\n",
|
||||
req, bio, bvec, seg_idx, databuf_idx);
|
||||
|
||||
// Get a new storvsc request
|
||||
if ( (!blkvsc_req) || // 1st-time
|
||||
/* Get a new storvsc request */
|
||||
if ( (!blkvsc_req) || /* 1st-time */
|
||||
(databuf_idx >= MAX_MULTIPAGE_BUFFER_COUNT) ||
|
||||
(bvec->bv_offset != 0) || // hole at the begin of page
|
||||
(prev_bvec && (prev_bvec->bv_len != PAGE_SIZE)) ) // hold at the end of page
|
||||
(bvec->bv_offset != 0) || /* hole at the begin of page */
|
||||
(prev_bvec && (prev_bvec->bv_len != PAGE_SIZE)) ) /* hold at the end of page */
|
||||
{
|
||||
// submit the prev one
|
||||
/* submit the prev one */
|
||||
if (blkvsc_req)
|
||||
{
|
||||
blkvsc_req->sector_start = start_sector;
|
||||
|
@ -1002,11 +1013,11 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
blkvsc_init_rw(blkvsc_req);
|
||||
}
|
||||
|
||||
// Create new blkvsc_req to represent the current bvec
|
||||
/* Create new blkvsc_req to represent the current bvec */
|
||||
blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
|
||||
if (!blkvsc_req)
|
||||
{
|
||||
// free up everything
|
||||
/* free up everything */
|
||||
list_for_each_entry_safe(blkvsc_req, tmp, &group->blkvsc_req_list, req_entry)
|
||||
{
|
||||
list_del(&blkvsc_req->req_entry);
|
||||
|
@ -1024,7 +1035,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
blkvsc_req->request.DataBuffer.Offset = bvec->bv_offset;
|
||||
blkvsc_req->request.DataBuffer.Length = 0;
|
||||
|
||||
// Add to the group
|
||||
/* Add to the group */
|
||||
blkvsc_req->group = group;
|
||||
blkvsc_req->group->outstanding++;
|
||||
list_add_tail(&blkvsc_req->req_entry, &blkvsc_req->group->blkvsc_req_list);
|
||||
|
@ -1034,7 +1045,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
databuf_idx = 0;
|
||||
}
|
||||
|
||||
// Add the curr bvec/segment to the curr blkvsc_req
|
||||
/* Add the curr bvec/segment to the curr blkvsc_req */
|
||||
blkvsc_req->request.DataBuffer.PfnArray[databuf_idx] = page_to_pfn(bvec->bv_page);
|
||||
blkvsc_req->request.DataBuffer.Length += bvec->bv_len;
|
||||
|
||||
|
@ -1043,11 +1054,11 @@ static int blkvsc_do_request(struct block_device_context *blkdev, struct request
|
|||
databuf_idx++;
|
||||
num_sectors += bvec->bv_len >> 9;
|
||||
|
||||
} // bio_for_each_segment
|
||||
} /* bio_for_each_segment */
|
||||
|
||||
} // rq_for_each_bio
|
||||
} /* rq_for_each_bio */
|
||||
|
||||
// Handle the last one
|
||||
/* Handle the last one */
|
||||
if (blkvsc_req)
|
||||
{
|
||||
DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p group %p count %d\n", blkdev, req, blkvsc_req->group, blkvsc_req->group->outstanding);
|
||||
|
@ -1134,8 +1145,11 @@ static void blkvsc_request_completion(STORVSC_REQUEST* request)
|
|||
blkdev->num_outstanding_reqs--;
|
||||
blkvsc_req->group->outstanding--;
|
||||
|
||||
// Only start processing when all the blkvsc_reqs are completed. This guarantees no out-of-order
|
||||
// blkvsc_req completion when calling end_that_request_first()
|
||||
/*
|
||||
* Only start processing when all the blkvsc_reqs are
|
||||
* completed. This guarantees no out-of-order blkvsc_req
|
||||
* completion when calling end_that_request_first()
|
||||
*/
|
||||
if (blkvsc_req->group->outstanding == 0)
|
||||
{
|
||||
list_for_each_entry_safe(comp_req, tmp, &blkvsc_req->group->blkvsc_req_list, req_entry)
|
||||
|
@ -1152,7 +1166,7 @@ static void blkvsc_request_completion(STORVSC_REQUEST* request)
|
|||
(!comp_req->request.Status ? 0: -EIO),
|
||||
comp_req->sector_count * blkdev->sector_size))
|
||||
{
|
||||
//All the sectors have been xferred ie the request is done
|
||||
/* All the sectors have been xferred ie the request is done */
|
||||
DPRINT_DBG(BLKVSC_DRV, "req %p COMPLETED\n", comp_req->req);
|
||||
kmem_cache_free(blkdev->request_pool, comp_req->group);
|
||||
}
|
||||
|
@ -1180,11 +1194,14 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
|
|||
|
||||
DPRINT_DBG(BLKVSC_DRV, "blkvsc_cancel_pending_reqs()");
|
||||
|
||||
// Flush the pending list first
|
||||
/* Flush the pending list first */
|
||||
list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list, pend_entry)
|
||||
{
|
||||
// The pend_req could be part of a partially completed request. If so, complete those req first
|
||||
// until we hit the pend_req
|
||||
/*
|
||||
* The pend_req could be part of a partially completed
|
||||
* request. If so, complete those req first until we
|
||||
* hit the pend_req
|
||||
*/
|
||||
list_for_each_entry_safe(comp_req, tmp2, &pend_req->group->blkvsc_req_list, req_entry)
|
||||
{
|
||||
DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p sect_start %llu sect_count %ld \n",
|
||||
|
@ -1222,7 +1239,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
|
|||
-EIO,
|
||||
pend_req->sector_count * blkdev->sector_size))
|
||||
{
|
||||
//All the sectors have been xferred ie the request is done
|
||||
/* All the sectors have been xferred ie the request is done */
|
||||
DPRINT_DBG(BLKVSC_DRV, "blkvsc_cancel_pending_reqs() - req %p COMPLETED\n", pend_req->req);
|
||||
kmem_cache_free(blkdev->request_pool, pend_req->group);
|
||||
}
|
||||
|
@ -1239,7 +1256,7 @@ static int blkvsc_do_pending_reqs(struct block_device_context *blkdev)
|
|||
struct blkvsc_request *pend_req, *tmp;
|
||||
int ret=0;
|
||||
|
||||
// Flush the pending list first
|
||||
/* Flush the pending list first */
|
||||
list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list, pend_entry)
|
||||
{
|
||||
DPRINT_DBG(BLKVSC_DRV, "working off pending_list - %p\n", pend_req);
|
||||
|
@ -1378,51 +1395,51 @@ int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
|
|||
int rem=0;
|
||||
|
||||
if (total_sectors > (65535 * 16 * 255)) {
|
||||
total_sectors = (65535 * 16 * 255);
|
||||
total_sectors = (65535 * 16 * 255);
|
||||
}
|
||||
|
||||
if (total_sectors >= (65535 * 16 * 63)) {
|
||||
sectors_per_track = 255;
|
||||
heads = 16;
|
||||
sectors_per_track = 255;
|
||||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
else
|
||||
{
|
||||
sectors_per_track = 17;
|
||||
sectors_per_track = 17;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
|
||||
temp = cylinder_times_heads + 1023;
|
||||
rem = sector_div(temp, 1024); // sector_div stores the quotient in temp
|
||||
rem = sector_div(temp, 1024); /* sector_div stores the quotient in temp */
|
||||
|
||||
heads = temp;
|
||||
|
||||
if (heads < 4) {
|
||||
heads = 4;
|
||||
}
|
||||
if (heads < 4) {
|
||||
heads = 4;
|
||||
}
|
||||
|
||||
if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
|
||||
sectors_per_track = 31;
|
||||
heads = 16;
|
||||
if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
|
||||
sectors_per_track = 31;
|
||||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
}
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
|
||||
if (cylinder_times_heads >= (heads * 1024)) {
|
||||
sectors_per_track = 63;
|
||||
heads = 16;
|
||||
if (cylinder_times_heads >= (heads * 1024)) {
|
||||
sectors_per_track = 63;
|
||||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
}
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
}
|
||||
|
||||
temp = cylinder_times_heads;
|
||||
rem = sector_div(temp, heads); // sector_div stores the quotient in temp
|
||||
rem = sector_div(temp, heads); /* sector_div stores the quotient in temp */
|
||||
cylinders = temp;
|
||||
|
||||
hg->heads = heads;
|
||||
|
@ -1442,8 +1459,8 @@ static int blkvsc_ioctl(struct inode *inode, struct file *filep, unsigned cmd, u
|
|||
|
||||
switch (cmd)
|
||||
{
|
||||
// TODO: I think there is certain format for HDIO_GET_IDENTITY rather than just
|
||||
// a GUID. Commented it out for now.
|
||||
/* TODO: I think there is certain format for HDIO_GET_IDENTITY rather than just */
|
||||
/* a GUID. Commented it out for now. */
|
||||
/*case HDIO_GET_IDENTITY:
|
||||
DPRINT_INFO(BLKVSC_DRV, "HDIO_GET_IDENTITY\n");
|
||||
|
||||
|
@ -1468,7 +1485,7 @@ static int __init blkvsc_init(void)
|
|||
{
|
||||
int ret;
|
||||
|
||||
ASSERT(sizeof(sector_t) == 8); // Make sure CONFIG_LBD is set
|
||||
ASSERT(sizeof(sector_t) == 8); /* Make sure CONFIG_LBD is set */
|
||||
|
||||
DPRINT_ENTER(BLKVSC_DRV);
|
||||
|
||||
|
@ -1495,4 +1512,4 @@ module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
|
|||
module_init(blkvsc_init);
|
||||
module_exit(blkvsc_exit);
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -31,9 +31,9 @@ typedef u32 NTSTATUS;
|
|||
|
||||
#pragma pack(push,1)
|
||||
|
||||
//
|
||||
// Version 1 messages
|
||||
//
|
||||
|
||||
/* Version 1 messages */
|
||||
|
||||
|
||||
typedef enum _VMBUS_CHANNEL_MESSAGE_TYPE
|
||||
{
|
||||
|
@ -61,9 +61,9 @@ typedef enum _VMBUS_CHANNEL_MESSAGE_TYPE
|
|||
ChannelMessageCount
|
||||
} VMBUS_CHANNEL_MESSAGE_TYPE, *PVMBUS_CHANNEL_MESSAGE_TYPE;
|
||||
|
||||
// begin_wpp config
|
||||
// CUSTOM_TYPE(ChannelMessageType, ItemEnum(_VMBUS_CHANNEL_MESSAGE_TYPE));
|
||||
// end_wpp
|
||||
/* begin_wpp config */
|
||||
/* CUSTOM_TYPE(ChannelMessageType, ItemEnum(_VMBUS_CHANNEL_MESSAGE_TYPE)); */
|
||||
/* end_wpp */
|
||||
|
||||
typedef struct _VMBUS_CHANNEL_MESSAGE_HEADER
|
||||
{
|
||||
|
@ -71,21 +71,21 @@ typedef struct _VMBUS_CHANNEL_MESSAGE_HEADER
|
|||
u32 Padding;
|
||||
} VMBUS_CHANNEL_MESSAGE_HEADER, *PVMBUS_CHANNEL_MESSAGE_HEADER;
|
||||
|
||||
// Query VMBus Version parameters
|
||||
/* Query VMBus Version parameters */
|
||||
typedef struct _VMBUS_CHANNEL_QUERY_VMBUS_VERSION
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
u32 Version;
|
||||
} VMBUS_CHANNEL_QUERY_VMBUS_VERSION, *PVMBUS_CHANNEL_QUERY_VMBUS_VERSION;
|
||||
|
||||
// VMBus Version Supported parameters
|
||||
/* VMBus Version Supported parameters */
|
||||
typedef struct _VMBUS_CHANNEL_VERSION_SUPPORTED
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
bool VersionSupported;
|
||||
} VMBUS_CHANNEL_VERSION_SUPPORTED, *PVMBUS_CHANNEL_VERSION_SUPPORTED;
|
||||
|
||||
// Offer Channel parameters
|
||||
/* Offer Channel parameters */
|
||||
typedef struct _VMBUS_CHANNEL_OFFER_CHANNEL
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
|
@ -95,67 +95,69 @@ typedef struct _VMBUS_CHANNEL_OFFER_CHANNEL
|
|||
bool MonitorAllocated;
|
||||
} VMBUS_CHANNEL_OFFER_CHANNEL, *PVMBUS_CHANNEL_OFFER_CHANNEL;
|
||||
|
||||
//
|
||||
// Make sure VMBUS_CHANNEL_OFFER_CHANNEL fits into Synic message.
|
||||
//
|
||||
|
||||
/* Make sure VMBUS_CHANNEL_OFFER_CHANNEL fits into Synic message. */
|
||||
|
||||
C_ASSERT(sizeof(VMBUS_CHANNEL_OFFER_CHANNEL) <= MAXIMUM_SYNIC_MESSAGE_BYTES);
|
||||
|
||||
// Rescind Offer parameters
|
||||
/* Rescind Offer parameters */
|
||||
typedef struct _VMBUS_CHANNEL_RESCIND_OFFER
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
u32 ChildRelId;
|
||||
} VMBUS_CHANNEL_RESCIND_OFFER, *PVMBUS_CHANNEL_RESCIND_OFFER;
|
||||
|
||||
// Request Offer -- no parameters, SynIC message contains the partition ID
|
||||
// Set Snoop -- no parameters, SynIC message contains the partition ID
|
||||
// Clear Snoop -- no parameters, SynIC message contains the partition ID
|
||||
// All Offers Delivered -- no parameters, SynIC message contains the partition ID
|
||||
// Flush Client -- no parameters, SynIC message contains the partition ID
|
||||
/* Request Offer -- no parameters, SynIC message contains the partition ID */
|
||||
/* Set Snoop -- no parameters, SynIC message contains the partition ID */
|
||||
/* Clear Snoop -- no parameters, SynIC message contains the partition ID */
|
||||
/* All Offers Delivered -- no parameters, SynIC message contains the partition ID */
|
||||
/* Flush Client -- no parameters, SynIC message contains the partition ID */
|
||||
|
||||
// Open Channel parameters
|
||||
/* Open Channel parameters */
|
||||
typedef struct _VMBUS_CHANNEL_OPEN_CHANNEL
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
|
||||
//
|
||||
// Identifies the specific VMBus channel that is being opened.
|
||||
//
|
||||
|
||||
/* Identifies the specific VMBus channel that is being opened. */
|
||||
|
||||
u32 ChildRelId;
|
||||
|
||||
//
|
||||
// ID making a particular open request at a channel offer unique.
|
||||
//
|
||||
|
||||
/* ID making a particular open request at a channel offer unique. */
|
||||
|
||||
u32 OpenId;
|
||||
|
||||
//
|
||||
// GPADL for the channel's ring buffer.
|
||||
//
|
||||
|
||||
/* GPADL for the channel's ring buffer. */
|
||||
|
||||
GPADL_HANDLE RingBufferGpadlHandle;
|
||||
|
||||
//
|
||||
// GPADL for the channel's server context save area.
|
||||
//
|
||||
|
||||
/* GPADL for the channel's server context save area. */
|
||||
|
||||
GPADL_HANDLE ServerContextAreaGpadlHandle;
|
||||
|
||||
//
|
||||
// The upstream ring buffer begins at offset zero in the memory described
|
||||
// by RingBufferGpadlHandle. The downstream ring buffer follows it at this
|
||||
// offset (in pages).
|
||||
//
|
||||
|
||||
/*
|
||||
* The upstream ring buffer begins at offset zero in the memory
|
||||
* described by RingBufferGpadlHandle. The downstream ring buffer
|
||||
* follows it at this offset (in pages).
|
||||
*/
|
||||
|
||||
u32 DownstreamRingBufferPageOffset;
|
||||
|
||||
//
|
||||
// User-specific data to be passed along to the server endpoint.
|
||||
//
|
||||
|
||||
/* User-specific data to be passed along to the server endpoint. */
|
||||
|
||||
unsigned char UserData[MAX_USER_DEFINED_BYTES];
|
||||
|
||||
} VMBUS_CHANNEL_OPEN_CHANNEL, *PVMBUS_CHANNEL_OPEN_CHANNEL;
|
||||
|
||||
// Reopen Channel parameters;
|
||||
/* Reopen Channel parameters; */
|
||||
typedef VMBUS_CHANNEL_OPEN_CHANNEL VMBUS_CHANNEL_REOPEN_CHANNEL, *PVMBUS_CHANNEL_REOPEN_CHANNEL;
|
||||
|
||||
// Open Channel Result parameters
|
||||
/* Open Channel Result parameters */
|
||||
typedef struct _VMBUS_CHANNEL_OPEN_RESULT
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
|
@ -164,24 +166,26 @@ typedef struct _VMBUS_CHANNEL_OPEN_RESULT
|
|||
NTSTATUS Status;
|
||||
} VMBUS_CHANNEL_OPEN_RESULT, *PVMBUS_CHANNEL_OPEN_RESULT;
|
||||
|
||||
// Close channel parameters;
|
||||
/* Close channel parameters; */
|
||||
typedef struct _VMBUS_CHANNEL_CLOSE_CHANNEL
|
||||
{
|
||||
VMBUS_CHANNEL_MESSAGE_HEADER Header;
|
||||
u32 ChildRelId;
|
||||
} VMBUS_CHANNEL_CLOSE_CHANNEL, *PVMBUS_CHANNEL_CLOSE_CHANNEL;
|
||||
|
||||
// Channel Message GPADL
|
||||
/* Channel Message GPADL */
|
||||
#define GPADL_TYPE_RING_BUFFER 1
|
||||
#define GPADL_TYPE_SERVER_SAVE_AREA 2
|
||||
#define GPADL_TYPE_TRANSACTION 8
|
||||
|
||||
//
|
||||
// The number of PFNs in a GPADL message is defined by the number of pages
|
||||
// that would be spanned by ByteCount and ByteOffset. If the implied number
|
||||
// of PFNs won't fit in this packet, there will be a follow-up packet that
|
||||
// contains more.
|
||||
//
|
||||
|
||||
/*
|
||||
* The number of PFNs in a GPADL message is defined by the number of
|
||||
* pages that would be spanned by ByteCount and ByteOffset. If the
|
||||
* implied number of PFNs won't fit in this packet, there will be a
|
||||
* follow-up packet that contains more.
|
||||
*/
|
||||
|
||||
|
||||
typedef struct _VMBUS_CHANNEL_GPADL_HEADER
|
||||
{
|
||||
|
@ -194,9 +198,9 @@ typedef struct _VMBUS_CHANNEL_GPADL_HEADER
|
|||
} VMBUS_CHANNEL_GPADL_HEADER, *PVMBUS_CHANNEL_GPADL_HEADER;
|
||||
|
||||
|
||||
//
|
||||
// This is the followup packet that contains more PFNs.
|
||||
//
|
||||
|
||||
/* This is the followup packet that contains more PFNs. */
|
||||
|
||||
|
||||
typedef struct _VMBUS_CHANNEL_GPADL_BODY
|
||||
{
|
||||
|
@ -269,10 +273,10 @@ typedef struct _VMBUS_CHANNEL_VERSION_RESPONSE
|
|||
|
||||
typedef VMBUS_CHANNEL_MESSAGE_HEADER VMBUS_CHANNEL_UNLOAD, *PVMBUS_CHANNEL_UNLOAD;
|
||||
|
||||
//
|
||||
// Kind of a table to use the preprocessor to get us the right type for a
|
||||
// specified message ID. Used with ChAllocateSendMessage()
|
||||
//
|
||||
|
||||
/* Kind of a table to use the preprocessor to get us the right type for a */
|
||||
/* specified message ID. Used with ChAllocateSendMessage() */
|
||||
|
||||
#define ChannelMessageQueryVmbusVersion_TYPE VMBUS_CHANNEL_MESSAGE_HEADER
|
||||
#define ChannelMessageVmbusVersionSupported_TYPE VMBUS_CHANNEL_VERSION_SUPPORTED
|
||||
#define ChannelMessageOfferChannel_TYPE VMBUS_CHANNEL_OFFER_CHANNEL
|
||||
|
@ -295,18 +299,17 @@ typedef VMBUS_CHANNEL_MESSAGE_HEADER VMBUS_CHANNEL_UNLOAD, *PVMBUS_CHANNEL_UNLOA
|
|||
#define ChannelMessageVersionResponse_TYPE VMBUS_CHANNEL_VERSION_RESPONSE
|
||||
#define ChannelMessageUnload_TYPE VMBUS_CHANNEL_UNLOAD
|
||||
|
||||
//
|
||||
// Preprocessor wrapper to ChAllocateSendMessageSize() converting the return
|
||||
// value to the correct pointer and calculate the needed size.
|
||||
//
|
||||
// Argument:
|
||||
//
|
||||
// Id - the numberic ID (type VMBUS_CHANNEL_MESSAGE_TYPE) of the message to
|
||||
// send.
|
||||
//
|
||||
|
||||
/* Preprocessor wrapper to ChAllocateSendMessageSize() converting the return */
|
||||
/* value to the correct pointer and calculate the needed size. */
|
||||
|
||||
/* Argument: */
|
||||
|
||||
/* Id - the numberic ID (type VMBUS_CHANNEL_MESSAGE_TYPE) of the message to */
|
||||
/* send. */
|
||||
|
||||
#define ChAllocateSendMessage(Id, Fn, Context) \
|
||||
(Id##_TYPE*)ChAllocateSendMessageSized(sizeof(Id##_TYPE), Id, Fn, Context)
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#pragma once
|
||||
|
||||
|
||||
//
|
||||
// Time in the hypervisor is measured in 100 nanosecond units
|
||||
//
|
||||
|
||||
/* Time in the hypervisor is measured in 100 nanosecond units */
|
||||
|
||||
typedef u64 HV_NANO100_TIME, *PHV_NANO100_TIME;
|
||||
typedef u64 HV_NANO100_DURATION, *PHV_NANO100_DURATION;
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Declare the various hypercall operations.
|
||||
//
|
||||
|
||||
/* Declare the various hypercall operations. */
|
||||
|
||||
typedef enum _HV_CALL_CODE
|
||||
{
|
||||
|
||||
|
@ -34,9 +34,9 @@ typedef enum _HV_CALL_CODE
|
|||
HvCallSignalEvent = 0x005d,
|
||||
|
||||
} HV_CALL_CODE, *PHV_CALL_CODE;
|
||||
//
|
||||
// Definition of the HvPostMessage hypercall input structure.
|
||||
//
|
||||
|
||||
/* Definition of the HvPostMessage hypercall input structure. */
|
||||
|
||||
|
||||
typedef struct _HV_INPUT_POST_MESSAGE
|
||||
{
|
||||
|
@ -48,9 +48,9 @@ typedef struct _HV_INPUT_POST_MESSAGE
|
|||
} HV_INPUT_POST_MESSAGE, *PHV_INPUT_POST_MESSAGE;
|
||||
|
||||
|
||||
//
|
||||
// Definition of the HvSignalEvent hypercall input structure.
|
||||
//
|
||||
|
||||
/* Definition of the HvSignalEvent hypercall input structure. */
|
||||
|
||||
|
||||
typedef struct _HV_INPUT_SIGNAL_EVENT
|
||||
{
|
||||
|
|
|
@ -24,15 +24,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Versioning definitions used for guests reporting themselves to the
|
||||
// hypervisor, and visa versa.
|
||||
// ==================================================================
|
||||
//
|
||||
|
||||
//
|
||||
// Version info reported by guest OS's
|
||||
//
|
||||
/* Versioning definitions used for guests reporting themselves to the */
|
||||
/* hypervisor, and visa versa. */
|
||||
/* ================================================================== */
|
||||
|
||||
|
||||
|
||||
/* Version info reported by guest OS's */
|
||||
|
||||
typedef enum _HV_GUEST_OS_VENDOR
|
||||
{
|
||||
HvGuestOsVendorMicrosoft = 0x0001
|
||||
|
@ -50,9 +50,9 @@ typedef enum _HV_GUEST_OS_MICROSOFT_IDS
|
|||
|
||||
} HV_GUEST_OS_MICROSOFT_IDS, *PHV_GUEST_OS_MICROSOFT_IDS;
|
||||
|
||||
//
|
||||
// Declare the MSR used to identify the guest OS.
|
||||
//
|
||||
|
||||
/* Declare the MSR used to identify the guest OS. */
|
||||
|
||||
#define HV_X64_MSR_GUEST_OS_ID 0x40000000
|
||||
|
||||
typedef union _HV_X64_MSR_GUEST_OS_ID_CONTENTS
|
||||
|
@ -61,17 +61,17 @@ typedef union _HV_X64_MSR_GUEST_OS_ID_CONTENTS
|
|||
struct
|
||||
{
|
||||
u64 BuildNumber : 16;
|
||||
u64 ServiceVersion : 8; // Service Pack, etc.
|
||||
u64 ServiceVersion : 8; /* Service Pack, etc. */
|
||||
u64 MinorVersion : 8;
|
||||
u64 MajorVersion : 8;
|
||||
u64 OsId : 8; // HV_GUEST_OS_MICROSOFT_IDS (If Vendor=MS)
|
||||
u64 VendorId : 16; // HV_GUEST_OS_VENDOR
|
||||
u64 OsId : 8; /* HV_GUEST_OS_MICROSOFT_IDS (If Vendor=MS) */
|
||||
u64 VendorId : 16; /* HV_GUEST_OS_VENDOR */
|
||||
};
|
||||
} HV_X64_MSR_GUEST_OS_ID_CONTENTS, *PHV_X64_MSR_GUEST_OS_ID_CONTENTS;
|
||||
|
||||
//
|
||||
// Declare the MSR used to setup pages used to communicate with the hypervisor.
|
||||
//
|
||||
|
||||
/* Declare the MSR used to setup pages used to communicate with the hypervisor. */
|
||||
|
||||
#define HV_X64_MSR_HYPERCALL 0x40000001
|
||||
|
||||
typedef union _HV_X64_MSR_HYPERCALL_CONTENTS
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -23,24 +23,24 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Define the virtual APIC registers
|
||||
//
|
||||
|
||||
/* Define the virtual APIC registers */
|
||||
|
||||
#define HV_X64_MSR_EOI (0x40000070)
|
||||
#define HV_X64_MSR_ICR (0x40000071)
|
||||
#define HV_X64_MSR_TPR (0x40000072)
|
||||
#define HV_X64_MSR_APIC_ASSIST_PAGE (0x40000073)
|
||||
|
||||
//
|
||||
// Define version of the synthetic interrupt controller.
|
||||
//
|
||||
|
||||
/* Define version of the synthetic interrupt controller. */
|
||||
|
||||
|
||||
#define HV_SYNIC_VERSION (1)
|
||||
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller model specific registers.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller model specific registers. */
|
||||
|
||||
|
||||
#define HV_X64_MSR_SCONTROL (0x40000080)
|
||||
#define HV_X64_MSR_SVERSION (0x40000081)
|
||||
|
@ -64,61 +64,61 @@
|
|||
#define HV_X64_MSR_SINT14 (0x4000009E)
|
||||
#define HV_X64_MSR_SINT15 (0x4000009F)
|
||||
|
||||
//
|
||||
// Define the expected SynIC version.
|
||||
//
|
||||
|
||||
/* Define the expected SynIC version. */
|
||||
|
||||
#define HV_SYNIC_VERSION_1 (0x1)
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller message constants.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller message constants. */
|
||||
|
||||
|
||||
#define HV_MESSAGE_SIZE (256)
|
||||
#define HV_MESSAGE_PAYLOAD_BYTE_COUNT (240)
|
||||
#define HV_MESSAGE_PAYLOAD_QWORD_COUNT (30)
|
||||
#define HV_ANY_VP (0xFFFFFFFF)
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller flag constants.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller flag constants. */
|
||||
|
||||
|
||||
#define HV_EVENT_FLAGS_COUNT (256 * 8)
|
||||
#define HV_EVENT_FLAGS_BYTE_COUNT (256)
|
||||
#define HV_EVENT_FLAGS_DWORD_COUNT (256 / sizeof(u32))
|
||||
|
||||
//
|
||||
// Define hypervisor message types.
|
||||
//
|
||||
|
||||
/* Define hypervisor message types. */
|
||||
|
||||
typedef enum _HV_MESSAGE_TYPE
|
||||
{
|
||||
HvMessageTypeNone = 0x00000000,
|
||||
|
||||
//
|
||||
// Memory access messages.
|
||||
//
|
||||
|
||||
/* Memory access messages. */
|
||||
|
||||
HvMessageTypeUnmappedGpa = 0x80000000,
|
||||
HvMessageTypeGpaIntercept = 0x80000001,
|
||||
|
||||
//
|
||||
// Timer notification messages.
|
||||
//
|
||||
|
||||
/* Timer notification messages. */
|
||||
|
||||
HvMessageTimerExpired = 0x80000010,
|
||||
|
||||
//
|
||||
// Error messages.
|
||||
//
|
||||
|
||||
/* Error messages. */
|
||||
|
||||
HvMessageTypeInvalidVpRegisterValue = 0x80000020,
|
||||
HvMessageTypeUnrecoverableException = 0x80000021,
|
||||
HvMessageTypeUnsupportedFeature = 0x80000022,
|
||||
|
||||
//
|
||||
// Trace buffer complete messages.
|
||||
//
|
||||
|
||||
/* Trace buffer complete messages. */
|
||||
|
||||
HvMessageTypeEventLogBufferComplete = 0x80000040,
|
||||
|
||||
//
|
||||
// Platform-specific processor intercept messages.
|
||||
//
|
||||
|
||||
/* Platform-specific processor intercept messages. */
|
||||
|
||||
HvMessageTypeX64IoPortIntercept = 0x80010000,
|
||||
HvMessageTypeX64MsrIntercept = 0x80010001,
|
||||
HvMessageTypeX64CpuidIntercept = 0x80010002,
|
||||
|
@ -128,33 +128,33 @@ typedef enum _HV_MESSAGE_TYPE
|
|||
|
||||
} HV_MESSAGE_TYPE, *PHV_MESSAGE_TYPE;
|
||||
|
||||
//
|
||||
// Define the number of synthetic interrupt sources.
|
||||
//
|
||||
|
||||
/* Define the number of synthetic interrupt sources. */
|
||||
|
||||
|
||||
#define HV_SYNIC_SINT_COUNT (16)
|
||||
#define HV_SYNIC_STIMER_COUNT (4)
|
||||
|
||||
//
|
||||
// Define the synthetic interrupt source index type.
|
||||
//
|
||||
|
||||
/* Define the synthetic interrupt source index type. */
|
||||
|
||||
|
||||
typedef u32 HV_SYNIC_SINT_INDEX, *PHV_SYNIC_SINT_INDEX;
|
||||
|
||||
//
|
||||
// Define partition identifier type.
|
||||
//
|
||||
|
||||
/* Define partition identifier type. */
|
||||
|
||||
|
||||
typedef u64 HV_PARTITION_ID, *PHV_PARTITION_ID;
|
||||
|
||||
//
|
||||
// Define invalid partition identifier.
|
||||
//
|
||||
|
||||
/* Define invalid partition identifier. */
|
||||
|
||||
#define HV_PARTITION_ID_INVALID ((HV_PARTITION_ID) 0x0)
|
||||
|
||||
//
|
||||
// Define connection identifier type.
|
||||
//
|
||||
|
||||
/* Define connection identifier type. */
|
||||
|
||||
|
||||
typedef union _HV_CONNECTION_ID
|
||||
{
|
||||
|
@ -162,15 +162,15 @@ typedef union _HV_CONNECTION_ID
|
|||
|
||||
struct
|
||||
{
|
||||
u32 Id:24;
|
||||
u32 Reserved:8;
|
||||
u32 Id:24;
|
||||
u32 Reserved:8;
|
||||
} u;
|
||||
|
||||
} HV_CONNECTION_ID, *PHV_CONNECTION_ID;
|
||||
|
||||
//
|
||||
// Define port identifier type.
|
||||
//
|
||||
|
||||
/* Define port identifier type. */
|
||||
|
||||
|
||||
typedef union _HV_PORT_ID
|
||||
{
|
||||
|
@ -178,15 +178,15 @@ typedef union _HV_PORT_ID
|
|||
|
||||
struct
|
||||
{
|
||||
u32 Id:24;
|
||||
u32 Reserved:8;
|
||||
u32 Id:24;
|
||||
u32 Reserved:8;
|
||||
} u ;
|
||||
|
||||
} HV_PORT_ID, *PHV_PORT_ID;
|
||||
|
||||
//
|
||||
// Define port type.
|
||||
//
|
||||
|
||||
/* Define port type. */
|
||||
|
||||
|
||||
typedef enum _HV_PORT_TYPE
|
||||
{
|
||||
|
@ -195,9 +195,9 @@ typedef enum _HV_PORT_TYPE
|
|||
HvPortTypeMonitor = 3
|
||||
} HV_PORT_TYPE, *PHV_PORT_TYPE;
|
||||
|
||||
//
|
||||
// Define port information structure.
|
||||
//
|
||||
|
||||
/* Define port information structure. */
|
||||
|
||||
|
||||
typedef struct _HV_PORT_INFO
|
||||
{
|
||||
|
@ -206,27 +206,27 @@ typedef struct _HV_PORT_INFO
|
|||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
HV_SYNIC_SINT_INDEX TargetSint;
|
||||
HV_VP_INDEX TargetVp;
|
||||
u64 RsvdZ;
|
||||
} MessagePortInfo;
|
||||
struct
|
||||
{
|
||||
HV_SYNIC_SINT_INDEX TargetSint;
|
||||
HV_VP_INDEX TargetVp;
|
||||
u64 RsvdZ;
|
||||
} MessagePortInfo;
|
||||
|
||||
struct
|
||||
{
|
||||
HV_SYNIC_SINT_INDEX TargetSint;
|
||||
HV_VP_INDEX TargetVp;
|
||||
u16 BaseFlagNumber;
|
||||
u16 FlagCount;
|
||||
u32 RsvdZ;
|
||||
} EventPortInfo;
|
||||
struct
|
||||
{
|
||||
HV_SYNIC_SINT_INDEX TargetSint;
|
||||
HV_VP_INDEX TargetVp;
|
||||
u16 BaseFlagNumber;
|
||||
u16 FlagCount;
|
||||
u32 RsvdZ;
|
||||
} EventPortInfo;
|
||||
|
||||
struct
|
||||
{
|
||||
HV_GPA MonitorAddress;
|
||||
u64 RsvdZ;
|
||||
} MonitorPortInfo;
|
||||
struct
|
||||
{
|
||||
HV_GPA MonitorAddress;
|
||||
u64 RsvdZ;
|
||||
} MonitorPortInfo;
|
||||
};
|
||||
} HV_PORT_INFO, *PHV_PORT_INFO;
|
||||
|
||||
|
@ -239,43 +239,43 @@ typedef struct _HV_CONNECTION_INFO
|
|||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
u64 RsvdZ;
|
||||
} MessageConnectionInfo;
|
||||
struct
|
||||
{
|
||||
u64 RsvdZ;
|
||||
} MessageConnectionInfo;
|
||||
|
||||
struct
|
||||
{
|
||||
u64 RsvdZ;
|
||||
} EventConnectionInfo;
|
||||
struct
|
||||
{
|
||||
u64 RsvdZ;
|
||||
} EventConnectionInfo;
|
||||
|
||||
struct
|
||||
{
|
||||
HV_GPA MonitorAddress;
|
||||
} MonitorConnectionInfo;
|
||||
struct
|
||||
{
|
||||
HV_GPA MonitorAddress;
|
||||
} MonitorConnectionInfo;
|
||||
};
|
||||
} HV_CONNECTION_INFO, *PHV_CONNECTION_INFO;
|
||||
|
||||
typedef const HV_CONNECTION_INFO *PCHV_CONNECTION_INFO;
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller message flags.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller message flags. */
|
||||
|
||||
|
||||
typedef union _HV_MESSAGE_FLAGS
|
||||
{
|
||||
u8 Asu8;
|
||||
struct
|
||||
{
|
||||
u8 MessagePending:1;
|
||||
u8 Reserved:7;
|
||||
u8 MessagePending:1;
|
||||
u8 Reserved:7;
|
||||
};
|
||||
} HV_MESSAGE_FLAGS, *PHV_MESSAGE_FLAGS;
|
||||
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller message header.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller message header. */
|
||||
|
||||
|
||||
typedef struct _HV_MESSAGE_HEADER
|
||||
{
|
||||
|
@ -285,45 +285,45 @@ typedef struct _HV_MESSAGE_HEADER
|
|||
u8 Reserved[2];
|
||||
union
|
||||
{
|
||||
HV_PARTITION_ID Sender;
|
||||
HV_PORT_ID Port;
|
||||
HV_PARTITION_ID Sender;
|
||||
HV_PORT_ID Port;
|
||||
};
|
||||
|
||||
} HV_MESSAGE_HEADER, *PHV_MESSAGE_HEADER;
|
||||
|
||||
//
|
||||
// Define timer message payload structure.
|
||||
//
|
||||
|
||||
/* Define timer message payload structure. */
|
||||
|
||||
typedef struct _HV_TIMER_MESSAGE_PAYLOAD
|
||||
{
|
||||
u32 TimerIndex;
|
||||
u32 Reserved;
|
||||
HV_NANO100_TIME ExpirationTime; // When the timer expired
|
||||
HV_NANO100_TIME DeliveryTime; // When the message was delivered
|
||||
HV_NANO100_TIME ExpirationTime; /* When the timer expired */
|
||||
HV_NANO100_TIME DeliveryTime; /* When the message was delivered */
|
||||
} HV_TIMER_MESSAGE_PAYLOAD, *PHV_TIMER_MESSAGE_PAYLOAD;
|
||||
|
||||
//
|
||||
// Define synthetic interrupt controller message format.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt controller message format. */
|
||||
|
||||
|
||||
typedef struct _HV_MESSAGE
|
||||
{
|
||||
HV_MESSAGE_HEADER Header;
|
||||
union
|
||||
{
|
||||
u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
||||
u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
|
||||
} u ;
|
||||
} HV_MESSAGE, *PHV_MESSAGE;
|
||||
|
||||
//
|
||||
// Define the number of message buffers associated with each port.
|
||||
//
|
||||
|
||||
/* Define the number of message buffers associated with each port. */
|
||||
|
||||
|
||||
#define HV_PORT_MESSAGE_BUFFER_COUNT (16)
|
||||
|
||||
//
|
||||
// Define the synthetic interrupt message page layout.
|
||||
//
|
||||
|
||||
/* Define the synthetic interrupt message page layout. */
|
||||
|
||||
|
||||
typedef struct _HV_MESSAGE_PAGE
|
||||
{
|
||||
|
@ -331,9 +331,9 @@ typedef struct _HV_MESSAGE_PAGE
|
|||
} HV_MESSAGE_PAGE, *PHV_MESSAGE_PAGE;
|
||||
|
||||
|
||||
//
|
||||
// Define the synthetic interrupt controller event flags format.
|
||||
//
|
||||
|
||||
/* Define the synthetic interrupt controller event flags format. */
|
||||
|
||||
|
||||
typedef union _HV_SYNIC_EVENT_FLAGS
|
||||
{
|
||||
|
@ -342,9 +342,9 @@ typedef union _HV_SYNIC_EVENT_FLAGS
|
|||
} HV_SYNIC_EVENT_FLAGS, *PHV_SYNIC_EVENT_FLAGS;
|
||||
|
||||
|
||||
//
|
||||
// Define the synthetic interrupt flags page layout.
|
||||
//
|
||||
|
||||
/* Define the synthetic interrupt flags page layout. */
|
||||
|
||||
|
||||
typedef struct _HV_SYNIC_EVENT_FLAGS_PAGE
|
||||
{
|
||||
|
@ -352,69 +352,69 @@ typedef struct _HV_SYNIC_EVENT_FLAGS_PAGE
|
|||
} HV_SYNIC_EVENT_FLAGS_PAGE, *PHV_SYNIC_EVENT_FLAGS_PAGE;
|
||||
|
||||
|
||||
//
|
||||
// Define SynIC control register.
|
||||
//
|
||||
|
||||
/* Define SynIC control register. */
|
||||
|
||||
typedef union _HV_SYNIC_SCONTROL
|
||||
{
|
||||
u64 AsUINT64;
|
||||
struct
|
||||
{
|
||||
u64 Enable:1;
|
||||
u64 Reserved:63;
|
||||
u64 Enable:1;
|
||||
u64 Reserved:63;
|
||||
};
|
||||
} HV_SYNIC_SCONTROL, *PHV_SYNIC_SCONTROL;
|
||||
|
||||
//
|
||||
// Define synthetic interrupt source.
|
||||
//
|
||||
|
||||
/* Define synthetic interrupt source. */
|
||||
|
||||
|
||||
typedef union _HV_SYNIC_SINT
|
||||
{
|
||||
u64 AsUINT64;
|
||||
struct
|
||||
{
|
||||
u64 Vector :8;
|
||||
u64 Reserved1 :8;
|
||||
u64 Masked :1;
|
||||
u64 AutoEoi :1;
|
||||
u64 Reserved2 :46;
|
||||
u64 Vector :8;
|
||||
u64 Reserved1 :8;
|
||||
u64 Masked :1;
|
||||
u64 AutoEoi :1;
|
||||
u64 Reserved2 :46;
|
||||
};
|
||||
} HV_SYNIC_SINT, *PHV_SYNIC_SINT;
|
||||
|
||||
//
|
||||
// Define the format of the SIMP register
|
||||
//
|
||||
|
||||
/* Define the format of the SIMP register */
|
||||
|
||||
|
||||
typedef union _HV_SYNIC_SIMP
|
||||
{
|
||||
u64 AsUINT64;
|
||||
struct
|
||||
{
|
||||
u64 SimpEnabled : 1;
|
||||
u64 Preserved : 11;
|
||||
u64 BaseSimpGpa : 52;
|
||||
u64 SimpEnabled : 1;
|
||||
u64 Preserved : 11;
|
||||
u64 BaseSimpGpa : 52;
|
||||
};
|
||||
} HV_SYNIC_SIMP, *PHV_SYNIC_SIMP;
|
||||
|
||||
//
|
||||
// Define the format of the SIEFP register
|
||||
//
|
||||
|
||||
/* Define the format of the SIEFP register */
|
||||
|
||||
|
||||
typedef union _HV_SYNIC_SIEFP
|
||||
{
|
||||
u64 AsUINT64;
|
||||
struct
|
||||
{
|
||||
u64 SiefpEnabled : 1;
|
||||
u64 Preserved : 11;
|
||||
u64 BaseSiefpGpa : 52;
|
||||
u64 SiefpEnabled : 1;
|
||||
u64 Preserved : 11;
|
||||
u64 BaseSiefpGpa : 52;
|
||||
};
|
||||
} HV_SYNIC_SIEFP, *PHV_SYNIC_SIEFP;
|
||||
|
||||
//
|
||||
// Definitions for the monitored notification facility
|
||||
//
|
||||
|
||||
/* Definitions for the monitored notification facility */
|
||||
|
||||
|
||||
typedef union _HV_MONITOR_TRIGGER_GROUP
|
||||
{
|
||||
|
@ -422,8 +422,8 @@ typedef union _HV_MONITOR_TRIGGER_GROUP
|
|||
|
||||
struct
|
||||
{
|
||||
u32 Pending;
|
||||
u32 Armed;
|
||||
u32 Pending;
|
||||
u32 Armed;
|
||||
};
|
||||
|
||||
} HV_MONITOR_TRIGGER_GROUP, *PHV_MONITOR_TRIGGER_GROUP;
|
||||
|
@ -441,32 +441,32 @@ typedef union _HV_MONITOR_TRIGGER_STATE
|
|||
|
||||
struct
|
||||
{
|
||||
u32 GroupEnable : 4;
|
||||
u32 RsvdZ : 28;
|
||||
u32 GroupEnable : 4;
|
||||
u32 RsvdZ : 28;
|
||||
};
|
||||
|
||||
} HV_MONITOR_TRIGGER_STATE, *PHV_MONITOR_TRIGGER_STATE;
|
||||
|
||||
//
|
||||
// HV_MONITOR_PAGE Layout
|
||||
// ------------------------------------------------------
|
||||
// | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) |
|
||||
// | 8 | TriggerGroup[0] |
|
||||
// | 10 | TriggerGroup[1] |
|
||||
// | 18 | TriggerGroup[2] |
|
||||
// | 20 | TriggerGroup[3] |
|
||||
// | 28 | Rsvd2[0] |
|
||||
// | 30 | Rsvd2[1] |
|
||||
// | 38 | Rsvd2[2] |
|
||||
// | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] |
|
||||
// | ... |
|
||||
// | 240 | Latency[0][0..3] |
|
||||
// | 340 | Rsvz3[0] |
|
||||
// | 440 | Parameter[0][0] |
|
||||
// | 448 | Parameter[0][1] |
|
||||
// | ... |
|
||||
// | 840 | Rsvd4[0] |
|
||||
// ------------------------------------------------------
|
||||
|
||||
/* HV_MONITOR_PAGE Layout */
|
||||
/* ------------------------------------------------------ */
|
||||
/* | 0 | TriggerState (4 bytes) | Rsvd1 (4 bytes) | */
|
||||
/* | 8 | TriggerGroup[0] | */
|
||||
/* | 10 | TriggerGroup[1] | */
|
||||
/* | 18 | TriggerGroup[2] | */
|
||||
/* | 20 | TriggerGroup[3] | */
|
||||
/* | 28 | Rsvd2[0] | */
|
||||
/* | 30 | Rsvd2[1] | */
|
||||
/* | 38 | Rsvd2[2] | */
|
||||
/* | 40 | NextCheckTime[0][0] | NextCheckTime[0][1] | */
|
||||
/* | ... | */
|
||||
/* | 240 | Latency[0][0..3] | */
|
||||
/* | 340 | Rsvz3[0] | */
|
||||
/* | 440 | Parameter[0][0] | */
|
||||
/* | 448 | Parameter[0][1] | */
|
||||
/* | ... | */
|
||||
/* | 840 | Rsvd4[0] | */
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
typedef struct _HV_MONITOR_PAGE
|
||||
{
|
||||
|
|
|
@ -23,16 +23,16 @@
|
|||
|
||||
|
||||
#pragma once
|
||||
//
|
||||
// Virtual Processor Indices
|
||||
//
|
||||
|
||||
/* Virtual Processor Indices */
|
||||
|
||||
typedef u32 HV_VP_INDEX, *PHV_VP_INDEX;
|
||||
|
||||
//
|
||||
// The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
|
||||
// is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
|
||||
// ==========================================================================
|
||||
//
|
||||
|
||||
/* The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent */
|
||||
/* is set by CPUID(HvCpuIdFunctionVersionAndFeatures). */
|
||||
/* ========================================================================== */
|
||||
|
||||
|
||||
typedef enum _HV_CPUID_FUNCTION
|
||||
{
|
||||
|
@ -40,9 +40,9 @@ typedef enum _HV_CPUID_FUNCTION
|
|||
HvCpuIdFunctionHvVendorAndMaxFunction = 0x40000000,
|
||||
HvCpuIdFunctionHvInterface = 0x40000001,
|
||||
|
||||
//
|
||||
// The remaining functions depend on the value of HvCpuIdFunctionInterface
|
||||
//
|
||||
|
||||
/* The remaining functions depend on the value of HvCpuIdFunctionInterface */
|
||||
|
||||
HvCpuIdFunctionMsHvVersion = 0x40000002,
|
||||
HvCpuIdFunctionMsHvFeatures = 0x40000003,
|
||||
HvCpuIdFunctionMsHvEnlightenmentInformation = 0x40000004,
|
||||
|
|
|
@ -36,10 +36,10 @@
|
|||
typedef DLIST_ENTRY LIST_ENTRY;
|
||||
typedef DLIST_ENTRY *PLIST_ENTRY;
|
||||
|
||||
//typedef struct LIST_ENTRY {
|
||||
// struct LIST_ENTRY * volatile Flink;
|
||||
// struct LIST_ENTRY * volatile Blink;
|
||||
//} LIST_ENTRY, *PLIST_ENTRY;
|
||||
/* typedef struct LIST_ENTRY { */
|
||||
/* struct LIST_ENTRY * volatile Flink; */
|
||||
/* struct LIST_ENTRY * volatile Blink; */
|
||||
/* } LIST_ENTRY, *PLIST_ENTRY; */
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -27,22 +27,22 @@
|
|||
|
||||
#include "VmbusApi.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
/* Defines */
|
||||
|
||||
#define NETVSC_DEVICE_RING_BUFFER_SIZE 64*PAGE_SIZE
|
||||
|
||||
#define HW_MACADDR_LEN 6
|
||||
|
||||
//
|
||||
// Fwd declaration
|
||||
//
|
||||
|
||||
/* Fwd declaration */
|
||||
|
||||
typedef struct _NETVSC_PACKET *PNETVSC_PACKET;
|
||||
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
typedef int (*PFN_ON_OPEN)(DEVICE_OBJECT *Device);
|
||||
typedef int (*PFN_ON_CLOSE)(DEVICE_OBJECT *Device);
|
||||
|
@ -54,27 +54,33 @@ typedef void (*PFN_ON_SENDRECVCOMPLETION)(void * Context);
|
|||
typedef int (*PFN_ON_RECVCALLBACK)(DEVICE_OBJECT *dev, PNETVSC_PACKET packet);
|
||||
typedef void (*PFN_ON_LINKSTATUS_CHANGED)(DEVICE_OBJECT *dev, u32 Status);
|
||||
|
||||
// Represent the xfer page packet which contains 1 or more netvsc packet
|
||||
/* Represent the xfer page packet which contains 1 or more netvsc packet */
|
||||
typedef struct _XFERPAGE_PACKET {
|
||||
DLIST_ENTRY ListEntry;
|
||||
|
||||
// # of netvsc packets this xfer packet contains
|
||||
/* # of netvsc packets this xfer packet contains */
|
||||
u32 Count;
|
||||
} XFERPAGE_PACKET;
|
||||
|
||||
|
||||
// The number of pages which are enough to cover jumbo frame buffer.
|
||||
/* The number of pages which are enough to cover jumbo frame buffer. */
|
||||
#define NETVSC_PACKET_MAXPAGE 4
|
||||
|
||||
// Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame within the RNDIS
|
||||
/*
|
||||
* Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
|
||||
* within the RNDIS
|
||||
*/
|
||||
typedef struct _NETVSC_PACKET {
|
||||
// Bookkeeping stuff
|
||||
/* Bookkeeping stuff */
|
||||
DLIST_ENTRY ListEntry;
|
||||
|
||||
DEVICE_OBJECT *Device;
|
||||
bool IsDataPacket;
|
||||
|
||||
// Valid only for receives when we break a xfer page packet into multiple netvsc packets
|
||||
/*
|
||||
* Valid only for receives when we break a xfer page packet
|
||||
* into multiple netvsc packets
|
||||
*/
|
||||
XFERPAGE_PACKET *XferPagePacket;
|
||||
|
||||
union {
|
||||
|
@ -90,40 +96,42 @@ typedef struct _NETVSC_PACKET {
|
|||
} Send;
|
||||
} Completion;
|
||||
|
||||
// This points to the memory after PageBuffers
|
||||
/* This points to the memory after PageBuffers */
|
||||
void * Extension;
|
||||
|
||||
u32 TotalDataBufferLength;
|
||||
// Points to the send/receive buffer where the ethernet frame is
|
||||
/* Points to the send/receive buffer where the ethernet frame is */
|
||||
u32 PageBufferCount;
|
||||
PAGE_BUFFER PageBuffers[NETVSC_PACKET_MAXPAGE];
|
||||
|
||||
} NETVSC_PACKET;
|
||||
|
||||
|
||||
// Represents the net vsc driver
|
||||
/* Represents the net vsc driver */
|
||||
typedef struct _NETVSC_DRIVER_OBJECT {
|
||||
DRIVER_OBJECT Base; // Must be the first field
|
||||
DRIVER_OBJECT Base; /* Must be the first field */
|
||||
|
||||
u32 RingBufferSize;
|
||||
u32 RequestExtSize;
|
||||
|
||||
// Additional num of page buffers to allocate
|
||||
/* Additional num of page buffers to allocate */
|
||||
u32 AdditionalRequestPageBufferCount;
|
||||
|
||||
// This is set by the caller to allow us to callback when we receive a packet
|
||||
// from the "wire"
|
||||
/*
|
||||
* This is set by the caller to allow us to callback when we
|
||||
* receive a packet from the "wire"
|
||||
*/
|
||||
PFN_ON_RECVCALLBACK OnReceiveCallback;
|
||||
|
||||
PFN_ON_LINKSTATUS_CHANGED OnLinkStatusChanged;
|
||||
|
||||
// Specific to this driver
|
||||
/* Specific to this driver */
|
||||
PFN_ON_OPEN OnOpen;
|
||||
PFN_ON_CLOSE OnClose;
|
||||
PFN_ON_SEND OnSend;
|
||||
//PFN_ON_RECVCOMPLETION OnReceiveCompletion;
|
||||
/* PFN_ON_RECVCOMPLETION OnReceiveCompletion; */
|
||||
|
||||
//PFN_QUERY_LINKSTATUS QueryLinkStatus;
|
||||
/* PFN_QUERY_LINKSTATUS QueryLinkStatus; */
|
||||
|
||||
void* Context;
|
||||
} NETVSC_DRIVER_OBJECT;
|
||||
|
@ -131,15 +139,15 @@ typedef struct _NETVSC_DRIVER_OBJECT {
|
|||
|
||||
typedef struct _NETVSC_DEVICE_INFO {
|
||||
unsigned char MacAddr[6];
|
||||
bool LinkState; // 0 - link up, 1 - link down
|
||||
bool LinkState; /* 0 - link up, 1 - link down */
|
||||
} NETVSC_DEVICE_INFO;
|
||||
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
|
||||
/* Interface */
|
||||
|
||||
int
|
||||
NetVscInitialize(
|
||||
DRIVER_OBJECT* drv
|
||||
);
|
||||
|
||||
#endif // _NETVSC_API_H_
|
||||
#endif /* _NETVSC_API_H_ */
|
||||
|
|
|
@ -27,33 +27,35 @@
|
|||
|
||||
#include "VmbusApi.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
||||
#define STORVSC_RING_BUFFER_SIZE 10*PAGE_SIZE
|
||||
#define BLKVSC_RING_BUFFER_SIZE 20*PAGE_SIZE
|
||||
|
||||
#define STORVSC_MAX_IO_REQUESTS 64
|
||||
|
||||
// In Hyper-V, each port/path/target maps to 1 scsi host adapter.
|
||||
// In reality, the path/target is not used (ie always set to 0) so
|
||||
// our scsi host adapter essentially has 1 bus with 1 target that contains
|
||||
// up to 256 luns.
|
||||
/*
|
||||
* In Hyper-V, each port/path/target maps to 1 scsi host adapter. In
|
||||
* reality, the path/target is not used (ie always set to 0) so our
|
||||
* scsi host adapter essentially has 1 bus with 1 target that contains
|
||||
* up to 256 luns.
|
||||
*/
|
||||
|
||||
#define STORVSC_MAX_LUNS_PER_TARGET 64
|
||||
#define STORVSC_MAX_TARGETS 1
|
||||
#define STORVSC_MAX_CHANNELS 1
|
||||
|
||||
|
||||
// Fwd decl
|
||||
//
|
||||
//struct VMBUS_CHANNEL;
|
||||
/* Fwd decl */
|
||||
|
||||
/* struct VMBUS_CHANNEL; */
|
||||
typedef struct _STORVSC_REQUEST* PSTORVSC_REQUEST;
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
typedef int (*PFN_ON_IO_REQUEST)(PDEVICE_OBJECT Device, PSTORVSC_REQUEST Request);
|
||||
typedef void (*PFN_ON_IO_REQUEST_COMPLTN)(PSTORVSC_REQUEST Request);
|
||||
|
||||
|
@ -61,7 +63,7 @@ typedef int (*PFN_ON_HOST_RESET)(PDEVICE_OBJECT Device);
|
|||
typedef void (*PFN_ON_HOST_RESCAN)(PDEVICE_OBJECT Device);
|
||||
|
||||
|
||||
// Matches Windows-end
|
||||
/* Matches Windows-end */
|
||||
typedef enum _STORVSC_REQUEST_TYPE{
|
||||
WRITE_TYPE,
|
||||
READ_TYPE,
|
||||
|
@ -87,30 +89,30 @@ typedef struct _STORVSC_REQUEST {
|
|||
|
||||
PFN_ON_IO_REQUEST_COMPLTN OnIOCompletion;
|
||||
|
||||
// This points to the memory after DataBuffer
|
||||
/* This points to the memory after DataBuffer */
|
||||
void * Extension;
|
||||
|
||||
MULTIPAGE_BUFFER DataBuffer;
|
||||
} STORVSC_REQUEST;
|
||||
|
||||
|
||||
// Represents the block vsc driver
|
||||
/* Represents the block vsc driver */
|
||||
typedef struct _STORVSC_DRIVER_OBJECT {
|
||||
DRIVER_OBJECT Base; // Must be the first field
|
||||
DRIVER_OBJECT Base; /* Must be the first field */
|
||||
|
||||
// Set by caller (in bytes)
|
||||
/* Set by caller (in bytes) */
|
||||
u32 RingBufferSize;
|
||||
|
||||
// Allocate this much private extension for each I/O request
|
||||
/* Allocate this much private extension for each I/O request */
|
||||
u32 RequestExtSize;
|
||||
|
||||
// Maximum # of requests in flight per channel/device
|
||||
/* Maximum # of requests in flight per channel/device */
|
||||
u32 MaxOutstandingRequestsPerChannel;
|
||||
|
||||
// Set by the caller to allow us to re-enumerate the bus on the host
|
||||
/* Set by the caller to allow us to re-enumerate the bus on the host */
|
||||
PFN_ON_HOST_RESCAN OnHostRescan;
|
||||
|
||||
// Specific to this driver
|
||||
/* Specific to this driver */
|
||||
PFN_ON_IO_REQUEST OnIORequest;
|
||||
PFN_ON_HOST_RESET OnHostReset;
|
||||
|
||||
|
@ -122,9 +124,9 @@ typedef struct _STORVSC_DEVICE_INFO {
|
|||
unsigned char TargetId;
|
||||
} STORVSC_DEVICE_INFO;
|
||||
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
|
||||
/* Interface */
|
||||
|
||||
int
|
||||
StorVscInitialize(
|
||||
DRIVER_OBJECT *Driver
|
||||
|
@ -134,4 +136,4 @@ int
|
|||
BlkVscInitialize(
|
||||
DRIVER_OBJECT *Driver
|
||||
);
|
||||
#endif // _STORVSC_API_H_
|
||||
#endif /* _STORVSC_API_H_ */
|
||||
|
|
|
@ -27,57 +27,57 @@
|
|||
|
||||
#include "osd.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
||||
#define MAX_PAGE_BUFFER_COUNT 16
|
||||
#define MAX_MULTIPAGE_BUFFER_COUNT 32 // 128K
|
||||
#define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */
|
||||
|
||||
|
||||
//
|
||||
// Fwd declarations
|
||||
//
|
||||
|
||||
/* Fwd declarations */
|
||||
|
||||
typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT;
|
||||
typedef struct _DEVICE_OBJECT *PDEVICE_OBJECT;
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
// Single-page buffer
|
||||
/* Single-page buffer */
|
||||
typedef struct _PAGE_BUFFER {
|
||||
u32 Length;
|
||||
u32 Offset;
|
||||
u64 Pfn;
|
||||
} PAGE_BUFFER;
|
||||
|
||||
// Multiple-page buffer
|
||||
/* Multiple-page buffer */
|
||||
typedef struct _MULTIPAGE_BUFFER {
|
||||
// Length and Offset determines the # of pfns in the array
|
||||
/* Length and Offset determines the # of pfns in the array */
|
||||
u32 Length;
|
||||
u32 Offset;
|
||||
u64 PfnArray[MAX_MULTIPAGE_BUFFER_COUNT];
|
||||
}MULTIPAGE_BUFFER;
|
||||
|
||||
//0x18 includes the proprietary packet header
|
||||
/* 0x18 includes the proprietary packet header */
|
||||
#define MAX_PAGE_BUFFER_PACKET (0x18 + (sizeof(PAGE_BUFFER) * MAX_PAGE_BUFFER_COUNT))
|
||||
#define MAX_MULTIPAGE_BUFFER_PACKET (0x18 + sizeof(MULTIPAGE_BUFFER))
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
// All drivers
|
||||
/* All drivers */
|
||||
typedef int (*PFN_ON_DEVICEADD)(PDEVICE_OBJECT Device, void* AdditionalInfo);
|
||||
typedef int (*PFN_ON_DEVICEREMOVE)(PDEVICE_OBJECT Device);
|
||||
typedef char** (*PFN_ON_GETDEVICEIDS)(void);
|
||||
typedef void (*PFN_ON_CLEANUP)(PDRIVER_OBJECT Driver);
|
||||
|
||||
// Vmbus extensions
|
||||
//typedef int (*PFN_ON_MATCH)(PDEVICE_OBJECT dev, PDRIVER_OBJECT drv);
|
||||
//typedef int (*PFN_ON_PROBE)(PDEVICE_OBJECT dev);
|
||||
/* Vmbus extensions */
|
||||
/* typedef int (*PFN_ON_MATCH)(PDEVICE_OBJECT dev, PDRIVER_OBJECT drv); */
|
||||
/* typedef int (*PFN_ON_PROBE)(PDEVICE_OBJECT dev); */
|
||||
typedef int (*PFN_ON_ISR)(PDRIVER_OBJECT drv);
|
||||
typedef void (*PFN_ON_DPC)(PDRIVER_OBJECT drv);
|
||||
typedef void (*PFN_GET_CHANNEL_OFFERS)(void);
|
||||
|
@ -87,7 +87,7 @@ typedef void (*PFN_ON_CHILDDEVICE_DESTROY)(PDEVICE_OBJECT Device);
|
|||
typedef int (*PFN_ON_CHILDDEVICE_ADD)(PDEVICE_OBJECT RootDevice, PDEVICE_OBJECT ChildDevice);
|
||||
typedef void (*PFN_ON_CHILDDEVICE_REMOVE)(PDEVICE_OBJECT Device);
|
||||
|
||||
// Vmbus channel interface
|
||||
/* Vmbus channel interface */
|
||||
typedef void (*VMBUS_CHANNEL_CALLBACK)(void * context);
|
||||
|
||||
typedef int (*VMBUS_CHANNEL_OPEN)(
|
||||
|
@ -148,8 +148,8 @@ typedef int (*VMBUS_CHANNEL_RECV_PACKET_PAW)(
|
|||
|
||||
typedef int (*VMBUS_CHANNEL_ESTABLISH_GPADL)(
|
||||
PDEVICE_OBJECT Device,
|
||||
void * Buffer, // from kmalloc()
|
||||
u32 BufferLen, // page-size multiple
|
||||
void * Buffer, /* from kmalloc() */
|
||||
u32 BufferLen, /* page-size multiple */
|
||||
u32* GpadlHandle
|
||||
);
|
||||
|
||||
|
@ -203,44 +203,44 @@ typedef struct _VMBUS_CHANNEL_INTERFACE {
|
|||
|
||||
typedef void (*VMBUS_GET_CHANNEL_INTERFACE)(VMBUS_CHANNEL_INTERFACE *Interface);
|
||||
|
||||
// Base driver object
|
||||
/* Base driver object */
|
||||
typedef struct _DRIVER_OBJECT {
|
||||
const char* name;
|
||||
GUID deviceType; // the device type supported by this driver
|
||||
GUID deviceType; /* the device type supported by this driver */
|
||||
|
||||
PFN_ON_DEVICEADD OnDeviceAdd;
|
||||
PFN_ON_DEVICEREMOVE OnDeviceRemove;
|
||||
PFN_ON_GETDEVICEIDS OnGetDeviceIds; // device ids supported by this driver
|
||||
PFN_ON_GETDEVICEIDS OnGetDeviceIds; /* device ids supported by this driver */
|
||||
PFN_ON_CLEANUP OnCleanup;
|
||||
|
||||
VMBUS_CHANNEL_INTERFACE VmbusChannelInterface;
|
||||
} DRIVER_OBJECT;
|
||||
|
||||
|
||||
// Base device object
|
||||
/* Base device object */
|
||||
typedef struct _DEVICE_OBJECT {
|
||||
DRIVER_OBJECT* Driver; // the driver for this device
|
||||
DRIVER_OBJECT* Driver; /* the driver for this device */
|
||||
char name[64];
|
||||
GUID deviceType; // the device type id of this device
|
||||
GUID deviceInstance; // the device instance id of this device
|
||||
GUID deviceType; /* the device type id of this device */
|
||||
GUID deviceInstance; /* the device instance id of this device */
|
||||
void* context;
|
||||
void* Extension; // Device extension;
|
||||
void* Extension; /* Device extension; */
|
||||
} DEVICE_OBJECT;
|
||||
|
||||
|
||||
// Vmbus driver object
|
||||
/* Vmbus driver object */
|
||||
typedef struct _VMBUS_DRIVER_OBJECT {
|
||||
DRIVER_OBJECT Base; // !! Must be the 1st field !!
|
||||
DRIVER_OBJECT Base; /* !! Must be the 1st field !! */
|
||||
|
||||
// Set by the caller
|
||||
/* Set by the caller */
|
||||
PFN_ON_CHILDDEVICE_CREATE OnChildDeviceCreate;
|
||||
PFN_ON_CHILDDEVICE_DESTROY OnChildDeviceDestroy;
|
||||
PFN_ON_CHILDDEVICE_ADD OnChildDeviceAdd;
|
||||
PFN_ON_CHILDDEVICE_REMOVE OnChildDeviceRemove;
|
||||
|
||||
// Set by the callee
|
||||
//PFN_ON_MATCH OnMatch;
|
||||
//PFN_ON_PROBE OnProbe;
|
||||
/* Set by the callee */
|
||||
/* PFN_ON_MATCH OnMatch; */
|
||||
/* PFN_ON_PROBE OnProbe; */
|
||||
PFN_ON_ISR OnIsr;
|
||||
PFN_ON_DPC OnMsgDpc;
|
||||
PFN_ON_DPC OnEventDpc;
|
||||
|
@ -251,12 +251,12 @@ typedef struct _VMBUS_DRIVER_OBJECT {
|
|||
} VMBUS_DRIVER_OBJECT;
|
||||
|
||||
|
||||
//
|
||||
// Interface
|
||||
//
|
||||
|
||||
/* Interface */
|
||||
|
||||
int
|
||||
VmbusInitialize(
|
||||
DRIVER_OBJECT* drv
|
||||
);
|
||||
|
||||
#endif // _VMBUS_API_H_
|
||||
#endif /* _VMBUS_API_H_ */
|
||||
|
|
|
@ -23,42 +23,42 @@
|
|||
|
||||
|
||||
#pragma once
|
||||
// allow nameless unions
|
||||
//#pragma warning(disable : 4201)
|
||||
/* allow nameless unions */
|
||||
/* #pragma warning(disable : 4201) */
|
||||
|
||||
|
||||
/* A revision number of vmbus that is used for ensuring both ends on a */
|
||||
/* partition are using compatible versions. */
|
||||
|
||||
//
|
||||
// A revision number of vmbus that is used for ensuring both ends on a
|
||||
// partition are using compatible versions.
|
||||
//
|
||||
#define VMBUS_REVISION_NUMBER 13
|
||||
|
||||
//
|
||||
// Make maximum size of pipe payload of 16K
|
||||
//
|
||||
#define MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384)
|
||||
|
||||
//
|
||||
// Define PipeMode values.
|
||||
//
|
||||
/* Make maximum size of pipe payload of 16K */
|
||||
|
||||
#define MAX_PIPE_DATA_PAYLOAD (sizeof(BYTE) * 16384)
|
||||
|
||||
|
||||
/* Define PipeMode values. */
|
||||
|
||||
#define VMBUS_PIPE_TYPE_BYTE 0x00000000
|
||||
#define VMBUS_PIPE_TYPE_MESSAGE 0x00000004
|
||||
|
||||
//
|
||||
// The size of the user defined data buffer for non-pipe offers.
|
||||
//
|
||||
|
||||
/* The size of the user defined data buffer for non-pipe offers. */
|
||||
|
||||
#define MAX_USER_DEFINED_BYTES 120
|
||||
|
||||
//
|
||||
// The size of the user defined data buffer for pipe offers.
|
||||
//
|
||||
|
||||
/* The size of the user defined data buffer for pipe offers. */
|
||||
|
||||
#define MAX_PIPE_USER_DEFINED_BYTES 116
|
||||
|
||||
|
||||
//
|
||||
// At the center of the Channel Management library is
|
||||
// the Channel Offer. This struct contains the
|
||||
// fundamental information about an offer.
|
||||
//
|
||||
|
||||
/* At the center of the Channel Management library is */
|
||||
/* the Channel Offer. This struct contains the */
|
||||
/* fundamental information about an offer. */
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
|
@ -68,30 +68,30 @@ typedef struct
|
|||
GUID InterfaceInstance;
|
||||
u64 InterruptLatencyIn100nsUnits;
|
||||
u32 InterfaceRevision;
|
||||
u32 ServerContextAreaSize; // in bytes
|
||||
u32 ServerContextAreaSize; /* in bytes */
|
||||
u16 ChannelFlags;
|
||||
u16 MmioMegabytes; // in bytes * 1024 * 1024
|
||||
u16 MmioMegabytes; /* in bytes * 1024 * 1024 */
|
||||
|
||||
union
|
||||
{
|
||||
//
|
||||
// Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes.
|
||||
//
|
||||
struct
|
||||
{
|
||||
unsigned char UserDefined[MAX_USER_DEFINED_BYTES];
|
||||
} Standard;
|
||||
|
||||
//
|
||||
// Pipes: The following sructure is an integrated pipe protocol, which
|
||||
// is implemented on top of standard user-defined data. Pipe clients
|
||||
// have MAX_PIPE_USER_DEFINED_BYTES left for their own use.
|
||||
//
|
||||
struct
|
||||
{
|
||||
u32 PipeMode;
|
||||
unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES];
|
||||
} Pipe;
|
||||
/* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
|
||||
|
||||
struct
|
||||
{
|
||||
unsigned char UserDefined[MAX_USER_DEFINED_BYTES];
|
||||
} Standard;
|
||||
|
||||
|
||||
/* Pipes: The following sructure is an integrated pipe protocol, which */
|
||||
/* is implemented on top of standard user-defined data. Pipe clients */
|
||||
/* have MAX_PIPE_USER_DEFINED_BYTES left for their own use. */
|
||||
|
||||
struct
|
||||
{
|
||||
u32 PipeMode;
|
||||
unsigned char UserDefined[MAX_PIPE_USER_DEFINED_BYTES];
|
||||
} Pipe;
|
||||
} u;
|
||||
u32 Padding;
|
||||
} VMBUS_CHANNEL_OFFER, *PVMBUS_CHANNEL_OFFER;
|
||||
|
@ -100,9 +100,9 @@ typedef struct
|
|||
|
||||
typedef u32 GPADL_HANDLE;
|
||||
|
||||
//
|
||||
// Server Flags
|
||||
//
|
||||
|
||||
/* Server Flags */
|
||||
|
||||
|
||||
#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1
|
||||
#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2
|
||||
|
@ -112,11 +112,10 @@ typedef u32 GPADL_HANDLE;
|
|||
#define VMBUS_CHANNEL_PARENT_OFFER 0x200
|
||||
#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400
|
||||
|
||||
//
|
||||
// TEMPTEMP -- move this next define to devioctl.h some day
|
||||
//
|
||||
|
||||
/* TEMPTEMP -- move this next define to devioctl.h some day */
|
||||
|
||||
|
||||
#ifndef FILE_DEVICE_VMBUS
|
||||
#define FILE_DEVICE_VMBUS 0x0000003E
|
||||
#endif
|
||||
|
||||
|
|
|
@ -24,33 +24,33 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//#ifndef PAGE_SIZE
|
||||
//#if defined(_IA64_)
|
||||
//#error This does not work for IA64
|
||||
//#else
|
||||
//#define PAGE_SIZE 0x1000
|
||||
//#endif
|
||||
//#endif
|
||||
/* #ifndef PAGE_SIZE */
|
||||
/* #if defined(_IA64_) */
|
||||
/* #error This does not work for IA64 */
|
||||
/* #else */
|
||||
/* #define PAGE_SIZE 0x1000 */
|
||||
/* #endif */
|
||||
/* #endif */
|
||||
|
||||
// allow nameless unions
|
||||
//#pragma warning(disable : 4201)
|
||||
/* allow nameless unions */
|
||||
/* #pragma warning(disable : 4201) */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
volatile u32 In; // Offset in bytes from the ring base
|
||||
volatile u32 Out; // Offset in bytes from the ring base
|
||||
};
|
||||
volatile long long InOut;
|
||||
struct
|
||||
{
|
||||
volatile u32 In; /* Offset in bytes from the ring base */
|
||||
volatile u32 Out; /* Offset in bytes from the ring base */
|
||||
};
|
||||
volatile long long InOut;
|
||||
};
|
||||
|
||||
//
|
||||
// If the receiving endpoint sets this to some non-zero value, the sending
|
||||
// endpoint should not send any interrupts.
|
||||
//
|
||||
|
||||
/* If the receiving endpoint sets this to some non-zero value, the sending */
|
||||
/* endpoint should not send any interrupts. */
|
||||
|
||||
|
||||
volatile u32 InterruptMask;
|
||||
|
||||
|
@ -60,18 +60,18 @@ typedef struct
|
|||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
VMRCB Control;
|
||||
};
|
||||
struct
|
||||
{
|
||||
VMRCB Control;
|
||||
};
|
||||
|
||||
u8 Reserved[PAGE_SIZE];
|
||||
u8 Reserved[PAGE_SIZE];
|
||||
};
|
||||
|
||||
//
|
||||
// Beginning of the ring data. Note: It must be guaranteed that
|
||||
// this data does not share a page with the control structure.
|
||||
//
|
||||
|
||||
/* Beginning of the ring data. Note: It must be guaranteed that */
|
||||
/* this data does not share a page with the control structure. */
|
||||
|
||||
u8 Data[1];
|
||||
} VMRING, *PVMRING;
|
||||
|
||||
|
@ -159,10 +159,10 @@ typedef struct _VMADD_REMOVE_TRANSFER_PAGE_SET {
|
|||
|
||||
#pragma pack(pop)
|
||||
|
||||
//
|
||||
// This structure defines a range in guest physical space that can be made
|
||||
// to look virtually contiguous.
|
||||
//
|
||||
|
||||
/* This structure defines a range in guest physical space that can be made */
|
||||
/* to look virtually contiguous. */
|
||||
|
||||
|
||||
typedef struct _GPA_RANGE {
|
||||
|
||||
|
@ -176,13 +176,13 @@ typedef struct _GPA_RANGE {
|
|||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
//
|
||||
// This is the format for an Establish Gpadl packet, which contains a handle
|
||||
// by which this GPADL will be known and a set of GPA ranges associated with
|
||||
// it. This can be converted to a MDL by the guest OS. If there are multiple
|
||||
// GPA ranges, then the resulting MDL will be "chained," representing multiple
|
||||
// VA ranges.
|
||||
//
|
||||
|
||||
/* This is the format for an Establish Gpadl packet, which contains a handle */
|
||||
/* by which this GPADL will be known and a set of GPA ranges associated with */
|
||||
/* it. This can be converted to a MDL by the guest OS. If there are multiple */
|
||||
/* GPA ranges, then the resulting MDL will be "chained," representing multiple */
|
||||
/* VA ranges. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -203,10 +203,10 @@ typedef struct _VMESTABLISH_GPADL {
|
|||
} VMESTABLISH_GPADL, *PVMESTABLISH_GPADL;
|
||||
|
||||
|
||||
//
|
||||
// This is the format for a Teardown Gpadl packet, which indicates that the
|
||||
// GPADL handle in the Establish Gpadl packet will never be referenced again.
|
||||
//
|
||||
|
||||
/* This is the format for a Teardown Gpadl packet, which indicates that the */
|
||||
/* GPADL handle in the Establish Gpadl packet will never be referenced again. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -221,14 +221,14 @@ typedef struct _VMTEARDOWN_GPADL {
|
|||
#endif
|
||||
|
||||
u32 Gpadl;
|
||||
u32 Reserved; // for alignment to a 8-byte boundary
|
||||
u32 Reserved; /* for alignment to a 8-byte boundary */
|
||||
} VMTEARDOWN_GPADL, *PVMTEARDOWN_GPADL;
|
||||
|
||||
|
||||
//
|
||||
// This is the format for a GPA-Direct packet, which contains a set of GPA
|
||||
// ranges, in addition to commands and/or data.
|
||||
//
|
||||
|
||||
/* This is the format for a GPA-Direct packet, which contains a set of GPA */
|
||||
/* ranges, in addition to commands and/or data. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -250,9 +250,9 @@ typedef struct _VMDATA_GPA_DIRECT {
|
|||
|
||||
|
||||
|
||||
//
|
||||
// This is the format for a Additional Data Packet.
|
||||
//
|
||||
|
||||
/* This is the format for a Additional Data Packet. */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
|
@ -318,5 +318,3 @@ typedef enum {
|
|||
} VMBUS_PACKET_TYPE, *PVMBUS_PACKET_TYPE;
|
||||
|
||||
#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED 1
|
||||
|
||||
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#ifndef _LOGGING_H_
|
||||
#define _LOGGING_H_
|
||||
|
||||
//#include <linux/init.h>
|
||||
//#include <linux/module.h>
|
||||
/* #include <linux/init.h> */
|
||||
/* #include <linux/module.h> */
|
||||
|
||||
#include "osd.h"
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
INPUTVSC_DRV|\
|
||||
BLKVSC_DRV)
|
||||
|
||||
// Logging Level
|
||||
/* Logging Level */
|
||||
#define ERROR_LVL 3
|
||||
#define WARNING_LVL 4
|
||||
#define INFO_LVL 6
|
||||
|
@ -117,4 +117,4 @@ extern unsigned int vmbus_loglevel;
|
|||
#define DPRINT_EXIT(mod)
|
||||
#endif
|
||||
|
||||
#endif //_LOGGING_H_
|
||||
#endif /* _LOGGING_H_ */
|
||||
|
|
|
@ -36,17 +36,17 @@ typedef enum _NVSP_MESSAGE_TYPE
|
|||
{
|
||||
NvspMessageTypeNone = 0,
|
||||
|
||||
//
|
||||
// Init Messages
|
||||
//
|
||||
|
||||
/* Init Messages */
|
||||
|
||||
NvspMessageTypeInit = 1,
|
||||
NvspMessageTypeInitComplete = 2,
|
||||
|
||||
NvspVersionMessageStart = 100,
|
||||
|
||||
//
|
||||
// Version 1 Messages
|
||||
//
|
||||
|
||||
/* Version 1 Messages */
|
||||
|
||||
NvspMessage1TypeSendNdisVersion = NvspVersionMessageStart,
|
||||
|
||||
NvspMessage1TypeSendReceiveBuffer,
|
||||
|
@ -60,10 +60,10 @@ typedef enum _NVSP_MESSAGE_TYPE
|
|||
NvspMessage1TypeSendRNDISPacket,
|
||||
NvspMessage1TypeSendRNDISPacketComplete,
|
||||
|
||||
//
|
||||
// This should be set to the number of messages for the version
|
||||
// with the maximum number of messages.
|
||||
//
|
||||
|
||||
/* This should be set to the number of messages for the version */
|
||||
/* with the maximum number of messages. */
|
||||
|
||||
NvspNumMessagePerVersion = 9,
|
||||
|
||||
} NVSP_MESSAGE_TYPE, *PNVSP_MESSAGE_TYPE;
|
||||
|
@ -87,27 +87,27 @@ typedef struct _NVSP_MESSAGE_HEADER
|
|||
u32 MessageType;
|
||||
} NVSP_MESSAGE_HEADER, *PNVSP_MESSAGE_HEADER;
|
||||
|
||||
//
|
||||
// Init Messages
|
||||
//
|
||||
|
||||
//
|
||||
// This message is used by the VSC to initialize the channel
|
||||
// after the channels has been opened. This message should
|
||||
// never include anything other then versioning (i.e. this
|
||||
// message will be the same for ever).
|
||||
//
|
||||
/* Init Messages */
|
||||
|
||||
|
||||
|
||||
/* This message is used by the VSC to initialize the channel */
|
||||
/* after the channels has been opened. This message should */
|
||||
/* never include anything other then versioning (i.e. this */
|
||||
/* message will be the same for ever). */
|
||||
|
||||
typedef struct _NVSP_MESSAGE_INIT
|
||||
{
|
||||
u32 MinProtocolVersion;
|
||||
u32 MaxProtocolVersion;
|
||||
} NVSP_MESSAGE_INIT, *PNVSP_MESSAGE_INIT;
|
||||
|
||||
//
|
||||
// This message is used by the VSP to complete the initialization
|
||||
// of the channel. This message should never include anything other
|
||||
// then versioning (i.e. this message will be the same for ever).
|
||||
//
|
||||
|
||||
/* This message is used by the VSP to complete the initialization */
|
||||
/* of the channel. This message should never include anything other */
|
||||
/* then versioning (i.e. this message will be the same for ever). */
|
||||
|
||||
typedef struct _NVSP_MESSAGE_INIT_COMPLETE
|
||||
{
|
||||
u32 NegotiatedProtocolVersion;
|
||||
|
@ -121,26 +121,26 @@ typedef union _NVSP_MESSAGE_INIT_UBER
|
|||
NVSP_MESSAGE_INIT_COMPLETE InitComplete;
|
||||
} NVSP_MESSAGE_INIT_UBER;
|
||||
|
||||
//
|
||||
// Version 1 Messages
|
||||
//
|
||||
|
||||
//
|
||||
// This message is used by the VSC to send the NDIS version
|
||||
// to the VSP. The VSP can use this information when handling
|
||||
// OIDs sent by the VSC.
|
||||
//
|
||||
/* Version 1 Messages */
|
||||
|
||||
|
||||
|
||||
/* This message is used by the VSC to send the NDIS version */
|
||||
/* to the VSP. The VSP can use this information when handling */
|
||||
/* OIDs sent by the VSC. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_NDIS_VERSION
|
||||
{
|
||||
u32 NdisMajorVersion;
|
||||
u32 NdisMinorVersion;
|
||||
} NVSP_1_MESSAGE_SEND_NDIS_VERSION, *PNVSP_1_MESSAGE_SEND_NDIS_VERSION;
|
||||
|
||||
//
|
||||
// This message is used by the VSC to send a receive buffer
|
||||
// to the VSP. The VSP can then use the receive buffer to
|
||||
// send data to the VSC.
|
||||
//
|
||||
|
||||
/* This message is used by the VSC to send a receive buffer */
|
||||
/* to the VSP. The VSP can then use the receive buffer to */
|
||||
/* send data to the VSC. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_RECEIVE_BUFFER
|
||||
{
|
||||
GPADL_HANDLE GpadlHandle;
|
||||
|
@ -155,117 +155,117 @@ typedef struct _NVSP_1_RECEIVE_BUFFER_SECTION
|
|||
u32 EndOffset;
|
||||
} NVSP_1_RECEIVE_BUFFER_SECTION, *PNVSP_1_RECEIVE_BUFFER_SECTION;
|
||||
|
||||
//
|
||||
// This message is used by the VSP to acknowledge a receive
|
||||
// buffer send by the VSC. This message must be sent by the
|
||||
// VSP before the VSP uses the receive buffer.
|
||||
//
|
||||
|
||||
/* This message is used by the VSP to acknowledge a receive */
|
||||
/* buffer send by the VSC. This message must be sent by the */
|
||||
/* VSP before the VSP uses the receive buffer. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_RECEIVE_BUFFER_COMPLETE
|
||||
{
|
||||
u32 Status;
|
||||
u32 NumSections;
|
||||
|
||||
//
|
||||
// The receive buffer is split into two parts, a large
|
||||
// suballocation section and a small suballocation
|
||||
// section. These sections are then suballocated by a
|
||||
// certain size.
|
||||
//
|
||||
// For example, the following break up of the receive
|
||||
// buffer has 6 large suballocations and 10 small
|
||||
// suballocations.
|
||||
//
|
||||
// | Large Section | | Small Section |
|
||||
// ------------------------------------------------------------
|
||||
// | | | | | | | | | | | | | | | | | |
|
||||
// | |
|
||||
// LargeOffset SmallOffset
|
||||
//
|
||||
|
||||
/* The receive buffer is split into two parts, a large */
|
||||
/* suballocation section and a small suballocation */
|
||||
/* section. These sections are then suballocated by a */
|
||||
/* certain size. */
|
||||
|
||||
/* For example, the following break up of the receive */
|
||||
/* buffer has 6 large suballocations and 10 small */
|
||||
/* suballocations. */
|
||||
|
||||
/* | Large Section | | Small Section | */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* | | | | | | | | | | | | | | | | | | */
|
||||
/* | | */
|
||||
/* LargeOffset SmallOffset */
|
||||
|
||||
NVSP_1_RECEIVE_BUFFER_SECTION Sections[1];
|
||||
|
||||
} NVSP_1_MESSAGE_SEND_RECEIVE_BUFFER_COMPLETE, *PNVSP_1_MESSAGE_SEND_RECEIVE_BUFFER_COMPLETE;
|
||||
|
||||
//
|
||||
// This message is sent by the VSC to revoke the receive buffer.
|
||||
// After the VSP completes this transaction, the vsp should never
|
||||
// use the receive buffer again.
|
||||
//
|
||||
|
||||
/* This message is sent by the VSC to revoke the receive buffer. */
|
||||
/* After the VSP completes this transaction, the vsp should never */
|
||||
/* use the receive buffer again. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_REVOKE_RECEIVE_BUFFER
|
||||
{
|
||||
u16 Id;
|
||||
} NVSP_1_MESSAGE_REVOKE_RECEIVE_BUFFER, *PNVSP_1_MESSAGE_REVOKE_RECEIVE_BUFFER;
|
||||
|
||||
//
|
||||
// This message is used by the VSC to send a send buffer
|
||||
// to the VSP. The VSC can then use the send buffer to
|
||||
// send data to the VSP.
|
||||
//
|
||||
|
||||
/* This message is used by the VSC to send a send buffer */
|
||||
/* to the VSP. The VSC can then use the send buffer to */
|
||||
/* send data to the VSP. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_SEND_BUFFER
|
||||
{
|
||||
GPADL_HANDLE GpadlHandle;
|
||||
u16 Id;
|
||||
} NVSP_1_MESSAGE_SEND_SEND_BUFFER, *PNVSP_1_MESSAGE_SEND_SEND_BUFFER;
|
||||
|
||||
//
|
||||
// This message is used by the VSP to acknowledge a send
|
||||
// buffer sent by the VSC. This message must be sent by the
|
||||
// VSP before the VSP uses the sent buffer.
|
||||
//
|
||||
|
||||
/* This message is used by the VSP to acknowledge a send */
|
||||
/* buffer sent by the VSC. This message must be sent by the */
|
||||
/* VSP before the VSP uses the sent buffer. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_SEND_BUFFER_COMPLETE
|
||||
{
|
||||
u32 Status;
|
||||
|
||||
//
|
||||
// The VSC gets to choose the size of the send buffer and
|
||||
// the VSP gets to choose the sections size of the buffer.
|
||||
// This was done to enable dynamic reconfigurations when
|
||||
// the cost of GPA-direct buffers decreases.
|
||||
//
|
||||
|
||||
/* The VSC gets to choose the size of the send buffer and */
|
||||
/* the VSP gets to choose the sections size of the buffer. */
|
||||
/* This was done to enable dynamic reconfigurations when */
|
||||
/* the cost of GPA-direct buffers decreases. */
|
||||
|
||||
u32 SectionSize;
|
||||
} NVSP_1_MESSAGE_SEND_SEND_BUFFER_COMPLETE, *PNVSP_1_MESSAGE_SEND_SEND_BUFFER_COMPLETE;
|
||||
|
||||
//
|
||||
// This message is sent by the VSC to revoke the send buffer.
|
||||
// After the VSP completes this transaction, the vsp should never
|
||||
// use the send buffer again.
|
||||
//
|
||||
|
||||
/* This message is sent by the VSC to revoke the send buffer. */
|
||||
/* After the VSP completes this transaction, the vsp should never */
|
||||
/* use the send buffer again. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_REVOKE_SEND_BUFFER
|
||||
{
|
||||
u16 Id;
|
||||
} NVSP_1_MESSAGE_REVOKE_SEND_BUFFER, *PNVSP_1_MESSAGE_REVOKE_SEND_BUFFER;
|
||||
|
||||
//
|
||||
// This message is used by both the VSP and the VSC to send
|
||||
// a RNDIS message to the opposite channel endpoint.
|
||||
//
|
||||
|
||||
/* This message is used by both the VSP and the VSC to send */
|
||||
/* a RNDIS message to the opposite channel endpoint. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_RNDIS_PACKET
|
||||
{
|
||||
//
|
||||
// This field is specified by RNIDS. They assume there's
|
||||
// two different channels of communication. However,
|
||||
// the Network VSP only has one. Therefore, the channel
|
||||
// travels with the RNDIS packet.
|
||||
//
|
||||
|
||||
/* This field is specified by RNIDS. They assume there's */
|
||||
/* two different channels of communication. However, */
|
||||
/* the Network VSP only has one. Therefore, the channel */
|
||||
/* travels with the RNDIS packet. */
|
||||
|
||||
u32 ChannelType;
|
||||
|
||||
//
|
||||
// This field is used to send part or all of the data
|
||||
// through a send buffer. This values specifies an
|
||||
// index into the send buffer. If the index is
|
||||
// 0xFFFFFFFF, then the send buffer is not being used
|
||||
// and all of the data was sent through other VMBus
|
||||
// mechanisms.
|
||||
//
|
||||
|
||||
/* This field is used to send part or all of the data */
|
||||
/* through a send buffer. This values specifies an */
|
||||
/* index into the send buffer. If the index is */
|
||||
/* 0xFFFFFFFF, then the send buffer is not being used */
|
||||
/* and all of the data was sent through other VMBus */
|
||||
/* mechanisms. */
|
||||
|
||||
u32 SendBufferSectionIndex;
|
||||
u32 SendBufferSectionSize;
|
||||
} NVSP_1_MESSAGE_SEND_RNDIS_PACKET, *PNVSP_1_MESSAGE_SEND_RNDIS_PACKET;
|
||||
|
||||
//
|
||||
// This message is used by both the VSP and the VSC to complete
|
||||
// a RNDIS message to the opposite channel endpoint. At this
|
||||
// point, the initiator of this message cannot use any resources
|
||||
// associated with the original RNDIS packet.
|
||||
//
|
||||
|
||||
/* This message is used by both the VSP and the VSC to complete */
|
||||
/* a RNDIS message to the opposite channel endpoint. At this */
|
||||
/* point, the initiator of this message cannot use any resources */
|
||||
/* associated with the original RNDIS packet. */
|
||||
|
||||
typedef struct _NVSP_1_MESSAGE_SEND_RNDIS_PACKET_COMPLETE
|
||||
{
|
||||
u32 Status;
|
||||
|
@ -294,9 +294,9 @@ typedef union _NVSP_ALL_MESSAGES
|
|||
|
||||
} NVSP_ALL_MESSAGES;
|
||||
|
||||
//
|
||||
// ALL Messages
|
||||
//
|
||||
|
||||
/* ALL Messages */
|
||||
|
||||
typedef struct _NVSP_MESSAGE
|
||||
{
|
||||
NVSP_MESSAGE_HEADER Header;
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#ifndef _OSD_H_
|
||||
#define _OSD_H_
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
||||
|
||||
#define ALIGN_UP(value, align) ( ((value) & (align-1))? ( ((value) + (align-1)) & ~(align-1) ): (value) )
|
||||
|
@ -42,10 +42,10 @@ typedef struct _DLIST_ENTRY {
|
|||
struct _DLIST_ENTRY *Blink;
|
||||
} DLIST_ENTRY;
|
||||
|
||||
//
|
||||
// Other types
|
||||
//
|
||||
//typedef unsigned char GUID[16];
|
||||
|
||||
/* Other types */
|
||||
|
||||
/* typedef unsigned char GUID[16]; */
|
||||
typedef void* HANDLE;
|
||||
|
||||
typedef struct {
|
||||
|
@ -95,9 +95,9 @@ static inline void do_cpuid(unsigned int op, unsigned int *eax, unsigned int *eb
|
|||
__asm__ __volatile__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "0" (op), "c" (ecx));
|
||||
}
|
||||
|
||||
//
|
||||
// Osd routines
|
||||
//
|
||||
|
||||
/* Osd routines */
|
||||
|
||||
extern void BitSet(unsigned int* addr, int value);
|
||||
extern void BitClear(unsigned int* addr, int value);
|
||||
extern int BitTest(unsigned int* addr, int value);
|
||||
|
@ -127,7 +127,7 @@ extern void WaitEventClose(HANDLE hWait);
|
|||
extern void WaitEventSet(HANDLE hWait);
|
||||
extern int WaitEventWait(HANDLE hWait);
|
||||
|
||||
// If >0, hWait got signaled. If ==0, timeout. If < 0, error
|
||||
/* If >0, hWait got signaled. If ==0, timeout. If < 0, error */
|
||||
extern int WaitEventWaitEx(HANDLE hWait, u32 TimeoutInMs);
|
||||
|
||||
|
||||
|
@ -149,4 +149,4 @@ extern int WorkQueueQueueWorkItem(HANDLE hWorkQueue, PFN_WORKITEM_CALLBACK workI
|
|||
|
||||
extern void QueueWorkItem(PFN_WORKITEM_CALLBACK workItem, void* context);
|
||||
|
||||
#endif // _OSD_H_
|
||||
#endif /* _OSD_H_ */
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#ifndef _RNDIS_H_
|
||||
#define _RNDIS_H_
|
||||
|
||||
//
|
||||
// Basic types
|
||||
//
|
||||
|
||||
/* Basic types */
|
||||
|
||||
typedef u32 RNDIS_REQUEST_ID;
|
||||
typedef u32 RNDIS_HANDLE;
|
||||
typedef u32 RNDIS_STATUS;
|
||||
|
@ -44,9 +44,9 @@ typedef u32 *PRNDIS_CLASS_ID;
|
|||
typedef u32 *PRNDIS_MEDIUM;
|
||||
typedef u32 RNDIS_AF;
|
||||
|
||||
//
|
||||
// Status codes
|
||||
//
|
||||
|
||||
/* Status codes */
|
||||
|
||||
|
||||
#ifndef STATUS_SUCCESS
|
||||
#define STATUS_SUCCESS (0x00000000L)
|
||||
|
@ -150,13 +150,13 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR ((RNDIS_STATUS)0xC0011000L)
|
||||
|
||||
|
||||
//
|
||||
// Object Identifiers used by NdisRequest Query/Set Information
|
||||
//
|
||||
|
||||
//
|
||||
// General Objects
|
||||
//
|
||||
/* Object Identifiers used by NdisRequest Query/Set Information */
|
||||
|
||||
|
||||
|
||||
/* General Objects */
|
||||
|
||||
|
||||
#define RNDIS_OID_GEN_SUPPORTED_LIST 0x00010101
|
||||
#define RNDIS_OID_GEN_HARDWARE_STATUS 0x00010102
|
||||
|
@ -210,10 +210,10 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_GEN_GET_TIME_CAPS 0x0002020F
|
||||
#define RNDIS_OID_GEN_GET_NETCARD_TIME 0x00020210
|
||||
|
||||
//
|
||||
// These are connection-oriented general OIDs.
|
||||
// These replace the above OIDs for connection-oriented media.
|
||||
//
|
||||
|
||||
/* These are connection-oriented general OIDs. */
|
||||
/* These replace the above OIDs for connection-oriented media. */
|
||||
|
||||
#define RNDIS_OID_GEN_CO_SUPPORTED_LIST 0x00010101
|
||||
#define RNDIS_OID_GEN_CO_HARDWARE_STATUS 0x00010102
|
||||
#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED 0x00010103
|
||||
|
@ -231,9 +231,9 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_GEN_CO_GET_TIME_CAPS 0x00010201
|
||||
#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME 0x00010202
|
||||
|
||||
//
|
||||
// These are connection-oriented statistics OIDs.
|
||||
//
|
||||
|
||||
/* These are connection-oriented statistics OIDs. */
|
||||
|
||||
#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK 0x00020101
|
||||
#define RNDIS_OID_GEN_CO_RCV_PDUS_OK 0x00020102
|
||||
#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR 0x00020103
|
||||
|
@ -248,9 +248,9 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING 0x00020205
|
||||
#define RNDIS_OID_GEN_CO_NETCARD_LOAD 0x00020206
|
||||
|
||||
//
|
||||
// These are objects for Connection-oriented media call-managers.
|
||||
//
|
||||
|
||||
/* These are objects for Connection-oriented media call-managers. */
|
||||
|
||||
#define RNDIS_OID_CO_ADD_PVC 0xFF000001
|
||||
#define RNDIS_OID_CO_DELETE_PVC 0xFF000002
|
||||
#define RNDIS_OID_CO_GET_CALL_INFORMATION 0xFF000003
|
||||
|
@ -262,9 +262,9 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_CO_SIGNALING_DISABLED 0xFF000009
|
||||
|
||||
|
||||
//
|
||||
// 802.3 Objects (Ethernet)
|
||||
//
|
||||
|
||||
/* 802.3 Objects (Ethernet) */
|
||||
|
||||
|
||||
#define RNDIS_OID_802_3_PERMANENT_ADDRESS 0x01010101
|
||||
#define RNDIS_OID_802_3_CURRENT_ADDRESS 0x01010102
|
||||
|
@ -272,8 +272,8 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE 0x01010104
|
||||
#define RNDIS_OID_802_3_MAC_OPTIONS 0x01010105
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001
|
||||
|
||||
#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101
|
||||
|
@ -289,9 +289,9 @@ typedef u32 RNDIS_AF;
|
|||
#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS 0x01020207
|
||||
|
||||
|
||||
//
|
||||
// Remote NDIS message types
|
||||
//
|
||||
|
||||
/* Remote NDIS message types */
|
||||
|
||||
#define REMOTE_NDIS_PACKET_MSG 0x00000001
|
||||
#define REMOTE_NDIS_INITIALIZE_MSG 0x00000002
|
||||
#define REMOTE_NDIS_HALT_MSG 0x00000003
|
||||
|
@ -308,7 +308,7 @@ typedef u32 RNDIS_AF;
|
|||
#define REMOTE_CONDIS_INDICATE_STATUS_MSG 0x00008007
|
||||
|
||||
|
||||
// Remote NDIS message completion types
|
||||
/* Remote NDIS message completion types */
|
||||
#define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002
|
||||
#define REMOTE_NDIS_QUERY_CMPLT 0x80000004
|
||||
#define REMOTE_NDIS_SET_CMPLT 0x80000005
|
||||
|
@ -320,24 +320,24 @@ typedef u32 RNDIS_AF;
|
|||
#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT 0x80008005
|
||||
#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT 0x80008006
|
||||
|
||||
//
|
||||
// Reserved message type for private communication between lower-layer
|
||||
// host driver and remote device, if necessary.
|
||||
//
|
||||
|
||||
/* Reserved message type for private communication between lower-layer */
|
||||
/* host driver and remote device, if necessary. */
|
||||
|
||||
#define REMOTE_NDIS_BUS_MSG 0xff000001
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Defines for DeviceFlags in RNDIS_INITIALIZE_COMPLETE
|
||||
//
|
||||
|
||||
/* Defines for DeviceFlags in RNDIS_INITIALIZE_COMPLETE */
|
||||
|
||||
#define RNDIS_DF_CONNECTIONLESS 0x00000001
|
||||
#define RNDIS_DF_CONNECTION_ORIENTED 0x00000002
|
||||
#define RNDIS_DF_RAW_DATA 0x00000004
|
||||
|
||||
//
|
||||
// Remote NDIS medium types.
|
||||
//
|
||||
|
||||
/* Remote NDIS medium types. */
|
||||
|
||||
#define RNdisMedium802_3 0x00000000
|
||||
#define RNdisMedium802_5 0x00000001
|
||||
#define RNdisMediumFddi 0x00000002
|
||||
|
@ -349,23 +349,23 @@ typedef u32 RNDIS_AF;
|
|||
#define RNdisMediumWirelessWan 0x00000009
|
||||
#define RNdisMediumIrda 0x0000000a
|
||||
#define RNdisMediumCoWan 0x0000000b
|
||||
#define RNdisMediumMax 0x0000000d // Not a real medium, defined as an upper-bound
|
||||
#define RNdisMediumMax 0x0000000d /* Not a real medium, defined as an upper-bound */
|
||||
|
||||
|
||||
/* Remote NDIS medium connection states. */
|
||||
|
||||
//
|
||||
// Remote NDIS medium connection states.
|
||||
//
|
||||
#define RNdisMediaStateConnected 0x00000000
|
||||
#define RNdisMediaStateDisconnected 0x00000001
|
||||
|
||||
//
|
||||
// Remote NDIS version numbers
|
||||
//
|
||||
|
||||
/* Remote NDIS version numbers */
|
||||
|
||||
#define RNDIS_MAJOR_VERSION 0x00000001
|
||||
#define RNDIS_MINOR_VERSION 0x00000000
|
||||
|
||||
//
|
||||
// NdisInitialize message
|
||||
//
|
||||
|
||||
/* NdisInitialize message */
|
||||
|
||||
typedef struct _RNDIS_INITIALIZE_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -375,9 +375,9 @@ typedef struct _RNDIS_INITIALIZE_REQUEST
|
|||
} RNDIS_INITIALIZE_REQUEST, *PRNDIS_INITIALIZE_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// Response to NdisInitialize
|
||||
//
|
||||
|
||||
/* Response to NdisInitialize */
|
||||
|
||||
typedef struct _RNDIS_INITIALIZE_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -394,10 +394,10 @@ typedef struct _RNDIS_INITIALIZE_COMPLETE
|
|||
} RNDIS_INITIALIZE_COMPLETE, *PRNDIS_INITIALIZE_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// Call manager devices only: Information about an address family
|
||||
// supported by the device is appended to the response to NdisInitialize.
|
||||
//
|
||||
|
||||
/* Call manager devices only: Information about an address family */
|
||||
/* supported by the device is appended to the response to NdisInitialize. */
|
||||
|
||||
typedef struct _RNDIS_CO_ADDRESS_FAMILY
|
||||
{
|
||||
RNDIS_AF AddressFamily;
|
||||
|
@ -406,18 +406,18 @@ typedef struct _RNDIS_CO_ADDRESS_FAMILY
|
|||
} RNDIS_CO_ADDRESS_FAMILY, *PRNDIS_CO_ADDRESS_FAMILY;
|
||||
|
||||
|
||||
//
|
||||
// NdisHalt message
|
||||
//
|
||||
|
||||
/* NdisHalt message */
|
||||
|
||||
typedef struct _RNDIS_HALT_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
} RNDIS_HALT_REQUEST, *PRNDIS_HALT_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// NdisQueryRequest message
|
||||
//
|
||||
|
||||
/* NdisQueryRequest message */
|
||||
|
||||
typedef struct _RNDIS_QUERY_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -428,9 +428,9 @@ typedef struct _RNDIS_QUERY_REQUEST
|
|||
} RNDIS_QUERY_REQUEST, *PRNDIS_QUERY_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// Response to NdisQueryRequest
|
||||
//
|
||||
|
||||
/* Response to NdisQueryRequest */
|
||||
|
||||
typedef struct _RNDIS_QUERY_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -440,9 +440,9 @@ typedef struct _RNDIS_QUERY_COMPLETE
|
|||
} RNDIS_QUERY_COMPLETE, *PRNDIS_QUERY_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// NdisSetRequest message
|
||||
//
|
||||
|
||||
/* NdisSetRequest message */
|
||||
|
||||
typedef struct _RNDIS_SET_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -453,9 +453,9 @@ typedef struct _RNDIS_SET_REQUEST
|
|||
} RNDIS_SET_REQUEST, *PRNDIS_SET_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// Response to NdisSetRequest
|
||||
//
|
||||
|
||||
/* Response to NdisSetRequest */
|
||||
|
||||
typedef struct _RNDIS_SET_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -463,17 +463,17 @@ typedef struct _RNDIS_SET_COMPLETE
|
|||
} RNDIS_SET_COMPLETE, *PRNDIS_SET_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// NdisReset message
|
||||
//
|
||||
|
||||
/* NdisReset message */
|
||||
|
||||
typedef struct _RNDIS_RESET_REQUEST
|
||||
{
|
||||
u32 Reserved;
|
||||
} RNDIS_RESET_REQUEST, *PRNDIS_RESET_REQUEST;
|
||||
|
||||
//
|
||||
// Response to NdisReset
|
||||
//
|
||||
|
||||
/* Response to NdisReset */
|
||||
|
||||
typedef struct _RNDIS_RESET_COMPLETE
|
||||
{
|
||||
RNDIS_STATUS Status;
|
||||
|
@ -481,9 +481,9 @@ typedef struct _RNDIS_RESET_COMPLETE
|
|||
} RNDIS_RESET_COMPLETE, *PRNDIS_RESET_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// NdisMIndicateStatus message
|
||||
//
|
||||
|
||||
/* NdisMIndicateStatus message */
|
||||
|
||||
typedef struct _RNDIS_INDICATE_STATUS
|
||||
{
|
||||
RNDIS_STATUS Status;
|
||||
|
@ -492,10 +492,10 @@ typedef struct _RNDIS_INDICATE_STATUS
|
|||
} RNDIS_INDICATE_STATUS, *PRNDIS_INDICATE_STATUS;
|
||||
|
||||
|
||||
//
|
||||
// Diagnostic information passed as the status buffer in
|
||||
// RNDIS_INDICATE_STATUS messages signifying error conditions.
|
||||
//
|
||||
|
||||
/* Diagnostic information passed as the status buffer in */
|
||||
/* RNDIS_INDICATE_STATUS messages signifying error conditions. */
|
||||
|
||||
typedef struct _RNDIS_DIAGNOSTIC_INFO
|
||||
{
|
||||
RNDIS_STATUS DiagStatus;
|
||||
|
@ -504,18 +504,18 @@ typedef struct _RNDIS_DIAGNOSTIC_INFO
|
|||
|
||||
|
||||
|
||||
//
|
||||
// NdisKeepAlive message
|
||||
//
|
||||
|
||||
/* NdisKeepAlive message */
|
||||
|
||||
typedef struct _RNDIS_KEEPALIVE_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
} RNDIS_KEEPALIVE_REQUEST, *PRNDIS_KEEPALIVE_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// Response to NdisKeepAlive
|
||||
//
|
||||
|
||||
/* Response to NdisKeepAlive */
|
||||
|
||||
typedef struct _RNDIS_KEEPALIVE_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -523,12 +523,12 @@ typedef struct _RNDIS_KEEPALIVE_COMPLETE
|
|||
} RNDIS_KEEPALIVE_COMPLETE, *PRNDIS_KEEPALIVE_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// Data message. All Offset fields contain byte offsets from the beginning
|
||||
// of the RNDIS_PACKET structure. All Length fields are in bytes.
|
||||
// VcHandle is set to 0 for connectionless data, otherwise it
|
||||
// contains the VC handle.
|
||||
//
|
||||
|
||||
/* Data message. All Offset fields contain byte offsets from the beginning */
|
||||
/* of the RNDIS_PACKET structure. All Length fields are in bytes. */
|
||||
/* VcHandle is set to 0 for connectionless data, otherwise it */
|
||||
/* contains the VC handle. */
|
||||
|
||||
typedef struct _RNDIS_PACKET
|
||||
{
|
||||
u32 DataOffset;
|
||||
|
@ -542,9 +542,9 @@ typedef struct _RNDIS_PACKET
|
|||
u32 Reserved;
|
||||
} RNDIS_PACKET, *PRNDIS_PACKET;
|
||||
|
||||
//
|
||||
// Optional Out of Band data associated with a Data message.
|
||||
//
|
||||
|
||||
/* Optional Out of Band data associated with a Data message. */
|
||||
|
||||
typedef struct _RNDIS_OOBD
|
||||
{
|
||||
u32 Size;
|
||||
|
@ -552,9 +552,9 @@ typedef struct _RNDIS_OOBD
|
|||
u32 ClassInformationOffset;
|
||||
} RNDIS_OOBD, *PRNDIS_OOBD;
|
||||
|
||||
//
|
||||
// Packet extension field contents associated with a Data message.
|
||||
//
|
||||
|
||||
/* Packet extension field contents associated with a Data message. */
|
||||
|
||||
typedef struct _RNDIS_PER_PACKET_INFO
|
||||
{
|
||||
u32 Size;
|
||||
|
@ -563,10 +563,10 @@ typedef struct _RNDIS_PER_PACKET_INFO
|
|||
} RNDIS_PER_PACKET_INFO, *PRNDIS_PER_PACKET_INFO;
|
||||
|
||||
|
||||
//
|
||||
// Format of Information buffer passed in a SetRequest for the OID
|
||||
// OID_GEN_RNDIS_CONFIG_PARAMETER.
|
||||
//
|
||||
|
||||
/* Format of Information buffer passed in a SetRequest for the OID */
|
||||
/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
|
||||
|
||||
typedef struct _RNDIS_CONFIG_PARAMETER_INFO
|
||||
{
|
||||
u32 ParameterNameOffset;
|
||||
|
@ -576,30 +576,30 @@ typedef struct _RNDIS_CONFIG_PARAMETER_INFO
|
|||
u32 ParameterValueLength;
|
||||
} RNDIS_CONFIG_PARAMETER_INFO, *PRNDIS_CONFIG_PARAMETER_INFO;
|
||||
|
||||
//
|
||||
// Values for ParameterType in RNDIS_CONFIG_PARAMETER_INFO
|
||||
//
|
||||
|
||||
/* Values for ParameterType in RNDIS_CONFIG_PARAMETER_INFO */
|
||||
|
||||
#define RNDIS_CONFIG_PARAM_TYPE_INTEGER 0
|
||||
#define RNDIS_CONFIG_PARAM_TYPE_STRING 2
|
||||
|
||||
|
||||
//
|
||||
// CONDIS Miniport messages for connection oriented devices
|
||||
// that do not implement a call manager.
|
||||
//
|
||||
|
||||
//
|
||||
// CoNdisMiniportCreateVc message
|
||||
//
|
||||
/* CONDIS Miniport messages for connection oriented devices */
|
||||
/* that do not implement a call manager. */
|
||||
|
||||
|
||||
|
||||
/* CoNdisMiniportCreateVc message */
|
||||
|
||||
typedef struct _RCONDIS_MP_CREATE_VC
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
RNDIS_HANDLE NdisVcHandle;
|
||||
} RCONDIS_MP_CREATE_VC, *PRCONDIS_MP_CREATE_VC;
|
||||
|
||||
//
|
||||
// Response to CoNdisMiniportCreateVc
|
||||
//
|
||||
|
||||
/* Response to CoNdisMiniportCreateVc */
|
||||
|
||||
typedef struct _RCONDIS_MP_CREATE_VC_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -608,18 +608,18 @@ typedef struct _RCONDIS_MP_CREATE_VC_COMPLETE
|
|||
} RCONDIS_MP_CREATE_VC_COMPLETE, *PRCONDIS_MP_CREATE_VC_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// CoNdisMiniportDeleteVc message
|
||||
//
|
||||
|
||||
/* CoNdisMiniportDeleteVc message */
|
||||
|
||||
typedef struct _RCONDIS_MP_DELETE_VC
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
RNDIS_HANDLE DeviceVcHandle;
|
||||
} RCONDIS_MP_DELETE_VC, *PRCONDIS_MP_DELETE_VC;
|
||||
|
||||
//
|
||||
// Response to CoNdisMiniportDeleteVc
|
||||
//
|
||||
|
||||
/* Response to CoNdisMiniportDeleteVc */
|
||||
|
||||
typedef struct _RCONDIS_MP_DELETE_VC_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -627,9 +627,9 @@ typedef struct _RCONDIS_MP_DELETE_VC_COMPLETE
|
|||
} RCONDIS_MP_DELETE_VC_COMPLETE, *PRCONDIS_MP_DELETE_VC_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// CoNdisMiniportQueryRequest message
|
||||
//
|
||||
|
||||
/* CoNdisMiniportQueryRequest message */
|
||||
|
||||
typedef struct _RCONDIS_MP_QUERY_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -641,9 +641,9 @@ typedef struct _RCONDIS_MP_QUERY_REQUEST
|
|||
} RCONDIS_MP_QUERY_REQUEST, *PRCONDIS_MP_QUERY_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// CoNdisMiniportSetRequest message
|
||||
//
|
||||
|
||||
/* CoNdisMiniportSetRequest message */
|
||||
|
||||
typedef struct _RCONDIS_MP_SET_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -655,9 +655,9 @@ typedef struct _RCONDIS_MP_SET_REQUEST
|
|||
} RCONDIS_MP_SET_REQUEST, *PRCONDIS_MP_SET_REQUEST;
|
||||
|
||||
|
||||
//
|
||||
// CoNdisIndicateStatus message
|
||||
//
|
||||
|
||||
/* CoNdisIndicateStatus message */
|
||||
|
||||
typedef struct _RCONDIS_INDICATE_STATUS
|
||||
{
|
||||
RNDIS_HANDLE NdisVcHandle;
|
||||
|
@ -667,9 +667,9 @@ typedef struct _RCONDIS_INDICATE_STATUS
|
|||
} RCONDIS_INDICATE_STATUS, *PRCONDIS_INDICATE_STATUS;
|
||||
|
||||
|
||||
//
|
||||
// CONDIS Call/VC parameters
|
||||
//
|
||||
|
||||
/* CONDIS Call/VC parameters */
|
||||
|
||||
|
||||
typedef struct _RCONDIS_SPECIFIC_PARAMETERS
|
||||
{
|
||||
|
@ -706,9 +706,9 @@ typedef struct _RCONDIS_CALL_MANAGER_PARAMETERS
|
|||
RCONDIS_SPECIFIC_PARAMETERS CallMgrSpecific;
|
||||
} RCONDIS_CALL_MANAGER_PARAMETERS, *PRCONDIS_CALL_MANAGER_PARAMETERS;
|
||||
|
||||
//
|
||||
// CoNdisMiniportActivateVc message
|
||||
//
|
||||
|
||||
/* CoNdisMiniportActivateVc message */
|
||||
|
||||
typedef struct _RCONDIS_MP_ACTIVATE_VC_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -720,9 +720,9 @@ typedef struct _RCONDIS_MP_ACTIVATE_VC_REQUEST
|
|||
u32 CallMgrParamsLength;
|
||||
} RCONDIS_MP_ACTIVATE_VC_REQUEST, *PRCONDIS_MP_ACTIVATE_VC_REQUEST;
|
||||
|
||||
//
|
||||
// Response to CoNdisMiniportActivateVc
|
||||
//
|
||||
|
||||
/* Response to CoNdisMiniportActivateVc */
|
||||
|
||||
typedef struct _RCONDIS_MP_ACTIVATE_VC_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -730,9 +730,9 @@ typedef struct _RCONDIS_MP_ACTIVATE_VC_COMPLETE
|
|||
} RCONDIS_MP_ACTIVATE_VC_COMPLETE, *PRCONDIS_MP_ACTIVATE_VC_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// CoNdisMiniportDeactivateVc message
|
||||
//
|
||||
|
||||
/* CoNdisMiniportDeactivateVc message */
|
||||
|
||||
typedef struct _RCONDIS_MP_DEACTIVATE_VC_REQUEST
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -740,9 +740,9 @@ typedef struct _RCONDIS_MP_DEACTIVATE_VC_REQUEST
|
|||
RNDIS_HANDLE DeviceVcHandle;
|
||||
} RCONDIS_MP_DEACTIVATE_VC_REQUEST, *PRCONDIS_MP_DEACTIVATE_VC_REQUEST;
|
||||
|
||||
//
|
||||
// Response to CoNdisMiniportDeactivateVc
|
||||
//
|
||||
|
||||
/* Response to CoNdisMiniportDeactivateVc */
|
||||
|
||||
typedef struct _RCONDIS_MP_DEACTIVATE_VC_COMPLETE
|
||||
{
|
||||
RNDIS_REQUEST_ID RequestId;
|
||||
|
@ -750,9 +750,9 @@ typedef struct _RCONDIS_MP_DEACTIVATE_VC_COMPLETE
|
|||
} RCONDIS_MP_DEACTIVATE_VC_COMPLETE, *PRCONDIS_MP_DEACTIVATE_VC_COMPLETE;
|
||||
|
||||
|
||||
//
|
||||
// union with all of the RNDIS messages
|
||||
//
|
||||
|
||||
/* union with all of the RNDIS messages */
|
||||
|
||||
typedef union _RNDIS_MESSAGE_CONTAINER
|
||||
{
|
||||
RNDIS_PACKET Packet;
|
||||
|
@ -781,56 +781,56 @@ typedef union _RNDIS_MESSAGE_CONTAINER
|
|||
|
||||
} RNDIS_MESSAGE_CONTAINER, *PRNDIS_MESSAGE_CONTAINER;
|
||||
|
||||
//
|
||||
// Remote NDIS message format
|
||||
//
|
||||
|
||||
/* Remote NDIS message format */
|
||||
|
||||
typedef __struct_bcount(MessageLength) struct _RNDIS_MESSAGE
|
||||
{
|
||||
u32 NdisMessageType;
|
||||
|
||||
//
|
||||
// Total length of this message, from the beginning
|
||||
// of the RNDIS_MESSAGE struct, in bytes.
|
||||
//
|
||||
|
||||
/* Total length of this message, from the beginning */
|
||||
/* of the RNDIS_MESSAGE struct, in bytes. */
|
||||
|
||||
u32 MessageLength;
|
||||
|
||||
// Actual message
|
||||
/* Actual message */
|
||||
RNDIS_MESSAGE_CONTAINER Message;
|
||||
|
||||
} RNDIS_MESSAGE, *PRNDIS_MESSAGE;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Handy macros
|
||||
|
||||
// get the size of an RNDIS message. Pass in the message type,
|
||||
// RNDIS_SET_REQUEST, RNDIS_PACKET for example
|
||||
/* Handy macros */
|
||||
|
||||
/* get the size of an RNDIS message. Pass in the message type, */
|
||||
/* RNDIS_SET_REQUEST, RNDIS_PACKET for example */
|
||||
#define RNDIS_MESSAGE_SIZE(Message) \
|
||||
(sizeof(Message) + (sizeof(RNDIS_MESSAGE) - sizeof(RNDIS_MESSAGE_CONTAINER)))
|
||||
|
||||
// get pointer to info buffer with message pointer
|
||||
/* get pointer to info buffer with message pointer */
|
||||
#define MESSAGE_TO_INFO_BUFFER(Message) \
|
||||
(((unsigned char *)(Message)) + Message->InformationBufferOffset)
|
||||
|
||||
// get pointer to status buffer with message pointer
|
||||
/* get pointer to status buffer with message pointer */
|
||||
#define MESSAGE_TO_STATUS_BUFFER(Message) \
|
||||
(((unsigned char *)(Message)) + Message->StatusBufferOffset)
|
||||
|
||||
// get pointer to OOBD buffer with message pointer
|
||||
/* get pointer to OOBD buffer with message pointer */
|
||||
#define MESSAGE_TO_OOBD_BUFFER(Message) \
|
||||
(((unsigned char *)(Message)) + Message->OOBDataOffset)
|
||||
|
||||
// get pointer to data buffer with message pointer
|
||||
/* get pointer to data buffer with message pointer */
|
||||
#define MESSAGE_TO_DATA_BUFFER(Message) \
|
||||
(((unsigned char *)(Message)) + Message->PerPacketInfoOffset)
|
||||
|
||||
// get pointer to contained message from NDIS_MESSAGE pointer
|
||||
/* get pointer to contained message from NDIS_MESSAGE pointer */
|
||||
#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(RndisMessage) \
|
||||
((void *) &RndisMessage->Message)
|
||||
|
||||
// get pointer to contained message from NDIS_MESSAGE pointer
|
||||
/* get pointer to contained message from NDIS_MESSAGE pointer */
|
||||
#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(RndisMessage) \
|
||||
((void *) RndisMessage)
|
||||
|
||||
#endif // _RNDIS_H_
|
||||
#endif /* _RNDIS_H_ */
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
|
||||
#include "VmbusApi.h"
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
|
||||
typedef int (*PFN_DRIVERINITIALIZE)(DRIVER_OBJECT *drv);
|
||||
typedef int (*PFN_DRIVEREXIT)(DRIVER_OBJECT *drv);
|
||||
|
@ -41,7 +41,7 @@ struct driver_context {
|
|||
|
||||
struct device_driver driver;
|
||||
|
||||
// Use these methods instead of the struct device_driver so 2.6 kernel stops complaining
|
||||
/* Use these methods instead of the struct device_driver so 2.6 kernel stops complaining */
|
||||
int (*probe)(struct device *);
|
||||
int (*remove)(struct device *);
|
||||
void (*shutdown)(struct device *);
|
||||
|
@ -57,13 +57,13 @@ struct device_context {
|
|||
};
|
||||
|
||||
|
||||
//
|
||||
// Global
|
||||
//
|
||||
|
||||
//
|
||||
// Inlines
|
||||
//
|
||||
/* Global */
|
||||
|
||||
|
||||
|
||||
/* Inlines */
|
||||
|
||||
static inline struct device_context *to_device_context(DEVICE_OBJECT *device_obj)
|
||||
{
|
||||
return container_of(device_obj, struct device_context, device_obj);
|
||||
|
@ -79,9 +79,9 @@ static inline struct driver_context *driver_to_driver_context(struct device_driv
|
|||
return container_of(driver, struct driver_context, driver);
|
||||
}
|
||||
|
||||
//
|
||||
// Vmbus interface
|
||||
//
|
||||
|
||||
/* Vmbus interface */
|
||||
|
||||
void
|
||||
vmbus_child_driver_register(
|
||||
struct driver_context* driver_ctx
|
||||
|
@ -97,4 +97,4 @@ vmbus_get_interface(
|
|||
VMBUS_CHANNEL_INTERFACE *interface
|
||||
);
|
||||
|
||||
#endif // _VMBUS_H_
|
||||
#endif /* _VMBUS_H_ */
|
||||
|
|
|
@ -24,28 +24,28 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
//#include <vmbuspacketformat.h>
|
||||
//#include <ntddscsi.h>
|
||||
/* #include <vmbuspacketformat.h> */
|
||||
/* #include <ntddscsi.h> */
|
||||
|
||||
#define C_ASSERT(x)
|
||||
//
|
||||
// public interface to the server
|
||||
//
|
||||
|
||||
//
|
||||
// Storvsp device interface guid
|
||||
//
|
||||
/* public interface to the server */
|
||||
|
||||
|
||||
//
|
||||
// Protocol versions.
|
||||
//
|
||||
|
||||
//
|
||||
// vstorage.w revision number. This is used in the case of a version match,
|
||||
// to alert the user that structure sizes may be mismatched even though the
|
||||
// protocol versions match.
|
||||
//
|
||||
/* Storvsp device interface guid */
|
||||
|
||||
|
||||
|
||||
|
||||
/* Protocol versions. */
|
||||
|
||||
|
||||
|
||||
/* vstorage.w revision number. This is used in the case of a version match, */
|
||||
/* to alert the user that structure sizes may be mismatched even though the */
|
||||
/* protocol versions match. */
|
||||
|
||||
|
||||
#define REVISION_STRING(REVISION_) #REVISION_
|
||||
#define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \
|
||||
|
@ -54,53 +54,53 @@
|
|||
RESULT_LVALUE_ = 0; \
|
||||
while (*revisionString >= '0' && *revisionString <= '9') \
|
||||
{ \
|
||||
RESULT_LVALUE_ *= 10; \
|
||||
RESULT_LVALUE_ += *revisionString - '0'; \
|
||||
revisionString++; \
|
||||
RESULT_LVALUE_ *= 10; \
|
||||
RESULT_LVALUE_ += *revisionString - '0'; \
|
||||
revisionString++; \
|
||||
} \
|
||||
}
|
||||
|
||||
//
|
||||
// Major/minor macros. Minor version is in LSB, meaning that earlier flat
|
||||
// version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1).
|
||||
//
|
||||
|
||||
/* Major/minor macros. Minor version is in LSB, meaning that earlier flat */
|
||||
/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
|
||||
|
||||
|
||||
#define VMSTOR_PROTOCOL_MAJOR(VERSION_) (((VERSION_) >> 8) & 0xff)
|
||||
#define VMSTOR_PROTOCOL_MINOR(VERSION_) (((VERSION_) ) & 0xff)
|
||||
#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_) ((((MAJOR_) & 0xff) << 8) | \
|
||||
(((MINOR_) & 0xff) ))
|
||||
(((MINOR_) & 0xff) ))
|
||||
|
||||
|
||||
/* Invalid version. */
|
||||
|
||||
//
|
||||
// Invalid version.
|
||||
//
|
||||
|
||||
#define VMSTOR_INVALID_PROTOCOL_VERSION -1
|
||||
|
||||
//
|
||||
// Version history:
|
||||
// V1 Beta 0.1
|
||||
// V1 RC < 2008/1/31 1.0
|
||||
// V1 RC > 2008/1/31 2.0
|
||||
//
|
||||
|
||||
/* Version history: */
|
||||
/* V1 Beta 0.1 */
|
||||
/* V1 RC < 2008/1/31 1.0 */
|
||||
/* V1 RC > 2008/1/31 2.0 */
|
||||
|
||||
#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
|
||||
|
||||
|
||||
//
|
||||
// This will get replaced with the max transfer length that is possible on
|
||||
// the host adapter.
|
||||
// The max transfer length will be published when we offer a vmbus channel.
|
||||
//
|
||||
|
||||
/* This will get replaced with the max transfer length that is possible on */
|
||||
/* the host adapter. */
|
||||
/* The max transfer length will be published when we offer a vmbus channel. */
|
||||
|
||||
|
||||
#define MAX_TRANSFER_LENGTH 0x40000
|
||||
#define DEFAULT_PACKET_SIZE (sizeof(VMDATA_GPA_DIRECT) + \
|
||||
sizeof(VSTOR_PACKET) + \
|
||||
(sizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
|
||||
sizeof(VSTOR_PACKET) + \
|
||||
(sizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Packet structure describing virtual storage requests.
|
||||
//
|
||||
|
||||
/* Packet structure describing virtual storage requests. */
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -119,11 +119,11 @@ typedef enum
|
|||
} VSTOR_PACKET_OPERATION;
|
||||
|
||||
|
||||
//
|
||||
// Platform neutral description of a scsi request -
|
||||
// this remains the same across the write regardless of 32/64 bit
|
||||
// note: it's patterned off the SCSI_PASS_THROUGH structure
|
||||
//
|
||||
|
||||
/* Platform neutral description of a scsi request - */
|
||||
/* this remains the same across the write regardless of 32/64 bit */
|
||||
/* note: it's patterned off the SCSI_PASS_THROUGH structure */
|
||||
|
||||
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
@ -159,11 +159,11 @@ typedef struct
|
|||
|
||||
union
|
||||
{
|
||||
unsigned char Cdb[CDB16GENERIC_LENGTH];
|
||||
unsigned char Cdb[CDB16GENERIC_LENGTH];
|
||||
|
||||
unsigned char SenseData[SENSE_BUFFER_SIZE];
|
||||
unsigned char SenseData[SENSE_BUFFER_SIZE];
|
||||
|
||||
unsigned char ReservedArray[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
|
||||
unsigned char ReservedArray[MAX_DATA_BUFFER_LENGTH_WITH_PADDING];
|
||||
};
|
||||
|
||||
} VMSCSI_REQUEST, *PVMSCSI_REQUEST;
|
||||
|
@ -171,10 +171,10 @@ typedef struct
|
|||
C_ASSERT((sizeof(VMSCSI_REQUEST) % 4) == 0);
|
||||
|
||||
|
||||
//
|
||||
// This structure is sent during the intialization phase to get the different
|
||||
// properties of the channel.
|
||||
//
|
||||
|
||||
/* This structure is sent during the intialization phase to get the different */
|
||||
/* properties of the channel. */
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -182,19 +182,19 @@ typedef struct
|
|||
unsigned char PathId;
|
||||
unsigned char TargetId;
|
||||
|
||||
//
|
||||
// Note: port number is only really known on the client side
|
||||
//
|
||||
|
||||
/* Note: port number is only really known on the client side */
|
||||
|
||||
unsigned int PortNumber;
|
||||
|
||||
unsigned int Flags;
|
||||
|
||||
unsigned int MaxTransferBytes;
|
||||
|
||||
//
|
||||
// This id is unique for each channel and will correspond with
|
||||
// vendor specific data in the inquirydata
|
||||
//
|
||||
|
||||
/* This id is unique for each channel and will correspond with */
|
||||
/* vendor specific data in the inquirydata */
|
||||
|
||||
|
||||
unsigned long long UniqueId;
|
||||
|
||||
|
@ -203,24 +203,24 @@ typedef struct
|
|||
C_ASSERT((sizeof(VMSTORAGE_CHANNEL_PROPERTIES) % 4) == 0);
|
||||
|
||||
|
||||
//
|
||||
// This structure is sent during the storage protocol negotiations.
|
||||
//
|
||||
|
||||
/* This structure is sent during the storage protocol negotiations. */
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//
|
||||
// Major (MSW) and minor (LSW) version numbers.
|
||||
//
|
||||
|
||||
/* Major (MSW) and minor (LSW) version numbers. */
|
||||
|
||||
|
||||
unsigned short MajorMinor;
|
||||
|
||||
|
||||
//
|
||||
// Revision number is auto-incremented whenever this file is changed
|
||||
// (See FILL_VMSTOR_REVISION macro above). Mismatch does not definitely
|
||||
// indicate incompatibility--but it does indicate mismatched builds.
|
||||
//
|
||||
|
||||
/* Revision number is auto-incremented whenever this file is changed */
|
||||
/* (See FILL_VMSTOR_REVISION macro above). Mismatch does not definitely */
|
||||
/* indicate incompatibility--but it does indicate mismatched builds. */
|
||||
|
||||
|
||||
unsigned short Revision;
|
||||
|
||||
|
@ -229,9 +229,9 @@ typedef struct
|
|||
C_ASSERT((sizeof(VMSTORAGE_PROTOCOL_VERSION) % 4) == 0);
|
||||
|
||||
|
||||
//
|
||||
// Channel Property Flags
|
||||
//
|
||||
|
||||
/* Channel Property Flags */
|
||||
|
||||
|
||||
#define STORAGE_CHANNEL_REMOVABLE_FLAG 0x1
|
||||
#define STORAGE_CHANNEL_EMULATED_IDE_FLAG 0x2
|
||||
|
@ -239,71 +239,69 @@ C_ASSERT((sizeof(VMSTORAGE_PROTOCOL_VERSION) % 4) == 0);
|
|||
|
||||
typedef struct _VSTOR_PACKET
|
||||
{
|
||||
//
|
||||
// Requested operation type
|
||||
//
|
||||
|
||||
/* Requested operation type */
|
||||
|
||||
|
||||
VSTOR_PACKET_OPERATION Operation;
|
||||
|
||||
//
|
||||
// Flags - see below for values
|
||||
//
|
||||
|
||||
/* Flags - see below for values */
|
||||
|
||||
|
||||
unsigned int Flags;
|
||||
|
||||
//
|
||||
// Status of the request returned from the server side.
|
||||
//
|
||||
|
||||
/* Status of the request returned from the server side. */
|
||||
|
||||
|
||||
unsigned int Status;
|
||||
|
||||
//
|
||||
// Data payload area
|
||||
//
|
||||
|
||||
/* Data payload area */
|
||||
|
||||
|
||||
union
|
||||
{
|
||||
//
|
||||
// Structure used to forward SCSI commands from the client to the server.
|
||||
//
|
||||
|
||||
VMSCSI_REQUEST VmSrb;
|
||||
/* Structure used to forward SCSI commands from the client to the server. */
|
||||
|
||||
//
|
||||
// Structure used to query channel properties.
|
||||
//
|
||||
|
||||
VMSTORAGE_CHANNEL_PROPERTIES StorageChannelProperties;
|
||||
VMSCSI_REQUEST VmSrb;
|
||||
|
||||
//
|
||||
// Used during version negotiations.
|
||||
//
|
||||
|
||||
VMSTORAGE_PROTOCOL_VERSION Version;
|
||||
/* Structure used to query channel properties. */
|
||||
|
||||
|
||||
VMSTORAGE_CHANNEL_PROPERTIES StorageChannelProperties;
|
||||
|
||||
|
||||
/* Used during version negotiations. */
|
||||
|
||||
|
||||
VMSTORAGE_PROTOCOL_VERSION Version;
|
||||
};
|
||||
|
||||
} VSTOR_PACKET, *PVSTOR_PACKET;
|
||||
|
||||
C_ASSERT((sizeof(VSTOR_PACKET) % 4) == 0);
|
||||
|
||||
//
|
||||
// Packet flags
|
||||
//
|
||||
|
||||
//
|
||||
// This flag indicates that the server should send back a completion for this
|
||||
// packet.
|
||||
//
|
||||
/* Packet flags */
|
||||
|
||||
|
||||
|
||||
/* This flag indicates that the server should send back a completion for this */
|
||||
/* packet. */
|
||||
|
||||
|
||||
#define REQUEST_COMPLETION_FLAG 0x1
|
||||
|
||||
//
|
||||
// This is the set of flags that the vsc can set in any packets it sends
|
||||
//
|
||||
|
||||
/* This is the set of flags that the vsc can set in any packets it sends */
|
||||
|
||||
|
||||
#define VSC_LEGAL_FLAGS (REQUEST_COMPLETION_FLAG)
|
||||
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
|
|
|
@ -43,9 +43,9 @@
|
|||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
//
|
||||
// Static decl
|
||||
//
|
||||
|
||||
/* Static decl */
|
||||
|
||||
static int netvsc_probe(struct device *device);
|
||||
static int netvsc_remove(struct device *device);
|
||||
static int netvsc_open(struct net_device *net);
|
||||
|
@ -56,32 +56,32 @@ static int netvsc_close(struct net_device *net);
|
|||
static struct net_device_stats *netvsc_get_stats(struct net_device *net);
|
||||
static void netvsc_linkstatus_callback(DEVICE_OBJECT *device_obj, unsigned int status);
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
struct net_device_context {
|
||||
struct device_context *device_ctx; // point back to our device context
|
||||
struct device_context *device_ctx; /* point back to our device context */
|
||||
struct net_device_stats stats;
|
||||
};
|
||||
|
||||
struct netvsc_driver_context {
|
||||
// !! These must be the first 2 fields !!
|
||||
/* !! These must be the first 2 fields !! */
|
||||
struct driver_context drv_ctx;
|
||||
NETVSC_DRIVER_OBJECT drv_obj;
|
||||
};
|
||||
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
|
||||
/* Globals */
|
||||
|
||||
|
||||
static int netvsc_ringbuffer_size = NETVSC_DEVICE_RING_BUFFER_SIZE;
|
||||
|
||||
// The one and only one
|
||||
/* The one and only one */
|
||||
static struct netvsc_driver_context g_netvsc_drv;
|
||||
|
||||
//
|
||||
// Routines
|
||||
//
|
||||
|
||||
/* Routines */
|
||||
|
||||
|
||||
/*++
|
||||
|
||||
|
@ -104,7 +104,7 @@ int netvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
net_drv_obj->OnReceiveCallback = netvsc_recv_callback;
|
||||
net_drv_obj->OnLinkStatusChanged = netvsc_linkstatus_callback;
|
||||
|
||||
// Callback to client driver to complete the initialization
|
||||
/* Callback to client driver to complete the initialization */
|
||||
pfn_drv_init(&net_drv_obj->Base);
|
||||
|
||||
drv_ctx->driver.name = net_drv_obj->Base.name;
|
||||
|
@ -113,7 +113,7 @@ int netvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
drv_ctx->probe = netvsc_probe;
|
||||
drv_ctx->remove = netvsc_remove;
|
||||
|
||||
// The driver belongs to vmbus
|
||||
/* The driver belongs to vmbus */
|
||||
vmbus_child_driver_register(drv_ctx);
|
||||
|
||||
DPRINT_EXIT(NETVSC_DRV);
|
||||
|
@ -186,13 +186,13 @@ static int netvsc_probe(struct device *device)
|
|||
}
|
||||
|
||||
net = alloc_netdev(sizeof(struct net_device_context), "seth%d", ether_setup);
|
||||
//net = alloc_etherdev(sizeof(struct net_device_context));
|
||||
/* net = alloc_etherdev(sizeof(struct net_device_context)); */
|
||||
if (!net)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set initial state
|
||||
/* Set initial state */
|
||||
netif_carrier_off(net);
|
||||
netif_stop_queue(net);
|
||||
|
||||
|
@ -200,7 +200,7 @@ static int netvsc_probe(struct device *device)
|
|||
net_device_ctx->device_ctx = device_ctx;
|
||||
dev_set_drvdata(device, net);
|
||||
|
||||
// Notify the netvsc driver of the new device
|
||||
/* Notify the netvsc driver of the new device */
|
||||
ret = net_drv_obj->Base.OnDeviceAdd(device_obj, (void*)&device_info);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -211,8 +211,8 @@ static int netvsc_probe(struct device *device)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// If carrier is still off ie we did not get a link status callback, update it if necessary
|
||||
// FIXME: We should use a atomic or test/set instead to avoid getting out of sync with the device's link status
|
||||
/* If carrier is still off ie we did not get a link status callback, update it if necessary */
|
||||
/* FIXME: We should use a atomic or test/set instead to avoid getting out of sync with the device's link status */
|
||||
if (!netif_carrier_ok(net))
|
||||
{
|
||||
if (!device_info.LinkState)
|
||||
|
@ -230,7 +230,7 @@ static int netvsc_probe(struct device *device)
|
|||
ret = register_netdev(net);
|
||||
if (ret != 0)
|
||||
{
|
||||
// Remove the device and release the resource
|
||||
/* Remove the device and release the resource */
|
||||
net_drv_obj->Base.OnDeviceRemove(device_obj);
|
||||
free_netdev(net);
|
||||
}
|
||||
|
@ -266,17 +266,17 @@ static int netvsc_remove(struct device *device)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Stop outbound asap
|
||||
/* Stop outbound asap */
|
||||
netif_stop_queue(net);
|
||||
//netif_carrier_off(net);
|
||||
/* netif_carrier_off(net); */
|
||||
|
||||
unregister_netdev(net);
|
||||
|
||||
// Call to the vsc driver to let it know that the device is being removed
|
||||
/* Call to the vsc driver to let it know that the device is being removed */
|
||||
ret = net_drv_obj->Base.OnDeviceRemove(device_obj);
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret);
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ static int netvsc_open(struct net_device *net)
|
|||
{
|
||||
memset(&net_device_ctx->stats, 0 , sizeof(struct net_device_stats));
|
||||
|
||||
// Open up the device
|
||||
/* Open up the device */
|
||||
ret = net_drv_obj->OnOpen(device_obj);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -418,16 +418,16 @@ static int netvsc_start_xmit (struct sk_buff *skb, struct net_device *net)
|
|||
|
||||
DPRINT_ENTER(NETVSC_DRV);
|
||||
|
||||
// Support only 1 chain of frags
|
||||
/* Support only 1 chain of frags */
|
||||
ASSERT(skb_shinfo(skb)->frag_list == NULL);
|
||||
ASSERT(skb->dev == net);
|
||||
|
||||
DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d", skb->len, skb->data_len);
|
||||
|
||||
// Add 1 for skb->data and any additional ones requested
|
||||
/* Add 1 for skb->data and any additional ones requested */
|
||||
num_frags = skb_shinfo(skb)->nr_frags + 1 + net_drv_obj->AdditionalRequestPageBufferCount;
|
||||
|
||||
// Allocate a netvsc packet based on # of frags.
|
||||
/* Allocate a netvsc packet based on # of frags. */
|
||||
packet = kzalloc(sizeof(NETVSC_PACKET) + (num_frags * sizeof(PAGE_BUFFER)) + net_drv_obj->RequestExtSize, GFP_ATOMIC);
|
||||
if (!packet)
|
||||
{
|
||||
|
@ -437,17 +437,17 @@ static int netvsc_start_xmit (struct sk_buff *skb, struct net_device *net)
|
|||
|
||||
packet->Extension = (void*)(unsigned long)packet + sizeof(NETVSC_PACKET) + (num_frags * sizeof(PAGE_BUFFER)) ;
|
||||
|
||||
// Setup the rndis header
|
||||
/* Setup the rndis header */
|
||||
packet->PageBufferCount = num_frags;
|
||||
|
||||
// TODO: Flush all write buffers/ memory fence ???
|
||||
//wmb();
|
||||
/* TODO: Flush all write buffers/ memory fence ??? */
|
||||
/* wmb(); */
|
||||
|
||||
// Initialize it from the skb
|
||||
/* Initialize it from the skb */
|
||||
ASSERT(skb->data);
|
||||
packet->TotalDataBufferLength = skb->len;
|
||||
|
||||
// Start filling in the page buffers starting at AdditionalRequestPageBufferCount offset
|
||||
/* Start filling in the page buffers starting at AdditionalRequestPageBufferCount offset */
|
||||
packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT;
|
||||
packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Offset = (unsigned long)skb->data & (PAGE_SIZE -1);
|
||||
packet->PageBuffers[net_drv_obj->AdditionalRequestPageBufferCount].Length = skb->len - skb->data_len;
|
||||
|
@ -461,7 +461,7 @@ static int netvsc_start_xmit (struct sk_buff *skb, struct net_device *net)
|
|||
packet->PageBuffers[i].Length = skb_shinfo(skb)->frags[i-(net_drv_obj->AdditionalRequestPageBufferCount+1)].size;
|
||||
}
|
||||
|
||||
// Set the completion routine
|
||||
/* Set the completion routine */
|
||||
packet->Completion.Send.OnSendCompletion = netvsc_xmit_completion;
|
||||
packet->Completion.Send.SendCompletionContext = packet;
|
||||
packet->Completion.Send.SendCompletionTid = (unsigned long)skb;
|
||||
|
@ -485,7 +485,7 @@ retry_send:
|
|||
goto retry_send;
|
||||
}
|
||||
|
||||
// no more room or we are shutting down
|
||||
/* no more room or we are shutting down */
|
||||
DPRINT_ERR(NETVSC_DRV, "unable to send (%d)...marking net device (%p) busy", ret, net);
|
||||
DPRINT_INFO(NETVSC_DRV, "net device (%p) stopping", net);
|
||||
|
||||
|
@ -494,10 +494,10 @@ retry_send:
|
|||
|
||||
netif_stop_queue(net);
|
||||
|
||||
// Null it since the caller will free it instead of the completion routine
|
||||
/* Null it since the caller will free it instead of the completion routine */
|
||||
packet->Completion.Send.SendCompletionTid = 0;
|
||||
|
||||
// Release the resources since we will not get any send completion
|
||||
/* Release the resources since we will not get any send completion */
|
||||
netvsc_xmit_completion((void*)packet);
|
||||
}
|
||||
|
||||
|
@ -571,18 +571,18 @@ static int netvsc_recv_callback(DEVICE_OBJECT *device_obj, NETVSC_PACKET* packet
|
|||
|
||||
net_device_ctx = netdev_priv(net);
|
||||
|
||||
// Allocate a skb - TODO preallocate this
|
||||
//skb = alloc_skb(packet->TotalDataBufferLength, GFP_ATOMIC);
|
||||
skb = dev_alloc_skb(packet->TotalDataBufferLength + 2); // Pad 2-bytes to align IP header to 16 bytes
|
||||
/* Allocate a skb - TODO preallocate this */
|
||||
/* skb = alloc_skb(packet->TotalDataBufferLength, GFP_ATOMIC); */
|
||||
skb = dev_alloc_skb(packet->TotalDataBufferLength + 2); /* Pad 2-bytes to align IP header to 16 bytes */
|
||||
ASSERT(skb);
|
||||
skb_reserve(skb, 2);
|
||||
skb->dev = net;
|
||||
|
||||
// for kmap_atomic
|
||||
/* for kmap_atomic */
|
||||
local_irq_save(flags);
|
||||
|
||||
// Copy to skb. This copy is needed here since the memory pointed by NETVSC_PACKET
|
||||
// cannot be deallocated
|
||||
/* Copy to skb. This copy is needed here since the memory pointed by NETVSC_PACKET */
|
||||
/* cannot be deallocated */
|
||||
for (i=0; i<packet->PageBufferCount; i++)
|
||||
{
|
||||
data = kmap_atomic(pfn_to_page(packet->PageBuffers[i].Pfn), KM_IRQ1);
|
||||
|
@ -599,7 +599,7 @@ static int netvsc_recv_callback(DEVICE_OBJECT *device_obj, NETVSC_PACKET* packet
|
|||
|
||||
skb->ip_summed = CHECKSUM_NONE;
|
||||
|
||||
// Pass the skb back up. Network stack will deallocate the skb when it is done
|
||||
/* Pass the skb back up. Network stack will deallocate the skb when it is done */
|
||||
ret = netif_rx(skb);
|
||||
|
||||
switch (ret)
|
||||
|
@ -624,7 +624,7 @@ static int netvsc_drv_exit_cb(struct device *dev, void *data)
|
|||
{
|
||||
struct device **curr = (struct device **)data;
|
||||
*curr = dev;
|
||||
return 1; // stop iterating
|
||||
return 1; /* stop iterating */
|
||||
}
|
||||
|
||||
/*++
|
||||
|
@ -647,13 +647,13 @@ void netvsc_drv_exit(void)
|
|||
{
|
||||
current_dev = NULL;
|
||||
|
||||
// Get the device
|
||||
/* Get the device */
|
||||
driver_for_each_device(&drv_ctx->driver, NULL, (void*)¤t_dev, netvsc_drv_exit_cb);
|
||||
|
||||
if (current_dev == NULL)
|
||||
break;
|
||||
|
||||
// Initiate removal from the top-down
|
||||
/* Initiate removal from the top-down */
|
||||
DPRINT_INFO(NETVSC_DRV, "unregistering device (%p)...", current_dev);
|
||||
|
||||
device_unregister(current_dev);
|
||||
|
|
|
@ -46,9 +46,9 @@
|
|||
|
||||
#include "include/osd.h"
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
/* Data types */
|
||||
|
||||
typedef struct _TIMER {
|
||||
struct timer_list timer;
|
||||
PFN_TIMER_CALLBACK callback;
|
||||
|
@ -113,7 +113,7 @@ int InterlockedDecrement(int *val)
|
|||
#endif
|
||||
int InterlockedCompareExchange(int *val, int new, int curr)
|
||||
{
|
||||
//return ((int)cmpxchg(((atomic_t*)val), curr, new));
|
||||
/* return ((int)cmpxchg(((atomic_t*)val), curr, new)); */
|
||||
return atomic_cmpxchg((atomic_t*)val, curr, new);
|
||||
|
||||
}
|
||||
|
@ -139,13 +139,13 @@ void* PageAlloc(unsigned int count)
|
|||
if (p) memset(p, 0, count * PAGE_SIZE);
|
||||
return p;
|
||||
|
||||
//struct page* page = alloc_page(GFP_KERNEL|__GFP_ZERO);
|
||||
//void *p;
|
||||
/* struct page* page = alloc_page(GFP_KERNEL|__GFP_ZERO); */
|
||||
/* void *p; */
|
||||
|
||||
////BUGBUG: We need to use kmap in case we are in HIMEM region
|
||||
//p = page_address(page);
|
||||
//if (p) memset(p, 0, PAGE_SIZE);
|
||||
//return p;
|
||||
/* BUGBUG: We need to use kmap in case we are in HIMEM region */
|
||||
/* p = page_address(page); */
|
||||
/* if (p) memset(p, 0, PAGE_SIZE); */
|
||||
/* return p; */
|
||||
}
|
||||
|
||||
void PageFree(void* page, unsigned int count)
|
||||
|
@ -171,17 +171,17 @@ void *MemMapIO(unsigned long phys, unsigned long size)
|
|||
#if X2V_LINUX
|
||||
#ifdef __x86_64__
|
||||
return (void*)(phys + 0xFFFF83000C000000);
|
||||
#else // i386
|
||||
#else /* i386 */
|
||||
return (void*)(phys + 0xfb000000);
|
||||
#endif
|
||||
#else
|
||||
return (void*)GetVirtualAddress(phys); //return ioremap_nocache(phys, size);
|
||||
return (void*)GetVirtualAddress(phys); /* return ioremap_nocache(phys, size); */
|
||||
#endif
|
||||
}
|
||||
|
||||
void MemUnmapIO(void *virt)
|
||||
{
|
||||
//iounmap(virt);
|
||||
/* iounmap(virt); */
|
||||
}
|
||||
|
||||
void TimerCallback(unsigned long data)
|
||||
|
|
|
@ -41,16 +41,16 @@
|
|||
|
||||
#include "include/StorVscApi.h"
|
||||
|
||||
//
|
||||
// #defines
|
||||
//
|
||||
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
/* #defines */
|
||||
|
||||
|
||||
|
||||
/* Data types */
|
||||
|
||||
struct host_device_context {
|
||||
struct work_struct host_rescan_work; //must be 1st field
|
||||
struct device_context *device_ctx; // point back to our device context
|
||||
struct work_struct host_rescan_work; /* must be 1st field */
|
||||
struct device_context *device_ctx; /* point back to our device context */
|
||||
struct kmem_cache *request_pool;
|
||||
unsigned int port;
|
||||
unsigned char path;
|
||||
|
@ -65,17 +65,17 @@ struct storvsc_cmd_request {
|
|||
struct scatterlist *bounce_sgl;
|
||||
|
||||
STORVSC_REQUEST request;
|
||||
// !!!DO NOT ADD ANYTHING BELOW HERE!!!
|
||||
// The extension buffer falls right here and is pointed to by request.Extension;
|
||||
/* !!!DO NOT ADD ANYTHING BELOW HERE!!! */
|
||||
/* The extension buffer falls right here and is pointed to by request.Extension; */
|
||||
};
|
||||
|
||||
struct storvsc_driver_context {
|
||||
// !! These must be the first 2 fields !!
|
||||
/* !! These must be the first 2 fields !! */
|
||||
struct driver_context drv_ctx;
|
||||
STORVSC_DRIVER_OBJECT drv_obj;
|
||||
};
|
||||
|
||||
// Static decl
|
||||
/* Static decl */
|
||||
static int storvsc_probe(struct device *dev);
|
||||
static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scsi_cmnd *));
|
||||
static int storvsc_device_alloc(struct scsi_device *);
|
||||
|
@ -97,10 +97,10 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
|
|||
|
||||
static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
|
||||
|
||||
// The one and only one
|
||||
/* The one and only one */
|
||||
static struct storvsc_driver_context g_storvsc_drv;
|
||||
|
||||
// Scsi driver
|
||||
/* Scsi driver */
|
||||
static struct scsi_host_template scsi_driver = {
|
||||
.module = THIS_MODULE,
|
||||
.name = "storvsc_host_t",
|
||||
|
@ -110,15 +110,15 @@ static struct scsi_host_template scsi_driver = {
|
|||
.slave_alloc = storvsc_device_alloc,
|
||||
.slave_configure = storvsc_device_configure,
|
||||
.cmd_per_lun = 1,
|
||||
.can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, // 64 max_queue * 1 target
|
||||
.can_queue = STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS, /* 64 max_queue * 1 target */
|
||||
.this_id = -1,
|
||||
// no use setting to 0 since ll_blk_rw reset it to 1
|
||||
.sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT,// currently 32
|
||||
// ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge into 1 sg element. If set, we must
|
||||
// limit the max_segment_size to PAGE_SIZE, otherwise we may get 1 sg element that represents multiple
|
||||
// physically contig pfns (ie sg[x].length > PAGE_SIZE).
|
||||
/* no use setting to 0 since ll_blk_rw reset it to 1 */
|
||||
.sg_tablesize = MAX_MULTIPAGE_BUFFER_COUNT,/* currently 32 */
|
||||
/* ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge into 1 sg element. If set, we must */
|
||||
/* limit the max_segment_size to PAGE_SIZE, otherwise we may get 1 sg element that represents multiple */
|
||||
/* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
|
||||
.use_clustering = ENABLE_CLUSTERING,
|
||||
// Make sure we dont get a sg segment crosses a page boundary
|
||||
/* Make sure we dont get a sg segment crosses a page boundary */
|
||||
.dma_boundary = PAGE_SIZE-1,
|
||||
};
|
||||
|
||||
|
@ -143,7 +143,7 @@ int storvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size;
|
||||
storvsc_drv_obj->OnHostRescan = storvsc_host_rescan;
|
||||
|
||||
// Callback to client driver to complete the initialization
|
||||
/* Callback to client driver to complete the initialization */
|
||||
pfn_drv_init(&storvsc_drv_obj->Base);
|
||||
|
||||
DPRINT_INFO(STORVSC_DRV, "request extension size %u, max outstanding reqs %u", storvsc_drv_obj->RequestExtSize, storvsc_drv_obj->MaxOutstandingRequestsPerChannel);
|
||||
|
@ -161,7 +161,7 @@ int storvsc_drv_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
drv_ctx->probe = storvsc_probe;
|
||||
drv_ctx->remove = storvsc_remove;
|
||||
|
||||
// The driver belongs to vmbus
|
||||
/* The driver belongs to vmbus */
|
||||
vmbus_child_driver_register(drv_ctx);
|
||||
|
||||
DPRINT_EXIT(STORVSC_DRV);
|
||||
|
@ -174,7 +174,7 @@ static int storvsc_drv_exit_cb(struct device *dev, void *data)
|
|||
{
|
||||
struct device **curr = (struct device **)data;
|
||||
*curr = dev;
|
||||
return 1; // stop iterating
|
||||
return 1; /* stop iterating */
|
||||
}
|
||||
|
||||
/*++
|
||||
|
@ -197,13 +197,13 @@ void storvsc_drv_exit(void)
|
|||
{
|
||||
current_dev = NULL;
|
||||
|
||||
// Get the device
|
||||
/* Get the device */
|
||||
driver_for_each_device(&drv_ctx->driver, NULL, (void*)¤t_dev, storvsc_drv_exit_cb);
|
||||
|
||||
if (current_dev == NULL)
|
||||
break;
|
||||
|
||||
// Initiate removal from the top-down
|
||||
/* Initiate removal from the top-down */
|
||||
device_unregister(current_dev);
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@ static int storvsc_probe(struct device *device)
|
|||
}
|
||||
|
||||
device_info.PortNumber = host->host_no;
|
||||
// Call to the vsc driver to add the device
|
||||
/* Call to the vsc driver to add the device */
|
||||
ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj, (void*)&device_info);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -289,15 +289,15 @@ static int storvsc_probe(struct device *device)
|
|||
return -1;
|
||||
}
|
||||
|
||||
//host_device_ctx->port = device_info.PortNumber;
|
||||
/* host_device_ctx->port = device_info.PortNumber; */
|
||||
host_device_ctx->path = device_info.PathId;
|
||||
host_device_ctx->target = device_info.TargetId;
|
||||
|
||||
host->max_lun = STORVSC_MAX_LUNS_PER_TARGET; // max # of devices per target
|
||||
host->max_id = STORVSC_MAX_TARGETS; // max # of targets per channel
|
||||
host->max_channel = STORVSC_MAX_CHANNELS -1; // max # of channels
|
||||
host->max_lun = STORVSC_MAX_LUNS_PER_TARGET; /* max # of devices per target */
|
||||
host->max_id = STORVSC_MAX_TARGETS; /* max # of targets per channel */
|
||||
host->max_channel = STORVSC_MAX_CHANNELS -1; /* max # of channels */
|
||||
|
||||
// Register the HBA and start the scsi bus scan
|
||||
/* Register the HBA and start the scsi bus scan */
|
||||
ret = scsi_add_host(host, device);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -350,11 +350,11 @@ static int storvsc_remove(struct device *device)
|
|||
return -1;
|
||||
}
|
||||
|
||||
// Call to the vsc driver to let it know that the device is being removed
|
||||
/* Call to the vsc driver to let it know that the device is being removed */
|
||||
ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj);
|
||||
if (ret != 0)
|
||||
{
|
||||
// TODO:
|
||||
/* TODO: */
|
||||
DPRINT_ERR(STORVSC, "unable to remove vsc device (ret %d)", ret);
|
||||
}
|
||||
|
||||
|
@ -397,11 +397,11 @@ static void storvsc_commmand_completion(STORVSC_REQUEST* request)
|
|||
|
||||
DPRINT_ENTER(STORVSC_DRV);
|
||||
|
||||
if (cmd_request->bounce_sgl_count)// using bounce buffer
|
||||
if (cmd_request->bounce_sgl_count)/* using bounce buffer */
|
||||
{
|
||||
//printk("copy_from_bounce_buffer\n");
|
||||
/* printk("copy_from_bounce_buffer\n"); */
|
||||
|
||||
// FIXME: We can optimize on writes by just skipping this
|
||||
/* FIXME: We can optimize on writes by just skipping this */
|
||||
copy_from_bounce_buffer(scsi_sglist(scmnd), cmd_request->bounce_sgl, scsi_sg_count(scmnd));
|
||||
destroy_bounce_buffer(cmd_request->bounce_sgl, cmd_request->bounce_sgl_count);
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ static void storvsc_commmand_completion(STORVSC_REQUEST* request)
|
|||
scmnd->host_scribble = NULL;
|
||||
scmnd->scsi_done = NULL;
|
||||
|
||||
// !!DO NOT MODIFY the scmnd after this call
|
||||
/* !!DO NOT MODIFY the scmnd after this call */
|
||||
scsi_done_fn(scmnd);
|
||||
|
||||
kmem_cache_free(host_device_ctx->request_pool, cmd_request);
|
||||
|
@ -436,24 +436,24 @@ static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
|
|||
{
|
||||
int i=0;
|
||||
|
||||
// No need to check
|
||||
/* No need to check */
|
||||
if (sg_count < 2)
|
||||
return -1;
|
||||
|
||||
// We have at least 2 sg entries
|
||||
/* We have at least 2 sg entries */
|
||||
for ( i=0; i<sg_count; i++ )
|
||||
{
|
||||
if (i == 0) // make sure 1st one does not have hole
|
||||
if (i == 0) /* make sure 1st one does not have hole */
|
||||
{
|
||||
if (sgl[i].offset + sgl[i].length != PAGE_SIZE)
|
||||
return i;
|
||||
}
|
||||
else if (i == sg_count - 1) // make sure last one does not have hole
|
||||
else if (i == sg_count - 1) /* make sure last one does not have hole */
|
||||
{
|
||||
if (sgl[i].offset != 0)
|
||||
return i;
|
||||
}
|
||||
else // make sure no hole in the middle
|
||||
else /* make sure no hole in the middle */
|
||||
{
|
||||
if (sgl[i].length != PAGE_SIZE || sgl[i].offset != 0)
|
||||
{
|
||||
|
@ -513,7 +513,7 @@ static void destroy_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count
|
|||
kfree(sgl);
|
||||
}
|
||||
|
||||
// Assume the bounce_sgl has enough room ie using the create_bounce_buffer()
|
||||
/* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
|
||||
static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct scatterlist *bounce_sgl, unsigned int orig_sgl_count)
|
||||
{
|
||||
int i=0,j=0;
|
||||
|
@ -532,8 +532,8 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct s
|
|||
src = src_addr;
|
||||
srclen = orig_sgl[i].length;
|
||||
|
||||
//if (PageHighMem(orig_sgl[i].page))
|
||||
// printk("HighMem page detected - addr %p", (void*)src);
|
||||
/* if (PageHighMem(orig_sgl[i].page)) */
|
||||
/* printk("HighMem page detected - addr %p", (void*)src); */
|
||||
|
||||
ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE);
|
||||
|
||||
|
@ -544,7 +544,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct s
|
|||
|
||||
while (srclen)
|
||||
{
|
||||
// assume bounce offset always == 0
|
||||
/* assume bounce offset always == 0 */
|
||||
dest = bounce_addr + bounce_sgl[j].length;
|
||||
destlen = PAGE_SIZE - bounce_sgl[j].length;
|
||||
|
||||
|
@ -556,18 +556,18 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct s
|
|||
srclen -= copylen;
|
||||
src += copylen;
|
||||
|
||||
if (bounce_sgl[j].length == PAGE_SIZE) // full..move to next entry
|
||||
if (bounce_sgl[j].length == PAGE_SIZE) /* full..move to next entry */
|
||||
{
|
||||
kunmap_atomic((void*)bounce_addr, KM_IRQ0);
|
||||
j++;
|
||||
|
||||
// if we need to use another bounce buffer
|
||||
/* if we need to use another bounce buffer */
|
||||
if (srclen || i != orig_sgl_count -1)
|
||||
{
|
||||
bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
|
||||
}
|
||||
}
|
||||
else if (srclen == 0 && i == orig_sgl_count -1) // // unmap the last bounce that is < PAGE_SIZE
|
||||
else if (srclen == 0 && i == orig_sgl_count -1) /* unmap the last bounce that is < PAGE_SIZE */
|
||||
{
|
||||
kunmap_atomic((void*)bounce_addr, KM_IRQ0);
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl, struct s
|
|||
return total_copied;
|
||||
}
|
||||
|
||||
// Assume the original sgl has enough room
|
||||
/* Assume the original sgl has enough room */
|
||||
static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, struct scatterlist *bounce_sgl, unsigned int orig_sgl_count)
|
||||
{
|
||||
int i=0,j=0;
|
||||
|
@ -619,18 +619,18 @@ static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl, struct
|
|||
destlen -= copylen;
|
||||
dest += copylen;
|
||||
|
||||
if (bounce_sgl[j].offset == bounce_sgl[j].length) // full
|
||||
if (bounce_sgl[j].offset == bounce_sgl[j].length) /* full */
|
||||
{
|
||||
kunmap_atomic((void*)bounce_addr, KM_IRQ0);
|
||||
j++;
|
||||
|
||||
// if we need to use another bounce buffer
|
||||
/* if we need to use another bounce buffer */
|
||||
if (destlen || i != orig_sgl_count -1)
|
||||
{
|
||||
bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
|
||||
}
|
||||
}
|
||||
else if (destlen == 0 && i == orig_sgl_count -1) // unmap the last bounce that is < PAGE_SIZE
|
||||
else if (destlen == 0 && i == orig_sgl_count -1) /* unmap the last bounce that is < PAGE_SIZE */
|
||||
{
|
||||
kunmap_atomic((void*)bounce_addr, KM_IRQ0);
|
||||
}
|
||||
|
@ -678,7 +678,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
scmnd->device->queue_depth,
|
||||
scmnd->device->tagged_supported);
|
||||
|
||||
// If retrying, no need to prep the cmd
|
||||
/* If retrying, no need to prep the cmd */
|
||||
if (scmnd->host_scribble)
|
||||
{
|
||||
ASSERT(scmnd->scsi_done != NULL);
|
||||
|
@ -705,7 +705,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
return SCSI_MLQUEUE_DEVICE_BUSY;
|
||||
}
|
||||
|
||||
// Setup the cmd request
|
||||
/* Setup the cmd request */
|
||||
cmd_request->bounce_sgl_count = 0;
|
||||
cmd_request->bounce_sgl = NULL;
|
||||
cmd_request->cmd = scmnd;
|
||||
|
@ -717,7 +717,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
request->Extension = (void*)((unsigned long)cmd_request + request_size);
|
||||
DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size, storvsc_drv_obj->RequestExtSize);
|
||||
|
||||
// Build the SRB
|
||||
/* Build the SRB */
|
||||
switch(scmnd->sc_data_direction)
|
||||
{
|
||||
case DMA_TO_DEVICE:
|
||||
|
@ -732,9 +732,9 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
}
|
||||
|
||||
request->OnIOCompletion = storvsc_commmand_completion;
|
||||
request->Context = cmd_request;//scmnd;
|
||||
request->Context = cmd_request;/* scmnd; */
|
||||
|
||||
//request->PortId = scmnd->device->channel;
|
||||
/* request->PortId = scmnd->device->channel; */
|
||||
request->Host = host_device_ctx->port;
|
||||
request->Bus = scmnd->device->channel;
|
||||
request->TargetId = scmnd->device->id;
|
||||
|
@ -753,7 +753,7 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
{
|
||||
sgl = (struct scatterlist*)scsi_sglist(scmnd);
|
||||
|
||||
// check if we need to bounce the sgl
|
||||
/* check if we need to bounce the sgl */
|
||||
if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1)
|
||||
{
|
||||
DPRINT_INFO(STORVSC_DRV, "need to bounce buffer for this scmnd %p", scmnd);
|
||||
|
@ -771,9 +771,9 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
|
||||
cmd_request->bounce_sgl_count = ALIGN_UP(scsi_bufflen(scmnd), PAGE_SIZE) >> PAGE_SHIFT;
|
||||
|
||||
//printk("bouncing buffer allocated %p original buffer %p\n", bounce_sgl, sgl);
|
||||
//printk("copy_to_bounce_buffer\n");
|
||||
// FIXME: We can optimize on reads by just skipping this
|
||||
/* printk("bouncing buffer allocated %p original buffer %p\n", bounce_sgl, sgl); */
|
||||
/* printk("copy_to_bounce_buffer\n"); */
|
||||
/* FIXME: We can optimize on reads by just skipping this */
|
||||
copy_to_bounce_buffer(sgl, cmd_request->bounce_sgl, scsi_sg_count(scmnd));
|
||||
|
||||
sgl = cmd_request->bounce_sgl;
|
||||
|
@ -801,15 +801,15 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, void (*done)(struct scs
|
|||
|
||||
retry_request:
|
||||
|
||||
// Invokes the vsc to start an IO
|
||||
/* Invokes the vsc to start an IO */
|
||||
ret = storvsc_drv_obj->OnIORequest(&device_ctx->device_obj, &cmd_request->request);
|
||||
if (ret == -1) // no more space
|
||||
if (ret == -1) /* no more space */
|
||||
{
|
||||
DPRINT_ERR(STORVSC_DRV, "scmnd (%p) - queue FULL...marking queue busy", scmnd);
|
||||
|
||||
if (cmd_request->bounce_sgl_count)
|
||||
{
|
||||
// FIXME: We can optimize on writes by just skipping this
|
||||
/* FIXME: We can optimize on writes by just skipping this */
|
||||
copy_from_bounce_buffer(scsi_sglist(scmnd), cmd_request->bounce_sgl, scsi_sg_count(scmnd));
|
||||
destroy_bounce_buffer(cmd_request->bounce_sgl, cmd_request->bounce_sgl_count);
|
||||
}
|
||||
|
@ -829,7 +829,7 @@ retry_request:
|
|||
|
||||
static int storvsc_merge_bvec(struct request_queue *q, struct bvec_merge_data *bmd, struct bio_vec *bvec)
|
||||
{
|
||||
return bvec->bv_len; //checking done by caller.
|
||||
return bvec->bv_len; /* checking done by caller. */
|
||||
}
|
||||
|
||||
/*++
|
||||
|
@ -842,7 +842,7 @@ Desc: Configure the specified scsi device
|
|||
static int storvsc_device_alloc(struct scsi_device *sdevice)
|
||||
{
|
||||
DPRINT_DBG(STORVSC_DRV, "sdev (%p) - setting device flag to %d", sdevice, BLIST_SPARSELUN);
|
||||
// This enables luns to be located sparsely. Otherwise, we may not discovered them.
|
||||
/* This enables luns to be located sparsely. Otherwise, we may not discovered them. */
|
||||
sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
|
||||
return 0;
|
||||
}
|
||||
|
@ -861,7 +861,7 @@ static int storvsc_device_configure(struct scsi_device *sdevice)
|
|||
blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
|
||||
|
||||
blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
|
||||
//sdevice->timeout = (2000 * HZ);//(75 * HZ);
|
||||
/* sdevice->timeout = (2000 * HZ);//(75 * HZ); */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -887,7 +887,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
|
|||
|
||||
DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...", scmnd->device, &device_ctx->device_obj);
|
||||
|
||||
// Invokes the vsc to reset the host/bus
|
||||
/* Invokes the vsc to reset the host/bus */
|
||||
ASSERT(storvsc_drv_obj->OnHostReset);
|
||||
ret = storvsc_drv_obj->OnHostReset(&device_ctx->device_obj);
|
||||
if (ret != 0)
|
||||
|
@ -945,12 +945,12 @@ static void storvsc_host_rescan_callback(struct work_struct *work)
|
|||
|
||||
DPRINT_INFO(STORVSC_DRV, "rescanning host for new scsi devices...", device_obj, host_device_ctx->target, host_device_ctx->path);
|
||||
|
||||
// Rescan for new device
|
||||
/* Rescan for new device */
|
||||
scsi_scan_target(&host->shost_gendev, host_device_ctx->path, host_device_ctx->target, SCAN_WILD_CARD, 1);
|
||||
|
||||
DPRINT_INFO(STORVSC_DRV, "rescanning host for removed scsi device...");
|
||||
|
||||
// Use the 1st device to send the report luns cmd
|
||||
/* Use the 1st device to send the report luns cmd */
|
||||
shost_for_each_device(sdev, host)
|
||||
{
|
||||
lun_count=STORVSC_MAX_LUNS_PER_TARGET;
|
||||
|
@ -968,12 +968,12 @@ static void storvsc_host_rescan_callback(struct work_struct *work)
|
|||
DPRINT_INFO(STORVSC_DRV, "%d) lun %u", i, lun_list[i]);
|
||||
}
|
||||
|
||||
// Rescan for devices that may have been removed.
|
||||
// We do not have to worry that new devices may have been added since
|
||||
// this callback is serialized by the workqueue ie add/remove are done here.
|
||||
/* Rescan for devices that may have been removed. */
|
||||
/* We do not have to worry that new devices may have been added since */
|
||||
/* this callback is serialized by the workqueue ie add/remove are done here. */
|
||||
shost_for_each_device(sdev, host)
|
||||
{
|
||||
// See if this device is still here
|
||||
/* See if this device is still here */
|
||||
found = 0;
|
||||
for (i=0; i<lun_count; i++)
|
||||
{
|
||||
|
@ -990,13 +990,13 @@ static void storvsc_host_rescan_callback(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
// Now remove the devices
|
||||
/* Now remove the devices */
|
||||
for (i=0; i< sdevs_count; i++)
|
||||
{
|
||||
DPRINT_INFO(STORVSC_DRV, "removing scsi device (%p) lun (%u)...",
|
||||
sdevs_remove_list[i], sdevs_remove_list[i]->lun);
|
||||
|
||||
// make sure it is not removed from underneath us
|
||||
/* make sure it is not removed from underneath us */
|
||||
if (!scsi_device_get(sdevs_remove_list[i]))
|
||||
{
|
||||
scsi_remove_device(sdevs_remove_list[i]);
|
||||
|
@ -1021,7 +1021,7 @@ static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], un
|
|||
unsigned char *data;
|
||||
struct scsi_sense_hdr sshdr;
|
||||
unsigned char cmd[16]={0};
|
||||
unsigned int report_len = 8*(STORVSC_MAX_LUNS_PER_TARGET+1); // Add 1 to cover the report_lun header
|
||||
unsigned int report_len = 8*(STORVSC_MAX_LUNS_PER_TARGET+1); /* Add 1 to cover the report_lun header */
|
||||
unsigned long long *report_luns;
|
||||
const unsigned int in_lun_count = *lun_count;
|
||||
|
||||
|
@ -1035,7 +1035,7 @@ static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], un
|
|||
|
||||
cmd[0] = REPORT_LUNS;
|
||||
|
||||
// cmd length
|
||||
/* cmd length */
|
||||
*(unsigned int*)&cmd[6] = cpu_to_be32(report_len);
|
||||
|
||||
result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, (unsigned char*)report_luns, report_len, &sshdr, 30*HZ, 3, NULL);
|
||||
|
@ -1045,7 +1045,7 @@ static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], un
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
// get the length from the first four bytes
|
||||
/* get the length from the first four bytes */
|
||||
report_len = be32_to_cpu(*(unsigned int*)&report_luns[0]);
|
||||
|
||||
num_luns = (report_len / sizeof(unsigned long long));
|
||||
|
@ -1059,7 +1059,7 @@ static int storvsc_report_luns(struct scsi_device *sdev, unsigned int luns[], un
|
|||
|
||||
DPRINT_DBG(STORVSC_DRV, "report luns on scsi device (%p) found %u luns ", sdev, num_luns);
|
||||
|
||||
// lun id starts at 1
|
||||
/* lun id starts at 1 */
|
||||
for (i=1; i< num_luns+1; i++)
|
||||
{
|
||||
lun = 0;
|
||||
|
@ -1088,8 +1088,8 @@ static void storvsc_host_rescan(DEVICE_OBJECT* device_obj)
|
|||
|
||||
DPRINT_INFO(STORVSC_DRV, "initiating rescan on dev obj (%p) target (%u) bus (%u)...", device_obj, host_device_ctx->target, host_device_ctx->path);
|
||||
|
||||
// We need to queue this since the scanning may block and the caller may be in an intr context
|
||||
//scsi_queue_work(host, &host_device_ctx->host_rescan_work);
|
||||
/* We need to queue this since the scanning may block and the caller may be in an intr context */
|
||||
/* scsi_queue_work(host, &host_device_ctx->host_rescan_work); */
|
||||
schedule_work(&host_device_ctx->host_rescan_work);
|
||||
DPRINT_EXIT(STORVSC_DRV);
|
||||
}
|
||||
|
@ -1114,17 +1114,17 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
|
|||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
else
|
||||
{
|
||||
sectors_per_track = 17;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
|
||||
temp = cylinder_times_heads + 1023;
|
||||
rem = sector_div(temp, 1024); // sector_div stores the quotient in temp
|
||||
rem = sector_div(temp, 1024); /* sector_div stores the quotient in temp */
|
||||
|
||||
heads = temp;
|
||||
|
||||
|
@ -1137,7 +1137,7 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
|
|||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
|
||||
if (cylinder_times_heads >= (heads * 1024)) {
|
||||
|
@ -1145,12 +1145,12 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
|
|||
heads = 16;
|
||||
|
||||
cylinder_times_heads = total_sectors;
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); // sector_div stores the quotient in cylinder_times_heads
|
||||
rem = sector_div(cylinder_times_heads, sectors_per_track); /* sector_div stores the quotient in cylinder_times_heads */
|
||||
}
|
||||
}
|
||||
|
||||
temp = cylinder_times_heads;
|
||||
rem = sector_div(temp, heads); // sector_div stores the quotient in temp
|
||||
rem = sector_div(temp, heads); /* sector_div stores the quotient in temp */
|
||||
cylinders = temp;
|
||||
|
||||
info[0] = heads;
|
||||
|
@ -1193,4 +1193,4 @@ module_param(storvsc_ringbuffer_size, int, S_IRUGO);
|
|||
module_init(storvsc_init);
|
||||
module_exit(storvsc_exit);
|
||||
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
|
@ -32,22 +32,22 @@
|
|||
#include "include/logging.h"
|
||||
#include "include/vmbus.h"
|
||||
|
||||
//
|
||||
// Defines
|
||||
//
|
||||
|
||||
// FIXME! We need to do this dynamically for PIC and APIC system
|
||||
/* Defines */
|
||||
|
||||
|
||||
/* FIXME! We need to do this dynamically for PIC and APIC system */
|
||||
#define VMBUS_IRQ 0x5
|
||||
#define VMBUS_IRQ_VECTOR IRQ5_VECTOR
|
||||
//
|
||||
// Data types
|
||||
//
|
||||
|
||||
// Main vmbus driver data structure
|
||||
/* Data types */
|
||||
|
||||
|
||||
/* Main vmbus driver data structure */
|
||||
struct vmbus_driver_context {
|
||||
// !! These must be the first 2 fields !!
|
||||
// The driver field is not used in here. Instead, the bus field is
|
||||
// used to represent the driver
|
||||
/* !! These must be the first 2 fields !! */
|
||||
/* The driver field is not used in here. Instead, the bus field is */
|
||||
/* used to represent the driver */
|
||||
struct driver_context drv_ctx;
|
||||
VMBUS_DRIVER_OBJECT drv_obj;
|
||||
|
||||
|
@ -55,13 +55,13 @@ struct vmbus_driver_context {
|
|||
struct tasklet_struct msg_dpc;
|
||||
struct tasklet_struct event_dpc;
|
||||
|
||||
// The bus root device
|
||||
/* The bus root device */
|
||||
struct device_context device_ctx;
|
||||
};
|
||||
|
||||
//
|
||||
// Static decl
|
||||
//
|
||||
|
||||
/* Static decl */
|
||||
|
||||
static int vmbus_match(struct device *device, struct device_driver *driver);
|
||||
static int vmbus_probe(struct device *device);
|
||||
static int vmbus_remove(struct device *device);
|
||||
|
@ -81,26 +81,26 @@ static int vmbus_child_device_register(DEVICE_OBJECT* root_device_obj, DEVICE_OB
|
|||
static void vmbus_child_device_unregister(DEVICE_OBJECT* child_device_obj);
|
||||
static void vmbus_child_device_get_info(DEVICE_OBJECT *device_obj, DEVICE_INFO *device_info);
|
||||
|
||||
//static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
//static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf);
|
||||
/* static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf); */
|
||||
/* static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf); */
|
||||
|
||||
static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf);
|
||||
|
||||
//
|
||||
// Global
|
||||
//
|
||||
|
||||
// Global logging setting
|
||||
/* Global */
|
||||
|
||||
//unsigned int vmbus_loglevel= (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT);
|
||||
//unsigned int vmbus_loglevel= (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT);
|
||||
|
||||
/* Global logging setting */
|
||||
|
||||
/* unsigned int vmbus_loglevel= (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
|
||||
/* unsigned int vmbus_loglevel= (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
|
||||
unsigned int vmbus_loglevel= (ALL_MODULES << 16 | INFO_LVL);
|
||||
EXPORT_SYMBOL(vmbus_loglevel);
|
||||
|
||||
static int vmbus_irq = VMBUS_IRQ;
|
||||
|
||||
// Setup /proc/sys/bus/vmbus/vmbus_loglevel
|
||||
// Allow usage of sysctl cmd to set the logging level
|
||||
/* Setup /proc/sys/bus/vmbus/vmbus_loglevel */
|
||||
/* Allow usage of sysctl cmd to set the logging level */
|
||||
static struct ctl_table_header *vmbus_ctl_table_hdr;
|
||||
|
||||
static ctl_table vmbus_dev_ctl_table[] = {
|
||||
|
@ -129,9 +129,9 @@ static ctl_table vmus_root_ctl_table[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
//
|
||||
// Set up per device attributes in /sys/bus/vmbus/devices/<bus device>
|
||||
//
|
||||
|
||||
/* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
|
||||
|
||||
static struct device_attribute vmbus_device_attrs[] = {
|
||||
__ATTR(id, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
__ATTR(state, S_IRUGO, vmbus_show_device_attr, NULL),
|
||||
|
@ -161,7 +161,7 @@ static struct device_attribute vmbus_device_attrs[] = {
|
|||
__ATTR_NULL
|
||||
};
|
||||
|
||||
// The one and only one
|
||||
/* The one and only one */
|
||||
static struct vmbus_driver_context g_vmbus_drv={
|
||||
.bus.name = "vmbus",
|
||||
.bus.match = vmbus_match,
|
||||
|
@ -172,9 +172,9 @@ static struct vmbus_driver_context g_vmbus_drv={
|
|||
.bus.dev_attrs = vmbus_device_attrs,
|
||||
};
|
||||
|
||||
//
|
||||
// Routines
|
||||
//
|
||||
|
||||
/* Routines */
|
||||
|
||||
|
||||
|
||||
/*++
|
||||
|
@ -299,15 +299,15 @@ Name: vmbus_show_class_id()
|
|||
Desc: Show the device class id in sysfs
|
||||
|
||||
--*/
|
||||
//static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
//{
|
||||
// struct device_context *device_ctx = device_to_device_context(dev);
|
||||
// return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n",
|
||||
// device_ctx->class_id[3], device_ctx->class_id[2], device_ctx->class_id[1], device_ctx->class_id[0],
|
||||
// device_ctx->class_id[5], device_ctx->class_id[4],
|
||||
// device_ctx->class_id[7], device_ctx->class_id[6],
|
||||
// device_ctx->class_id[8], device_ctx->class_id[9], device_ctx->class_id[10], device_ctx->class_id[11], device_ctx->class_id[12], device_ctx->class_id[13], device_ctx->class_id[14], device_ctx->class_id[15]);
|
||||
//}
|
||||
/* static ssize_t vmbus_show_class_id(struct device *dev, struct device_attribute *attr, char *buf) */
|
||||
/* { */
|
||||
/* struct device_context *device_ctx = device_to_device_context(dev); */
|
||||
/* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
|
||||
/* device_ctx->class_id[3], device_ctx->class_id[2], device_ctx->class_id[1], device_ctx->class_id[0], */
|
||||
/* device_ctx->class_id[5], device_ctx->class_id[4], */
|
||||
/* device_ctx->class_id[7], device_ctx->class_id[6], */
|
||||
/* device_ctx->class_id[8], device_ctx->class_id[9], device_ctx->class_id[10], device_ctx->class_id[11], device_ctx->class_id[12], device_ctx->class_id[13], device_ctx->class_id[14], device_ctx->class_id[15]); */
|
||||
/* } */
|
||||
|
||||
/*++
|
||||
|
||||
|
@ -316,15 +316,15 @@ Name: vmbus_show_device_id()
|
|||
Desc: Show the device instance id in sysfs
|
||||
|
||||
--*/
|
||||
//static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
//{
|
||||
// struct device_context *device_ctx = device_to_device_context(dev);
|
||||
// return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n",
|
||||
// device_ctx->device_id[3], device_ctx->device_id[2], device_ctx->device_id[1], device_ctx->device_id[0],
|
||||
// device_ctx->device_id[5], device_ctx->device_id[4],
|
||||
// device_ctx->device_id[7], device_ctx->device_id[6],
|
||||
// device_ctx->device_id[8], device_ctx->device_id[9], device_ctx->device_id[10], device_ctx->device_id[11], device_ctx->device_id[12], device_ctx->device_id[13], device_ctx->device_id[14], device_ctx->device_id[15]);
|
||||
//}
|
||||
/* static ssize_t vmbus_show_device_id(struct device *dev, struct device_attribute *attr, char *buf) */
|
||||
/* { */
|
||||
/* struct device_context *device_ctx = device_to_device_context(dev); */
|
||||
/* return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x%02x%02x}\n", */
|
||||
/* device_ctx->device_id[3], device_ctx->device_id[2], device_ctx->device_id[1], device_ctx->device_id[0], */
|
||||
/* device_ctx->device_id[5], device_ctx->device_id[4], */
|
||||
/* device_ctx->device_id[7], device_ctx->device_id[6], */
|
||||
/* device_ctx->device_id[8], device_ctx->device_id[9], device_ctx->device_id[10], device_ctx->device_id[11], device_ctx->device_id[12], device_ctx->device_id[13], device_ctx->device_id[14], device_ctx->device_id[15]); */
|
||||
/* } */
|
||||
|
||||
/*++
|
||||
|
||||
|
@ -351,13 +351,13 @@ int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Set this up to allow lower layer to callback to add/remove child devices on the bus
|
||||
/* Set this up to allow lower layer to callback to add/remove child devices on the bus */
|
||||
vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create;
|
||||
vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy;
|
||||
vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register;
|
||||
vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister;
|
||||
|
||||
// Call to bus driver to initialize
|
||||
/* Call to bus driver to initialize */
|
||||
ret = pfn_drv_init(&vmbus_drv_obj->Base);
|
||||
if (ret != 0)
|
||||
{
|
||||
|
@ -365,7 +365,7 @@ int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
/* Sanity checks */
|
||||
if (!vmbus_drv_obj->Base.OnDeviceAdd)
|
||||
{
|
||||
DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set");
|
||||
|
@ -375,14 +375,14 @@ int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
|
||||
vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name;
|
||||
|
||||
// Initialize the bus context
|
||||
/* Initialize the bus context */
|
||||
tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, (unsigned long)vmbus_drv_obj);
|
||||
tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, (unsigned long)vmbus_drv_obj);
|
||||
|
||||
// Now, register the bus driver with LDM
|
||||
/* Now, register the bus driver with LDM */
|
||||
bus_register(&vmbus_drv_ctx->bus);
|
||||
|
||||
// Get the interrupt resource
|
||||
/* Get the interrupt resource */
|
||||
ret = request_irq(vmbus_irq,
|
||||
vmbus_isr,
|
||||
IRQF_SAMPLE_RANDOM,
|
||||
|
@ -402,7 +402,7 @@ int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
|
||||
DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
|
||||
|
||||
// Call to bus driver to add the root device
|
||||
/* Call to bus driver to add the root device */
|
||||
memset(dev_ctx, 0, sizeof(struct device_context));
|
||||
|
||||
ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector);
|
||||
|
@ -417,19 +417,19 @@ int vmbus_bus_init(PFN_DRIVERINITIALIZE pfn_drv_init)
|
|||
ret = -1;
|
||||
goto cleanup;
|
||||
}
|
||||
//strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name);
|
||||
/* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
|
||||
dev_set_name(&dev_ctx->device, "vmbus_0_0");
|
||||
memcpy(&dev_ctx->class_id, &dev_ctx->device_obj.deviceType, sizeof(GUID));
|
||||
memcpy(&dev_ctx->device_id, &dev_ctx->device_obj.deviceInstance, sizeof(GUID));
|
||||
|
||||
// No need to bind a driver to the root device.
|
||||
/* No need to bind a driver to the root device. */
|
||||
dev_ctx->device.parent = NULL;
|
||||
dev_ctx->device.bus = &vmbus_drv_ctx->bus; //NULL; // vmbus_remove() does not get invoked
|
||||
dev_ctx->device.bus = &vmbus_drv_ctx->bus; /* NULL; vmbus_remove() does not get invoked */
|
||||
|
||||
// Setup the device dispatch table
|
||||
/* Setup the device dispatch table */
|
||||
dev_ctx->device.release = vmbus_bus_release;
|
||||
|
||||
// Setup the bus as root device
|
||||
/* Setup the bus as root device */
|
||||
device_register(&dev_ctx->device);
|
||||
|
||||
vmbus_drv_obj->GetChannelOffers();
|
||||
|
@ -457,14 +457,14 @@ void vmbus_bus_exit(void)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Remove the root device
|
||||
/* Remove the root device */
|
||||
if (vmbus_drv_obj->Base.OnDeviceRemove)
|
||||
vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj);
|
||||
|
||||
if (vmbus_drv_obj->Base.OnCleanup)
|
||||
vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base);
|
||||
|
||||
// Unregister the root bus device
|
||||
/* Unregister the root bus device */
|
||||
device_unregister(&dev_ctx->device);
|
||||
|
||||
bus_unregister(&vmbus_drv_ctx->bus);
|
||||
|
@ -494,7 +494,7 @@ void vmbus_child_driver_register(struct driver_context* driver_ctx)
|
|||
|
||||
DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", driver_ctx, driver_ctx->driver.name);
|
||||
|
||||
// The child driver on this vmbus
|
||||
/* The child driver on this vmbus */
|
||||
driver_ctx->driver.bus = &g_vmbus_drv.bus;
|
||||
|
||||
driver_register(&driver_ctx->driver);
|
||||
|
@ -573,7 +573,7 @@ static DEVICE_OBJECT* vmbus_child_device_create(GUID type, GUID instance, void*
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Allocate the new child device
|
||||
/* Allocate the new child device */
|
||||
child_device_ctx = kzalloc(sizeof(struct device_context), GFP_KERNEL);
|
||||
if (!child_device_ctx)
|
||||
{
|
||||
|
@ -620,9 +620,9 @@ static int vmbus_child_device_register(DEVICE_OBJECT* root_device_obj, DEVICE_OB
|
|||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
DPRINT_DBG(VMBUS_DRV, "child device (%p) registering", child_device_ctx);
|
||||
//
|
||||
// Make sure we are not registered already
|
||||
//
|
||||
|
||||
/* Make sure we are not registered already */
|
||||
|
||||
if (strlen(dev_name(&child_device_ctx->device)) != 0)
|
||||
{
|
||||
DPRINT_ERR(VMBUS_DRV, "child device (%p) already registered - busid %s", child_device_ctx, dev_name(&child_device_ctx->device));
|
||||
|
@ -631,19 +631,19 @@ static int vmbus_child_device_register(DEVICE_OBJECT* root_device_obj, DEVICE_OB
|
|||
goto Cleanup;
|
||||
}
|
||||
|
||||
// Set the device bus id. Otherwise, device_register()will fail.
|
||||
/* Set the device bus id. Otherwise, device_register()will fail. */
|
||||
dev_set_name(&child_device_ctx->device, "vmbus_0_%d", InterlockedIncrement(&device_num));
|
||||
|
||||
// The new device belongs to this bus
|
||||
child_device_ctx->device.bus = &g_vmbus_drv.bus; //device->dev.bus;
|
||||
/* The new device belongs to this bus */
|
||||
child_device_ctx->device.bus = &g_vmbus_drv.bus; /* device->dev.bus; */
|
||||
child_device_ctx->device.parent = &root_device_ctx->device;
|
||||
child_device_ctx->device.release = vmbus_device_release;
|
||||
|
||||
// Register with the LDM. This will kick off the driver/device binding...which will
|
||||
// eventually call vmbus_match() and vmbus_probe()
|
||||
/* Register with the LDM. This will kick off the driver/device binding...which will */
|
||||
/* eventually call vmbus_match() and vmbus_probe() */
|
||||
ret = device_register(&child_device_ctx->device);
|
||||
|
||||
// vmbus_probe() error does not get propergate to device_register().
|
||||
/* vmbus_probe() error does not get propergate to device_register(). */
|
||||
ret = child_device_ctx->probe_error;
|
||||
|
||||
if (ret)
|
||||
|
@ -672,8 +672,8 @@ static void vmbus_child_device_unregister(DEVICE_OBJECT* device_obj)
|
|||
|
||||
DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)", &device_ctx->device);
|
||||
|
||||
// Kick off the process of unregistering the device.
|
||||
// This will call vmbus_remove() and eventually vmbus_device_release()
|
||||
/* Kick off the process of unregistering the device. */
|
||||
/* This will call vmbus_remove() and eventually vmbus_device_release() */
|
||||
device_unregister(&device_ctx->device);
|
||||
|
||||
DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered", &device_ctx->device);
|
||||
|
@ -770,11 +770,11 @@ static int vmbus_match(struct device *device, struct device_driver *driver)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// We found our driver ?
|
||||
/* We found our driver ? */
|
||||
if (memcmp(&device_ctx->class_id, &driver_ctx->class_id, sizeof(GUID)) == 0)
|
||||
{
|
||||
// !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast it here to access the
|
||||
// DRIVER_OBJECT field
|
||||
/* !! NOTE: The driver_ctx is not a vmbus_drv_ctx. We typecast it here to access the */
|
||||
/* DRIVER_OBJECT field */
|
||||
struct vmbus_driver_context *vmbus_drv_ctx = (struct vmbus_driver_context*)driver_ctx;
|
||||
device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base;
|
||||
DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, device_ctx->device_obj.Driver);
|
||||
|
@ -804,11 +804,11 @@ static void vmbus_probe_failed_cb(struct work_struct *context)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Kick off the process of unregistering the device.
|
||||
// This will call vmbus_remove() and eventually vmbus_device_release()
|
||||
/* Kick off the process of unregistering the device. */
|
||||
/* This will call vmbus_remove() and eventually vmbus_device_release() */
|
||||
device_unregister(&device_ctx->device);
|
||||
|
||||
//put_device(&device_ctx->device);
|
||||
/* put_device(&device_ctx->device); */
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
}
|
||||
|
||||
|
@ -828,7 +828,7 @@ static int vmbus_probe(struct device *child_device)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Let the specific open-source driver handles the probe if it can
|
||||
/* Let the specific open-source driver handles the probe if it can */
|
||||
if (driver_ctx->probe)
|
||||
{
|
||||
ret = device_ctx->probe_error = driver_ctx->probe(child_device);
|
||||
|
@ -865,10 +865,10 @@ static int vmbus_remove(struct device *child_device)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Special case root bus device
|
||||
/* Special case root bus device */
|
||||
if (child_device->parent == NULL)
|
||||
{
|
||||
// No-op since it is statically defined and handle in vmbus_bus_exit()
|
||||
/* No-op since it is statically defined and handle in vmbus_bus_exit() */
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
return 0;
|
||||
}
|
||||
|
@ -877,7 +877,7 @@ static int vmbus_remove(struct device *child_device)
|
|||
{
|
||||
driver_ctx = driver_to_driver_context(child_device->driver);
|
||||
|
||||
// Let the specific open-source driver handles the removal if it can
|
||||
/* Let the specific open-source driver handles the removal if it can */
|
||||
if (driver_ctx->remove)
|
||||
{
|
||||
ret = driver_ctx->remove(child_device);
|
||||
|
@ -911,15 +911,15 @@ static void vmbus_shutdown(struct device *child_device)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
// Special case root bus device
|
||||
/* Special case root bus device */
|
||||
if (child_device->parent == NULL)
|
||||
{
|
||||
// No-op since it is statically defined and handle in vmbus_bus_exit()
|
||||
/* No-op since it is statically defined and handle in vmbus_bus_exit() */
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
return;
|
||||
}
|
||||
|
||||
// The device may not be attached yet
|
||||
/* The device may not be attached yet */
|
||||
if (!child_device->driver)
|
||||
{
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
|
@ -928,7 +928,7 @@ static void vmbus_shutdown(struct device *child_device)
|
|||
|
||||
driver_ctx = driver_to_driver_context(child_device->driver);
|
||||
|
||||
// Let the specific open-source driver handles the removal if it can
|
||||
/* Let the specific open-source driver handles the removal if it can */
|
||||
if (driver_ctx->shutdown)
|
||||
{
|
||||
driver_ctx->shutdown(child_device);
|
||||
|
@ -965,10 +965,10 @@ static void vmbus_device_release(struct device *device)
|
|||
|
||||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
//vmbus_child_device_destroy(&device_ctx->device_obj);
|
||||
/* vmbus_child_device_destroy(&device_ctx->device_obj); */
|
||||
kfree(device_ctx);
|
||||
|
||||
// !!DO NOT REFERENCE device_ctx anymore at this point!!
|
||||
/* !!DO NOT REFERENCE device_ctx anymore at this point!! */
|
||||
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
|
||||
|
@ -990,7 +990,7 @@ static void vmbus_msg_dpc(unsigned long data)
|
|||
|
||||
ASSERT(vmbus_drv_obj->OnMsgDpc != NULL);
|
||||
|
||||
// Call to bus driver to handle interrupt
|
||||
/* Call to bus driver to handle interrupt */
|
||||
vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base);
|
||||
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
|
@ -1011,7 +1011,7 @@ static void vmbus_event_dpc(unsigned long data)
|
|||
|
||||
ASSERT(vmbus_drv_obj->OnEventDpc != NULL);
|
||||
|
||||
// Call to bus driver to handle interrupt
|
||||
/* Call to bus driver to handle interrupt */
|
||||
vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base);
|
||||
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
|
@ -1033,10 +1033,10 @@ static irqreturn_t vmbus_isr(int irq, void* dev_id)
|
|||
|
||||
ASSERT(vmbus_driver_obj->OnIsr != NULL);
|
||||
|
||||
// Call to bus driver to handle interrupt
|
||||
/* Call to bus driver to handle interrupt */
|
||||
ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base);
|
||||
|
||||
// Schedules a dpc if necessary
|
||||
/* Schedules a dpc if necessary */
|
||||
if (ret > 0)
|
||||
{
|
||||
if (test_bit(0, (unsigned long*)&ret))
|
||||
|
@ -1078,7 +1078,7 @@ static int __init vmbus_init(void)
|
|||
DPRINT_INFO(VMBUS_DRV,
|
||||
"Vmbus initializing.... current log level 0x%x (%x,%x)",
|
||||
vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
|
||||
//Todo: it is used for loglevel, to be ported to new kernel.
|
||||
/* Todo: it is used for loglevel, to be ported to new kernel. */
|
||||
|
||||
ret = vmbus_bus_init(VmbusInitialize);
|
||||
|
||||
|
@ -1100,7 +1100,7 @@ static void __exit vmbus_exit(void)
|
|||
DPRINT_ENTER(VMBUS_DRV);
|
||||
|
||||
vmbus_bus_exit();
|
||||
//Todo: it is used for loglevel, to be ported to new kernel.
|
||||
/* Todo: it is used for loglevel, to be ported to new kernel. */
|
||||
DPRINT_EXIT(VMBUS_DRV);
|
||||
|
||||
return;
|
||||
|
@ -1111,4 +1111,4 @@ module_param(vmbus_loglevel, int, S_IRUGO);
|
|||
|
||||
module_init(vmbus_init);
|
||||
module_exit(vmbus_exit);
|
||||
// eof
|
||||
/* eof */
|
||||
|
|
Loading…
Reference in New Issue