- Queue the work item directly from MiniQueueWorkItem

- Handle an invalid SelectedMediumIndex separately
 - Cancel the hang timer before calling MiniportHalt
 - Handle a BindAdapter failure

svn path=/branches/aicom-network-fixes/; revision=36738
This commit is contained in:
Cameron Gutman 2008-10-13 00:41:48 +00:00
parent 3d33a2e976
commit 23d01c2592
2 changed files with 57 additions and 62 deletions

View file

@ -662,37 +662,52 @@ MiniQueueWorkItem(
* Status of operation * Status of operation
*/ */
{ {
PNDIS_MINIPORT_WORK_ITEM Item; PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem;
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkQueueItem;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
ASSERT(Adapter); ASSERT(Adapter);
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL); ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM)); MiniportWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM));
if (Item == NULL) if (!MiniportWorkItem)
{ {
NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES; return NDIS_STATUS_RESOURCES;
} }
Item->WorkItemType = WorkItemType; NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
Item->WorkItemContext = WorkItemContext; if (!NdisWorkItem)
{
ExFreePool(MiniportWorkItem);
return NDIS_STATUS_RESOURCES;
}
MiniportWorkItem->WorkItemType = WorkItemType;
MiniportWorkItem->WorkItemContext = WorkItemContext;
/* safe due to adapter lock held */ /* safe due to adapter lock held */
Item->Link.Next = NULL; MiniportWorkItem->Link.Next = NULL;
if (!Adapter->WorkQueueHead) if (!Adapter->WorkQueueHead)
{ {
Adapter->WorkQueueHead = Item; Adapter->WorkQueueHead = MiniportWorkItem;
Adapter->WorkQueueTail = Item; Adapter->WorkQueueTail = MiniportWorkItem;
} }
else else
{ {
Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item; Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)MiniportWorkItem;
Adapter->WorkQueueTail = Item; Adapter->WorkQueueTail = MiniportWorkItem;
} }
KeInsertQueueDpc(&Adapter->NdisMiniportBlock.DeferredDpc, NULL, NULL); WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = Adapter;
ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue);
return NDIS_STATUS_SUCCESS; return NDIS_STATUS_SUCCESS;
} }
@ -717,30 +732,38 @@ MiniDequeueWorkItem(
* Status of operation * Status of operation
*/ */
{ {
PNDIS_MINIPORT_WORK_ITEM Item; PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem;
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkQueueItem;
NDIS_DbgPrint(MAX_TRACE, ("Called.\n")); NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
if (Adapter->MiniportBusy) { if (Adapter->MiniportBusy) {
NDIS_DbgPrint(MID_TRACE, ("Waiting for miniport to become free.\n")); NDIS_DbgPrint(MID_TRACE, ("Waiting for miniport to become free.\n"));
KeInsertQueueDpc(&Adapter->NdisMiniportBlock.DeferredDpc, NULL, NULL); NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
if (!NdisWorkItem) return NDIS_STATUS_RESOURCES;
WorkQueueItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = Adapter;
ExInitializeWorkItem(WorkQueueItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkQueueItem, CriticalWorkQueue);
return NDIS_STATUS_FAILURE; return NDIS_STATUS_FAILURE;
} }
Item = Adapter->WorkQueueHead; MiniportWorkItem = Adapter->WorkQueueHead;
if (Item) if (MiniportWorkItem)
{ {
/* safe due to adapter lock held */ /* safe due to adapter lock held */
Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)Item->Link.Next; Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)MiniportWorkItem->Link.Next;
if (Item == Adapter->WorkQueueTail) if (MiniportWorkItem == Adapter->WorkQueueTail)
Adapter->WorkQueueTail = NULL; Adapter->WorkQueueTail = NULL;
*WorkItemType = Item->WorkItemType; *WorkItemType = MiniportWorkItem->WorkItemType;
*WorkItemContext = Item->WorkItemContext; *WorkItemContext = MiniportWorkItem->WorkItemContext;
ExFreePool(Item); ExFreePool(MiniportWorkItem);
Adapter->MiniportBusy = TRUE; Adapter->MiniportBusy = TRUE;
@ -998,38 +1021,6 @@ VOID NTAPI MiniportWorker(IN PVOID WorkItem)
} }
VOID NTAPI MiniportDpc(
IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
/*
* FUNCTION: Deferred routine to handle serialization
* ARGUMENTS:
* Dpc = Pointer to DPC object
* DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
* SystemArgument1 = Unused
* SystemArgument2 = Unused
*/
{
PNDIS_WORK_ITEM NdisWorkItem;
PWORK_QUEUE_ITEM WorkItem;
NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
NdisWorkItem = ExAllocatePool(NonPagedPool, sizeof(NDIS_WORK_ITEM));
if (!NdisWorkItem) return;
WorkItem = (PWORK_QUEUE_ITEM)NdisWorkItem->WrapperReserved;
NdisWorkItem->Context = DeferredContext;
ExInitializeWorkItem(WorkItem, MiniportWorker, NdisWorkItem);
ExQueueWorkItem(WorkItem, CriticalWorkQueue);
}
VOID VOID
NTAPI NTAPI
@ -1665,15 +1656,20 @@ NdisIPnPStartDevice(
ZwClose(WrapperContext.RegistryHandle); ZwClose(WrapperContext.RegistryHandle);
if (NdisStatus != NDIS_STATUS_SUCCESS || if (NdisStatus != NDIS_STATUS_SUCCESS)
SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{ {
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n")); NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter.\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock ); ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
if (NdisStatus == NDIS_STATUS_SUCCESS) NdisStatus = NDIS_STATUS_FAILURE;
return NdisStatus; return NdisStatus;
} }
if (SelectedMediumIndex >= MEDIA_ARRAY_SIZE)
{
NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed for an adapter\n"));
ExInterlockedRemoveEntryList( &Adapter->ListEntry, &AdapterListLock );
return NDIS_STATUS_UNSUPPORTED_MEDIA;
}
Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex]; Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
switch (Adapter->NdisMiniportBlock.MediaType) switch (Adapter->NdisMiniportBlock.MediaType)
@ -1762,6 +1758,8 @@ NdisIPnPStopDevice(
RemoveEntryList(&Adapter->ListEntry); RemoveEntryList(&Adapter->ListEntry);
KeReleaseSpinLock(&AdapterListLock, OldIrql); KeReleaseSpinLock(&AdapterListLock, OldIrql);
KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
(*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter); (*Adapter->NdisMiniportBlock.DriverHandle->MiniportCharacteristics.HaltHandler)(Adapter);
if (Adapter->LookaheadBuffer) if (Adapter->LookaheadBuffer)
@ -1783,8 +1781,6 @@ NdisIPnPStopDevice(
Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState; Adapter->NdisMiniportBlock.OldPnPDeviceState = Adapter->NdisMiniportBlock.PnPDeviceState;
Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped; Adapter->NdisMiniportBlock.PnPDeviceState = NdisPnPDeviceStopped;
KeCancelTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1995,7 +1991,6 @@ NdisIAddDevice(
KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer); KeInitializeTimer(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Timer);
KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter); KeInitializeDpc(&Adapter->NdisMiniportBlock.WakeUpDpcTimer.Dpc, MiniportHangDpc, Adapter);
KeInitializeDpc(&Adapter->NdisMiniportBlock.DeferredDpc, MiniportDpc, Adapter);
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

View file

@ -798,13 +798,13 @@ NdisRegisterProtocol(
/* Put protocol binding struct on global list */ /* Put protocol binding struct on global list */
ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock); ExInterlockedInsertTailList(&ProtocolListHead, &Protocol->ListEntry, &ProtocolListLock);
} }
/*
else if(*Status != NDIS_STATUS_PENDING) else if(*Status != NDIS_STATUS_PENDING)
{ {
// what to do here? ExFreePool(Protocol);
ExFreePool(KeyInformation);
*NdisProtocolHandle = NULL;
return;
} }
*/
} }
ExFreePool(KeyInformation); ExFreePool(KeyInformation);