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

📄 miniport.c

📁 wince底层驱动开发代码 ARM作为一种嵌入式系统处理器
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1998	 Microsoft Corporation

Module Name:

    miniport.c

Abstract:

    This is the	main file for the CS8900 Ethernet controller.
    This driver	conforms to the	NDIS 3.0 miniport interface.

--*/

#include "precomp.h"

//
// On debug builds tell	the compiler to	keep the symbols for
// internal functions, otw throw them out.
//
#if DBG
#define	STATIC
#else
#define	STATIC static
#endif

//
// Debugging definitions
//
#if DBG

//
// Default debug mode
//
ULONG Cs8900DebugFlag =	
		       CS8900_DEBUG_LOUD
		       | CS8900_DEBUG_VERY_LOUD
		       // | CS8900_DEBUG_LOG
		       // | CS8900_DEBUG_CHECK_DUP_SENDS
		       // | CS8900_DEBUG_TRACK_PACKET_LENS
		       // | CS8900_DEBUG_WORKAROUND1
		       // | CS8900_DEBUG_CARD_BAD
		       // | CS8900_DEBUG_CARD_TESTS 
		       ;

//
// Debug tracing defintions
//
#define	CS8900_LOG_SIZE	256
UCHAR Cs8900LogBuffer[CS8900_LOG_SIZE]={0};
UINT Cs8900LogLoc = 0;

extern
VOID
Cs8900Log(UCHAR	c) {

    Cs8900LogBuffer[Cs8900LogLoc++] = c;

	Cs8900LogBuffer[(Cs8900LogLoc +	4) % CS8900_LOG_SIZE] =	'\0';

	if (Cs8900LogLoc >= CS8900_LOG_SIZE)
		Cs8900LogLoc = 0;
}

#endif

volatile unsigned char*	ioPacketPage;
volatile struct	gpioreg	*gpioRegs;
volatile unsigned long *v_pBlank, *v_pPort2;
volatile PLONG		v_pGpioRegs, v_pIcRegs;

//
// This	constant is used for places where NdisAllocateMemory
// needs to be called and the HighestAcceptableAddress does
// not matter.
//
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
    NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);

//
// The global Miniport driver block.
//

DRIVER_BLOCK CS8900MiniportBlock={0};

//
// List	of supported OID for this driver.
//
STATIC UINT CS8900SupportedOids[] = {
    OID_GEN_SUPPORTED_LIST,
    OID_GEN_HARDWARE_STATUS,
    OID_GEN_MEDIA_SUPPORTED,
    OID_GEN_MEDIA_IN_USE,
    OID_GEN_MAXIMUM_LOOKAHEAD,
    OID_GEN_MAXIMUM_FRAME_SIZE,
    OID_GEN_MAXIMUM_TOTAL_SIZE,
    OID_GEN_MAC_OPTIONS,
    OID_GEN_PROTOCOL_OPTIONS,
    OID_GEN_LINK_SPEED,
    OID_GEN_TRANSMIT_BUFFER_SPACE,
    OID_GEN_RECEIVE_BUFFER_SPACE,
    OID_GEN_TRANSMIT_BLOCK_SIZE,
    OID_GEN_RECEIVE_BLOCK_SIZE,
    OID_GEN_VENDOR_DESCRIPTION,
    OID_GEN_VENDOR_ID,
    OID_GEN_DRIVER_VERSION,
    OID_GEN_CURRENT_PACKET_FILTER,
    OID_GEN_CURRENT_LOOKAHEAD,
    OID_GEN_XMIT_OK,
    OID_GEN_RCV_OK,
    OID_GEN_XMIT_ERROR,
    OID_GEN_RCV_ERROR,
    OID_GEN_RCV_NO_BUFFER,
    OID_802_3_PERMANENT_ADDRESS,
    OID_802_3_CURRENT_ADDRESS,
    OID_802_3_MULTICAST_LIST,
    OID_802_3_MAXIMUM_LIST_SIZE,
    OID_802_3_RCV_ERROR_ALIGNMENT,
    OID_802_3_XMIT_ONE_COLLISION,
    OID_802_3_XMIT_MORE_COLLISIONS,
    
    OID_GEN_MEDIA_CONNECT_STATUS,
    OID_GEN_MAXIMUM_SEND_PACKETS,
    OID_GEN_VENDOR_DRIVER_VERSION,
    };

//
// Determines whether failing the initial card test will prevent
// the adapter from being registered.
//
#ifdef CARD_TEST

BOOLEAN	InitialCardTest	= TRUE;

#else  // CARD_TEST

BOOLEAN	InitialCardTest	= FALSE;

#endif // CARD_TEST

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    );

#pragma	NDIS_INIT_FUNCTION(DriverEntry)


NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine	Description:

    This is the	primary	initialization routine for the CS8900 driver.
    It is simply responsible for the intializing the wrapper and registering
    the	Miniport driver.  It then calls	a system and architecture specific
    routine that will initialize and register each adapter.

Arguments:

    DriverObject - Pointer to driver object created by the system.

    RegistryPath - Path	to the parameters for this driver in the registry.

Return Value:

    The	status of the operation.

--*/

{
    //
    // Receives	the status of the NdisMRegisterMiniport	operation.
    //
    NDIS_STATUS	Status;

    //
    // Characteristics table for this driver.
    //
    NDIS_MINIPORT_CHARACTERISTICS CS8900Char;

    //
    // Pointer to the global information for this driver
    //
    PDRIVER_BLOCK NewDriver = &CS8900MiniportBlock;

    //
    // Handle for referring to the wrapper about this driver.
    //
    NDIS_HANDLE	NdisWrapperHandle;

    DEBUGMSG(1, (TEXT("+CS8900:DriverEntry\r\n")));
    
    RETAILMSG(1, (TEXT("+CS8900:DriverEntry\r\n")));
    
    //
    // Initialize the wrapper.
    //
    NdisMInitializeWrapper(
		&NdisWrapperHandle,
		DriverObject,
		RegistryPath,
		NULL
		);

    //
    // Save the	global information about this driver.
    //
    NewDriver->NdisWrapperHandle = NdisWrapperHandle;
    NewDriver->AdapterQueue = (PCS8900_ADAPTER)NULL;

    //
    // Initialize the Miniport characteristics for the call to
    // NdisMRegisterMiniport.
    //
    memset(&CS8900Char,0,sizeof(CS8900Char));
    CS8900Char.MajorNdisVersion	= CS8900_NDIS_MAJOR_VERSION;
    CS8900Char.MinorNdisVersion	= CS8900_NDIS_MINOR_VERSION;
    CS8900Char.CheckForHangHandler = NULL;
    CS8900Char.DisableInterruptHandler = CS8900DisableInterrupt;
    CS8900Char.EnableInterruptHandler =	CS8900EnableInterrupt;
    CS8900Char.HaltHandler = CS8900Halt;
    CS8900Char.HandleInterruptHandler =	CS8900HandleInterrupt;
    CS8900Char.InitializeHandler = MiniportInitialize;
    CS8900Char.ISRHandler = CS8900Isr;
    CS8900Char.QueryInformationHandler = CS8900QueryInformation;
    CS8900Char.ReconfigureHandler = NULL;
    CS8900Char.ResetHandler = CS8900Reset;
    CS8900Char.SendHandler = CS8900Send;
    CS8900Char.SetInformationHandler = CS8900SetInformation;
    CS8900Char.TransferDataHandler = CS8900TransferData;

    DEBUGMSG(1, (TEXT("CS8900:	-> NdisMRegisterMiniport\r\n")));

    Status = NdisMRegisterMiniport(
		 NdisWrapperHandle,
		 &CS8900Char,
		 sizeof(CS8900Char)
		 );

    if (Status == NDIS_STATUS_SUCCESS)
    {
		DEBUGMSG(1,
				 (TEXT("-CS8900:DriverEntry: Success!\r\n")));
		return STATUS_SUCCESS;
    }

	// Terminate the wrapper.
	NdisTerminateWrapper (CS8900MiniportBlock.NdisWrapperHandle, NULL);
	CS8900MiniportBlock.NdisWrapperHandle =	NULL;

    DEBUGMSG(1, (TEXT("-CS8900:DriverEntry: Fail!\r\n")));
    return STATUS_UNSUCCESSFUL;
}


#pragma	NDIS_PAGEABLE_FUNCTION(MiniportInitialize)
extern
NDIS_STATUS
MiniportInitialize(
    OUT	PNDIS_STATUS OpenErrorStatus,
    OUT	PUINT SelectedMediumIndex,
    IN PNDIS_MEDIUM MediumArray,
    IN UINT MediumArraySize,
    IN NDIS_HANDLE MiniportAdapterHandle,
    IN NDIS_HANDLE ConfigurationHandle
    )

/*++

Routine	Description:

    CS8900Initialize starts an adapter and registers resources with the
    wrapper.

Arguments:

    OpenErrorStatus - Extra status bytes for opening token ring	adapters.

    SelectedMediumIndex	- Index	of the media type chosen by the	driver.

    MediumArray	- Array	of media types for the driver to chose from.

    MediumArraySize - Number of	entries	in the array.

    MiniportAdapterHandle - Handle for passing to the wrapper when
       referring to this adapter.

    ConfigurationHandle	- A handle to pass to NdisOpenConfiguration.

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING

--*/

{
    //
    // Pointer to our newly allocated adapter.
    //
    PCS8900_ADAPTER Adapter;

    //
    // The handle for reading from the registry.
    //
    NDIS_HANDLE	ConfigHandle;

    //
    // The value read from the registry.
    //
    PNDIS_CONFIGURATION_PARAMETER ReturnedValue;

    //
    // String names of all the parameters that will be read.
    //
    NDIS_STRING	IOAddressStr = IOADDRESS;
    NDIS_STRING	InterruptStr = INTERRUPT;
    NDIS_STRING	MaxMulticastListStr = MAX_MULTICAST_LIST;
    NDIS_STRING	NetworkAddressStr = NETWORK_ADDRESS;
    NDIS_STRING	BusTypeStr = NDIS_STRING_CONST("BusType");
    NDIS_STRING	CardTypeStr = NDIS_STRING_CONST("CardType");

    //
    // TRUE if there is	a configuration	error.
    //
    BOOLEAN ConfigError	= FALSE;

    //
    // A special value to log concerning the error.
    //
    ULONG ConfigErrorValue = 0;

    //
    // The slot	number the adapter is located in, used for
    // Microchannel adapters.
    //
    UINT SlotNumber = 0;

    //
    // TRUE if it is unnecessary to read the Io	Base Address
    // and Interrupt from the registry.	 Used for Microchannel
    // adapters, which get this	information from the slot
    // information.
    //
    BOOLEAN SkipIobaseAndInterrupt = FALSE;

    //
    // The network address the adapter should use instead of the
    // the default burned in address.
    //
    PVOID NetAddress;

    //
    // The number of bytes in the address.  It should be
    // CS8900_LENGTH_OF_ADDRESS
    //
    ULONG Length;

    //
    // These are used when calling CS8900RegisterAdapter.
    //

    //
    // The physical address of the base	I/O port.
    //
    PVOID IoBaseAddr;

    //
    // The interrupt number to use.
    //
    CCHAR InterruptNumber;

    //
    // The number of multicast address to be supported.
    //
    UINT MaxMulticastList;

    //
    // Temporary looping variable.
    //
    ULONG i;

    //
    // Status of Ndis calls.
    //
    NDIS_STATUS	Status;

//    NDIS_MCA_POS_DATA	McaData;

	DEBUGMSG(1, (TEXT("+CS8900:CS8900Initialize\r\n")));

    //
    // Search for the medium type (802.3) in the given array.
    //
    for	(i = 0;	i < MediumArraySize; i++)
    {
		if (MediumArray[i] == NdisMedium802_3)
		{
		    break;
		}
    }

    if (i == MediumArraySize)
    {
		DEBUGMSG(1, (TEXT("CS8900: No Supported Media!\r\n")));
		return(	NDIS_STATUS_UNSUPPORTED_MEDIA );
    }

    *SelectedMediumIndex = i;

    //
    // Set default values.
    //
    IoBaseAddr = DEFAULT_IOBASEADDR;
    InterruptNumber = DEFAULT_INTERRUPTNUMBER;
    MaxMulticastList = DEFAULT_MULTICASTLISTMAX;

    //
    // Allocate	memory for the adapter block now.
    //
    Status = NdisAllocateMemory( (PVOID	*)&Adapter,
		   sizeof(CS8900_ADAPTER),
		   0,
		   HighestAcceptableMax
		   );

    if (Status != NDIS_STATUS_SUCCESS)
    {
		DEBUGMSG(1,
	    	(TEXT("CS8900: NdisAllocateMemory(CS8900_ADAPTER) Fail!\r\n")));
		return Status;
    }

    //
    // Clear out the adapter block, which sets all default values to FALSE,
    // or NULL.
    //
    NdisZeroMemory (Adapter, sizeof(CS8900_ADAPTER));

    //
    // Open the	configuration space.
    //
    NdisOpenConfiguration(
	    &Status,
	    &ConfigHandle,
	    ConfigurationHandle
	    );

    if (Status != NDIS_STATUS_SUCCESS)
    {
		NdisFreeMemory(Adapter,	sizeof(CS8900_ADAPTER),	0);

		DEBUGMSG(1,
	 	   (TEXT("CS8900: NdisOpenconfiguration Fail! - 0x%x\n"),
	 	   Status));
		return Status;
    }

    //
    //	Read in	the card type.
    //
    NdisReadConfiguration(
	    &Status,
	    &ReturnedValue,
	    ConfigHandle,
	    &CardTypeStr,
	    NdisParameterHexInteger
	    );
	    
    if (Status == NDIS_STATUS_SUCCESS)
		Adapter->CardType = (UINT)ReturnedValue->ParameterData.IntegerData;

	//
	// Read net	address
	//
    NdisReadNetworkAddress(
		&Status,
		&NetAddress,
		&Length,
		ConfigHandle
		);

    if ((Length	== CS8900_LENGTH_OF_ADDRESS) &&
		(Status	== NDIS_STATUS_SUCCESS)) {

		//
		// Save	the address that should	be used.
		//
		NdisMoveMemory(
			Adapter->StationAddress,
			NetAddress,
			CS8900_LENGTH_OF_ADDRESS
			);

   	}

    //
    // Read Bus	Type (for NE2/AE2 support)
    //
    NdisReadConfiguration(
	   	&Status,
	    &ReturnedValue,
	    ConfigHandle,
		&BusTypeStr,
		NdisParameterHexInteger
		);

	if (Status == NDIS_STATUS_SUCCESS) {
		Adapter->BusType = (UCHAR)ReturnedValue->ParameterData.IntegerData;
	}

	if (!SkipIobaseAndInterrupt)
	{
		//
		// Read	I/O Address
		//
		NdisReadConfiguration(
			&Status,
			&ReturnedValue,
			ConfigHandle,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -