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/net…
==============================================================================
--- 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/net…
==============================================================================
--- 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/net…
==============================================================================
--- 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;
}