- 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"
/* Define this to bugcheck on double complete */
/* #define BREAK_ON_DOUBLE_COMPLETE */
UINT TransferDataCalled = 0;
UINT TransferDataCompleteCalled = 0;
UINT LanReceiveWorkerCalled = 0;
@ -51,54 +48,6 @@ BOOLEAN ProtocolRegistered = FALSE;
LIST_ENTRY AdapterListHead;
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(
PLAN_ADAPTER Adapter,
NDIS_REQUEST_TYPE Type,
@ -283,13 +232,11 @@ VOID NTAPI ProtocolSendComplete(
*/
{
TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
if( LanShouldComplete( (PLAN_ADAPTER)BindingContext, Packet ) ) {
ASSERT_KM_POINTER(Packet);
ASSERT_KM_POINTER(PC(Packet));
ASSERT_KM_POINTER(PC(Packet)->DLComplete);
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
}
ASSERT_KM_POINTER(Packet);
ASSERT_KM_POINTER(PC(Packet));
ASSERT_KM_POINTER(PC(Packet)->DLComplete);
(*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
}
VOID LanReceiveWorker( PVOID Context ) {
@ -646,8 +593,6 @@ VOID LANTransmit(
* not needed immediately */
GetDataPtr( NdisPacket, 0, &Data, &Size );
LanChainCompletion( Adapter, NdisPacket );
switch (Adapter->Media) {
case NdisMedium802_3:
EHeader = (PETH_HEADER)Data;
@ -1046,6 +991,7 @@ BOOLEAN BindAdapter(
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
IPUnregisterInterface(IF);
IPDestroyInterface(IF);
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 */

View file

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

View file

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

View file

@ -216,7 +216,13 @@ NTSTATUS SendFragments(
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,

View file

@ -230,7 +230,11 @@ NTSTATUS RawIPSendDatagram(
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"));

View file

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

View file

@ -47,8 +47,6 @@ NTSTATUS AddUDPHeaderIPv4(
if (!NT_SUCCESS(Status))
return Status;
/* Build UDP header */
UDPHeader = (PUDP_HEADER)((ULONG_PTR)IPPacket->Data - sizeof(UDP_HEADER));
/* Port values are already big-endian values */
UDPHeader->SourcePort = LocalPort;
UDPHeader->DestPort = RemotePort;
@ -57,8 +55,6 @@ NTSTATUS AddUDPHeaderIPv4(
/* Length of UDP header and data */
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",
(PCHAR)UDPHeader - (PCHAR)IPPacket->Header,
(PCHAR)IPPacket->Data - (PCHAR)UDPHeader,
@ -204,7 +200,11 @@ NTSTATUS UDPSendDatagram(
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;
}