📄 miniport.c
字号:
#include "precomp.h"
#if DBG
#define STATIC
#else
#define STATIC static
#endif
#if DBG
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
;
#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;
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
DRIVER_BLOCK CS8900MiniportBlock={0};
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,
};
#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
);
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NDIS_STATUS Status;
NDIS_MINIPORT_CHARACTERISTICS CS8900Char;
PDRIVER_BLOCK NewDriver = &CS8900MiniportBlock;
NDIS_HANDLE NdisWrapperHandle;
DEBUGMSG(1, (TEXT("+CS8900:DriverEntry\r\n")));
RETAILMSG(1, (TEXT("+CS8900:DriverEntry\r\n")));
/*Basic function 1:
*notify the NDIS library that the driver is about to register itself as a miniport driver
*which return NdisWrapperHandle for driver call Ndisxxx later
*/
NdisMInitializeWrapper(
&NdisWrapperHandle,
DriverObject,
RegistryPath,
NULL
);
NewDriver->NdisWrapperHandle = NdisWrapperHandle;
NewDriver->AdapterQueue = (PCS8900_ADAPTER)NULL;
/*Basic function 2:
*fill NDIS_MINIPORT_CHARACTERISTICS for NdisMRegisterMiniport
*/
// memset(&CS8900Char,0,sizeof(CS8900Char));
NdisZeroMemory(&CS8900Char,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")));
/*Basic function 3:
*call NdisMRegisterMiniport ,which will run MiniportInitialize
*/
Status = NdisMRegisterMiniport(
NdisWrapperHandle,
&CS8900Char,
sizeof(CS8900Char)
);
if (Status == NDIS_STATUS_SUCCESS)
{
DEBUGMSG(1,
(TEXT("-CS8900:DriverEntry: Success!\r\n")));
return STATUS_SUCCESS;
}
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
)
{
PCS8900_ADAPTER Adapter;
NDIS_HANDLE ConfigHandle;
PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
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");
BOOLEAN ConfigError = FALSE;
ULONG ConfigErrorValue = 0;
UINT SlotNumber = 0;
BOOLEAN SkipIobaseAndInterrupt = FALSE;
PVOID NetAddress;
ULONG Length;
PVOID IoBaseAddr;
CCHAR InterruptNumber;
UINT MaxMulticastList;
ULONG i;
NDIS_STATUS Status;
DEBUGMSG(1, (TEXT("+CS8900:CS8900Initialize\r\n")));
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;
IoBaseAddr = DEFAULT_IOBASEADDR; /*0x0300 */
InterruptNumber = DEFAULT_INTERRUPTNUMBER; /*3 */
MaxMulticastList = DEFAULT_MULTICASTLISTMAX;/*8 */
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;
}
NdisZeroMemory (Adapter, sizeof(CS8900_ADAPTER));
/*open configuration for read */
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;
}
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&CardTypeStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS)
Adapter->CardType = (UINT)ReturnedValue->ParameterData.IntegerData;
NdisReadNetworkAddress(
&Status,
&NetAddress,
&Length,
ConfigHandle
);
if ((Length == CS8900_LENGTH_OF_ADDRESS) &&
(Status == NDIS_STATUS_SUCCESS)) {
NdisMoveMemory(
Adapter->StationAddress,
NetAddress,
CS8900_LENGTH_OF_ADDRESS
);
}
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&BusTypeStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
Adapter->BusType = (UCHAR)ReturnedValue->ParameterData.IntegerData;
}
if (!SkipIobaseAndInterrupt)
{
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&IOAddressStr,
NdisParameterHexInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
IoBaseAddr = (PVOID)(ReturnedValue->ParameterData.IntegerData);
}
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&InterruptStr,
NdisParameterInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
InterruptNumber = (CCHAR)(ReturnedValue->ParameterData.IntegerData);
}
}
NdisReadConfiguration(
&Status,
&ReturnedValue,
ConfigHandle,
&MaxMulticastListStr,
NdisParameterInteger
);
if (Status == NDIS_STATUS_SUCCESS) {
MaxMulticastList = ReturnedValue->ParameterData.IntegerData;
if (ReturnedValue->ParameterData.IntegerData <= DEFAULT_MULTICASTLISTMAX)
MaxMulticastList = ReturnedValue->ParameterData.IntegerData;
}
NdisCloseConfiguration(ConfigHandle);
DEBUGMSG(1, (TEXT("CS8900:Card type: 0x%x\r\n"), Adapter->CardType));
DEBUGMSG(1, (TEXT("CS8900:I/O base addr 0x%lx\r\n"), IoBaseAddr));
DEBUGMSG(1, (TEXT("CS8900:interrupt number %ld\r\n"),
InterruptNumber));
DEBUGMSG(1, (TEXT("CS8900:max multicast %ld\r\n"),
DEFAULT_MULTICASTLISTMAX));
DEBUGMSG(1, (TEXT("CS8900:attribute memory address 0x%X\r\n"),
Adapter->AttributeMemoryAddress));
DEBUGMSG(1, (TEXT("CS8900:attribute memory size 0x%X\r\n"),
Adapter->AttributeMemorySize));
DEBUGMSG(1, (TEXT("CS8900:Bus type: %d\r\n"), Adapter->BusType));
/*Setup Adapter */
Adapter->IoBaseAddr = IoBaseAddr;
Adapter->InterruptNumber = InterruptNumber;
Adapter->MulticastListMax = MaxMulticastList;
Adapter->MiniportAdapterHandle = MiniportAdapterHandle;
Adapter->MaxLookAhead = CS8900_MAX_LOOKAHEAD;
/*RegisterAdaptr */
if (CS8900RegisterAdapter(Adapter,
ConfigurationHandle,
ConfigError,
ConfigErrorValue
) != NDIS_STATUS_SUCCESS) {
NdisFreeMemory(Adapter, sizeof(CS8900_ADAPTER), 0);
return NDIS_STATUS_FAILURE;
}
DEBUGMSG(1, (TEXT("-CS8900:CS8900Initialize Success!\r\n")));
return NDIS_STATUS_SUCCESS;
}
#pragma NDIS_PAGEABLE_FUNCTION(CS8900RegisterAdapter)
NDIS_STATUS
CS8900RegisterAdapter(
IN PCS8900_ADAPTER Adapter,
IN NDIS_HANDLE ConfigurationHandle,
IN BOOLEAN ConfigError,
IN ULONG ConfigErrorValue
)
{
unsigned char *m_pCS8900IoPort;
NDIS_STATUS status;
DEBUGMSG(1, (TEXT("+CS8900:CS8900RegisterAdapter\r\n")));
if (ConfigError)
{
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
1,
ConfigErrorValue
);
DEBUGMSG(1,
(TEXT("CS8900:RegisterAdapter: CS8900Initialize had a config error %d\r\n"),
ConfigErrorValue));
return(NDIS_STATUS_FAILURE);
}
DEBUGMSG(1, (TEXT("CS8900: -> NdisMSetAttributes\r\n")));
NdisMSetAttributes(
Adapter->MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
FALSE,
Adapter->BusType
);
/*Alloc 4k virtual space for cs8900's PacketPage,don't alloc actual mem*/
m_pCS8900IoPort = VirtualAlloc(0, 0x1000, MEM_RESERVE, PAGE_NOACCESS);
DEBUGMSG(1,
(TEXT("[CS8900] VirtualAlloc of m_pCS8900IoPort returns %x\r\n"), m_pCS8900IoPort));
/*map IO_PACKET_PAGE_BASE_ADDR&0xfffff000 to the virtual space */
if (!VirtualCopy(m_pCS8900IoPort, (LPVOID)((IO_PACKET_PAGE_BASE_ADDR) & 0xFFFFF000),
0x1000, PAGE_READWRITE|PAGE_NOCACHE) )
DEBUGMSG(1, (TEXT("[CS8900] m_pCS8900IoPort Virtual Copy failed\r\n")));
else
DEBUGMSG(1, (TEXT("[CS8900] m_pCS8900IoPort Virtual Copy OK!\r\n")));
/*ioPacketPage =0xA7000000 +0x0300 */
ioPacketPage = (volatile unsigned char *)(m_pCS8900IoPort +
(IO_PACKET_PAGE_BASE_ADDR - ((IO_PACKET_PAGE_BASE_ADDR) & 0xFFFFF000)) );
Adapter->IoPAddr = (unsigned long)ioPacketPage;
DEBUGMSG(1, (TEXT("[CS8900] m_pCS8900IoPort= %x\r\n"), Adapter->IoPAddr));
DEBUGMSG(1,
(TEXT("CS8900: -> NdisMRegisterIoPortRange\r\n")));
/*Regisetr I/O port */
status = NdisMRegisterIoPortRange(
(PVOID *)(&(Adapter->IoPAddr)),
Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20
);
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(1,
(TEXT("CS8900:NdisMRegisterIoPortRange unsuccessful!\r\n")));
return(status);
}
if (Adapter->IoPAddr == 0)
{
DEBUGMSG(1, (TEXT("CS8900:Invalid IoPAddr!\r\n")));
return NDIS_STATUS_FAILURE;
}
DEBUGMSG(1, (TEXT("+CS8900:CS8900Initialize\r\n")));
/*Initialize */
if (!CS8900Initialize(Adapter))
{
DEBUGMSG(1, (TEXT("-CS8900:CS8900Initialize - Fail!\r\n")));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0
);
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto fail2;
}
DEBUGMSG(1, (TEXT("-CS8900:CS8900Initialize - Success!\r\n")));
/*Read EthernetAddress */
if (!CS8900ReadEthernetAddress(Adapter))
{
DEBUGMSG(1, (TEXT("CS8900:RegisterAdapter Could not read the ethernet address\n")));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0
);
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto fail2;
}
/*Register Interruptehandler */
status = NdisMRegisterInterrupt(
&Adapter->Interrupt,
Adapter->MiniportAdapterHandle,
Adapter->InterruptNumber,
Adapter->InterruptNumber,
TRUE,
FALSE,
NdisInterruptLatched
);
if (status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(1, (TEXT("CS8900:RegisterAdapter -> NdisMRegisterInterrupt failed 0x%x\r\n"), status));
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_INTERRUPT_CONNECT,
0
);
goto fail3;
}
DEBUGMSG(1,
(TEXT("CS8900:RegisterAdapter Interrupt Connected\r\n")));
// register a shutdown handler for this card
NdisMRegisterAdapterShutdownHandler(
Adapter->MiniportAdapterHandle, // miniport handle.
Adapter, // shutdown context.
CS8900Shutdown // shutdown handler.
);
/* Initialize The Interrupt */
DEBUGMSG(1, (TEXT("CS8900RegisterAdapter:Initialize the Interrupt!\r\n")));
//
// Initialization completed successfully.
//
DEBUGMSG(1, (TEXT("CS8900:RegisterAdapter OK\r\n")));
return(NDIS_STATUS_SUCCESS);
//
// Code to unwind what has already been set up when a part of
// initialization fails, which is jumped into at various
// points based on where the failure occured. Jumping to
// a higher-numbered failure point will execute the code
// for that block and all lower-numbered ones.
//
fail3:
//
// Take us out of the AdapterQueue.
//
if (CS8900MiniportBlock.AdapterQueue == Adapter)
{
CS8900MiniportBlock.AdapterQueue = Adapter->NextAdapter;
}
else
{
PCS8900_ADAPTER TmpAdapter = CS8900MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != Adapter)
{
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
fail2:
NdisMDeregisterIoPortRange(
Adapter->MiniportAdapterHandle,
(ULONG)Adapter->IoBaseAddr,
0x20,
(PVOID)Adapter->IoPAddr
);
return(status);
}
extern
VOID
CS8900Shutdown(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
CS8900Shutdown is called to shut down the adapter. We need to unblock any
threads which may be called in, and terminate any loops. This function is
called by the WinCE NDIS.DLL when a PCMCIA card removal is detected. At that
point, any access to the CS8900 registers may return random data, as the bus
is floating.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from CS8900Initialize; actually as pointer to an CS8900_ADAPTER.
Return Value:
None.
--*/
{
PCS8900_ADAPTER Adapter;
Adapter = PCS8900_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
Adapter->ShuttingDown = TRUE;
DEBUGMSG(1, (TEXT("+CS8900:CS8900Shutdown - Not Implemented!\r\n")));
}
extern
VOID
CS8900Halt(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
CS8900Halt removes an adapter that was previously initialized.
Arguments:
MiniportAdapterContext - The context value that the Miniport returned
from CS8900Initialize; actually as pointer to an CS8900_ADAPTER.
Return Value:
None.
--*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -