Author: cgutman Date: Fri Jan 8 20:15:03 2010 New Revision: 45009
URL: http://svn.reactos.org/svn/reactos?rev=45009&view=rev Log: - Rewrite request queuing - We now use the documented members of NDIS_MINIPORT_BLOCK - It also fixes the issue of determining if the miniport is currently processing a request - Remove unneeded IRQL raises - Half-plement MiniSendResourcesAvailable (NdisMSendResourcesAvailable) - Comment out the code inside ProSendPackets (only used by protocols, not miniports)
Modified: branches/aicom-network-branch/drivers/network/ndis/include/miniport.h branches/aicom-network-branch/drivers/network/ndis/ndis/miniport.c branches/aicom-network-branch/drivers/network/ndis/ndis/protocol.c
Modified: branches/aicom-network-branch/drivers/network/ndis/include/miniport.h URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-branch/drivers/net... ============================================================================== --- branches/aicom-network-branch/drivers/network/ndis/include/miniport.h [iso-8859-1] (original) +++ branches/aicom-network-branch/drivers/network/ndis/include/miniport.h [iso-8859-1] Fri Jan 8 20:15:03 2010 @@ -90,8 +90,6 @@ typedef struct _LOGICAL_ADAPTER { NDIS_MINIPORT_BLOCK NdisMiniportBlock; /* NDIS defined fields */ - PNDIS_MINIPORT_WORK_ITEM WorkQueueHead; /* Head of work queue */ - PNDIS_MINIPORT_WORK_ITEM WorkQueueTail; /* Tail of work queue */ LIST_ENTRY ListEntry; /* Entry on global list */ LIST_ENTRY MiniportListEntry; /* Entry on miniport driver list */ LIST_ENTRY ProtocolListHead; /* List of bound protocols */ @@ -142,20 +140,22 @@ PVOID Buffer, PULONG BytesWritten);
-VOID -FASTCALL -MiniQueueWorkItem( +NDIS_STATUS +MiniBeginRequest( PLOGICAL_ADAPTER Adapter, NDIS_WORK_ITEM_TYPE WorkItemType, - PVOID WorkItemContext, - BOOLEAN Top); - -NDIS_STATUS -FASTCALL -MiniDequeueWorkItem( - PLOGICAL_ADAPTER Adapter, - NDIS_WORK_ITEM_TYPE *WorkItemType, - PVOID *WorkItemContext); + PVOID WorkItemContext); + +NDIS_STATUS +MiniQueueWorkItemHead( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE WorkItemType, + PVOID WorkItemContext); + +VOID +MiniEndRequest( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE WorkItemType);
NDIS_STATUS MiniDoRequest(
Modified: branches/aicom-network-branch/drivers/network/ndis/ndis/miniport.c URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-branch/drivers/net... ============================================================================== --- branches/aicom-network-branch/drivers/network/ndis/ndis/miniport.c [iso-8859-1] (original) +++ branches/aicom-network-branch/drivers/network/ndis/ndis/miniport.c [iso-8859-1] Fri Jan 8 20:15:03 2010 @@ -121,55 +121,6 @@ #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( @@ -316,6 +267,7 @@ if (!LookAheadBuffer) { NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate lookahead buffer!\n")); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); return; }
@@ -357,6 +309,8 @@ PADAPTER_BINDING AdapterBinding; KIRQL OldIrql;
+ MiniEndRequest(Adapter, NdisWorkItemResetRequested); + if (AddressingReset) MiniDoAddressingReset(Adapter);
@@ -364,8 +318,6 @@ NdisMIndicateStatusComplete(Adapter);
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - - Adapter->NdisMiniportBlock.ResetStatus = Status;
CurrentEntry = Adapter->ProtocolListHead.Flink;
@@ -395,11 +347,11 @@
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); Request = Adapter->NdisMiniportBlock.PendingRequest; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + MiniEndRequest(Adapter, NdisWorkItemRequest);
MacBlock = (PNDIS_REQUEST_MAC_BLOCK)Request->MacReserved;
@@ -409,12 +361,22 @@ Request, Status); } - - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->NdisMiniportBlock.PendingRequest = NULL; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - - KeLowerIrql(OldIrql); +} + +VOID NTAPI +MiniIndicateComplete( + IN NDIS_HANDLE MiniportAdapterHandle, + IN PNDIS_PACKET Packet, + IN NDIS_STATUS Status) +{ + PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1]; + + MiniEndRequest(MiniportAdapterHandle, NdisWorkItemSendLoopback); + + (*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)( + AdapterBinding->NdisOpenBlock.ProtocolBindingContext, + Packet, + Status); }
VOID NTAPI @@ -440,14 +402,14 @@
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1];
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0) { NDIS_DbgPrint(MAX_TRACE, ("Freeing Scatter/Gather list\n"));
SGList = NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo); + + KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
Adapter->NdisMiniportBlock.SystemAdapterObject-> DmaOperations->PutScatterGatherList( @@ -455,28 +417,42 @@ SGList, TRUE);
+ KeLowerIrql(OldIrql); + NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, ScatterGatherListPacketInfo) = NULL; } + + MiniEndRequest(Adapter, NdisWorkItemSend);
(*AdapterBinding->ProtocolBinding->Chars.SendCompleteHandler)( AdapterBinding->NdisOpenBlock.ProtocolBindingContext, Packet, Status); - - KeLowerIrql(OldIrql); -} - +} + +NDIS_STATUS +SignalQueue(PLOGICAL_ADAPTER Adapter) +{ + PIO_WORKITEM WorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); + + ASSERT(WorkItem); + if (!WorkItem) return NDIS_STATUS_RESOURCES; + + IoQueueWorkItem(WorkItem, + MiniportWorker, + DelayedWorkQueue, + WorkItem); + + return NDIS_STATUS_SUCCESS; +}
VOID NTAPI MiniSendResourcesAvailable( IN NDIS_HANDLE MiniportAdapterHandle) { -/* - UNIMPLEMENTED -*/ -} - + SignalQueue(MiniportAdapterHandle); +}
VOID NTAPI MiniTransferDataComplete( @@ -486,19 +462,16 @@ IN UINT BytesTransferred) { PADAPTER_BINDING AdapterBinding; - KIRQL OldIrql;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[1];
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); (*AdapterBinding->ProtocolBinding->Chars.TransferDataCompleteHandler)( AdapterBinding->NdisOpenBlock.ProtocolBindingContext, Packet, Status, BytesTransferred); - KeLowerIrql(OldIrql); }
@@ -597,12 +570,6 @@ ASSERT(AdapterName);
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n")); - - if(IsListEmpty(&AdapterListHead)) - { - NDIS_DbgPrint(MIN_TRACE, ("No registered miniports for protocol to bind to\n")); - return NULL; - }
KeAcquireSpinLock(&AdapterListLock, &OldIrql); { @@ -667,9 +634,15 @@ NdisRequest->DATA.SET_INFORMATION.InformationBuffer = Buffer; NdisRequest->DATA.SET_INFORMATION.InformationBufferLength = Size;
+ NdisStatus = MiniBeginRequest(Adapter, NdisWorkItemRequest, NdisRequest); + if (!NT_SUCCESS(NdisStatus)) + return NdisStatus; + NdisStatus = MiniDoRequest(Adapter, NdisRequest);
/* FIXME: Wait in pending case! */ + if (NdisStatus != NDIS_STATUS_PENDING) + MiniEndRequest(Adapter, NdisWorkItemRequest);
ASSERT(NdisStatus != NDIS_STATUS_PENDING);
@@ -717,9 +690,15 @@ NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer = Buffer; NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength = Size;
+ NdisStatus = MiniBeginRequest(Adapter, NdisWorkItemRequest, NdisRequest); + if (!NT_SUCCESS(NdisStatus)) + return NdisStatus; + NdisStatus = MiniDoRequest(Adapter, NdisRequest);
/* FIXME: Wait in pending case! */ + if (NdisStatus != NDIS_STATUS_PENDING) + MiniEndRequest(Adapter, NdisWorkItemRequest);
ASSERT(NdisStatus != NDIS_STATUS_PENDING);
@@ -742,13 +721,10 @@ */ { BOOLEAN Ret = FALSE; - KIRQL OldIrql; - - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + if (Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CheckForHangHandler) Ret = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CheckForHangHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext); - KeLowerIrql(OldIrql);
return Ret; } @@ -779,31 +755,24 @@ */ { NDIS_STATUS Status; - KIRQL OldIrql; BOOLEAN AddressingReset = TRUE;
- if (MiniIsBusy(Adapter, NdisWorkItemResetRequested)) { - MiniQueueWorkItem(Adapter, NdisWorkItemResetRequested, NULL, FALSE); - return NDIS_STATUS_PENDING; - } + Status = MiniBeginRequest(Adapter, NdisWorkItemResetRequested, NULL); + if (!NT_SUCCESS(Status)) + return Status;
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); NdisMIndicateStatusComplete(Adapter);
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); 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) { if (AddressingReset) MiniDoAddressingReset(Adapter); + + MiniEndRequest(Adapter, NdisWorkItemResetRequested);
NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_END, NULL, 0); NdisMIndicateStatusComplete(Adapter); @@ -827,78 +796,45 @@ } }
- -VOID -FASTCALL -MiniQueueWorkItem( +NDIS_STATUS +MiniBeginRequest( PLOGICAL_ADAPTER Adapter, NDIS_WORK_ITEM_TYPE WorkItemType, - PVOID WorkItemContext, - BOOLEAN Top) -/* - * FUNCTION: Queues a work item for execution at a later time - * ARGUMENTS: - * Adapter = Pointer to the logical adapter object to queue work item on - * WorkItemType = Type of work item to queue - * WorkItemContext = Pointer to context information for work item - * RETURNS: - * Status of operation - */ -{ + PVOID WorkItemContext) +{ + KIRQL OldIrql; + BOOLEAN QueueBusy; PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; - PIO_WORKITEM IoWorkItem; - KIRQL OldIrql; - - NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); - - ASSERT(Adapter); + PSINGLE_LIST_ENTRY CurrentEntry;
KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - if (Top) - { - if (WorkItemType == NdisWorkItemSend) - { - NDIS_DbgPrint(MIN_TRACE, ("Requeuing failed packet (%x).\n", WorkItemContext)); - Adapter->NdisMiniportBlock.FirstPendingPacket = WorkItemContext; - } - else - { - //This should never happen - ASSERT(FALSE); - } - } - else - { - MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); - if (!MiniportWorkItem) - { - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - return; - } - - MiniportWorkItem->WorkItemType = WorkItemType; - MiniportWorkItem->WorkItemContext = WorkItemContext; - - /* safe due to adapter lock held */ - MiniportWorkItem->Link.Next = NULL; - if (!Adapter->WorkQueueHead) - { - Adapter->WorkQueueHead = MiniportWorkItem; - Adapter->WorkQueueTail = MiniportWorkItem; - } - else - { - Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem; - Adapter->WorkQueueTail = MiniportWorkItem; - } - } - - IoWorkItem = IoAllocateWorkItem(Adapter->NdisMiniportBlock.DeviceObject); - if (IoWorkItem) - IoQueueWorkItem(IoWorkItem, MiniportWorker, DelayedWorkQueue, IoWorkItem); + + QueueBusy = (Adapter->NdisMiniportBlock.WorkQueue[WorkItemType].Next != NULL); + + MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); + if (!MiniportWorkItem) + { + NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + return NDIS_STATUS_RESOURCES; + } + + MiniportWorkItem->WorkItemType = WorkItemType; + MiniportWorkItem->WorkItemContext = WorkItemContext; + MiniportWorkItem->Link.Next = NULL; + + CurrentEntry = &Adapter->NdisMiniportBlock.WorkQueue[WorkItemType]; + while (CurrentEntry->Next) + CurrentEntry = CurrentEntry->Next; + + CurrentEntry->Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem;
KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + if (QueueBusy) + NDIS_DbgPrint(MIN_TRACE, ("Queue %d busy!\n", WorkItemType)); + + return (QueueBusy ? NDIS_STATUS_PENDING : NDIS_STATUS_SUCCESS); }
@@ -906,7 +842,7 @@ FASTCALL MiniDequeueWorkItem( PLOGICAL_ADAPTER Adapter, - NDIS_WORK_ITEM_TYPE *WorkItemType, + NDIS_WORK_ITEM_TYPE WorkItemType, PVOID *WorkItemContext) /* * FUNCTION: Dequeues a work item from the work queue of a logical adapter @@ -922,42 +858,49 @@ */ { PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; - PNDIS_PACKET Packet; + KIRQL OldIrql;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
- MiniportWorkItem = Adapter->WorkQueueHead; - - if ((Packet = Adapter->NdisMiniportBlock.FirstPendingPacket)) - { - Adapter->NdisMiniportBlock.FirstPendingPacket = NULL; - - *WorkItemType = NdisWorkItemSend; - *WorkItemContext = Packet; + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + MiniportWorkItem = (PNDIS_MINIPORT_WORK_ITEM)Adapter->NdisMiniportBlock.WorkQueue[WorkItemType].Next; + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + if (MiniportWorkItem) + { + /* This is VERY IMPORTANT! We dequeue the work item AFTER completion */ + + *WorkItemContext = MiniportWorkItem->WorkItemContext;
return NDIS_STATUS_SUCCESS; } - else if (MiniportWorkItem) - { - /* safe due to adapter lock held */ - Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)MiniportWorkItem->Link.Next; - - if (MiniportWorkItem == Adapter->WorkQueueTail) - Adapter->WorkQueueTail = NULL; - - *WorkItemType = MiniportWorkItem->WorkItemType; - *WorkItemContext = MiniportWorkItem->WorkItemContext; - - ExFreePool(MiniportWorkItem); - - return NDIS_STATUS_SUCCESS; - } else { - NDIS_DbgPrint(MIN_TRACE, ("No work item to dequeue\n")); - return NDIS_STATUS_FAILURE; } +} + +VOID +MiniEndRequest( + PLOGICAL_ADAPTER Adapter, + NDIS_WORK_ITEM_TYPE WorkItemType) +{ + KIRQL OldIrql; + BOOLEAN QueueBusy; + PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem; + + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); + + MiniportWorkItem = (PNDIS_MINIPORT_WORK_ITEM)Adapter->NdisMiniportBlock.WorkQueue[WorkItemType].Next; + ASSERT(MiniportWorkItem); + Adapter->NdisMiniportBlock.WorkQueue[WorkItemType].Next = MiniportWorkItem->Link.Next; + ExFreePool(MiniportWorkItem); + + QueueBusy = (Adapter->NdisMiniportBlock.WorkQueue[WorkItemType].Next != NULL); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + + if (QueueBusy) + SignalQueue(Adapter); }
@@ -976,13 +919,12 @@ { NDIS_STATUS Status; KIRQL OldIrql; + NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
- KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); Adapter->NdisMiniportBlock.PendingRequest = NdisRequest; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
if (!Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.CoRequestHandler) { @@ -1021,13 +963,13 @@ NdisRequest); }
- if (Status != NDIS_STATUS_PENDING) { - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); + if (Status != NDIS_STATUS_PENDING) + { + KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); Adapter->NdisMiniportBlock.PendingRequest = NULL; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - } - - KeLowerIrql(OldIrql); + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); + } + return Status; }
@@ -1044,12 +986,10 @@ { PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; - KIRQL OldIrql; - ASSERT(Adapter); - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - if (Adapter->NdisMiniportBlock.SetCompleteHandler) - (Adapter->NdisMiniportBlock.SetCompleteHandler)(MiniportAdapterHandle, Status); - KeLowerIrql(OldIrql); + + (Adapter->NdisMiniportBlock.SetCompleteHandler)(MiniportAdapterHandle, Status); + + MiniEndRequest(Adapter, NdisWorkItemRequest); }
@@ -1065,12 +1005,10 @@ { PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; - KIRQL OldIrql; - ASSERT(Adapter); - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); - if( Adapter->NdisMiniportBlock.QueryCompleteHandler ) - (Adapter->NdisMiniportBlock.QueryCompleteHandler)(MiniportAdapterHandle, Status); - KeLowerIrql(OldIrql); + + (Adapter->NdisMiniportBlock.QueryCompleteHandler)(MiniportAdapterHandle, Status); + + MiniEndRequest(Adapter, NdisWorkItemRequest); }
VOID @@ -1078,25 +1016,20 @@ MiniportWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context) { PLOGICAL_ADAPTER Adapter = DeviceObject->DeviceExtension; - KIRQL OldIrql, RaiseOldIrql; + KIRQL RaiseOldIrql; NDIS_STATUS NdisStatus; PVOID WorkItemContext; NDIS_WORK_ITEM_TYPE WorkItemType; - BOOLEAN AddressingReset; + BOOLEAN AddressingReset, NextQueue;
IoFreeWorkItem((PIO_WORKITEM)Context);
- KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql); - - NdisStatus = - MiniDequeueWorkItem - (Adapter, &WorkItemType, &WorkItemContext); - - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); - - if (NdisStatus == NDIS_STATUS_SUCCESS) - { - switch (WorkItemType) + for (WorkItemType = 0; WorkItemType < NUMBER_OF_WORK_ITEM_TYPES; WorkItemType++) + { + NextQueue = FALSE; + while (!NextQueue && MiniDequeueWorkItem(Adapter, WorkItemType, &WorkItemContext) == NDIS_STATUS_SUCCESS) + { + switch (WorkItemType) { case NdisWorkItemSend: /* @@ -1125,7 +1058,7 @@
NdisStatus = NDIS_GET_PACKET_STATUS((PNDIS_PACKET)WorkItemContext); if( NdisStatus == NDIS_STATUS_RESOURCES ) { - MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext, TRUE); + NextQueue = TRUE; break; } } @@ -1151,7 +1084,7 @@ NDIS_DbgPrint(MAX_TRACE, ("back from miniport's send handler\n")); KeLowerIrql(RaiseOldIrql); if( NdisStatus == NDIS_STATUS_RESOURCES ) { - MiniQueueWorkItem(Adapter, WorkItemType, WorkItemContext, TRUE); + NextQueue = TRUE; break; } } @@ -1171,26 +1104,16 @@ NdisStatus = ProIndicatePacket(Adapter, (PNDIS_PACKET)WorkItemContext);
if( NdisStatus != NDIS_STATUS_PENDING ) - MiniSendComplete((NDIS_HANDLE)Adapter, (PNDIS_PACKET)WorkItemContext, NdisStatus); + MiniIndicateComplete((NDIS_HANDLE)Adapter, (PNDIS_PACKET)WorkItemContext, NdisStatus); break;
case NdisWorkItemReturnPackets: break;
case NdisWorkItemResetRequested: - NdisMIndicateStatus(Adapter, NDIS_STATUS_RESET_START, NULL, 0); - NdisMIndicateStatusComplete(Adapter); - - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); NdisStatus = (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.ResetHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext, &AddressingReset); - - KeAcquireSpinLockAtDpcLevel(&Adapter->NdisMiniportBlock.Lock); - Adapter->NdisMiniportBlock.ResetStatus = NdisStatus; - KeReleaseSpinLockFromDpcLevel(&Adapter->NdisMiniportBlock.Lock); - - KeLowerIrql(OldIrql);
if (NdisStatus != NDIS_STATUS_PENDING) MiniResetComplete(Adapter, NdisStatus, AddressingReset); @@ -1220,15 +1143,18 @@
default: NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS request type.\n")); + MiniEndRequest(Adapter, NdisWorkItemRequest); break; } break;
default: + MiniEndRequest(Adapter, WorkItemType); NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS work item type (%d).\n", WorkItemType)); break; } - } + } + } }
@@ -1337,6 +1263,7 @@ if (Adapter->NdisMiniportBlock.Log) { *LogHandle = NULL; + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); return NDIS_STATUS_FAILURE; }
@@ -1344,6 +1271,7 @@ if (!Log) { *LogHandle = NULL; + KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); return NDIS_STATUS_RESOURCES; }
@@ -2231,6 +2159,7 @@ PDEVICE_OBJECT DeviceObject; PLOGICAL_ADAPTER Adapter; NTSTATUS Status; + UINT i;
/* * Gain the access to the miniport data structure first. @@ -2353,6 +2282,9 @@
Adapter->NdisMiniportBlock.OldPnPDeviceState = 0; Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceAdded; + + for (i = 0; i < NUMBER_OF_WORK_ITEM_TYPES; i++) + Adapter->NdisMiniportBlock.WorkQueue[i].Next = NULL;
KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter);
Modified: branches/aicom-network-branch/drivers/network/ndis/ndis/protocol.c URL: http://svn.reactos.org/svn/reactos/branches/aicom-network-branch/drivers/net... ============================================================================== --- branches/aicom-network-branch/drivers/network/ndis/ndis/protocol.c [iso-8859-1] (original) +++ branches/aicom-network-branch/drivers/network/ndis/ndis/protocol.c [iso-8859-1] Fri Jan 8 20:15:03 2010 @@ -325,6 +325,7 @@ PADAPTER_BINDING AdapterBinding; PLOGICAL_ADAPTER Adapter; PNDIS_REQUEST_MAC_BLOCK MacBlock = (PNDIS_REQUEST_MAC_BLOCK)NdisRequest->MacReserved; + NDIS_STATUS Status;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
@@ -336,17 +337,15 @@
MacBlock->Binding = &AdapterBinding->NdisOpenBlock;
-#if WORKER_TEST - 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 + Status = MiniBeginRequest(Adapter, NdisWorkItemRequest, NdisRequest); + if (!NT_SUCCESS(Status)) + return Status; + + Status = MiniDoRequest(Adapter, NdisRequest); + if (Status != NDIS_STATUS_PENDING) + MiniEndRequest(Adapter, NdisWorkItemRequest); + + return Status; }
@@ -393,17 +392,12 @@ NDIS_STATUS proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet) { -#if WORKER_TEST - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); - return NDIS_STATUS_PENDING; -#else KIRQL RaiseOldIrql; NDIS_STATUS NdisStatus;
- if(MiniIsBusy(Adapter, NdisWorkItemSend)) { - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, FALSE); - return NDIS_STATUS_PENDING; - } + NdisStatus = MiniBeginRequest(Adapter, NdisWorkItemSend, Packet); + if (!NT_SUCCESS(NdisStatus)) + return NdisStatus;
if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) { @@ -425,10 +419,14 @@
NdisStatus = NDIS_GET_PACKET_STATUS(Packet); if (NdisStatus == NDIS_STATUS_RESOURCES) { - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE); + /* We don't need to add to head here because it's already guaranteed to the + the first packet in the queue */ NdisStatus = NDIS_STATUS_PENDING; } } + + if (NdisStatus != NDIS_STATUS_PENDING) + MiniEndRequest(Adapter, NdisWorkItemSend);
return NdisStatus; } else { @@ -448,14 +446,16 @@ KeLowerIrql(RaiseOldIrql);
if (NdisStatus == NDIS_STATUS_RESOURCES) { - MiniQueueWorkItem(Adapter, NdisWorkItemSend, Packet, TRUE); + /* See comment above */ NdisStatus = NDIS_STATUS_PENDING; } }
+ if (NdisStatus != NDIS_STATUS_PENDING) + MiniEndRequest(Adapter, NdisWorkItemSend); + return NdisStatus; } -#endif }
@@ -508,12 +508,7 @@ if ((Adapter->NdisMiniportBlock.MacOptions & NDIS_MAC_OPTION_NO_LOOPBACK) && MiniAdapterHasAddress(Adapter, Packet)) { -#if WORKER_TEST - MiniQueueWorkItem(Adapter, NdisWorkItemSendLoopback, Packet, FALSE); - return NDIS_STATUS_PENDING; -#else return ProIndicatePacket(Adapter, Packet); -#endif } else { if (Adapter->NdisMiniportBlock.ScatterGatherListSize != 0) { @@ -570,11 +565,14 @@ IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets) { + UNIMPLEMENTED +#if 0 PADAPTER_BINDING AdapterBinding = NdisBindingHandle; PLOGICAL_ADAPTER Adapter = AdapterBinding->Adapter; KIRQL RaiseOldIrql; NDIS_STATUS NdisStatus; UINT i; + BOOLEAN QueuePackets;
if(Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler) { @@ -590,10 +588,15 @@ (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.SendPacketsHandler)( Adapter->NdisMiniportBlock.MiniportAdapterContext, PacketArray, NumberOfPackets); KeLowerIrql(RaiseOldIrql); - for (i = 0; i < NumberOfPackets; i++) + for (i = 0, QueuePackets = FALSE; i < NumberOfPackets; i++) { NdisStatus = NDIS_GET_PACKET_STATUS(PacketArray[i]); - if (NdisStatus != NDIS_STATUS_PENDING) + if (NdisStatus == NDIS_STATUS_RESOURCES) + QueuePackets = TRUE; + + if (QueuePackets) + NdisQueueWorkItemHead(Adapter, NdisWorkItemSend, PacketArray[i]); + else MiniSendComplete(Adapter, PacketArray[i], NdisStatus); } } @@ -624,6 +627,7 @@ KeLowerIrql(RaiseOldIrql); } } +#endif }