⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndisdevice.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ---------------------------------------------------------------------------
          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 + -