mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
897 lines
18 KiB
897 lines
18 KiB
/*++
|
|
|
|
Copyright (c) 1990 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
Ndis 3.0 MAC driver for the 3Com Etherlink III
|
|
|
|
|
|
Author:
|
|
|
|
Brian Lieuallen (BrianLie) 12/14/92
|
|
|
|
|
|
Environment:
|
|
|
|
Kernel Mode Operating Systems : NT
|
|
|
|
Revision History:
|
|
|
|
Portions borrowed from ELNK3 driver by
|
|
Earle R. Horton (EarleH)
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
#include <ndis.h>
|
|
|
|
//#include <efilter.h>
|
|
|
|
#include "debug.h"
|
|
|
|
#include "elnk3hrd.h"
|
|
#include "elnk3sft.h"
|
|
#include "elnk3.h"
|
|
|
|
#if defined(ALLOC_PRAGMA)
|
|
#pragma NDIS_INIT_FUNCTION(DriverEntry)
|
|
#pragma NDIS_INIT_FUNCTION(Elnk3Initialize)
|
|
#pragma NDIS_INIT_FUNCTION(Elnk3InitializeAdapter)
|
|
#pragma NDIS_INIT_FUNCTION(Elnk3Init3C589)
|
|
#endif
|
|
|
|
|
|
#if DBG
|
|
|
|
ULONG Elnk3DebugFlag;
|
|
ULONG Elnk3LogArray[ELNK3_MAX_LOG_SIZE+16];
|
|
ULONG ElnkLogPointer;
|
|
|
|
#endif
|
|
|
|
MAC_BLOCK MacBlock = {0};
|
|
|
|
|
|
NTSTATUS
|
|
DriverEntry(
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
IN PUNICODE_STRING RegistryPath
|
|
)
|
|
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This is the transfer address of the driver. It initializes all the
|
|
appropriate variables used and calls NdisInitializeWrapper() and
|
|
NdisRegisterMac().
|
|
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Indicates the success or failure of the initialization.
|
|
|
|
--*/
|
|
|
|
{
|
|
NDIS_STATUS InitStatus;
|
|
NDIS_MINIPORT_CHARACTERISTICS Characteristics;
|
|
NDIS_HANDLE WrapperHandle;
|
|
|
|
|
|
|
|
#if DBG
|
|
|
|
Elnk3DebugFlag = 0;
|
|
Elnk3DebugFlag|= ELNK3_DEBUG_LOG;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_LOUD;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_VERY_LOUD;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_INIT;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_IO;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_REQ;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_RCV;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_SEND;
|
|
// Elnk3DebugFlag|= ELNK3_DEBUG_INIT_BREAK;
|
|
|
|
|
|
#endif
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: DriverEntry\n");)
|
|
#if DBG
|
|
if (Elnk3DebugFlag & ELNK3_DEBUG_INIT_BREAK) DbgBreakPoint();
|
|
if (Elnk3DebugFlag & ELNK3_DEBUG_INIT_FAIL) return STATUS_UNSUCCESSFUL;
|
|
#endif
|
|
|
|
NdisMInitializeWrapper(
|
|
&WrapperHandle,
|
|
DriverObject,
|
|
RegistryPath,
|
|
NULL
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// Prepare to call NdisRegisterMac.
|
|
//
|
|
|
|
Characteristics.MajorNdisVersion = ELNK3_NDIS_MAJOR_VERSION;
|
|
Characteristics.MinorNdisVersion = ELNK3_NDIS_MINOR_VERSION;
|
|
Characteristics.Reserved = 0;
|
|
Characteristics.CheckForHangHandler = Elnk3CheckForHang;
|
|
|
|
// Characteristics.DisableInterruptHandler = Elnk3DisableInterrupts;
|
|
// Characteristics.EnableInterruptHandler = Elnk3EnableInterrupts;
|
|
Characteristics.DisableInterruptHandler = NULL;
|
|
Characteristics.EnableInterruptHandler = NULL;
|
|
|
|
Characteristics.SendHandler = Elnk3MacSend;
|
|
Characteristics.TransferDataHandler = Elnk3TransferData;
|
|
Characteristics.ResetHandler = Elnk3Reset;
|
|
Characteristics.SetInformationHandler = Elnk3SetInformation;
|
|
Characteristics.QueryInformationHandler = Elnk3QueryInformation;
|
|
Characteristics.InitializeHandler = Elnk3Initialize;
|
|
Characteristics.HaltHandler = Elnk3Halt;
|
|
Characteristics.ISRHandler = Elnk3Isr;
|
|
Characteristics.HandleInterruptHandler = Elnk3IsrDpc;
|
|
Characteristics.ReconfigureHandler = Elnk3Reconfigure;
|
|
|
|
InitStatus=NdisMRegisterMiniport(
|
|
WrapperHandle,
|
|
&Characteristics,
|
|
sizeof(Characteristics)
|
|
);
|
|
|
|
|
|
#if DBG
|
|
|
|
if (InitStatus != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_LOUD(DbgPrint("Elnk3: NdisMRegisterMiniport failed with code 0x%x\n", InitStatus );)
|
|
|
|
} else {
|
|
|
|
IF_INIT_LOUD (DbgPrint("Elnk3: NdisMRegisterMiniport succeeded\n" );)
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return InitStatus;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3Initialize(
|
|
OUT PNDIS_STATUS OpenErrorStatus,
|
|
OUT PUINT SelectedMediumIndex,
|
|
IN PNDIS_MEDIUM MediumArray,
|
|
IN UINT MediumArraySize,
|
|
IN NDIS_HANDLE AdapterHandle,
|
|
IN NDIS_HANDLE ConfigurationHandle
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
This is the Elnk3 MacAddAdapter routine. The system calls this routine
|
|
to add support for particular UB adapter. This routine extracts
|
|
configuration information from the configuration data base and registers
|
|
the adapter with NDIS.
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
NDIS_STATUS_SUCCESS - Adapter was successfully added.
|
|
NDIS_STATUS_FAILURE - Adapter was not added
|
|
|
|
--*/
|
|
{
|
|
|
|
PELNK3_ADAPTER pAdapter;
|
|
NDIS_STATUS status;
|
|
|
|
|
|
|
|
|
|
*OpenErrorStatus=NDIS_STATUS_SUCCESS;
|
|
|
|
IF_LOUD (DbgPrint("ELNK3: Initialize\n");)
|
|
|
|
//
|
|
// Scan the media list for our media type (802.3)
|
|
//
|
|
|
|
*SelectedMediumIndex =(UINT) -1;
|
|
|
|
while (MediumArraySize > 0) {
|
|
|
|
if (MediumArray[--MediumArraySize] == NdisMedium802_3 ) {
|
|
|
|
*SelectedMediumIndex = MediumArraySize;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
if (*SelectedMediumIndex == -1) {
|
|
|
|
return NDIS_STATUS_UNSUPPORTED_MEDIA;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = NdisAllocateMemory(
|
|
(PVOID *)&pAdapter,
|
|
sizeof(ELNK3_ADAPTER),
|
|
0,
|
|
HighestAcceptableMax
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_LOUD (DbgPrint("Elnk3AddAdapter():NdisAllocateMemory() failed\n");)
|
|
|
|
return NDIS_STATUS_RESOURCES;
|
|
|
|
}
|
|
|
|
NdisZeroMemory(pAdapter,sizeof(ELNK3_ADAPTER));
|
|
|
|
pAdapter->NdisAdapterHandle=AdapterHandle;
|
|
|
|
//
|
|
// Read Registery information into Adapter structure
|
|
//
|
|
|
|
if (Elnk3ReadRegistry(pAdapter,ConfigurationHandle)==NDIS_STATUS_SUCCESS) {
|
|
//
|
|
// We got the registry info try to register the adpater
|
|
//
|
|
|
|
if (Elnk3InitializeAdapter(
|
|
&MacBlock,
|
|
pAdapter,
|
|
ConfigurationHandle)== NDIS_STATUS_SUCCESS) {
|
|
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
IF_LOUD(DbgPrint("Failed to get config info, probably bad Slot number\n");)
|
|
|
|
}
|
|
|
|
//
|
|
// We failed to register the adapter for some reason, so free the
|
|
// memory for the adapter block and return failure
|
|
|
|
NdisFreeMemory(pAdapter,
|
|
sizeof(ELNK3_ADAPTER),
|
|
0);
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3InitializeAdapter(
|
|
IN PMAC_BLOCK pMac,
|
|
IN PELNK3_ADAPTER pAdapter,
|
|
IN NDIS_HANDLE ConfigurationHandle
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Called when a new adapter should be registered.
|
|
Initializes the adapter block, and calls NdisRegisterAdapter().
|
|
|
|
Arguments:
|
|
|
|
AdapterName - The name that the system will refer to the adapter by.
|
|
Others - Adapter-specific parameters as defined in defaults.h.
|
|
|
|
Return Value:
|
|
|
|
Indicates the success or failure of the registration.
|
|
|
|
--*/
|
|
|
|
{
|
|
NDIS_STATUS Status;
|
|
NDIS_INTERFACE_TYPE InterfaceType;
|
|
UINT i;
|
|
PVOID TranslatedIdPort=NULL;
|
|
|
|
|
|
Elnk3InitAdapterBlock(pAdapter);
|
|
|
|
//
|
|
// Initialize various elments in the Adapter Structure;
|
|
//
|
|
|
|
if ((pAdapter->CardType==ELNK3_3C509) ||
|
|
((pAdapter->CardType==ELNK3_3C589))) {
|
|
|
|
InterfaceType = NdisInterfaceIsa;
|
|
|
|
} else {
|
|
|
|
if (pAdapter->CardType==ELNK3_3C579) {
|
|
|
|
InterfaceType = NdisInterfaceEisa;
|
|
|
|
} else {
|
|
|
|
InterfaceType = NdisInterfaceMca;
|
|
}
|
|
|
|
}
|
|
|
|
NdisMSetAttributes(
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter,
|
|
FALSE,
|
|
InterfaceType
|
|
);
|
|
|
|
if ((pMac->TranslatedIdPort==0) && (pAdapter->CardType==ELNK3_3C509)) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: First ISA card claiming Id port\n");)
|
|
|
|
Status=NdisMRegisterIoPortRange(
|
|
&TranslatedIdPort,
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IdPortBaseAddr,
|
|
1
|
|
);
|
|
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: First ISA card claiming Id port---FAILED\n");)
|
|
|
|
goto fail0;
|
|
|
|
}
|
|
|
|
|
|
pAdapter->IdPortOwner=TRUE;
|
|
|
|
pMac->TranslatedIdPort=TranslatedIdPort;
|
|
|
|
//
|
|
// See if there are any boards around
|
|
//
|
|
Elnk3FindIsaBoards(pMac);
|
|
}
|
|
|
|
Status=NdisMRegisterIoPortRange(
|
|
&pAdapter->TranslatedIoBase,
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IoPortBaseAddr,
|
|
16
|
|
);
|
|
|
|
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Failed to register i/o ports\n");)
|
|
|
|
goto fail1;
|
|
|
|
}
|
|
|
|
//
|
|
// Compute the portaddresses now so we don't have to
|
|
// do it on each port access
|
|
//
|
|
for (i=0;i<16;i++) {
|
|
|
|
pAdapter->PortOffsets[i]=(PUCHAR)pAdapter->TranslatedIoBase+i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (pAdapter->CardType==ELNK3_3C509) {
|
|
//
|
|
// Lets try to find a card at the address specified
|
|
//
|
|
// Note: this service may change the I/O base aquired
|
|
// from the registry. This will happen if we can't
|
|
// find a match.
|
|
//
|
|
|
|
if (!Elnk3ActivateIsaBoard(
|
|
pMac,
|
|
pAdapter,
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->TranslatedIoBase,
|
|
pAdapter->IoPortBaseAddr,
|
|
&pAdapter->IrqLevel,
|
|
pAdapter->Transceiver,
|
|
ConfigurationHandle
|
|
)) {
|
|
|
|
NdisWriteErrorLogEntry(
|
|
pAdapter->NdisAdapterHandle,
|
|
NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
|
|
8,
|
|
pAdapter->IoPortBaseAddr,
|
|
pMac->IsaCards[0].IOPort,
|
|
pMac->IsaCards[1].IOPort,
|
|
pMac->IsaCards[2].IOPort,
|
|
pMac->IsaCards[3].IOPort,
|
|
pMac->IsaCards[4].IOPort,
|
|
pMac->IsaCards[5].IOPort,
|
|
pMac->IsaCards[6].IOPort
|
|
);
|
|
|
|
Status=NDIS_STATUS_ADAPTER_NOT_FOUND;
|
|
|
|
goto fail2;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (pAdapter->CardType==ELNK3_3C579) {
|
|
//
|
|
// Get the Irq from the eisa adapter since the 3com
|
|
// CFG put the interrupt information in the second
|
|
// function of the EISA info instead of making it
|
|
// a sub function.
|
|
//
|
|
|
|
Elnk3GetEisaResources(
|
|
pAdapter,
|
|
&pAdapter->IrqLevel
|
|
);
|
|
}
|
|
|
|
else if (pAdapter->CardType==ELNK3_3C589)
|
|
{
|
|
Status = Elnk3Init3C589( pAdapter);
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Failed to initialize 3C589\n");)
|
|
|
|
goto fail1;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate the Send, LookAhead and LoopBack buffers
|
|
//
|
|
Status=Elnk3AllocateBuffers(
|
|
pAdapter,
|
|
pAdapter->NdisAdapterHandle,
|
|
TRUE
|
|
);
|
|
|
|
|
|
if (Status!=NDIS_STATUS_SUCCESS) {
|
|
|
|
goto fail2;
|
|
}
|
|
|
|
|
|
//
|
|
// Make sure the card is inactive
|
|
//
|
|
CardReset(pAdapter);
|
|
|
|
pAdapter->AdapterInitializing=TRUE;
|
|
|
|
|
|
|
|
//
|
|
// Set up the interrupt handlers.
|
|
//
|
|
|
|
NdisZeroMemory (&pAdapter->NdisInterrupt, sizeof(NDIS_MINIPORT_INTERRUPT) );
|
|
|
|
Status=NdisMRegisterInterrupt(
|
|
&pAdapter->NdisInterrupt, // interrupt info str
|
|
pAdapter->NdisAdapterHandle, // NDIS adapter handle
|
|
(UINT)pAdapter->IrqLevel, // vector or int number
|
|
(UINT)pAdapter->IrqLevel, // level or priority
|
|
TRUE,
|
|
FALSE, // NOT shared
|
|
pAdapter->InterruptMode
|
|
);
|
|
|
|
|
|
if (Status != NDIS_STATUS_SUCCESS) {
|
|
|
|
IF_LOUD (DbgPrint("ELNK3: NdisInitializeInterruptFailed\n");)
|
|
NdisWriteErrorLogEntry(
|
|
pAdapter->NdisAdapterHandle,
|
|
NDIS_ERROR_CODE_INTERRUPT_CONNECT,
|
|
1,
|
|
(ULONG)pAdapter->IrqLevel
|
|
);
|
|
|
|
|
|
goto fail3;
|
|
}
|
|
|
|
|
|
//
|
|
// Perform card tests.
|
|
//
|
|
if (!CardTest(pAdapter) ) {
|
|
|
|
IF_LOUD ( DbgPrint("ELNK3: CardTest() failed, game over\n");)
|
|
|
|
NdisWriteErrorLogEntry(
|
|
pAdapter->NdisAdapterHandle,
|
|
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
|
|
2,
|
|
(ULONG)pAdapter->IrqLevel,
|
|
(ULONG)pAdapter->IoPortBaseAddr
|
|
);
|
|
|
|
|
|
Status = NDIS_STATUS_FAILURE;
|
|
goto fail4;
|
|
}
|
|
|
|
// register a shutdown handler for this card
|
|
NdisMRegisterAdapterShutdownHandler(
|
|
pAdapter->NdisAdapterHandle, // miniport handle.
|
|
pAdapter, // shutdown context.
|
|
Elnk3Shutdown // shutdown handler.
|
|
);
|
|
|
|
CardReStart(pAdapter);
|
|
CardReStartDone(pAdapter);
|
|
|
|
IF_LOUD (DbgPrint("Elnk3: Elnk3InitializeAdapter() Succeeded\n");)
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
|
|
|
|
//
|
|
// IF WE ARE HERE SOME INITIALIZATION FAILURE OCCURRED
|
|
//
|
|
|
|
|
|
//
|
|
// 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.
|
|
//
|
|
|
|
|
|
fail4:
|
|
|
|
NdisMDeregisterInterrupt(&pAdapter->NdisInterrupt);
|
|
|
|
|
|
fail3:
|
|
|
|
Elnk3AllocateBuffers(
|
|
pAdapter,
|
|
pAdapter->NdisAdapterHandle,
|
|
FALSE
|
|
);
|
|
|
|
fail2:
|
|
|
|
NdisMDeregisterIoPortRange(
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IoPortBaseAddr,
|
|
16,
|
|
pAdapter->TranslatedIoBase
|
|
);
|
|
|
|
|
|
|
|
fail1:
|
|
|
|
if (pAdapter->IdPortOwner) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Id port owner going away\n");)
|
|
|
|
NdisMDeregisterIoPortRange(
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IdPortBaseAddr,
|
|
1,
|
|
pMac->TranslatedIdPort
|
|
);
|
|
|
|
|
|
|
|
pMac->TranslatedIdPort=0;
|
|
}
|
|
|
|
fail0:
|
|
|
|
IF_LOUD (DbgPrint("Elnk3RegisterAdapter() Failed\n");)
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3AllocateBuffers(
|
|
IN PELNK3_ADAPTER pAdapter,
|
|
IN NDIS_HANDLE NdisAdapterHandle,
|
|
BOOLEAN Allocate
|
|
)
|
|
|
|
{
|
|
NDIS_STATUS Status;
|
|
|
|
|
|
if (Allocate) {
|
|
|
|
//
|
|
// Allocate the memory to hold the loopback indication
|
|
//
|
|
|
|
Status=NdisAllocateMemory(
|
|
(PVOID *)(&pAdapter->TransContext[0].LookAhead),
|
|
4096,
|
|
0,
|
|
HighestAcceptableMax
|
|
);
|
|
|
|
if (Status!=NDIS_STATUS_SUCCESS) {
|
|
goto Fail0000;
|
|
}
|
|
|
|
pAdapter->TransContext[1].LookAhead=
|
|
(PNIC_RCV_HEADER)((PUCHAR)pAdapter->TransContext[0].LookAhead+2048);
|
|
|
|
IF_INIT_LOUD(DbgPrint("ELNK3: Lookahead->%08lx\n",pAdapter->TransContext[0].LookAhead);)
|
|
|
|
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
NdisFreeMemory(
|
|
pAdapter->TransContext[0].LookAhead,
|
|
4096,
|
|
0
|
|
);
|
|
|
|
|
|
|
|
Fail0000:
|
|
|
|
return NDIS_STATUS_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
Elnk3InitAdapterBlock(
|
|
IN PELNK3_ADAPTER pAdapter
|
|
)
|
|
|
|
{
|
|
UINT i;
|
|
|
|
|
|
//
|
|
// BUGBUG: This could probably be smaller, but NBF doesn't currently set a
|
|
// lookahead size
|
|
//
|
|
|
|
pAdapter->MaxLookAhead=60 ; //ELNK3_MAX_LOOKAHEAD_SIZE;
|
|
|
|
Elnk3AdjustMaxLookAhead(pAdapter);
|
|
|
|
for (i=0; i<TIMER_ARRAY_SIZE; i++) {
|
|
pAdapter->TimerValues[i]=25;
|
|
}
|
|
|
|
pAdapter->TransContext[0].pAdapter = pAdapter;
|
|
pAdapter->TransContext[1].pAdapter = pAdapter;
|
|
|
|
|
|
if (pAdapter->CardType==ELNK3_3C529) {
|
|
//
|
|
// MCA card does not hide bytes
|
|
//
|
|
pAdapter->RxHiddenBytes=0;
|
|
|
|
} else {
|
|
//
|
|
// ISA hides 16
|
|
//
|
|
pAdapter->RxHiddenBytes=16;
|
|
}
|
|
|
|
pAdapter->RxMinimumThreshold=8;
|
|
|
|
//
|
|
// Set the minimum amount that needs to be in the fifo
|
|
// before we draw out some of an incomplete packet
|
|
//
|
|
pAdapter->LowWaterMark=64;
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
VOID
|
|
Elnk3Shutdown(
|
|
IN NDIS_HANDLE MiniportHandle
|
|
)
|
|
{
|
|
PELNK3_ADAPTER pAdapter=MiniportHandle;
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Shutdown\n");)
|
|
|
|
//
|
|
// It's time to rock and roll
|
|
//
|
|
CardReStart(pAdapter);
|
|
}
|
|
|
|
VOID
|
|
Elnk3Halt(
|
|
IN NDIS_HANDLE MiniportHandle
|
|
)
|
|
{
|
|
|
|
PELNK3_ADAPTER pAdapter=MiniportHandle;
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Halt\n");)
|
|
//
|
|
// It's time to rock and roll
|
|
//
|
|
CardReStart(pAdapter);
|
|
|
|
NdisMDeregisterInterrupt(&pAdapter->NdisInterrupt);
|
|
|
|
if (pAdapter->IdPortOwner) {
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Id port owner going away\n");)
|
|
|
|
NdisMDeregisterIoPortRange(
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IdPortBaseAddr,
|
|
1,
|
|
MacBlock.TranslatedIdPort
|
|
);
|
|
|
|
MacBlock.TranslatedIdPort=0;
|
|
}
|
|
|
|
|
|
NdisMDeregisterIoPortRange(
|
|
pAdapter->NdisAdapterHandle,
|
|
pAdapter->IoPortBaseAddr,
|
|
16,
|
|
pAdapter->TranslatedIoBase
|
|
);
|
|
|
|
Elnk3AllocateBuffers(
|
|
pAdapter,
|
|
pAdapter->NdisAdapterHandle,
|
|
FALSE
|
|
);
|
|
|
|
|
|
NdisFreeMemory(
|
|
pAdapter,
|
|
sizeof(ELNK3_ADAPTER),
|
|
0
|
|
);
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3Reconfigure(
|
|
OUT PNDIS_STATUS OpenErrorStatus,
|
|
IN NDIS_HANDLE MiniportAdapterContext,
|
|
IN NDIS_HANDLE ConfigurationHandle
|
|
)
|
|
|
|
{
|
|
|
|
IF_INIT_LOUD(DbgPrint("Elnk3: Reconfigure\n");)
|
|
|
|
return NDIS_STATUS_NOT_SUPPORTED;
|
|
|
|
|
|
}
|
|
|
|
|
|
NDIS_STATUS
|
|
Elnk3Init3C589(
|
|
IN OUT PELNK3_ADAPTER pAdapter
|
|
)
|
|
|
|
{
|
|
ELNK3_Address_Configuration_Register acr;
|
|
ELNK3_Resource_Configuration_Register rcr;
|
|
USHORT i, window;
|
|
NDIS_STATUS Status;
|
|
|
|
Status = NDIS_STATUS_SUCCESS;
|
|
|
|
ELNK3ReadAdapterUshort ( pAdapter , PORT_CmdStatus , &window );
|
|
window &= 0xE000; // Current window - high 3 bits
|
|
|
|
ELNK3_SELECT_WINDOW( pAdapter, WNO_SETUP );
|
|
|
|
//
|
|
// init address configuration
|
|
//
|
|
acr.eacf_contents = 0;
|
|
|
|
if ( pAdapter->Transceiver == TRANSCEIVER_BNC ) {
|
|
acr.eacf_XCVR = TRANSCEIVER_BNC;
|
|
}
|
|
|
|
ELNK3WriteAdapterUshort(pAdapter,PORT_CfgAddress,acr.eacf_contents);
|
|
|
|
// Believe it or not, to make the 3C589 (not 3C589B) the IRQ have to be set
|
|
// to 3 (it can be anything - the card must be told 3).
|
|
rcr.ercf_contents = 0;
|
|
// rcr.ercf_IRQ = (USHORT)pAdapter->IrqLevel;
|
|
rcr.ercf_IRQ = 3;
|
|
rcr.ercf_reserved_F = 0xF;
|
|
ELNK3WriteAdapterUshort(pAdapter,PORT_CfgResource,rcr.ercf_contents);
|
|
|
|
// read in product ID
|
|
i = ELNK3ReadEEProm( pAdapter, EEPROM_PRODUCT_ID );
|
|
ELNK3WriteAdapterUshort( pAdapter, PORT_ProductID, i );
|
|
|
|
// Enable the adapter by setting the bit in the configuration control register
|
|
ELNK3WriteAdapterUchar(pAdapter,PORT_CfgControl,CCR_ENABLE);
|
|
|
|
// restore to whatever it used to be
|
|
ELNK3_SELECT_WINDOW( pAdapter, window);
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|