[NDISUIO]

- Bug fixes
- Make the packet and buffer pools per adapter
- Crashes during bind for some reason

svn path=/branches/wlan-bringup/; revision=54855
This commit is contained in:
Cameron Gutman 2012-01-06 19:43:15 +00:00
parent fa180d7efb
commit d665699bee
6 changed files with 94 additions and 51 deletions

View file

@ -532,6 +532,7 @@ drivers\network\tcpip\tcpip.sys 2
drivers\network\tdi\tdi.sys 2
drivers\network\dd\ne2000\ne2000.sys 2
drivers\network\dd\pcnet\pcnet.sys 2
drivers\network\ndisuio\ndisuio.sys 2
drivers\serial\serenum\serenum.sys 2
drivers\serial\serial\serial.sys 2

View file

@ -15,8 +15,6 @@ PDEVICE_OBJECT GlobalDeviceObject;
NDIS_HANDLE GlobalProtocolHandle;
KSPIN_LOCK GlobalAdapterListLock;
LIST_ENTRY GlobalAdapterList;
NDIS_HANDLE GlobalPacketPoolHandle;
NDIS_HANDLE GlobalBufferPoolHandle;
NDIS_STRING ProtocolName = RTL_CONSTANT_STRING(L"NDISUIO");
@ -70,32 +68,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
return Status;
}
/* Create the buffer pool */
NdisAllocateBufferPool(&Status,
&GlobalBufferPoolHandle,
100);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(GlobalDeviceObject);
return Status;
}
/* Create the packet pool */
NdisAllocatePacketPool(&Status,
&GlobalPacketPoolHandle,
50,
0);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
NdisFreeBufferPool(GlobalBufferPoolHandle);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(GlobalDeviceObject);
return Status;
}
/* Register the protocol with NDIS */
RtlZeroMemory(&Chars, sizeof(Chars));
Chars.MajorNdisVersion = NDIS_MAJOR_VERSION;
@ -121,8 +93,6 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to register protocol with status 0x%x\n", Status);
NdisFreePacketPool(GlobalPacketPoolHandle);
NdisFreeBufferPool(GlobalBufferPoolHandle);
IoDeleteSymbolicLink(&DosDeviceName);
IoDeleteDevice(GlobalDeviceObject);
return Status;

View file

@ -12,7 +12,11 @@
#include <debug.h>
NDIS_STATUS
AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOLEAN Front)
AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDIS_PACKET Packet,
PVOID Buffer,
ULONG BufferSize,
BOOLEAN Front)
{
NDIS_STATUS Status;
PNDIS_BUFFER NdisBuffer;
@ -20,7 +24,7 @@ AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOL
/* Allocate the NDIS buffer mapping the pool */
NdisAllocateBuffer(&Status,
&NdisBuffer,
GlobalBufferPoolHandle,
AdapterContext->BufferPoolHandle,
Buffer,
BufferSize);
if (Status != NDIS_STATUS_SUCCESS)
@ -45,7 +49,9 @@ AllocateAndChainBuffer(PNDIS_PACKET Packet, PVOID Buffer, ULONG BufferSize, BOOL
}
PNDIS_PACKET
CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize)
CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PVOID Buffer,
ULONG BufferSize)
{
PNDIS_PACKET Packet;
NDIS_STATUS Status;
@ -53,7 +59,7 @@ CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize)
/* Allocate a packet descriptor */
NdisAllocatePacket(&Status,
&Packet,
GlobalPacketPoolHandle);
AdapterContext->PacketPoolHandle);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("No free packet descriptors\n");
@ -61,7 +67,8 @@ CreatePacketFromPoolBuffer(PVOID Buffer, ULONG BufferSize)
}
/* Use the helper to chain the buffer */
Status = AllocateAndChainBuffer(Packet, Buffer, BufferSize, TRUE);
Status = AllocateAndChainBuffer(AdapterContext, Packet,
Buffer, BufferSize, TRUE);
if (Status != NDIS_STATUS_SUCCESS)
{
NdisFreePacket(Packet);

View file

@ -15,8 +15,6 @@ extern PDEVICE_OBJECT GlobalDeviceObject;
extern NDIS_HANDLE GlobalProtocolHandle;
extern LIST_ENTRY GlobalAdapterList;
extern KSPIN_LOCK GlobalAdapterListLock;
extern NDIS_HANDLE GlobalPacketPoolHandle;
extern NDIS_HANDLE GlobalBufferPoolHandle;
typedef struct _NDISUIO_ADAPTER_CONTEXT
{
@ -31,6 +29,10 @@ typedef struct _NDISUIO_ADAPTER_CONTEXT
ULONG OpenCount;
LIST_ENTRY OpenEntryList;
/* NDIS pools */
NDIS_HANDLE PacketPoolHandle;
NDIS_HANDLE BufferPoolHandle;
/* Receive packet list */
LIST_ENTRY PacketList;
KEVENT PacketReadEvent;
@ -92,13 +94,15 @@ NduDispatchDeviceControl(PDEVICE_OBJECT DeviceObject,
/* misc.c */
NDIS_STATUS
AllocateAndChainBuffer(PNDIS_PACKET Packet,
AllocateAndChainBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PNDIS_PACKET Packet,
PVOID Buffer,
ULONG BufferSize,
BOOLEAN Front);
PNDIS_PACKET
CreatePacketFromPoolBuffer(PVOID Buffer,
CreatePacketFromPoolBuffer(PNDISUIO_ADAPTER_CONTEXT AdapterContext,
PVOID Buffer,
ULONG BufferSize);
VOID

View file

@ -8,7 +8,7 @@
#include "ndisuio.h"
#define NDEBUG
//#define NDEBUG
#include <debug.h>
PNDIS_MEDIUM SupportedMedia = {NdisMedium802_3};
@ -119,13 +119,20 @@ NduReceive(NDIS_HANDLE ProtocolBindingContext,
NDIS_STATUS Status;
UINT BytesTransferred;
DPRINT("Received a %d byte packet on %wZ\n", PacketSize + HeaderBufferSize, &AdapterContext->DeviceName);
/* Discard if nobody is waiting for it */
if (AdapterContext->OpenCount == 0)
return NDIS_STATUS_NOT_ACCEPTED;
/* Allocate a buffer to hold the packet data and header */
PacketBuffer = ExAllocatePool(NonPagedPool, PacketSize);
if (!PacketBuffer)
return NDIS_STATUS_NOT_ACCEPTED;
/* Allocate the packet descriptor and buffer */
Packet = CreatePacketFromPoolBuffer((PUCHAR)PacketBuffer + HeaderBufferSize,
Packet = CreatePacketFromPoolBuffer(AdapterContext,
(PUCHAR)PacketBuffer + HeaderBufferSize,
PacketSize);
if (!Packet)
{
@ -221,20 +228,28 @@ NDIS_STATUS
UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
{
KIRQL OldIrql;
PLIST_ENTRY CurrentOpenEntry;
PLIST_ENTRY CurrentEntry;
PNDISUIO_OPEN_ENTRY OpenEntry;
PNDISUIO_PACKET_ENTRY PacketEntry;
NDIS_STATUS Status;
DPRINT("Unbinding adapter %wZ\n", &AdapterContext->DeviceName);
/* FIXME: We don't do anything with outstanding reads */
/* Remove the adapter context from the global list */
KeAcquireSpinLock(&GlobalAdapterListLock, &OldIrql);
RemoveEntryList(&AdapterContext->ListEntry);
KeReleaseSpinLock(&GlobalAdapterListLock, OldIrql);
/* Free the device name string */
RtlFreeUnicodeString(&AdapterContext->DeviceName);
/* Invalidate all handles to this adapter */
CurrentOpenEntry = AdapterContext->OpenEntryList.Flink;
while (CurrentOpenEntry != &AdapterContext->OpenEntryList)
CurrentEntry = AdapterContext->OpenEntryList.Flink;
while (CurrentEntry != &AdapterContext->OpenEntryList)
{
OpenEntry = CONTAINING_RECORD(CurrentOpenEntry, NDISUIO_OPEN_ENTRY, ListEntry);
OpenEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_OPEN_ENTRY, ListEntry);
/* Make sure the entry is sane */
ASSERT(OpenEntry->FileObject);
@ -249,7 +264,7 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
OpenEntry->FileObject->FsContext2 = NULL;
/* Move to the next entry */
CurrentOpenEntry = CurrentOpenEntry->Flink;
CurrentEntry = CurrentEntry->Flink;
/* Free the open entry */
ExFreePool(OpenEntry);
@ -258,6 +273,19 @@ UnbindAdapterByContext(PNDISUIO_ADAPTER_CONTEXT AdapterContext)
/* If this fails, we have a refcount mismatch somewhere */
ASSERT(AdapterContext->OpenCount == 0);
/* Free all pending packet entries */
CurrentEntry = AdapterContext->PacketList.Flink;
while (CurrentEntry != &AdapterContext->PacketList)
{
PacketEntry = CONTAINING_RECORD(CurrentEntry, NDISUIO_PACKET_ENTRY, ListEntry);
/* Move to the next entry */
CurrentEntry = CurrentEntry->Flink;
/* Free the packet entry */
ExFreePool(PacketEntry);
}
/* Send the close request */
NdisCloseAdapter(&Status,
AdapterContext->BindingHandle);
@ -288,6 +316,8 @@ BindAdapterByName(PNDIS_STRING DeviceName)
UINT SelectedMedium;
NDIS_STATUS Status;
DPRINT("Binding adapter %wZ\n", &AdapterContext->DeviceName);
/* Allocate the adapter context */
AdapterContext = ExAllocatePool(NonPagedPool, sizeof(*AdapterContext));
if (!AdapterContext)
@ -313,15 +343,42 @@ BindAdapterByName(PNDIS_STRING DeviceName)
return NDIS_STATUS_RESOURCES;
}
/* Copy the device name into the adapter context */
RtlCopyMemory(AdapterContext->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
/* Create the buffer pool */
NdisAllocateBufferPool(&Status,
&AdapterContext->BufferPoolHandle,
50);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate buffer pool with status 0x%x\n", Status);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
return Status;
}
/* Create the packet pool */
NdisAllocatePacketPool(&Status,
&AdapterContext->PacketPoolHandle,
25,
PROTOCOL_RESERVED_SIZE_IN_PACKET);
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to allocate packet pool with status 0x%x\n", Status);
NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
return Status;
}
/* Send the open request */
NdisOpenAdapter(&Status,
&OpenErrorStatus,
&AdapterContext->BindingHandle,
&SelectedMedium,
SupportedMedia,
sizeof(SupportedMedia),
&SupportedMedia[0],
1,
GlobalProtocolHandle,
AdapterContext,
DeviceName,
@ -343,6 +400,9 @@ BindAdapterByName(PNDIS_STRING DeviceName)
if (Status != NDIS_STATUS_SUCCESS)
{
DPRINT1("Failed to open adapter for bind with status 0x%x\n", Status);
NdisFreePacketPool(AdapterContext->PacketPoolHandle);
NdisFreeBufferPool(AdapterContext->BufferPoolHandle);
RtlFreeUnicodeString(&AdapterContext->DeviceName);
ExFreePool(AdapterContext);
return Status;
}

View file

@ -167,7 +167,8 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
ASSERT(DeviceObject == GlobalDeviceObject);
/* Create a packet and buffer descriptor for this user buffer */
Packet = CreatePacketFromPoolBuffer(Irp->AssociatedIrp.SystemBuffer,
Packet = CreatePacketFromPoolBuffer(AdapterContext,
Irp->AssociatedIrp.SystemBuffer,
IrpSp->Parameters.Write.Length);
if (Packet)
{
@ -191,7 +192,7 @@ NduDispatchWrite(PDEVICE_OBJECT DeviceObject,
if (Status == NDIS_STATUS_SUCCESS)
BytesCopied = IrpSp->Parameters.Write.Length;
CleanupAndFreePacket(Packet, TRUE);
CleanupAndFreePacket(Packet, FALSE);
}
else
{