[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\tdi\tdi.sys 2
drivers\network\dd\ne2000\ne2000.sys 2 drivers\network\dd\ne2000\ne2000.sys 2
drivers\network\dd\pcnet\pcnet.sys 2 drivers\network\dd\pcnet\pcnet.sys 2
drivers\network\ndisuio\ndisuio.sys 2
drivers\serial\serenum\serenum.sys 2 drivers\serial\serenum\serenum.sys 2
drivers\serial\serial\serial.sys 2 drivers\serial\serial\serial.sys 2

View file

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

View file

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

View file

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

View file

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

View file

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