Author: cgutman Date: Thu Dec 1 23:04:22 2011 New Revision: 54558
URL: http://svn.reactos.org/svn/reactos?rev=54558&view=rev Log: [NDIS] - Call FreeCommonBuffer() synchronously if we're running at PASSIVE_LEVEL to avoid cases where the miniport could be freed before the work item runs
Modified: trunk/reactos/drivers/network/ndis/ndis/memory.c
Modified: trunk/reactos/drivers/network/ndis/ndis/memory.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/ndis/ndis/m... ============================================================================== --- trunk/reactos/drivers/network/ndis/ndis/memory.c [iso-8859-1] (original) +++ trunk/reactos/drivers/network/ndis/ndis/memory.c [iso-8859-1] Thu Dec 1 23:04:22 2011 @@ -239,10 +239,32 @@ { PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle; PMINIPORT_SHARED_MEMORY Memory; + PDMA_ADAPTER DmaAdapter = Adapter->NdisMiniportBlock.SystemAdapterObject;
NDIS_DbgPrint(MAX_TRACE,("Called.\n"));
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL); + + /* Call FreeCommonBuffer synchronously if we are at PASSIVE_LEVEL */ + if (KeGetCurrentIrql() == PASSIVE_LEVEL) + { + /* We need this case because we free shared memory asynchronously + * and the miniport (and DMA adapter object) could be freed before + * our work item executes. Lucky for us, the scenarios where the + * freeing needs to be synchronous (failed init, MiniportHalt, + * and driver unload) are all at PASSIVE_LEVEL so we can just + * call FreeCommonBuffer synchronously and not have to worry + * about the miniport falling out from under us */ + + NDIS_DbgPrint(MID_TRACE,("Freeing shared memory synchronously\n")); + + DmaAdapter->DmaOperations->FreeCommonBuffer(DmaAdapter, + Length, + PhysicalAddress, + VirtualAddress, + Cached); + return; + }
/* Must be NonpagedPool because by definition we're at DISPATCH_LEVEL */ Memory = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_SHARED_MEMORY));