📄 ndisdevice.c
字号:
/* ---------------------------------------------------------------------------
Copyright (c) 2003-2006 Micrel, Inc. All rights reserved.
---------------------------------------------------------------------------
NdisDevice.c - NDIS driver device functions.
Author Date Description
THa 12/01/03 Created file.
THa 06/27/05 Updated for version 0.1.5.
THa 08/16/05 Added PCI configuration I/O.
THa 09/29/05 Changed descriptor structure.
THa 02/23/06 Updated for WinCE 5.0.
THa 04/13/06 Add EEPROM access support.
THa 06/02/06 Report statistics from MIB counters.
THa 07/27/06 Version 1.4 supports NDIS 5.
---------------------------------------------------------------------------
*/
#include "target.h"
#include "NdisDevice.h"
PHARDWARE phw;
/* -------------------------------------------------------------------------- */
/*
GetConfigEntryUlong
Description:
This function retrieves a double-word value from the registry.
Parameters:
NDIS_HANDLE hRegistry
Handle to registry key.
NDIS_STRING* EntryString
Pointer to NDIS string indicating the registry value.
PULONG pulValue
Buffer to store the value.
Return (BOOLEAN):
TRUE if successful; otherwise FALSE.
*/
BOOLEAN GetConfigEntryUlong (
NDIS_HANDLE hRegistry,
NDIS_STRING* EntryString,
PULONG pulValue )
{
PNDIS_CONFIGURATION_PARAMETER pReturnedValue;
NDIS_STATUS nsStatus;
NDIS_PARAMETER_TYPE parameter = NdisParameterHexInteger;
NdisReadConfiguration( &nsStatus, &pReturnedValue, hRegistry, EntryString,
parameter );
if ( NDIS_STATUS_SUCCESS == nsStatus )
{
*pulValue = pReturnedValue->ParameterData.IntegerData;
return TRUE;
}
return FALSE;
} // GetConfigEntryUlong
/*
GetConfigEntryUshort
Description:
This function retrieves a word value from the registry.
Parameters:
NDIS_HANDLE hRegistry
Handle to registry key.
NDIS_STRING* EntryString
Pointer to NDIS string indicating the registry value.
PUSHORT pusValue
Buffer to store the value.
Return (BOOLEAN):
TRUE if successful; otherwise FALSE.
*/
BOOLEAN GetConfigEntryUshort (
NDIS_HANDLE hRegistry,
NDIS_STRING* EntryString,
PUSHORT pusValue )
{
PNDIS_CONFIGURATION_PARAMETER pReturnedValue;
NDIS_STATUS nsStatus;
NDIS_PARAMETER_TYPE parameter = NdisParameterHexInteger;
NdisReadConfiguration( &nsStatus, &pReturnedValue, hRegistry, EntryString,
parameter );
if ( NDIS_STATUS_SUCCESS == nsStatus )
{
*pusValue = ( USHORT ) pReturnedValue->ParameterData.IntegerData;
return TRUE;
}
return FALSE;
} // GetConfigEntryUshort
/*
GetConfigEntryUchar
Description:
This function retrieves a byte value from the registry.
Parameters:
NDIS_HANDLE hRegistry
Handle to registry key.
NDIS_STRING* EntryString
Pointer to NDIS string indicating the registry value.
PUCHAR pbValue
Buffer to store the value.
Return (BOOLEAN):
TRUE if successful; otherwise FALSE.
*/
BOOLEAN GetConfigEntryUchar (
NDIS_HANDLE hRegistry,
NDIS_STRING* EntryString,
PUCHAR pbValue )
{
PNDIS_CONFIGURATION_PARAMETER pReturnedValue;
NDIS_STATUS nsStatus;
NDIS_PARAMETER_TYPE parameter = NdisParameterHexInteger;
NdisReadConfiguration( &nsStatus, &pReturnedValue, hRegistry, EntryString,
parameter );
if ( NDIS_STATUS_SUCCESS == nsStatus )
{
*pbValue = ( UCHAR ) pReturnedValue->ParameterData.IntegerData;
return TRUE;
}
return FALSE;
} // GetConfigEntryUchar
/*
GetConfigEntryString
Description:
This function retrieves a string value from the registry.
Parameters:
NDIS_HANDLE hRegistry
Handle to registry key.
NDIS_STRING* EntryString
Pointer to NDIS string indicating the registry value.
PCHAR szValue
Buffer to store the string value.
USHORT wLength
The length of the buffer.
Return (int):
The length of the string.
*/
int GetConfigEntryString (
NDIS_HANDLE hRegistry,
NDIS_STRING* EntryString,
PCHAR szValue,
USHORT wLength )
{
PNDIS_CONFIGURATION_PARAMETER pReturnedValue;
NDIS_STATUS nsStatus;
ANSI_STRING anszString;
anszString.MaximumLength = wLength;
anszString.Buffer = szValue;
NdisReadConfiguration( &nsStatus, &pReturnedValue, hRegistry, EntryString,
NdisParameterString );
if ( NDIS_STATUS_SUCCESS == nsStatus )
{
NdisUnicodeStringToAnsiString( &anszString,
&pReturnedValue->ParameterData.StringData );
return( anszString.Length );
}
return( 0 );
} // GetConfigEntryString
/* -------------------------------------------------------------------------- */
#define nszcBusType NDIS_STRING_CONST( "BusType" )
#define nszcIoBaseAddress NDIS_STRING_CONST( "IoBaseAddress" )
#define nszcInterruptNumber NDIS_STRING_CONST( "InterruptNumber" )
#define nszcIoBaseLength NDIS_STRING_CONST( "IoLen" )
#define nszcMemoryAddress NDIS_STRING_CONST( "MemoryBaseAddress" )
#define nszcMemorySize NDIS_STRING_CONST( "MemorySize" )
#define nszcSlotNumber NDIS_STRING_CONST( "SlotNumber" )
#define DEFAULT_IO_BASE_ADDRESS 0x300
#define DEFAULT_IO_BASE_LENGTH 0x10
#define DEFAULT_MEMORY_SIZE 0x1000
#define DEFAULT_MEMORY_WINDOW 0xd4000
#define DEFAULT_INTERRUPT_NUMBER 3
#define MAX_IOBASEADDR 0xFFFFFFFF
#define MIN_IOBASEADDR 0x0100
#define MAX_IRQ 15
#define MIN_IRQ 2
/*
GetResources
Description:
This function gets adapter resources from the operating system and the
registry.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
NDIS_HANDLE hConfiguration
Handle to adapter configuration.
NDIS_HANDLE hRegistry
Handle to registry key.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
NDIS_STATUS GetResources (
PNDIS_ADAPTER pAdapter,
IN NDIS_HANDLE hConfiguration,
IN NDIS_HANDLE hRegistry )
{
UCHAR bBuffer[ sizeof( NDIS_RESOURCE_LIST ) +
( sizeof( CM_PARTIAL_RESOURCE_DESCRIPTOR ) * 10 )];
PNDIS_RESOURCE_LIST pResource = ( PNDIS_RESOURCE_LIST ) bBuffer;
UINT uiBufferSize = sizeof( bBuffer );
NDIS_STATUS nsStatus;
ULONG ulIndex;
int NextIo = 0;
PHARDWARE pHardware = &pAdapter->m_Hardware;
NDIS_STRING nszSlotNumber = nszcSlotNumber;
NdisMQueryAdapterResources( &nsStatus, hConfiguration, pResource,
&uiBufferSize );
if ( NDIS_STATUS_SUCCESS == nsStatus )
{
#if 0
// Assume Windows 9X
pAdapter->ucOSEnvironment = WIN9X;
// if NdisMQueryAdapterResources returns success check the OS environment
NdisReadConfiguration ( &nsStatus,
&pncpReturnValue,
hRegistryHandle,
&nsEnvironment,
NdisParameterInteger);
if (nsStatus == NDIS_STATUS_SUCCESS)
// NT = NdisEnvironmentWindowsNt, 95 = NdisEnvironmentWindows.
if (NdisEnvironmentWindowsNt == (UINT) pncpReturnValue->ParameterData.IntegerData)
// must be Win2k
pAdapter->ucOSEnvironment = WIN2K;
#endif
}
else
{
#if 0
// if NdisMQueryAdapterResources returns fail the OS is WinNT
pAdapter->ucOSEnvironment = WINNT40;
#endif
}
pAdapter->m_ulSlot = 0;
GetConfigEntryUlong( hRegistry, &nszSlotNumber,
&pAdapter->m_ulSlot );
#if DBG
DbgPrint( " slot: %d"NEWLINE, pAdapter->m_ulSlot );
#endif
NdisReadPciSlotInformation( pAdapter->m_hAdapter, pAdapter->m_ulSlot, CFIT,
&pAdapter->m_ulInterruptVector, sizeof( UCHAR ));
#if DBG
DbgPrint( " vect: %d"NEWLINE, pAdapter->m_ulInterruptVector );
#endif
if ( pResource )
{
// Parse the NDIS_RESOURCE_LIST (CM_PARTIAL_RESOURCE_LIST/
// CM_PARTIAL_RESOURCE_DESCRIPTOR).
for ( ulIndex = 0; ulIndex < pResource->Count; ulIndex++ )
{
// We handle 3 types of resources: I/O port, interrupt, and
// memory base. Ignore all others.
switch ( pResource->PartialDescriptors[ ulIndex ].Type )
{
case CmResourceTypePort:
pAdapter->m_ulIOBaseAddress = ( ULONG )
pResource->PartialDescriptors[ ulIndex ].u.Port.
Start.u.LowPart;
pAdapter->m_ulIOLength =
pResource->PartialDescriptors[ ulIndex ].u.Port.
Length;
#ifdef DBG
DbgPrint( " io: %x, %x"NEWLINE, pAdapter->m_ulIOBaseAddress,
pAdapter->m_ulIOLength );
#endif
break;
case CmResourceTypeInterrupt:
pAdapter->m_ulInterruptNumber =
pResource->PartialDescriptors[ ulIndex ].u.Interrupt.
Vector;
#ifdef DBG
DbgPrint( " intr: %d"NEWLINE, pAdapter->m_ulInterruptNumber );
#endif
break;
case CmResourceTypeMemory:
pAdapter->m_ulMemoryAddress = ( ULONG )
pResource->PartialDescriptors[ ulIndex ].u.Memory.
Start.u.LowPart;
pAdapter->m_ulMemorySize =
pResource->PartialDescriptors[ ulIndex ].u.Memory.
Length;
#ifdef DBG
DbgPrint( " mem: %x, %x"NEWLINE, pAdapter->m_ulMemoryAddress,
pAdapter->m_ulMemorySize );
#endif
break;
}
}
}
else
{
NDIS_STRING nszIoBaseAddress = nszcIoBaseAddress;
NDIS_STRING nszIoBaseLength = nszcIoBaseLength;
NDIS_STRING nszInterruptNumber = nszcInterruptNumber;
NDIS_STRING nszMemoryAddress = nszcMemoryAddress;
NDIS_STRING nszMemorySize = nszcMemorySize;
pAdapter->m_ulIOBaseAddress = DEFAULT_IO_BASE_ADDRESS;
GetConfigEntryUlong( hRegistry, &nszIoBaseAddress,
&pAdapter->m_ulIOBaseAddress );
if ( pAdapter->m_ulIOBaseAddress < MIN_IOBASEADDR ||
pAdapter->m_ulIOBaseAddress > MAX_IOBASEADDR )
{
NdisWriteErrorLogEntry( pAdapter->m_hAdapter,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, 1,
pAdapter->m_ulIOBaseAddress );
return( NDIS_STATUS_FAILURE );
}
pAdapter->m_ulIOLength = DEFAULT_IO_BASE_LENGTH;
GetConfigEntryUlong( hRegistry, &nszIoBaseLength,
&pAdapter->m_ulIOLength );
pAdapter->m_ulInterruptNumber = DEFAULT_INTERRUPT_NUMBER;
GetConfigEntryUlong( hRegistry, &nszInterruptNumber,
&pAdapter->m_ulInterruptNumber );
if ( pAdapter->m_ulInterruptNumber < MIN_IRQ ||
pAdapter->m_ulInterruptNumber > MAX_IRQ )
{
NdisWriteErrorLogEntry( pAdapter->m_hAdapter,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, 1,
pAdapter->m_ulInterruptNumber );
return( NDIS_STATUS_FAILURE );
}
pAdapter->m_ulMemoryAddress = DEFAULT_MEMORY_WINDOW;
GetConfigEntryUlong( hRegistry, &nszMemoryAddress,
&pAdapter->m_ulMemoryAddress );
pAdapter->m_ulMemorySize = DEFAULT_MEMORY_SIZE;
GetConfigEntryUlong( hRegistry, &nszMemorySize,
&pAdapter->m_ulMemorySize );
}
return NDIS_STATUS_SUCCESS;
} // GetResources
/*
ReadConfiguration
Description:
This function gets configuration for the adapter from the operating
system and the registry.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
NDIS_HANDLE hConfiguration
Handle to adapter configuration.
Return (NDIS_STATUS):
NDIS_STATUS_SUCCESS if successful; otherwise an error code indicating
failure.
*/
NDIS_STATUS ReadConfiguration (
PNDIS_ADAPTER pAdapter,
IN NDIS_HANDLE hConfiguration )
{
// Handle for reading from registry.
NDIS_HANDLE hRegistry;
NDIS_STATUS nsStatus;
BOOLEAN bStatus;
PHARDWARE pHardware = &pAdapter->m_Hardware;
NDIS_STRING nszBusType = nszcBusType;
// Open the configuration space.
NdisOpenConfiguration( &nsStatus, &hRegistry, hConfiguration );
if ( nsStatus != NDIS_STATUS_SUCCESS )
{
NdisWriteErrorLogEntry( pAdapter->m_hAdapter,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, 0 );
return( nsStatus );
}
// get bus type
pAdapter->m_BusType = NdisInterfacePci;
bStatus = GetConfigEntryUlong( hRegistry, &nszBusType,
( PULONG ) &pAdapter->m_BusType );
#ifdef DBG
if ( !bStatus )
DbgPrint( " def" );
DbgPrint( " bustype: %x"NEWLINE, pAdapter->m_BusType );
#endif
#if 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -