📄 miniport.c
字号:
/*++
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 + -