Author: cgutman Date: Fri Nov 28 18:06:25 2008 New Revision: 37712
URL: http://svn.reactos.org/svn/reactos?rev=37712&view=rev Log: - Fix queuing request and reset work items - Fix a problem that could result in packets being sent in the wrong order
Modified: branches/aicom-network-fixes/drivers/network/ndis/include/miniport.h branches/aicom-network-fixes/drivers/network/ndis/ndis/miniport.c branches/aicom-network-fixes/drivers/network/ndis/ndis/protocol.c
Modified: branches/aicom-network-fixes/drivers/network/ndis/include/miniport.h URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-fixes/drivers/netw... ============================================================================== --- branches/aicom-network-fixes/drivers/network/ndis/include/miniport.h [iso-8859-1] (original) +++ branches/aicom-network-fixes/drivers/network/ndis/include/miniport.h [iso-8859-1] Fri Nov 28 18:06:25 2008 @@ -169,6 +169,11 @@ IN PNDIS_PACKET Packet, IN NDIS_STATUS Status);
+BOOLEAN +MiniIsBusy( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE Type); + #endif /* __MINIPORT_H */
/* EOF */
Modified: branches/aicom-network-fixes/drivers/network/ndis/ndis/miniport.c URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-fixes/drivers/netw... ============================================================================== --- branches/aicom-network-fixes/drivers/network/ndis/ndis/miniport.c [iso-8859-1] (original) +++ branches/aicom-network-fixes/drivers/network/ndis/ndis/miniport.c [iso-8859-1] Fri Nov 28 18:06:25 2008 @@ -134,6 +134,55 @@ #endif /* DBG */ }
+PNDIS_MINIPORT_WORK_ITEM +MiniGetFirstWorkItem( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE Type) +{ + PNDIS_MINIPORT_WORK_ITEM CurrentEntry = Adapter->WorkQueueHead; + + while (CurrentEntry) + { + if (CurrentEntry->WorkItemType == Type) + return CurrentEntry; + + CurrentEntry = (PNDIS_MINIPORT_WORK_ITEM)CurrentEntry->Link.Next; + } + + return NULL; +} + +BOOLEAN +MiniIsBusy( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE Type) +{ + BOOLEAN Busy = FALSE; + KIRQL OldIrql; + + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + + if (Type == NdisWorkItemRequest && + (Adapter->NdisMiniportBlock.PendingRequest || MiniGetFirstWorkItem(Adapter, NdisWorkItemRequest))) + { + Busy = TRUE; + } + else if (Type == NdisWorkItemSend && + (Adapter->NdisMiniportBlock.FirstPendingPacket || MiniGetFirstWorkItem(Adapter, NdisWorkItemSend))) + { + Busy = TRUE; + } + else if (Type == NdisWorkItemResetRequested && + (Adapter->NdisMiniportBlock.ResetStatus == NDIS_STATUS_PENDING || MiniGetFirstWorkItem(Adapter, NdisWorkItemResetRequested))) + { + Busy = TRUE; + } + + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + return Busy; +} + VOID MiniIndicateData( @@ -274,6 +323,8 @@
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
+ Adapter->NdisMiniportBlock.ResetStatus = Status; + CurrentEntry = Adapter->ProtocolListHead.Flink;
while (CurrentEntry != &Adapter->ProtocolListHead) @@ -298,12 +349,18 @@ IN PNDIS_REQUEST Request, IN NDIS_STATUS Status) { + PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; PNDIS_REQUEST_MAC_BLOCK MacBlock = (PNDIS_REQUEST_MAC_BLOCK)Request->MacReserved; KIRQL OldIrql;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + Adapter->NdisMiniportBlock.PendingRequest = NULL; + KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + if( MacBlock->Binding->RequestCompleteHandler ) { (*MacBlock->Binding->RequestCompleteHandler)( MacBlock->Binding->ProtocolBindingContext, @@ -601,6 +658,11 @@ NDIS_STATUS Status; KIRQL OldIrql;
+ if (MiniIsBusy(Adapter, NdisWorkItemResetRequested)) { + MiniQueueWorkItem(Adapter, NdisWorkItemResetRequested, NULL, FALSE); + return NDIS_STATUS_PENDING; + } + NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); NdisMIndicateStatusComplete(Adapter);
@@ -608,6 +670,11 @@ Status = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext, AddressingReset); + + KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + Adapter->NdisMiniportBlock.ResetStatus = Status; + KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeLowerIrql(OldIrql);
if (Status != NDIS_STATUS_PENDING) { @@ -668,6 +735,7 @@ { if (WorkItemType == NdisWorkItemSend) { + NDIS_DbgPrint(MIN_TRACE, ("Requeuing failed packet (%x).\n", WorkItemContext)); Adapter->NdisMiniportBlock.FirstPendingPacket = WorkItemContext; } else @@ -786,6 +854,11 @@ NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + + KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + Adapter->NdisMiniportBlock.PendingRequest = NdisRequest; + KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + switch (NdisRequest->RequestType) { case NdisRequestQueryInformation: @@ -810,6 +883,12 @@
default: Status = NDIS_STATUS_FAILURE; + } + + if (Status != NDIS_STATUS_PENDING) { + KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + Adapter->NdisMiniportBlock.PendingRequest = NULL; + KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); }
KeLowerIrql(OldIrql); @@ -968,12 +1047,18 @@ NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext, &AddressingReset); + + if (NdisStatus == NDIS_STATUS_PENDING) + { + KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + Adapter->NdisMiniportBlock.ResetStatus = NDIS_STATUS_PENDING; + KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + } + KeLowerIrql(OldIrql);
- if (NdisStatus == NDIS_STATUS_PENDING) - break; - - MiniResetComplete(Adapter, NdisStatus, AddressingReset); + if (NdisStatus != NDIS_STATUS_PENDING) + MiniResetComplete(Adapter, NdisStatus, AddressingReset); break;
case NdisWorkItemResetInProgress: @@ -1002,6 +1087,7 @@
default: NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS request type.\n")); + MiniRequestComplete( (NDIS_HANDLE)Adapter, (PNDIS_REQUEST)WorkItemContext, NdisStatus ); break; } break;
Modified: branches/aicom-network-fixes/drivers/network/ndis/ndis/protocol.c URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-fixes/drivers/netw... ============================================================================== --- branches/aicom-network-fixes/drivers/network/ndis/ndis/protocol.c [iso-8859-1] (original) +++ branches/aicom-network-fixes/drivers/network/ndis/ndis/protocol.c [iso-8859-1] Fri Nov 28 18:06:25 2008 @@ -140,6 +140,11 @@ MiniQueueWorkItem(Adapter, NdisWorkItemRequest, NdisRequest, FALSE); return NDIS_STATUS_PENDING; #else + if (MiniIsBusy(Adapter, NdisWorkItemRequest)) { + MiniQueueWorkItem(Adapter, NdisWorkItemRequest, NdisRequest, FALSE); + return NDIS_STATUS_PENDING; + } + return MiniDoRequest(Adapter, NdisRequest); #endif } @@ -164,7 +169,7 @@ KIRQL RaiseOldIrql; NDIS_STATUS NdisStatus;
- if(Adapter->NdisMiniportBlock.FirstPendingPacket) { + if(MiniIsBusy(Adapter, NdisWorkItemSend)) { MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); return NDIS_STATUS_PENDING; }