- Merge aicom-network-fixes up to r38205

svn path=/trunk/; revision=38213
This commit is contained in:
Cameron Gutman 2008-12-21 01:29:35 +00:00
parent 5c760c2d22
commit ed4682a617
7 changed files with 75 additions and 124 deletions

View file

@ -10,9 +10,6 @@
#include "precomp.h" #include "precomp.h"
/* Define this to bugcheck on double complete */
/* #define BREAK_ON_DOUBLE_COMPLETE */
UINT TransferDataCalled = 0; UINT TransferDataCalled = 0;
UINT TransferDataCompleteCalled = 0; UINT TransferDataCompleteCalled = 0;
UINT LanReceiveWorkerCalled = 0; UINT LanReceiveWorkerCalled = 0;
@ -51,54 +48,6 @@ BOOLEAN ProtocolRegistered = FALSE;
LIST_ENTRY AdapterListHead; LIST_ENTRY AdapterListHead;
KSPIN_LOCK AdapterListLock; KSPIN_LOCK AdapterListLock;
/* Double complete protection */
KSPIN_LOCK LanSendCompleteLock;
LIST_ENTRY LanSendCompleteList;
VOID LanChainCompletion( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
PLAN_WQ_ITEM PendingCompletion =
ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
if( !PendingCompletion ) return;
PendingCompletion->Packet = NdisPacket;
PendingCompletion->Adapter = Adapter;
ExInterlockedInsertTailList( &LanSendCompleteList,
&PendingCompletion->ListEntry,
&LanSendCompleteLock );
}
BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
PLIST_ENTRY ListEntry;
PLAN_WQ_ITEM CompleteEntry;
KIRQL OldIrql;
KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
for( ListEntry = LanSendCompleteList.Flink;
ListEntry != &LanSendCompleteList;
ListEntry = ListEntry->Flink ) {
CompleteEntry = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
if( CompleteEntry->Adapter == Adapter &&
CompleteEntry->Packet == NdisPacket ) {
RemoveEntryList( ListEntry );
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
ExFreePool( CompleteEntry );
return TRUE;
}
}
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
DbgPrint("NDIS completed the same send packet twice "
"(Adapter %x Packet %x)!!\n", Adapter, NdisPacket);
#ifdef BREAK_ON_DOUBLE_COMPLETE
KeBugCheck(0);
#endif
return FALSE;
}
NDIS_STATUS NDISCall( NDIS_STATUS NDISCall(
PLAN_ADAPTER Adapter, PLAN_ADAPTER Adapter,
NDIS_REQUEST_TYPE Type, NDIS_REQUEST_TYPE Type,
@ -283,13 +232,11 @@ VOID NTAPI ProtocolSendComplete(
*/ */
{ {
TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n")); TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
if( LanShouldComplete( (PLAN_ADAPTER)BindingContext, Packet ) ) { ASSERT_KM_POINTER(Packet);
ASSERT_KM_POINTER(Packet); ASSERT_KM_POINTER(PC(Packet));
ASSERT_KM_POINTER(PC(Packet)); ASSERT_KM_POINTER(PC(Packet)->DLComplete);
ASSERT_KM_POINTER(PC(Packet)->DLComplete); (*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status); TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
}
} }
VOID LanReceiveWorker( PVOID Context ) { VOID LanReceiveWorker( PVOID Context ) {
@ -646,8 +593,6 @@ VOID LANTransmit(
* not needed immediately */ * not needed immediately */
GetDataPtr( NdisPacket, 0, &Data, &Size ); GetDataPtr( NdisPacket, 0, &Data, &Size );
LanChainCompletion( Adapter, NdisPacket );
switch (Adapter->Media) { switch (Adapter->Media) {
case NdisMedium802_3: case NdisMedium802_3:
EHeader = (PETH_HEADER)Data; EHeader = (PETH_HEADER)Data;
@ -1046,6 +991,7 @@ BOOLEAN BindAdapter(
if (NdisStatus != NDIS_STATUS_SUCCESS) { if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus)); TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
IPUnregisterInterface(IF);
IPDestroyInterface(IF); IPDestroyInterface(IF);
return FALSE; return FALSE;
} }
@ -1380,24 +1326,4 @@ VOID LANUnregisterProtocol(
} }
} }
VOID LANStartup() {
InitializeListHead( &LanSendCompleteList );
KeInitializeSpinLock( &LanSendCompleteLock );
}
VOID LANShutdown() {
KIRQL OldIrql;
PLAN_WQ_ITEM WorkItem;
PLIST_ENTRY ListEntry;
KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
while( !IsListEmpty( &LanSendCompleteList ) ) {
ListEntry = RemoveHeadList( &LanSendCompleteList );
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
FreeNdisPacket( WorkItem->Packet );
ExFreePool( WorkItem );
}
KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
}
/* EOF */ /* EOF */

View file

@ -585,9 +585,6 @@ VOID NTAPI TiUnload(
/* Shutdown network level protocol subsystem */ /* Shutdown network level protocol subsystem */
IPShutdown(); IPShutdown();
/* Shutdown the lan worker */
LANShutdown();
/* Free NDIS buffer descriptors */ /* Free NDIS buffer descriptors */
if (GlobalBufferPool) if (GlobalBufferPool)
NdisFreeBufferPool(GlobalBufferPool); NdisFreeBufferPool(GlobalBufferPool);
@ -827,9 +824,6 @@ DriverEntry(
return Status; return Status;
} }
/* Initialize the lan worker */
LANStartup();
/* Register protocol with NDIS */ /* Register protocol with NDIS */
/* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */ /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
Status = LANRegisterProtocol(&strNdisDeviceName); Status = LANRegisterProtocol(&strNdisDeviceName);
@ -843,7 +837,6 @@ DriverEntry(
NULL, NULL,
0, 0,
NULL); NULL);
LANShutdown();
TCPShutdown(); TCPShutdown();
UDPShutdown(); UDPShutdown();
RawIPShutdown(); RawIPShutdown();
@ -863,7 +856,6 @@ DriverEntry(
Status = LoopRegisterAdapter(NULL, NULL); Status = LoopRegisterAdapter(NULL, NULL);
if (!NT_SUCCESS(Status)) { if (!NT_SUCCESS(Status)) {
TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
LANShutdown();
TCPShutdown(); TCPShutdown();
UDPShutdown(); UDPShutdown();
RawIPShutdown(); RawIPShutdown();

View file

@ -22,6 +22,7 @@ typedef struct _LAN_WQ_ITEM {
KSPIN_LOCK LoopWorkLock; KSPIN_LOCK LoopWorkLock;
LIST_ENTRY LoopWorkList; LIST_ENTRY LoopWorkList;
WORK_QUEUE_ITEM LoopWorkItem; WORK_QUEUE_ITEM LoopWorkItem;
BOOLEAN LoopReceiveWorkerBusy = FALSE;
VOID NTAPI LoopReceiveWorker( PVOID Context ) { VOID NTAPI LoopReceiveWorker( PVOID Context ) {
PLIST_ENTRY ListEntry; PLIST_ENTRY ListEntry;
@ -34,43 +35,46 @@ VOID NTAPI LoopReceiveWorker( PVOID Context ) {
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
ListEntry = ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock ); while( (ListEntry =
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); ExInterlockedRemoveHeadList( &LoopWorkList, &LoopWorkLock )) ) {
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem));
Packet = WorkItem->Packet; Packet = WorkItem->Packet;
Adapter = WorkItem->Adapter; Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred; BytesTransferred = WorkItem->BytesTransferred;
ExFreePool( WorkItem ); ExFreePool( WorkItem );
IPPacket.NdisPacket = Packet; IPPacket.NdisPacket = Packet;
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n", TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x Trans %x\n",
Packet, Adapter, BytesTransferred)); Packet, Adapter, BytesTransferred));
NdisGetFirstBufferFromPacket(Packet, NdisGetFirstBufferFromPacket(Packet,
&NdisBuffer, &NdisBuffer,
&IPPacket.Header, &IPPacket.Header,
&IPPacket.ContigSize, &IPPacket.ContigSize,
&IPPacket.TotalSize); &IPPacket.TotalSize);
IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
/* Determine which upper layer protocol that should receive /* Determine which upper layer protocol that should receive
this packet and pass it to the correct receive handler */ this packet and pass it to the correct receive handler */
TI_DbgPrint(MID_TRACE, TI_DbgPrint(MID_TRACE,
("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
IPPacket.ContigSize, IPPacket.TotalSize, IPPacket.ContigSize, IPPacket.TotalSize,
BytesTransferred)); BytesTransferred));
IPPacket.Position = 0; IPPacket.Position = 0;
IPReceive(Loopback, &IPPacket); IPReceive(Loopback, &IPPacket);
FreeNdisPacket( Packet ); FreeNdisPacket( Packet );
}
TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n"));
LoopReceiveWorkerBusy = FALSE;
} }
VOID LoopSubmitReceiveWork( VOID LoopSubmitReceiveWork(
@ -80,19 +84,34 @@ VOID LoopSubmitReceiveWork(
UINT BytesTransferred) { UINT BytesTransferred) {
PLAN_WQ_ITEM WQItem; PLAN_WQ_ITEM WQItem;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
KIRQL OldIrql;
TcpipAcquireSpinLock( &LoopWorkLock, &OldIrql );
WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
if( !WQItem ) return; if( !WQItem ) {
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
return;
}
WQItem->Packet = Packet; WQItem->Packet = Packet;
WQItem->Adapter = Adapter; WQItem->Adapter = Adapter;
WQItem->BytesTransferred = BytesTransferred; WQItem->BytesTransferred = BytesTransferred;
ExInterlockedInsertTailList( &LoopWorkList, &WQItem->ListEntry, &LoopWorkLock ); InsertTailList( &LoopWorkList, &WQItem->ListEntry );
TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n", TI_DbgPrint(DEBUG_DATALINK, ("Packet %x Adapter %x BytesTrans %x\n",
Packet, Adapter, BytesTransferred)); Packet, Adapter, BytesTransferred));
ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue ); if( !LoopReceiveWorkerBusy ) {
LoopReceiveWorkerBusy = TRUE;
ExQueueWorkItem( &LoopWorkItem, CriticalWorkQueue );
TI_DbgPrint(DEBUG_DATALINK,
("Work item inserted %x %x\n", &LoopWorkItem, WQItem));
} else {
TI_DbgPrint(DEBUG_DATALINK,
("LOOP WORKER BUSY %x %x\n", &LoopWorkItem, WQItem));
}
TcpipReleaseSpinLock( &LoopWorkLock, OldIrql );
} }
VOID LoopTransmit( VOID LoopTransmit(

View file

@ -216,7 +216,13 @@ NTSTATUS SendFragments(
return NDIS_STATUS_FAILURE; return NDIS_STATUS_FAILURE;
} }
return IPSendFragment(IFC->NdisPacket, NCE, IFC); if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC))))
{
FreeNdisPacket(IFC->NdisPacket);
ExFreePool(IFC);
}
return NdisStatus;
} }
NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE, NTSTATUS IPSendDatagram(PIP_PACKET IPPacket, PNEIGHBOR_CACHE_ENTRY NCE,

View file

@ -230,7 +230,11 @@ NTSTATUS RawIPSendDatagram(
TI_DbgPrint(MID_TRACE,("About to send datagram\n")); TI_DbgPrint(MID_TRACE,("About to send datagram\n"));
IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ); if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
return Status;
}
TI_DbgPrint(MID_TRACE,("Leaving\n")); TI_DbgPrint(MID_TRACE,("Leaving\n"));

View file

@ -102,7 +102,11 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) {
Packet.SrcAddr = LocalAddress; Packet.SrcAddr = LocalAddress;
Packet.DstAddr = RemoteAddress; Packet.DstAddr = RemoteAddress;
IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL ); if (!NT_SUCCESS(IPSendDatagram( &Packet, NCE, TCPPacketSendComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
return OSK_EINVAL;
}
return 0; return 0;
} }

View file

@ -47,8 +47,6 @@ NTSTATUS AddUDPHeaderIPv4(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return Status; return Status;
/* Build UDP header */
UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPPacket->Data - sizeof(UDP_HEADER));
/* Port values are already big-endian values */ /* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort; UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = RemotePort; UDPHeader->DestPort = RemotePort;
@ -57,8 +55,6 @@ NTSTATUS AddUDPHeaderIPv4(
/* Length of UDP header and data */ /* Length of UDP header and data */
UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER)); UDPHeader->Length = WH2N(DataLength + sizeof(UDP_HEADER));
IPPacket->Data = ((PCHAR)UDPHeader) + sizeof(UDP_HEADER);
TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n", TI_DbgPrint(MID_TRACE, ("Packet: %d ip %d udp %d payload\n",
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header, (PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader, (PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
@ -204,7 +200,11 @@ NTSTATUS UDPSendDatagram(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ); if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL )))
{
FreeNdisPacket(Packet.NdisPacket);
return Status;
}
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }