windows-nt/Source/XPSP1/NT/net/ndis/sys/config.c

335 lines
9.2 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1990-1995 Microsoft Corporation
Module Name:
config.c
Abstract:
NDIS wrapper functions for full mac drivers configuration/initialization
Author:
Sean Selitrennikoff (SeanSe) 05-Oct-93
Jameel Hyder (JameelH) 01-Jun-95 Re-organization/optimization
Environment:
Kernel mode, FSD
Revision History:
--*/
#include <precomp.h>
#include <stdarg.h>
//
// Define the module number for debug code.
//
#define MODULE_NUMBER MODULE_CONFIG
//
// Requests Used by MAC Drivers
//
//
VOID
NdisInitializeWrapper(
OUT PNDIS_HANDLE NdisWrapperHandle,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3
)
/*++
Routine Description:
Called at the beginning of every MAC's initialization routine.
Arguments:
NdisWrapperHandle - A MAC specific handle for the wrapper.
SystemSpecific1, a pointer to the driver object for the MAC.
SystemSpecific2, a PUNICODE_STRING containing the location of
the registry subtree for this driver.
SystemSpecific3, unused on NT.
Return Value:
None.
--*/
{
NDIS_STATUS Status;
PNDIS_WRAPPER_HANDLE WrapperHandle;
ULONG cbSize;
UNREFERENCED_PARAMETER (SystemSpecific3);
#if TRACK_UNLOAD
DbgPrint("NdisInitializeWrapper: DriverObject %p\n",SystemSpecific1);
#endif
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("==>NdisInitializeWrapper\n"));
*NdisWrapperHandle = NULL;
cbSize = sizeof(NDIS_WRAPPER_HANDLE) + ((PUNICODE_STRING)SystemSpecific2)->Length + sizeof(WCHAR);
WrapperHandle = (PNDIS_WRAPPER_HANDLE)ALLOC_FROM_POOL(cbSize, NDIS_TAG_WRAPPER_HANDLE);
if (WrapperHandle != NULL)
{
*NdisWrapperHandle = WrapperHandle;
NdisZeroMemory(WrapperHandle, cbSize);
WrapperHandle->DriverObject = (PDRIVER_OBJECT)SystemSpecific1;
WrapperHandle->ServiceRegPath.Buffer = (PWSTR)((PUCHAR)WrapperHandle + sizeof(NDIS_WRAPPER_HANDLE));
WrapperHandle->ServiceRegPath.Length = ((PUNICODE_STRING)SystemSpecific2)->Length;
WrapperHandle->ServiceRegPath.MaximumLength = WrapperHandle->ServiceRegPath.Length + sizeof(WCHAR);
NdisMoveMemory(WrapperHandle->ServiceRegPath.Buffer,
((PUNICODE_STRING)SystemSpecific2)->Buffer,
WrapperHandle->ServiceRegPath.Length);
}
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("<==NdisInitializeWrapper\n"));
}
VOID
NdisTerminateWrapper(
IN NDIS_HANDLE NdisWrapperHandle,
IN PVOID SystemSpecific
)
/*++
Routine Description:
Called at the end of every MAC's termination routine.
Arguments:
NdisWrapperHandle - The handle returned from NdisInitializeWrapper.
SystemSpecific - No defined value.
Return Value:
None.
--*/
{
PNDIS_WRAPPER_HANDLE WrapperHandle = (PNDIS_WRAPPER_HANDLE)NdisWrapperHandle;
PNDIS_M_DRIVER_BLOCK MiniBlock;
#if TRACK_UNLOAD
DbgPrint("NdisTerminateWrapper: WrapperHandle %p\n",WrapperHandle);
#endif
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("==>NdisTerminateWrapper: NdisWrapperHandle %p\n", NdisWrapperHandle));
UNREFERENCED_PARAMETER(SystemSpecific);
if ((WrapperHandle != NULL) && (WrapperHandle->DriverObject != NULL))
{
#if TRACK_UNLOAD
DbgPrint("NdisTerminateWrapper: DriverObject %p\n",WrapperHandle->DriverObject);
#endif
MiniBlock = (PNDIS_M_DRIVER_BLOCK)IoGetDriverObjectExtension(WrapperHandle->DriverObject,
(PVOID)NDIS_PNP_MINIPORT_DRIVER_ID);
if (MiniBlock != NULL)
{
#if TRACK_UNLOAD
DbgPrint("NdisTerminateWrapper: MiniBlock %p\n",MiniBlock);
#endif
MiniBlock->Flags |= fMINIBLOCK_RECEIVED_TERMINATE_WRAPPER;
//
// Miniports should not be terminating the wrapper unless they are failing DriverEntry
//
if ((MiniBlock->MiniportQueue != NULL) || (MiniBlock->Flags & fMINIBLOCK_UNLOADING))
{
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("<==NdisTerminateWrapper\n"));
return;
}
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("NdisTerminateWrapper: MiniBlock %p\n", MiniBlock));
//
// if the driver is going to fail DriverEntry, we expect it to have enough sense
// to undo what it is done so far and not to wait for UnloadHandler
//
MiniBlock->UnloadHandler = NULL;
MiniBlock->Flags |= fMINIBLOCK_TERMINATE_WRAPPER_UNLOAD;
//
// call unload entry point since PnP is not going to do it
//
ndisMUnload(WrapperHandle->DriverObject);
}
else
{
FREE_POOL(WrapperHandle);
}
}
DBGPRINT_RAW(DBG_COMP_INIT, DBG_LEVEL_INFO,
("<==NdisTerminateWrapper\n"));
}
VOID
NdisSetupDmaTransfer(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice
)
/*++
Routine Description:
Sets up the host DMA controller for a DMA transfer. The
DMA controller is set up to transfer the specified MDL.
Since we register all DMA channels as non-scatter/gather,
IoMapTransfer will ensure that the entire MDL is
in a single logical piece for transfer.
Arguments:
Status - Returns the status of the request.
NdisDmaHandle - Handle returned by NdisAllocateDmaChannel.
Buffer - An NDIS_BUFFER which describes the host memory involved in the
transfer.
Offset - An offset within buffer where the transfer should
start.
Length - The length of the transfer. VirtualAddress plus Length must not
extend beyond the end of the buffer.
WriteToDevice - TRUE for a download operation (host to adapter); FALSE
for an upload operation (adapter to host).
Return Value:
None.
--*/
{
PNDIS_DMA_BLOCK DmaBlock = (PNDIS_DMA_BLOCK)NdisDmaHandle;
PMAP_TRANSFER mapTransfer = *((PDMA_ADAPTER)DmaBlock->SystemAdapterObject)->DmaOperations->MapTransfer;
PFLUSH_ADAPTER_BUFFERS flushAdapterBuffers = *((PDMA_ADAPTER)DmaBlock->SystemAdapterObject)->DmaOperations->FlushAdapterBuffers;
ULONG LengthMapped;
//
// Make sure another request is not in progress.
//
if (DmaBlock->InProgress)
{
*Status = NDIS_STATUS_RESOURCES;
return;
}
DmaBlock->InProgress = TRUE;
//
// Use IoMapTransfer to set up the transfer.
//
LengthMapped = Length;
mapTransfer(DmaBlock->SystemAdapterObject,
(PMDL)Buffer,
DmaBlock->MapRegisterBase,
(PUCHAR)(MDL_VA(Buffer)) + Offset,
&LengthMapped,
WriteToDevice);
if (LengthMapped != Length)
{
//
// Somehow the request could not be mapped competely,
// this should not happen for a non-scatter/gather adapter.
//
flushAdapterBuffers(DmaBlock->SystemAdapterObject,
(PMDL)Buffer,
DmaBlock->MapRegisterBase,
(PUCHAR)(MDL_VA(Buffer)) + Offset,
LengthMapped,
WriteToDevice);
DmaBlock->InProgress = FALSE;
*Status = NDIS_STATUS_RESOURCES;
}
else *Status = NDIS_STATUS_SUCCESS;
}
VOID
NdisCompleteDmaTransfer(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE NdisDmaHandle,
IN PNDIS_BUFFER Buffer,
IN ULONG Offset,
IN ULONG Length,
IN BOOLEAN WriteToDevice
)
/*++
Routine Description:
Completes a previously started DMA transfer.
Arguments:
Status - Returns the status of the transfer.
NdisDmaHandle - Handle returned by NdisAllocateDmaChannel.
Buffer - An NDIS_BUFFER which was passed to NdisSetupDmaTransfer.
Offset - the offset passed to NdisSetupDmaTransfer.
Length - The length passed to NdisSetupDmaTransfer.
WriteToDevice - TRUE for a download operation (host to adapter); FALSE
for an upload operation (adapter to host).
Return Value:
None.
--*/
{
PNDIS_DMA_BLOCK DmaBlock = (PNDIS_DMA_BLOCK)NdisDmaHandle;
PFLUSH_ADAPTER_BUFFERS flushAdapterBuffers = *((PDMA_ADAPTER)DmaBlock->SystemAdapterObject)->DmaOperations->FlushAdapterBuffers;
BOOLEAN Successful;
Successful = flushAdapterBuffers(DmaBlock->SystemAdapterObject,
(PMDL)Buffer,
DmaBlock->MapRegisterBase,
(PUCHAR)(MDL_VA(Buffer)) + Offset,
Length,
WriteToDevice);
*Status = (Successful ? NDIS_STATUS_SUCCESS : NDIS_STATUS_RESOURCES);
DmaBlock->InProgress = FALSE;
}
#pragma hdrstop