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.
3393 lines
93 KiB
3393 lines
93 KiB
/***************************************************************************
|
|
*
|
|
* MADGE.C
|
|
*
|
|
* FastMAC Plus based NDIS3 miniport driver entry, initialisation and
|
|
* closedown module.
|
|
*
|
|
* Copyright (c) Madge Networks Ltd 1994
|
|
*
|
|
* COMPANY CONFIDENTIAL
|
|
*
|
|
* Created: PBA 21/06/1994
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include <ndis.h>
|
|
|
|
#include "ftk_defs.h"
|
|
#include "ftk_extr.h"
|
|
#include "ftk_intr.h"
|
|
|
|
#include "mdgmport.upd"
|
|
#include "ndismod.h"
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Identification string for MVER.
|
|
|
|
|
---------------------------------------------------------------------------*/
|
|
|
|
char MVerString[] = MVER_STRING;
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Option strings for registry queries.
|
|
|
|
|
| There is a lot of fuss here to get the various strings defined in the
|
|
| correct way - those that are optional need to be defined in the parm.
|
|
| table as string constants, while those that are passed directly to the
|
|
| registry query functions need to be explicitly defined outside any
|
|
| structures.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
#define HIDDEN_OFFS 0x80
|
|
|
|
#define EmptyString NDIS_STRING_CONST("")
|
|
|
|
//
|
|
// These are the NT versions of the option strings.
|
|
//
|
|
|
|
#define IOAddrString NDIS_STRING_CONST("IoLocation")
|
|
#define IOBaseString NDIS_STRING_CONST("IoBaseAddress")
|
|
#define InterruptNumString NDIS_STRING_CONST("InterruptNumber")
|
|
#define DMAChanString NDIS_STRING_CONST("DmaChannel")
|
|
#define TxSlotNumString NDIS_STRING_CONST("TxSlots")
|
|
#define RxSlotNumString NDIS_STRING_CONST("RxSlots")
|
|
#define MaxFrameSizeString NDIS_STRING_CONST("MaxFrameSize")
|
|
#define CardBuffSizeString NDIS_STRING_CONST("CardBufferSize")
|
|
#define AlternateIoString NDIS_STRING_CONST("Alternate")
|
|
#define TestAndXIDString NDIS_STRING_CONST("TestAndXIDEnabled")
|
|
#define RxTxSlotsString NDIS_STRING_CONST("RxTxSlots")
|
|
#define ForceOpenString NDIS_STRING_CONST("ForceOpen")
|
|
#define Force4String NDIS_STRING_CONST("Force4")
|
|
#define Force16String NDIS_STRING_CONST("Force16")
|
|
#define SlotNumString NDIS_STRING_CONST("SlotNumber")
|
|
#define NoPciMmioString NDIS_STRING_CONST("NoMmio")
|
|
#define RingSpeedString NDIS_STRING_CONST("RingSpeed")
|
|
#define AdapterTypeString NDIS_STRING_CONST("AdapterType")
|
|
#define MmioAddrString NDIS_STRING_CONST("MemBase")
|
|
#define PlatformTypeString NDIS_STRING_CONST("PlatformType")
|
|
#define TransferTypeString NDIS_STRING_CONST("TransferType")
|
|
|
|
WCHAR PromModeString[] =
|
|
{ L'P' + HIDDEN_OFFS, L'r' + HIDDEN_OFFS, L'o' + HIDDEN_OFFS,
|
|
L'm' + HIDDEN_OFFS, L'i' + HIDDEN_OFFS, L's' + HIDDEN_OFFS,
|
|
L'c' + HIDDEN_OFFS, L'u' + HIDDEN_OFFS, L'o' + HIDDEN_OFFS,
|
|
L'u' + HIDDEN_OFFS, L's' + HIDDEN_OFFS, L'M' + HIDDEN_OFFS,
|
|
L'o' + HIDDEN_OFFS, L'd' + HIDDEN_OFFS, L'e' + HIDDEN_OFFS,
|
|
L'X' + HIDDEN_OFFS, 000 };
|
|
|
|
#define PromiscuousString { sizeof(PromModeString) - 2, \
|
|
sizeof(PromModeString), \
|
|
PromModeString }
|
|
|
|
//
|
|
// These strings are passed direct to NdisReadConfiguration.
|
|
//
|
|
|
|
STATIC NDIS_STRING BusTypeString = NDIS_STRING_CONST("BusType");
|
|
STATIC NDIS_STRING BusNumberString = NDIS_STRING_CONST("BusNumber");
|
|
STATIC NDIS_STRING IOAddressString = IOAddrString;
|
|
STATIC NDIS_STRING IOBaseAddrString = IOBaseString;
|
|
STATIC NDIS_STRING InterruptNumberString = InterruptNumString;
|
|
STATIC NDIS_STRING DMAChannelString = DMAChanString;
|
|
STATIC NDIS_STRING SlotNumberString = SlotNumString;
|
|
STATIC NDIS_STRING NoMmioString = NoPciMmioString;
|
|
STATIC NDIS_STRING AdapterString = AdapterTypeString;
|
|
STATIC NDIS_STRING MmioAddressString = MmioAddrString;
|
|
STATIC NDIS_STRING PlatformString = PlatformTypeString;
|
|
STATIC NDIS_STRING TransferModeString = TransferTypeString;
|
|
|
|
STATIC NDIS_STRING NullString = EmptyString;
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Optional parameter structure.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
//
|
|
// The Keyword parameters here use the #define's above, so the compiler is
|
|
// kept happy about string initialisers.
|
|
//
|
|
|
|
STATIC struct
|
|
{
|
|
MADGE_PARM_DEFINITION TxSlots;
|
|
MADGE_PARM_DEFINITION RxSlots;
|
|
MADGE_PARM_DEFINITION MaxFrameSize;
|
|
MADGE_PARM_DEFINITION CardBufferSize;
|
|
MADGE_PARM_DEFINITION PromiscuousMode;
|
|
MADGE_PARM_DEFINITION AlternateIo;
|
|
MADGE_PARM_DEFINITION TestAndXIDEnabled;
|
|
MADGE_PARM_DEFINITION RxTxSlots;
|
|
MADGE_PARM_DEFINITION ForceOpen;
|
|
MADGE_PARM_DEFINITION Force4;
|
|
MADGE_PARM_DEFINITION Force16;
|
|
MADGE_PARM_DEFINITION RingSpeed;
|
|
MADGE_PARM_DEFINITION NullParm;
|
|
}
|
|
MadgeParmTable =
|
|
{
|
|
{TxSlotNumString, 2, 32, {NdisParameterInteger, 0}},
|
|
{RxSlotNumString, 2, 32, {NdisParameterInteger, 0}},
|
|
{MaxFrameSizeString, 1024, 17839, {NdisParameterInteger, 4096}},
|
|
{CardBuffSizeString, 0, 0xFFFF, {NdisParameterInteger, 0}},
|
|
{PromiscuousString, 0, 1, {NdisParameterInteger, 0}},
|
|
{AlternateIoString, 0, 1, {NdisParameterInteger, 0}},
|
|
{TestAndXIDString, 0, 1, {NdisParameterInteger, 0}},
|
|
{RxTxSlotsString, 0, 5, {NdisParameterInteger, 2}},
|
|
{ForceOpenString, 0, 1, {NdisParameterInteger, 0}},
|
|
{Force4String, 0, 1, {NdisParameterInteger, 0}},
|
|
{Force16String, 0, 1, {NdisParameterInteger, 0}},
|
|
{RingSpeedString, 0, 2, {NdisParameterInteger, 0}},
|
|
{EmptyString}
|
|
};
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Name of the FastMAC Plus image file.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STRING FmpImageFileName = MADGE_FMP_NAME;
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| List of PCI adapters in use.
|
|
|
|
|
---------------------------------------------------------------------------*/
|
|
|
|
STATIC struct
|
|
{
|
|
UINT BusNumber;
|
|
UINT SlotNumber;
|
|
}
|
|
PciSlotsUsedList[MAX_NUMBER_OF_ADAPTERS];
|
|
|
|
STATIC int
|
|
PciSlotsUsedCount = 0;
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* NDIS3 level adapter structure pointer table.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadRegistryForMC
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
|
|
|
| Purpose - Read configuration information for MC adapters out of
|
|
Ý the registry.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForMC(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadRegistryForMC)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForMC(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
)
|
|
{
|
|
static WORD mcaIrqMap[4] = { 0, 3, 9, 10};
|
|
static WORD mcaIoMap[8] = {0x0a20, 0x1a20, 0x2a20, 0x3a20,
|
|
0x0e20, 0x1e20, 0x2e20, 0x3e20};
|
|
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
UINT slotNumber;
|
|
NDIS_MCA_POS_DATA mcaData;
|
|
BYTE iOSelect;
|
|
|
|
//
|
|
// Note the information that is always true for MC adapters.
|
|
//
|
|
|
|
ndisAdap->NTCardBusType = NdisInterfaceMca;
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_MC_BUS_TYPE;
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
|
|
//
|
|
// MicroChannel is easy - the POS registers contain all the info
|
|
// we need, so read those and save the information.
|
|
//
|
|
|
|
NdisReadMcaPosInformation(
|
|
&status,
|
|
wrapperConfigHandle,
|
|
&slotNumber,
|
|
&mcaData
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_MCA_POS
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Decode the Interrupt Number. Note: the FTK will throw
|
|
// IRQ 0 out as invalid.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.InterruptNumber = mcaIrqMap[mcaData.PosData1 >> 6];
|
|
|
|
//
|
|
// NB: Arbitration Level 15 => PIO, which we do not allow -
|
|
// the FTK will throw this out as an invalid DMA channel.
|
|
// NB: We call it DmaChannel to be compatible with ISA cards.
|
|
//
|
|
|
|
ndisAdap->DmaChannel = (mcaData.PosData1 >> 1) & 0x0F;
|
|
|
|
//
|
|
// Build the IO Location select value from several sources.
|
|
//
|
|
|
|
iOSelect = (mcaData.PosData1 >> 5) & 0x01;
|
|
iOSelect |= (mcaData.PosData4 >> 4) & 0x02;
|
|
iOSelect |= (mcaData.PosData3 >> 0) & 0x04;
|
|
|
|
//
|
|
// NB: IO locations 0x2e20 and 0x3e20 are only valid for
|
|
// MC32 cards, but the .ADF file will have prevented them
|
|
// being set for MC16s.
|
|
//
|
|
|
|
ndisAdap->IoLocation1 = mcaIoMap[iOSelect];
|
|
ndisAdap->UsedInISR.InterruptMode = NdisInterruptLevelSensitive;
|
|
ndisAdap->UsedInISR.InterruptShared = TRUE;
|
|
ndisAdap->IORange1 = MC_IO_RANGE;
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadRegistryForEISA
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
|
|
|
| Purpose - Read configuration information for an EISA adapter
|
|
Ý out of the registry.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForEISA(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadRegistryForEISA)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForEISA(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
UINT slotNumber;
|
|
NDIS_EISA_FUNCTION_INFORMATION eisaData;
|
|
|
|
//
|
|
// For Eisa bus systems, we could have an Isa card or an Eisa
|
|
// card - try to read the Eisa information, and if that fails
|
|
// MadgeReadRegistry will assume it is an Isa card instead.
|
|
//
|
|
|
|
NdisReadEisaSlotInformation(
|
|
&status,
|
|
wrapperConfigHandle,
|
|
&slotNumber,
|
|
&eisaData
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Note the information that is always true for EISA
|
|
// adapters.
|
|
//
|
|
|
|
ndisAdap->NTCardBusType = NdisInterfaceEisa;
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_EISA_BUS_TYPE;
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
|
|
//
|
|
// Got EISA configuration data - decode the relevant bits.
|
|
//
|
|
|
|
ndisAdap->IoLocation1 = slotNumber << 12;
|
|
|
|
//
|
|
// Get the Interrupt number from the NVRAM data - we know it
|
|
// is going to be the first Irq element in the Irq array
|
|
// because the card only uses one interrupt.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.InterruptNumber =
|
|
eisaData.EisaIrq[0].ConfigurationByte.Interrupt;
|
|
|
|
ndisAdap->UsedInISR.InterruptMode = (NDIS_INTERRUPT_MODE)
|
|
(eisaData.EisaIrq[0].ConfigurationByte.LevelTriggered
|
|
? NdisInterruptLevelSensitive
|
|
: NdisInterruptLatched);
|
|
|
|
ndisAdap->UsedInISR.InterruptShared = (BOOLEAN)
|
|
eisaData.EisaIrq[0].ConfigurationByte.Shared;
|
|
|
|
//
|
|
// For EISA cards we don't care what the DMA setting is. So
|
|
// we leave it set to 0 forget about it.
|
|
//
|
|
|
|
ndisAdap->IORange1 = EISA_IO_RANGE;
|
|
ndisAdap->IoLocation2 = ndisAdap->IoLocation1 + EISA_IO_RANGE2_BASE;
|
|
ndisAdap->IORange2 = EISA_IO_RANGE2;
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadRegistryForISA
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
Ý adapterType -> Adapter type.
|
|
|
|
|
| Purpose - Read configuration information for ISA adapters out
|
|
Ý of the registry.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForISA(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
ULONG adapterType
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadRegistryForISA)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForISA(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
ULONG adapterType
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
|
|
//
|
|
// Note the information that is always TRUE for ISA adapters.
|
|
//
|
|
|
|
ndisAdap->NTCardBusType = NdisInterfaceIsa;
|
|
|
|
//
|
|
// Do some adapter type specific setup. If we don't
|
|
// know what sort of adapter it is we'll assume it's
|
|
// an ATULA adapter so we are backwards compatible.
|
|
//
|
|
|
|
switch (adapterType)
|
|
{
|
|
case MADGE_ADAPTER_UNKNOWN:
|
|
case MADGE_ADAPTER_ATULA:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_ATULA_BUS_TYPE;
|
|
ndisAdap->IORange1 = ATULA_IO_RANGE;
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_SMART16:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_SMART16_BUS_TYPE;
|
|
ndisAdap->IORange1 = SMART16_IO_RANGE;
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_PCMCIA:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_PCMCIA_BUS_TYPE;
|
|
ndisAdap->IORange1 = PCMCIA_IO_RANGE;
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_PNP:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_PNP_BUS_TYPE;
|
|
ndisAdap->IORange1 = PNP_IO_RANGE;
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
break;
|
|
|
|
default:
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Get the IO location - must have this. First try
|
|
// "IoLocation" and then "IoBaseAddress".
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&IOAddressString,
|
|
NdisParameterHexInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&IOBaseAddrString,
|
|
NdisParameterHexInteger
|
|
);
|
|
}
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_ISA_IO
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->IoLocation1 = configParam->ParameterData.IntegerData;
|
|
|
|
//
|
|
// Er, slight hack here. We used to pretend that Smart16
|
|
// adapters were ATULA adapters. We now don't. So to
|
|
// be backwards compatible, if we have an unknown adapter
|
|
// with an IO base >= 0x4a20 and <= 0x6e20 we'll assume it's
|
|
// really a Smart16.
|
|
//
|
|
|
|
if (adapterType == MADGE_ADAPTER_UNKNOWN &&
|
|
ndisAdap->IoLocation1 >= 0x4a20 &&
|
|
ndisAdap->IoLocation1 <= 0x6e20)
|
|
{
|
|
adapterType = MADGE_ADAPTER_SMART16;
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_SMART16_BUS_TYPE;
|
|
ndisAdap->IORange1 = SMART16_IO_RANGE;
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
|
|
//
|
|
// Get the IRQ number - we must have this.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&InterruptNumberString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_ISA_IRQ
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->UsedInISR.InterruptNumber =
|
|
configParam->ParameterData.IntegerData;
|
|
|
|
ndisAdap->UsedInISR.InterruptMode = NdisInterruptLatched;
|
|
ndisAdap->UsedInISR.InterruptShared = FALSE;
|
|
|
|
//
|
|
// Read the TransferType parameter and switch into PIO
|
|
// mode if specified.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&TransferModeString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
if (configParam->ParameterData.IntegerData == MADGE_PIO_MODE)
|
|
{
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Get the DMA channel (PIO is specified as channel 0,
|
|
// multiprocessor safe PIO is specified as 0x8000). We
|
|
// don't need a DMA channel if the adapter isn't an ATULA so
|
|
// the only reason for reading the DMA channel for none
|
|
// ATULA adapters is to allow backwards compatability with old
|
|
// registry set ups that specify multiprocessor safe PIO
|
|
// with the DmaChannel == 0x8000. Using the DMA channel
|
|
// to specify PIO is retained for backwards compatibility
|
|
// the correct way is to set the TransferType parameter.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&DMAChannelString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
ndisAdap->DmaChannel = 0;
|
|
}
|
|
else
|
|
{
|
|
ndisAdap->DmaChannel = configParam->ParameterData.IntegerData;
|
|
}
|
|
|
|
//
|
|
// Note if we should be using multiprocessor safe PIO.
|
|
//
|
|
|
|
if (ndisAdap->DmaChannel == 0x8000)
|
|
{
|
|
ndisAdap->DmaChannel = 0;
|
|
ndisAdap->UseMPSafePIO = TRUE;
|
|
}
|
|
|
|
//
|
|
// If we did not get a DMA channel then we must use PIO.
|
|
//
|
|
|
|
if (ndisAdap->DmaChannel == 0)
|
|
{
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeFindPciInfoForWin95
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
Ý pciSlotInfo -> Pointer to a buffer that will
|
|
Ý be filled with the configuration
|
|
Ý data for the adapter.
|
|
|
|
|
| Purpose - Read configuration information for PCI adapters out
|
|
Ý of the registry when running on Windows95. The slot
|
|
Ý containing the adapter is also found and the configuration
|
|
Ý data from the slot returned in the pciSlotInfo buffer.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeFindPciInfoForWin95(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
BYTE * pciSlotInfo
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeFindPciInfoForWin95)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeFindPciInfoForWin95(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
BYTE * pciSlotInfo
|
|
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
UINT i;
|
|
|
|
//
|
|
// Unfortunately Windows95 (M7) and NT handle PCI configuration
|
|
// in different ways. Under NT one has to read the slot
|
|
// configuration. Under Windows95 the resource information
|
|
// is faked up by the configuration manager and can be read
|
|
// directly from the wrapper.
|
|
//
|
|
|
|
//
|
|
// Get the IO location - must have this. First try
|
|
// "IoLocation" and then "IoBaseAddress".
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&IOAddressString,
|
|
NdisParameterHexInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&IOBaseAddrString,
|
|
NdisParameterHexInteger
|
|
);
|
|
}
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_PCI_IO
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->IoLocation1 = configParam->ParameterData.IntegerData;
|
|
|
|
//
|
|
// Get the IRQ number - we must have this.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&InterruptNumberString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_PCI_IRQ
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->UsedInISR.InterruptNumber =
|
|
configParam->ParameterData.IntegerData;
|
|
|
|
//
|
|
// Get the MMIO base address - optional.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&MmioAddressString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
ndisAdap->MmioRawAddress =
|
|
configParam->ParameterData.IntegerData;
|
|
}
|
|
|
|
//
|
|
// We also need to know which slot the adapter is in so we can
|
|
// read and write configuration space directly. We'll search for
|
|
// a slot which contains a Madge adapter which the correct I/O
|
|
// location. As a side effect we'll store the configuration data
|
|
// for the slot in pciSlotInfo. Note: Under Windows 95 (build 490)
|
|
// NdisReadPciSlotInformation does appear to return the number
|
|
// of bytes read as it does under NT - not sure what it returns ...
|
|
//
|
|
|
|
ndisAdap->SlotNumber = PCI_FIND_ADAPTER;
|
|
|
|
for (i = 0; i < MAX_PCI_SLOTS; i++)
|
|
{
|
|
NdisReadPciSlotInformation(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
i,
|
|
0,
|
|
(VOID *) pciSlotInfo,
|
|
PCI_CONFIG_SIZE
|
|
);
|
|
|
|
if (PCI_VENDOR_ID(pciSlotInfo) == MADGE_PCI_VENDOR_ID &&
|
|
PCI_IO_BASE(pciSlotInfo) == ndisAdap->IoLocation1)
|
|
{
|
|
ndisAdap->SlotNumber = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ndisAdap->SlotNumber == PCI_FIND_ADAPTER)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_DRIVER_FAILURE,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
Ý
|
|
Ý Function - MadgePciSlotUsed
|
|
Ý
|
|
Ý Parameters - busNumber -> Bus number containing the adapter.
|
|
Ý slotNumber -> Slot number containing the adapter.
|
|
Ý
|
|
Ý Purpose - Check if a PCI slot is already in use.
|
|
Ý
|
|
Ý Returns - TRUE if the slot is in use or FALSE if not.
|
|
Ý
|
|
Ý--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
MadgePciSlotUsed(
|
|
UINT busNumber,
|
|
UINT slotNumber
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgePciSlotUsed)
|
|
|
|
STATIC BOOLEAN
|
|
MadgePciSlotUsed(
|
|
UINT busNumber,
|
|
UINT slotNumber
|
|
)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < PciSlotsUsedCount; i++)
|
|
{
|
|
if (PciSlotsUsedList[i].BusNumber == busNumber &&
|
|
PciSlotsUsedList[i].SlotNumber == slotNumber)
|
|
{
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeFindPciInfoForNt
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
Ý pciSlotInfo -> Pointer to a buffer that will
|
|
Ý be filled with the configuration
|
|
Ý data for the adapter.
|
|
|
|
|
| Purpose - Read configuration information for PCI adapters out
|
|
Ý of the registry when running on Windows95. The slot
|
|
Ý containing the adapter is also found and the configuration
|
|
Ý data from the slot returned in the pciSlotInfo buffer.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeFindPciInfoForNt(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
BYTE * pciSlotInfo
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeFindPciInfoForNt)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeFindPciInfoForNt(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
BYTE * pciSlotInfo
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
UINT slotNumber;
|
|
BOOLEAN pciSlotRead;
|
|
BOOLEAN useMmio;
|
|
UINT i;
|
|
PNDIS_RESOURCE_LIST pciResources;
|
|
PCM_PARTIAL_RESOURCE_DESCRIPTOR resDesc;
|
|
UINT busNumber;
|
|
|
|
//
|
|
// Unfortunately Windows95 (M7) and NT handle PCI configuration
|
|
// in different ways. Under NT one has to read the slot
|
|
// configuration. Under Windows95 the resource information
|
|
// is faked up by the configuration manager and can be read
|
|
// directly from the wrapper.
|
|
//
|
|
|
|
//
|
|
// Find out what the slot number is. This is in fact the
|
|
// PCI device number. Values 0 through 31 represent real
|
|
// slot numbers. 0xffff means we should search for the
|
|
// first unused Madge PCI adapter.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&SlotNumberString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
slotNumber = configParam->ParameterData.IntegerData;
|
|
pciSlotRead = FALSE;
|
|
|
|
//
|
|
// Read the bus number.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&BusNumberString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
busNumber = configParam->ParameterData.IntegerData;
|
|
|
|
//
|
|
// If the slot number is PCI_FIND_ADAPTER (0xffff) then we
|
|
// will attempt to search for the first Madge PCI adapter
|
|
// that is not already in use.
|
|
//
|
|
|
|
if (slotNumber == PCI_FIND_ADAPTER)
|
|
{
|
|
for (i = 0; !pciSlotRead && i < MAX_PCI_SLOTS; i++)
|
|
{
|
|
if (!MadgePciSlotUsed(busNumber, i))
|
|
{
|
|
//
|
|
// Extract the PCI configuration information from
|
|
// the slot.
|
|
//
|
|
|
|
status = NdisReadPciSlotInformation(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
i,
|
|
0,
|
|
(VOID *) pciSlotInfo,
|
|
PCI_CONFIG_SIZE
|
|
);
|
|
//
|
|
// Check if the slot contains a Madge adapter and
|
|
// break out of the loop if it does.
|
|
//
|
|
|
|
if (status == PCI_CONFIG_SIZE &&
|
|
PCI_VENDOR_ID(pciSlotInfo) == MADGE_PCI_VENDOR_ID)
|
|
{
|
|
slotNumber = i;
|
|
pciSlotRead = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check if the slotNumber is valid. This will fail if the
|
|
// above adapter search failed.
|
|
//
|
|
|
|
if (slotNumber < 0 ||
|
|
slotNumber >= MAX_PCI_SLOTS ||
|
|
MadgePciSlotUsed(busNumber, slotNumber))
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_DRIVER_FAILURE,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Note that the PCI slot is in use.
|
|
//
|
|
|
|
PciSlotsUsedList[PciSlotsUsedCount].BusNumber = busNumber;
|
|
PciSlotsUsedList[PciSlotsUsedCount].SlotNumber = slotNumber;
|
|
PciSlotsUsedCount++;
|
|
|
|
ndisAdap->SlotNumber = slotNumber;
|
|
|
|
//
|
|
// There two methods for getting the PCI configuration. One is
|
|
// to read it directly from the PCI configuration space. This
|
|
// works for Intel patforms where a PCI BIOS has configured
|
|
// all of the adapters at boot time. It does not work for
|
|
// none Intel platforms where the PCI devices are not
|
|
// configured at boot time. Unfortunately the call which
|
|
// provokes NT to configure a PCI device, NdisMPciAssignResources
|
|
// is not available in the NT 3.5 wrapper. So, until NT 3.51
|
|
// becomes dominant we must support both configuration methods.
|
|
//
|
|
|
|
//
|
|
// If we haven't already extracted the PCI configuration
|
|
// information from the slot and check that it is valid.
|
|
//
|
|
|
|
if (!pciSlotRead)
|
|
{
|
|
status = NdisReadPciSlotInformation(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
slotNumber,
|
|
0,
|
|
(VOID *) pciSlotInfo,
|
|
PCI_CONFIG_SIZE
|
|
);
|
|
|
|
if (status != PCI_CONFIG_SIZE ||
|
|
PCI_VENDOR_ID(pciSlotInfo) != MADGE_PCI_VENDOR_ID)
|
|
{
|
|
MadgePrint1("No Madge adapter in slot\n");
|
|
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_DRIVER_FAILURE,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Call NdisMPciAssignResources for the specified slot to
|
|
// get the adapter configuration.
|
|
//
|
|
|
|
status = NdisMPciAssignResources(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
slotNumber,
|
|
&pciResources
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_DRIVER_FAILURE,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PCI_SLOTNUMBER
|
|
);
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Iterate through the returned resource list recording the values
|
|
// in the PCI configuration
|
|
//
|
|
|
|
for (i = 0; i < pciResources->Count; i++)
|
|
{
|
|
resDesc = &pciResources->PartialDescriptors[i];
|
|
|
|
switch (resDesc->Type)
|
|
{
|
|
case CmResourceTypeInterrupt:
|
|
|
|
ndisAdap->UsedInISR.InterruptNumber =
|
|
(ULONG) resDesc->u.Interrupt.Vector;
|
|
break;
|
|
|
|
case CmResourceTypePort:
|
|
|
|
ndisAdap->IoLocation1 =
|
|
(UINT) NdisGetPhysicalAddressLow(resDesc->u.Port.Start);
|
|
break;
|
|
|
|
case CmResourceTypeMemory:
|
|
|
|
ndisAdap->MmioRawAddress =
|
|
(DWORD) NdisGetPhysicalAddressLow(resDesc->u.Memory.Start);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// On none-Intel platforms it's possible for the PCI adapter's I/O
|
|
// base to be greater than 0xffff. Since the FTK uses 16bit
|
|
// I/O locations we make a note of the I/O base in a 32bit cell
|
|
// that we can add in inside the I/O functions in sys_mem.c
|
|
//
|
|
|
|
#ifndef _M_IX86
|
|
|
|
ndisAdap->IoLocationBase = ndisAdap->IoLocation1;
|
|
ndisAdap->IoLocation1 = 0;
|
|
|
|
#endif
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadRegistryForPCI
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
Ý platformType -> Type of platform: NT or Win95.
|
|
|
|
|
| Purpose - Read configuration information for PCI.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForPCI(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
UINT platformType
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadRegistryForPCI)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistryForPCI(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap,
|
|
UINT platformType
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
BYTE pciSlotInfo[PCI_CONFIG_SIZE];
|
|
BOOLEAN useMmio;
|
|
|
|
//
|
|
// Note the information that is always true for PCI adapters.
|
|
//
|
|
|
|
ndisAdap->NTCardBusType = NdisInterfacePci;
|
|
|
|
//
|
|
// Set up the fixed configuration information.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.InterruptMode = NdisInterruptLevelSensitive;
|
|
ndisAdap->UsedInISR.InterruptShared = TRUE;
|
|
|
|
//
|
|
// We know need to find the PCI adapter and read in the configuration
|
|
// information for the slot. Unfortunatetly the method we have to use
|
|
// is different for NT and Win95.
|
|
//
|
|
|
|
if (platformType == MADGE_OS_WIN95)
|
|
{
|
|
status = MadgeFindPciInfoForWin95(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap,
|
|
pciSlotInfo
|
|
);
|
|
}
|
|
else
|
|
{
|
|
status = MadgeFindPciInfoForNt(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap,
|
|
pciSlotInfo
|
|
);
|
|
}
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// Now we know we have a Madge PCI adapter of some sort but
|
|
// as yet we don't know what type. We'll work this out by
|
|
// looking at the device/revision ID in the slot's configuration
|
|
// data. At the same time we'll note the default transfer type
|
|
// for the adapter.
|
|
//
|
|
|
|
switch (PCI_REVISION(pciSlotInfo))
|
|
{
|
|
case MADGE_PCI_RAP1B_REVISION:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_PCI_BUS_TYPE;
|
|
ndisAdap->TransferMode = MMIO_DATA_TRANSFER_MODE;
|
|
ndisAdap->IORange1 = PCI_IO_RANGE;
|
|
break;
|
|
|
|
case MADGE_PCI_PCI2_REVISION:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_PCI2_BUS_TYPE;
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
ndisAdap->IORange1 = PCI2_IO_RANGE;
|
|
break;
|
|
|
|
case MADGE_PCI_PCIT_REVISION:
|
|
|
|
ndisAdap->FTKCardBusType = ADAPTER_CARD_TI_PCI_BUS_TYPE;
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
ndisAdap->IORange1 = SIF_IO_RANGE;
|
|
break;
|
|
|
|
default:
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Now we need to work out the transfer type. There are three
|
|
// things that affect the transfer type: the setting of
|
|
// the TransferType registry parameter, the setting of the
|
|
// NoMmio registry flag and whether we have been allocated any
|
|
// MMIO memory. Ideally we would just use the TransferType flag.
|
|
// The NoMmio flag is to preserve backwards compatibility with old
|
|
// registry set ups.
|
|
//
|
|
|
|
//
|
|
// Read the transfer type flag if possible.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&TransferModeString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// Set the transfer type depending on the TransferType parameter
|
|
// and the adapter type.
|
|
//
|
|
|
|
if (configParam->ParameterData.IntegerData == MADGE_DMA_MODE)
|
|
{
|
|
if (ndisAdap->FTKCardBusType == ADAPTER_CARD_PCI2_BUS_TYPE ||
|
|
ndisAdap->FTKCardBusType == ADAPTER_CARD_TI_PCI_BUS_TYPE)
|
|
{
|
|
ndisAdap->TransferMode = DMA_DATA_TRANSFER_MODE;
|
|
}
|
|
}
|
|
|
|
if (configParam->ParameterData.IntegerData == MADGE_PIO_MODE)
|
|
{
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
|
|
if (configParam->ParameterData.IntegerData == MADGE_MMIO_MODE)
|
|
{
|
|
if (ndisAdap->FTKCardBusType == ADAPTER_CARD_PCI_BUS_TYPE)
|
|
{
|
|
ndisAdap->TransferMode = MMIO_DATA_TRANSFER_MODE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// To preserve backwards compatibility if we find the NoMmio flag
|
|
// set then switch to PIO mode.
|
|
//
|
|
|
|
if (ndisAdap->TransferMode == MMIO_DATA_TRANSFER_MODE)
|
|
{
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&NoMmioString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
if (configParam->ParameterData.IntegerData != 0)
|
|
{
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we are in MMIO mode then check that we were allocated some MMIO
|
|
// memory. If not switch to PIO mode.
|
|
//
|
|
|
|
if (ndisAdap->TransferMode == MMIO_DATA_TRANSFER_MODE)
|
|
{
|
|
if (ndisAdap->MmioRawAddress == 0)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MEMORY_CONFLICT,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PCI_MMIO
|
|
);
|
|
|
|
ndisAdap->TransferMode == PIO_DATA_TRANSFER_MODE;
|
|
|
|
}
|
|
}
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadRegistry
|
|
|
|
|
| Parameters - wrapperConfigHandle -> Wrapper context handle.
|
|
| registryConfigHandle -> Already open registry query handle.
|
|
| ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
|
|
|
| Purpose - Read configuration information out of the registry.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistry(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadRegistry)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadRegistry(
|
|
NDIS_HANDLE wrapperConfigHandle,
|
|
NDIS_HANDLE registryConfigHandle,
|
|
PMADGE_ADAPTER ndisAdap
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PNDIS_CONFIGURATION_PARAMETER configParam;
|
|
MADGE_PARM_DEFINITION * pMadgeParmTable;
|
|
PVOID networkAddress;
|
|
ULONG networkAddressLength;
|
|
UINT adapterType;
|
|
UINT platformType;
|
|
|
|
//
|
|
// Try to read the OS platform type. If we don't find one then
|
|
// assume we are running on NT.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&PlatformString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
platformType = MADGE_OS_NT;
|
|
}
|
|
else
|
|
{
|
|
platformType = configParam->ParameterData.IntegerData;
|
|
}
|
|
|
|
//
|
|
// Read the system bus type - that will give us a direction
|
|
// in which to search for further details.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&BusTypeString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_NO_BUS_TYPE
|
|
);
|
|
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->BusType = configParam->ParameterData.IntegerData;
|
|
|
|
//
|
|
// Originally we determined what sort of adapter we had based
|
|
// on the bus type returned by the configuration call to the
|
|
// wrapper. This works for NT but doesn't for Windows95 (M7)
|
|
// which seems to fail to identify a card as being in a PCI
|
|
// bus. We also cannot tell between the various sorts of ISA
|
|
// adapter now available. To fix this we look in the registry
|
|
// for an adapter type parameter. We use this and the bus type
|
|
// returned by the wrapper to work out where to start. We don't
|
|
// fail if we can't read an adapter type so that we will work with
|
|
// old registry set ups.
|
|
//
|
|
// Build 310 of Windows95 seems to return the native bus type of the
|
|
// PC. This means on a PCI machine we always get NdisInterfacePci.
|
|
// To get around this problem we will work out the bus type from
|
|
// the adapter type parameter if one is present.
|
|
//
|
|
// Unfortunately we can't just abandon the bus type de-multiplexing
|
|
// if we are to work with old NT registry set ups.
|
|
//
|
|
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&AdapterString,
|
|
NdisParameterInteger
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
adapterType = MADGE_ADAPTER_UNKNOWN;
|
|
}
|
|
else
|
|
{
|
|
adapterType = configParam->ParameterData.IntegerData;
|
|
}
|
|
|
|
switch (adapterType)
|
|
{
|
|
case MADGE_ADAPTER_ATULA:
|
|
case MADGE_ADAPTER_PCMCIA:
|
|
case MADGE_ADAPTER_PNP:
|
|
case MADGE_ADAPTER_SMART16:
|
|
|
|
ndisAdap->BusType = NdisInterfaceIsa;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_EISA:
|
|
|
|
ndisAdap->BusType = NdisInterfaceEisa;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_MC:
|
|
|
|
ndisAdap->BusType = NdisInterfaceMca;
|
|
break;
|
|
|
|
case MADGE_ADAPTER_PCI:
|
|
|
|
ndisAdap->BusType = NdisInterfacePci;
|
|
break;
|
|
|
|
default:
|
|
|
|
//
|
|
// We don't have a valid adapter type parameter so we'll
|
|
// just have to beleive the bus type the wrapper passed
|
|
// us.
|
|
//
|
|
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Based on the determined Bus Type, try to find details of the card.
|
|
//
|
|
|
|
//
|
|
// Remember, all fields of the MADGE_ADAPTER structure were zeroed
|
|
// after the structure's allocation.
|
|
//
|
|
|
|
switch (ndisAdap->BusType)
|
|
{
|
|
case NdisInterfaceMca:
|
|
|
|
status = MadgeReadRegistryForMC(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisInterfaceEisa:
|
|
|
|
//
|
|
// For Eisa bus systems, we could have an Isa card or an Eisa
|
|
// card - try to read the Eisa information, and if that fails
|
|
// assume it is an Isa card instead.
|
|
//
|
|
|
|
status = MadgeReadRegistryForEISA(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Failed to read EISA data for this card, so it is unlikely
|
|
// to be one - try ISA instead - fall through.
|
|
//
|
|
|
|
case NdisInterfaceIsa:
|
|
|
|
status = MadgeReadRegistryForISA(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap,
|
|
adapterType
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
break;
|
|
|
|
case NdisInterfacePci:
|
|
|
|
status = MadgeReadRegistryForPCI(
|
|
wrapperConfigHandle,
|
|
registryConfigHandle,
|
|
ndisAdap,
|
|
platformType
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
//
|
|
// Unsupported Bus Type, so return failure - no point being more
|
|
// explicit than that at the moment since any of the bits above
|
|
// could have failed too, and they do not return anything more
|
|
// meaningful either.
|
|
//
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
MadgePrint2("FTKCardBusType = %d\n", ndisAdap->FTKCardBusType);
|
|
MadgePrint2("SlotNumber = %d\n", ndisAdap->SlotNumber);
|
|
MadgePrint2("IoLocation1 = %lx\n", ndisAdap->IoLocation1);
|
|
MadgePrint2("MmioAddress = %lx\n", ndisAdap->MmioRawAddress);
|
|
MadgePrint2("InterruptNumber = %lx\n", ndisAdap->UsedInISR.InterruptNumber);
|
|
MadgePrint2("TransferMode = %d\n", ndisAdap->TransferMode);
|
|
MadgePrint2("DmaChannel = %d\n", ndisAdap->DmaChannel);
|
|
|
|
//
|
|
// To get here, we must have worked out the IO Address, IRQ number, DMA
|
|
// channel/arbitration level, and all the interrupt details. This just
|
|
// leaves the optional parameters for tuning the performance of the MAC
|
|
// code.
|
|
//
|
|
|
|
pMadgeParmTable = (MADGE_PARM_DEFINITION *) &MadgeParmTable;
|
|
|
|
while (!NdisEqualString(&pMadgeParmTable->Keyword, &NullString, TRUE))
|
|
{
|
|
NdisReadConfiguration(
|
|
&status,
|
|
&configParam,
|
|
registryConfigHandle,
|
|
&pMadgeParmTable->Keyword,
|
|
pMadgeParmTable->DefaultValue.ParameterType
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// Did read something. Check bounds. We assume all are Integers.
|
|
//
|
|
|
|
if (configParam->ParameterData.IntegerData <
|
|
pMadgeParmTable->Minimum ||
|
|
configParam->ParameterData.IntegerData >
|
|
pMadgeParmTable->Maximum)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_DRIVER_FAILURE,
|
|
2,
|
|
readRegistry,
|
|
MADGE_ERRMSG_BAD_PARAMETER
|
|
);
|
|
|
|
pMadgeParmTable->ActualValue = pMadgeParmTable->DefaultValue;
|
|
}
|
|
else
|
|
{
|
|
pMadgeParmTable->ActualValue = *configParam;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// We didn't read anything, so use the default value.
|
|
//
|
|
|
|
pMadgeParmTable->ActualValue = pMadgeParmTable->DefaultValue;
|
|
}
|
|
|
|
pMadgeParmTable++;
|
|
}
|
|
|
|
//
|
|
// We have successfully read any optional keywords and none of them is
|
|
// too small or big. The other thing we need the registry for is the
|
|
// locally administered address, for which there is a specific NDIS call
|
|
//
|
|
|
|
NdisReadNetworkAddress(
|
|
&status,
|
|
&networkAddress,
|
|
&networkAddressLength,
|
|
registryConfigHandle
|
|
);
|
|
|
|
if (status == NDIS_STATUS_SUCCESS &&
|
|
networkAddressLength == TR_LENGTH_OF_ADDRESS)
|
|
{
|
|
//
|
|
// We read a valid length TR address, but if the
|
|
// top two bits are not "01", it is not legal.
|
|
//
|
|
|
|
if ((((BYTE *) networkAddress)[0] & 0xc0) == 0x40)
|
|
{
|
|
ndisAdap->OpeningNodeAddress =
|
|
*((NODE_ADDRESS *) networkAddress);
|
|
}
|
|
}
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Function - MadgeShutdown
|
|
*
|
|
* Parameters - context -> Adapter context.
|
|
*
|
|
* Purpose - Quickly shutdown the adapter.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID
|
|
MadgeShutdown(
|
|
NDIS_HANDLE context
|
|
)
|
|
{
|
|
MADGE_ADAPTER * ndisAdap;
|
|
|
|
ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(context);
|
|
|
|
MadgePrint1("MadgeShutdown called\n");
|
|
|
|
if (ndisAdap->TimerInitialized)
|
|
{
|
|
BOOLEAN timerOutstanding;
|
|
|
|
NdisMCancelTimer(&ndisAdap->WakeUpTimer, &timerOutstanding);
|
|
NdisMCancelTimer(&ndisAdap->CompletionTimer, &timerOutstanding);
|
|
|
|
ndisAdap->TimerInitialized = FALSE;
|
|
}
|
|
|
|
//
|
|
// Just call the FTK to shutdown the adapter.
|
|
//
|
|
|
|
if (ndisAdap->FtkInitialized)
|
|
{
|
|
rxtx_await_empty_tx_slots(ndisAdap->FtkAdapterHandle);
|
|
driver_remove_adapter(ndisAdap->FtkAdapterHandle);
|
|
ndisAdap->FtkInitialized = FALSE;
|
|
ndisAdap->AdapterRemoved = TRUE;
|
|
}
|
|
|
|
MadgePrint1("MadgeShutdown ended\n");
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeRegisterAdapter
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter
|
|
| structure.
|
|
| wrapperConfigHandle -> Wrapper context handle.
|
|
|
|
|
| Purpose - Register an adapter instance with the NDIS3 wrapper.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeRegisterAdapter(
|
|
PMADGE_ADAPTER ndisAdap,
|
|
NDIS_HANDLE wrapperConfigHandle
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeRegisterAdapter)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeRegisterAdapter(
|
|
PMADGE_ADAPTER ndisAdap,
|
|
NDIS_HANDLE wrapperConfigHandle
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
BOOLEAN busMaster;
|
|
|
|
MadgePrint1("MadgeRegisterAdapter started\n");
|
|
|
|
//
|
|
// Register a shutdown handler with the wrapper.
|
|
//
|
|
|
|
NdisMRegisterAdapterShutdownHandler(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap,
|
|
MadgeShutdown
|
|
);
|
|
|
|
ndisAdap->ShutdownHandlerRegistered = TRUE;
|
|
|
|
//
|
|
// Register our attributes with the wrapper. These are our adapter
|
|
// context (i.e. a pointer to our adapter structure), whether we
|
|
// are a bus master device and our bus type.
|
|
//
|
|
|
|
busMaster = (ndisAdap->TransferMode == DMA_DATA_TRANSFER_MODE);
|
|
|
|
MadgePrint1("NdisMSetAttributes called\n");
|
|
MadgePrint2("busMaster = %d\n", (UINT) busMaster);
|
|
|
|
NdisMSetAttributes(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
(NDIS_HANDLE) ndisAdap,
|
|
busMaster,
|
|
ndisAdap->NTCardBusType
|
|
);
|
|
|
|
MadgePrint1("NdisMSetAttributes returned\n");
|
|
|
|
//
|
|
// Register our IO port usage.
|
|
//
|
|
|
|
MadgePrint1("NdisMRegisterIoPortRange called\n");
|
|
|
|
status = NdisMRegisterIoPortRange(
|
|
&ndisAdap->MappedIOLocation1,
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap->IoLocation1 + ndisAdap->IoLocationBase,
|
|
ndisAdap->IORange1
|
|
);
|
|
|
|
MadgePrint1("NdisMRegisterIoPortRange returned\n");
|
|
MadgePrint2("MappedIORange1 = %x\n", (UINT) ndisAdap->MappedIOLocation1);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
MadgePrint2("NdisMRegisterIoPortRange failed rc = %x\n", status);
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->IORange1Initialized = TRUE;
|
|
|
|
//
|
|
// If we are using an EISA card then we have a second range of IO
|
|
// locations.
|
|
//
|
|
|
|
if (ndisAdap->IORange2 > 0)
|
|
{
|
|
MadgePrint1("NdisMRegisterIoPortRange called\n");
|
|
|
|
status = NdisMRegisterIoPortRange(
|
|
&ndisAdap->MappedIOLocation2,
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap->IoLocation2 + ndisAdap->IoLocationBase,
|
|
ndisAdap->IORange2
|
|
);
|
|
|
|
MadgePrint1("NdisMRegisterIoPortRange returned\n");
|
|
MadgePrint2("MappedIORange2 = %x\n", (UINT) ndisAdap->MappedIOLocation2);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
MadgePrint2("NdisMRegisterIoPortRange failed rc = %x\n", status);
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->IORange2Initialized = TRUE;
|
|
}
|
|
|
|
MadgePrint1("MadgeRegisterAdapter finished\n");
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - FlagIsTrue
|
|
|
|
|
| Parameters - flag -> Pointer to a flag to find the value of.
|
|
|
|
|
| Purpose - Return the value of a flag. Can be called by a function
|
|
Ý that polls a flag to avoid the compiler optimising out
|
|
Ý the test of the flag.
|
|
|
|
|
| Returns - The value of the flag.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC BOOLEAN
|
|
FlagIsTrue(BOOLEAN * flag);
|
|
|
|
#pragma FTK_INIT_FUNCTION(FlagIsTrue)
|
|
|
|
STATIC BOOLEAN
|
|
FlagIsTrue(BOOLEAN * flag)
|
|
{
|
|
MadgePrint1("FlagIsTrue\n");
|
|
|
|
return *flag;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeMapMmioMemory
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter structure.
|
|
|
|
|
| Purpose - Attempt to map in our MMIO memory.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeMapMmioMemory(PMADGE_ADAPTER ndisAdap);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeMapMmioMemory)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeMapMmioMemory(PMADGE_ADAPTER ndisAdap)
|
|
{
|
|
NDIS_PHYSICAL_ADDRESS mmioPhysAddr = NDIS_PHYSICAL_ADDRESS_CONST(0, 0);
|
|
UINT status;
|
|
|
|
NdisSetPhysicalAddressLow(
|
|
mmioPhysAddr,
|
|
ndisAdap->MmioRawAddress
|
|
);
|
|
|
|
status = NdisMMapIoSpace(
|
|
&ndisAdap->MmioVirtualAddress,
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
mmioPhysAddr,
|
|
PCI_MMIO_SIZE
|
|
);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_MEMORY_CONFLICT,
|
|
2,
|
|
initAdapter,
|
|
MADGE_ERRMSG_MAPPING_PCI_MMIO
|
|
);
|
|
}
|
|
else
|
|
{
|
|
ndisAdap->MmioMapped = TRUE;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
#ifndef LINK_FMPLUS
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeReadDownload
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter structure.
|
|
Ý downloadFile -> Pointer to as handle for the download file.
|
|
| download -> Pointer to a holder for a pointer to the
|
|
Ý download image read into memory.
|
|
Ý
|
|
| Purpose - Read the download into memory. If the function returns
|
|
Ý success then must unmap and close *downloadFile.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadDownload(
|
|
PMADGE_ADAPTER ndisAdap,
|
|
NDIS_HANDLE * downloadFile,
|
|
void * * download
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeReadDownload)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeReadDownload(
|
|
PMADGE_ADAPTER ndisAdap,
|
|
NDIS_HANDLE * downloadFile,
|
|
void * * download
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
NDIS_HANDLE imageFile;
|
|
UINT imageLength;
|
|
PVOID imagePtr;
|
|
NDIS_PHYSICAL_ADDRESS highestAddress = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
|
|
DOWNLOAD_FILE_HEADER * downHdrPtr;
|
|
UCHAR * chkPtr;
|
|
ULONG chkSum;
|
|
UINT i;
|
|
|
|
//
|
|
// Open the FastMAC Plus image file.
|
|
//
|
|
|
|
MadgePrint1("NdisOpenFile called\n");
|
|
|
|
NdisOpenFile(
|
|
&status,
|
|
&imageFile,
|
|
&imageLength,
|
|
&FmpImageFileName,
|
|
highestAddress
|
|
);
|
|
|
|
MadgePrint1("NdisOpenFile returned\n");
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
MadgePrint2("NdisOpenFile failed rc= %x\n", status);
|
|
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_INVALID_DOWNLOAD_FILE_ERROR,
|
|
2,
|
|
initAdapter,
|
|
MADGE_ERRMSG_OPEN_IMAGE_FILE
|
|
);
|
|
|
|
return NDIS_STATUS_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Map in the FastMAC Plus image file.
|
|
//
|
|
|
|
NdisMapFile(&status, &imagePtr, imageFile);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_OUT_OF_RESOURCES,
|
|
2,
|
|
initAdapter,
|
|
MADGE_ERRMSG_MAP_IMAGE_FILE
|
|
);
|
|
|
|
NdisCloseFile(imageFile);
|
|
|
|
return NDIS_STATUS_RESOURCES;
|
|
}
|
|
|
|
//
|
|
// Make sure that the image file is valid by checking its checksum,
|
|
// version number and signature.
|
|
//
|
|
|
|
downHdrPtr = (DOWNLOAD_FILE_HEADER *) imagePtr;
|
|
chkPtr = ((UCHAR *) imagePtr) + DOWNLOAD_CHECKSUM_SKIP;
|
|
chkSum = 0;
|
|
|
|
for (i = DOWNLOAD_CHECKSUM_SKIP; i < imageLength; i++)
|
|
{
|
|
DOWNLOAD_CHECKSUM_BYTE(chkSum, *chkPtr);
|
|
chkPtr++;
|
|
}
|
|
|
|
if (!IS_DOWNLOAD_OK(downHdrPtr, chkSum))
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_INVALID_DOWNLOAD_FILE_ERROR,
|
|
2,
|
|
initAdapter,
|
|
MADGE_ERRMSG_BAD_IMAGE_FILE
|
|
);
|
|
|
|
NdisUnmapFile(imageFile);
|
|
NdisCloseFile(imageFile);
|
|
|
|
return NDIS_STATUS_RESOURCES;
|
|
}
|
|
|
|
*downloadFile = imageFile;
|
|
*download = imagePtr;
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
#else
|
|
|
|
#include "fmplus.c"
|
|
|
|
#endif
|
|
|
|
#ifdef _M_IX86
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeArbitrateBufferMemory
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter structure.
|
|
|
|
|
| Purpose - Determine if we can allocate all the shared memory
|
|
Ý we need for DMA buffer space and if we can't then
|
|
Ý reduce our requirements until we can or we reach
|
|
Ý our minimum requirements. If the buffer space cannot
|
|
Ý be aribtrated then the requirements are left as is and
|
|
Ý it is assumed that the FTK initialisation will fail
|
|
Ý and generate an out of memory error.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC VOID
|
|
MadgeArbitrateBufferMemory(PMADGE_ADAPTER ndisAdap);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeArbitrateBufferMemory)
|
|
|
|
STATIC VOID
|
|
MadgeArbitrateBufferMemory(PMADGE_ADAPTER ndisAdap)
|
|
{
|
|
VOID * testVirt;
|
|
VOID * rxVirt;
|
|
VOID * txVirt;
|
|
NDIS_PHYSICAL_ADDRESS testPhys;
|
|
NDIS_PHYSICAL_ADDRESS rxPhys;
|
|
NDIS_PHYSICAL_ADDRESS txPhys;
|
|
ULONG rxBufferSize;
|
|
ULONG txBufferSize;
|
|
UINT maxFrameSize;
|
|
UINT rxSlots;
|
|
UINT txSlots;
|
|
BOOLEAN succeeded;
|
|
BOOLEAN failed;
|
|
BOOLEAN arbitrated;
|
|
|
|
//
|
|
// There doesn't seem to be a problem allocating none
|
|
// shared memory so if we aren't in DMA mode then
|
|
// don't do anything.
|
|
//
|
|
|
|
if (ndisAdap->TransferMode != DMA_DATA_TRANSFER_MODE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// The first bit of shared memory we must have is for the DMA
|
|
// test buffers.
|
|
//
|
|
|
|
testVirt = NULL;
|
|
|
|
NdisMAllocateSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
SCB_TEST_PATTERN_LENGTH + SSB_TEST_PATTERN_LENGTH,
|
|
FALSE,
|
|
&testVirt,
|
|
&testPhys
|
|
);
|
|
|
|
//
|
|
// If we can't allocate the test buffer then just give up.
|
|
//
|
|
|
|
if (testVirt == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// We've got the test buffer memory so now arbitrate the
|
|
// RX/TX buffers. Note: the buffer allocation MUST MATCH
|
|
// THAT IN FTK_USER.C.
|
|
//
|
|
|
|
maxFrameSize = ndisAdap->MaxFrameSize;
|
|
rxSlots = ndisAdap->FastmacRxSlots;
|
|
txSlots = ndisAdap->FastmacTxSlots;
|
|
|
|
failed = FALSE;
|
|
succeeded = FALSE;
|
|
arbitrated = FALSE;
|
|
|
|
while (!failed && !succeeded)
|
|
{
|
|
rxVirt = NULL;
|
|
txVirt = NULL;
|
|
|
|
//
|
|
// Try to allocate the receive buffer.
|
|
//
|
|
|
|
rxBufferSize = ((maxFrameSize + 4 + 32 + 3) & ~3) * rxSlots;
|
|
|
|
NdisMAllocateSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
rxBufferSize,
|
|
FALSE,
|
|
&rxVirt,
|
|
&rxPhys
|
|
);
|
|
|
|
//
|
|
// If we allocated the RX buffer space then try to allocate
|
|
// the TX buffer space.
|
|
//
|
|
|
|
if (rxVirt != NULL)
|
|
{
|
|
txBufferSize = ((maxFrameSize + 3) & ~3) * txSlots;
|
|
|
|
NdisMAllocateSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
txBufferSize,
|
|
FALSE,
|
|
&txVirt,
|
|
&txPhys
|
|
);
|
|
}
|
|
|
|
//
|
|
// Free any buffers we managed to allocate.
|
|
//
|
|
|
|
if (rxVirt != NULL)
|
|
{
|
|
NdisMFreeSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
rxBufferSize,
|
|
FALSE,
|
|
rxVirt,
|
|
rxPhys
|
|
);
|
|
}
|
|
|
|
if (txVirt != NULL)
|
|
{
|
|
NdisMFreeSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
txBufferSize,
|
|
FALSE,
|
|
txVirt,
|
|
txPhys
|
|
);
|
|
}
|
|
|
|
//
|
|
// If we managed to allocate both buffers then we have
|
|
// succeeded.
|
|
//
|
|
|
|
if (rxVirt != NULL && txVirt != NULL)
|
|
{
|
|
succeeded = TRUE;
|
|
}
|
|
|
|
//
|
|
// Otherwise we must reduce our memory requirements.
|
|
//
|
|
|
|
else
|
|
{
|
|
arbitrated = TRUE;
|
|
|
|
//
|
|
// First try reducing the number of transmit slots.
|
|
//
|
|
|
|
if (txSlots > FMPLUS_MIN_TX_SLOTS)
|
|
{
|
|
txSlots--;
|
|
}
|
|
|
|
//
|
|
// Next try reducing the number of receive slots.
|
|
//
|
|
|
|
else if (rxSlots > FMPLUS_MIN_RX_SLOTS)
|
|
{
|
|
rxSlots--;
|
|
}
|
|
|
|
//
|
|
// Finally try reducing the frame size. 1800 bytes has
|
|
// empirically shown to be the minimum value required
|
|
// for the DOMAIN server startup to work at NT installation.
|
|
//
|
|
|
|
else if (maxFrameSize > 1800)
|
|
{
|
|
maxFrameSize -= 512;
|
|
|
|
if (maxFrameSize < 1800)
|
|
{
|
|
maxFrameSize = 1800;
|
|
}
|
|
}
|
|
|
|
//
|
|
// If we can't reduce our buffer requirements any further
|
|
// then fail.
|
|
//
|
|
|
|
else
|
|
{
|
|
failed = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Free the memory for the DMA test buffer.
|
|
//
|
|
|
|
NdisMFreeSharedMemory(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
SCB_TEST_PATTERN_LENGTH + SSB_TEST_PATTERN_LENGTH,
|
|
FALSE,
|
|
testVirt,
|
|
testPhys
|
|
);
|
|
|
|
//
|
|
// If we have succeded then we must update the requirements in
|
|
// adapter structure and if we have changed any values we must
|
|
// write a message to the event log.
|
|
//
|
|
|
|
if (succeeded && arbitrated)
|
|
{
|
|
ndisAdap->MaxFrameSize = maxFrameSize;
|
|
ndisAdap->FastmacRxSlots = rxSlots;
|
|
ndisAdap->FastmacTxSlots = txSlots;
|
|
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
|
|
1,
|
|
initAdapter
|
|
);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeInitAdapter
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter structure.
|
|
|
|
|
| Purpose - Initialise an adapter.
|
|
|
|
|
| Returns - An NDIS3 status code.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeInitAdapter(PMADGE_ADAPTER ndisAdap);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeInitAdapter)
|
|
|
|
STATIC NDIS_STATUS
|
|
MadgeInitAdapter(PMADGE_ADAPTER ndisAdap)
|
|
{
|
|
WORD ftkStatus;
|
|
NDIS_STATUS status;
|
|
PREPARE_ARGS prepare;
|
|
START_ARGS start;
|
|
|
|
#ifndef LINK_FMPLUS
|
|
|
|
NDIS_HANDLE imageFile;
|
|
PVOID imagePtr;
|
|
|
|
#endif
|
|
|
|
MadgePrint1("MadgeInitAdapter started\n");
|
|
|
|
//
|
|
// If we are doing MMIO then we need to map in the MMIO memory.
|
|
// If we fail to map in the memory then default ti PIO.
|
|
//
|
|
|
|
if (ndisAdap->TransferMode == MMIO_DATA_TRANSFER_MODE)
|
|
{
|
|
if (MadgeMapMmioMemory(ndisAdap) != NDIS_STATUS_SUCCESS)
|
|
{
|
|
ndisAdap->TransferMode = PIO_DATA_TRANSFER_MODE;
|
|
}
|
|
}
|
|
|
|
#ifdef _M_IX86
|
|
|
|
//
|
|
// Arbitrate "DMA" buffer memory.
|
|
//
|
|
|
|
MadgeArbitrateBufferMemory(ndisAdap);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Set up the arguments to pass to driver_prepare_adapter.
|
|
//
|
|
|
|
MADGE_ZERO_MEMORY(&prepare, sizeof(PREPARE_ARGS));
|
|
|
|
prepare.user_information = (void *) ndisAdap;
|
|
prepare.number_of_rx_slots = (WORD) ndisAdap->FastmacRxSlots;
|
|
prepare.number_of_tx_slots = (WORD) ndisAdap->FastmacTxSlots;
|
|
prepare.max_frame_size = (WORD) ndisAdap->MaxFrameSize;
|
|
|
|
//
|
|
// Try to prepare the adapter for use.
|
|
//
|
|
|
|
//
|
|
// Mark the fact that the FTK has been called, so that we know if we
|
|
// have to call driver_remove_adapter() when doing clean up.
|
|
//
|
|
|
|
ndisAdap->FtkInitialized = TRUE;
|
|
|
|
MadgePrint1("driver_prepare_adapter called\n");
|
|
|
|
if (!driver_prepare_adapter(&prepare, &(ndisAdap->FtkAdapterHandle)))
|
|
{
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
MadgePrint1("driver_prepare_adapter returned\n");
|
|
MadgePrint2("adapter_handle = %d\n", ndisAdap->FtkAdapterHandle);
|
|
|
|
#ifndef LINK_FMPLUS
|
|
|
|
//
|
|
// Read in the download file.
|
|
//
|
|
|
|
status = MadgeReadDownload(ndisAdap, &imageFile, &imagePtr);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
#endif
|
|
|
|
//
|
|
// Set up the arguments to driver_start_adapter.
|
|
//
|
|
|
|
MADGE_ZERO_MEMORY(&start, sizeof(START_ARGS));
|
|
|
|
start.adapter_card_bus_type = (UINT) ndisAdap->FTKCardBusType;
|
|
|
|
start.io_location = (WORD) ndisAdap->IoLocation1;
|
|
start.transfer_mode = (UINT) ndisAdap->TransferMode;
|
|
start.dma_channel = (WORD) ndisAdap->DmaChannel;
|
|
start.interrupt_number = (WORD) ndisAdap->UsedInISR.InterruptNumber;
|
|
start.set_dma_channel = TRUE;
|
|
start.set_interrupt_number = TRUE;
|
|
start.mmio_base_address = (DWORD) ndisAdap->MmioVirtualAddress;
|
|
start.pci_handle = (DWORD) ndisAdap->SlotNumber;
|
|
|
|
if (ndisAdap->Force16)
|
|
{
|
|
start.set_ring_speed = 16;
|
|
}
|
|
else if (ndisAdap->Force4)
|
|
{
|
|
start.set_ring_speed = 4;
|
|
}
|
|
|
|
start.opening_node_address = ndisAdap->OpeningNodeAddress;
|
|
start.auto_open_option = TRUE;
|
|
|
|
if (ndisAdap->ForceOpen)
|
|
{
|
|
ndisAdap->OpenOptions |= OPEN_OPT_FORCE_OPEN;
|
|
}
|
|
|
|
start.open_options = (WORD) ndisAdap->OpenOptions;
|
|
|
|
start.rx_tx_buffer_size = (WORD) ndisAdap->CardBufferSize;
|
|
|
|
#ifndef LINK_FMPLUS
|
|
|
|
start.code = (DOWNLOAD_IMAGE *)
|
|
(((UCHAR *) imagePtr) + sizeof(DOWNLOAD_FILE_HEADER));
|
|
|
|
#else
|
|
|
|
start.code = (DOWNLOAD_IMAGE *) fmplus_image;
|
|
|
|
#endif
|
|
|
|
MadgePrint1("driver_start_adapter called\n");
|
|
|
|
ftkStatus = driver_start_adapter(
|
|
ndisAdap->FtkAdapterHandle,
|
|
&start,
|
|
&ndisAdap->PermanentNodeAddress
|
|
);
|
|
|
|
MadgePrint1("driver_start_adapter returned\n");
|
|
MadgePrint2("MAC buffer size = %d\n",
|
|
adapter_record[ndisAdap->FtkAdapterHandle
|
|
]->init_block->smart_parms.rx_tx_buffer_size
|
|
);
|
|
|
|
#ifndef LINK_FMPLUS
|
|
|
|
//
|
|
// No matter what we have finished with the FastMAC Plus image file.
|
|
//
|
|
|
|
NdisUnmapFile(imageFile);
|
|
NdisCloseFile(imageFile);
|
|
|
|
#endif
|
|
|
|
if (!ftkStatus)
|
|
{
|
|
MadgePrint1("driver_start_adapter failed\n");
|
|
|
|
//
|
|
// Were it not for the fact that we are going to clean up and fail
|
|
// as soon as we return, we ought to set the CurrentRingState to
|
|
// NdisRingStateOpenFailure here if AutoOpen was selected.
|
|
//
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Warn the user if FastMAC Plus had to reduce the frame size.
|
|
//
|
|
|
|
if (ndisAdap->MaxFrameSize > start.max_frame_size)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
|
|
3,
|
|
initAdapter,
|
|
MADGE_ERRMSG_REDUCE_MAX_FSIZE,
|
|
ndisAdap->MaxFrameSize
|
|
);
|
|
}
|
|
|
|
ndisAdap->MaxFrameSize = start.max_frame_size;
|
|
|
|
//
|
|
// If we did not specify a locally administered address then copy the
|
|
// permanent one across to the local one.
|
|
//
|
|
|
|
if (ndisAdap->OpeningNodeAddress.byte[0] == 0)
|
|
{
|
|
MADGE_MOVE_MEMORY(
|
|
&ndisAdap->OpeningNodeAddress,
|
|
&ndisAdap->PermanentNodeAddress,
|
|
sizeof(ndisAdap->PermanentNodeAddress)
|
|
);
|
|
}
|
|
|
|
//
|
|
// Note that the adapter is open.
|
|
//
|
|
|
|
ndisAdap->CurrentRingState = NdisRingStateOpened;
|
|
ndisAdap->LastOpenStatus = start.open_status;
|
|
|
|
//
|
|
// Nasty hack. If we have a PciT atapter with broken dma and we are
|
|
// running on a multiprocessor we need set the multiprocessor safe
|
|
// PIO flag to make sure that we don't do DIO whilst our interrupt
|
|
// hander is running. Unfortunately we don't know if we have
|
|
// broken DMA until after we've started the adapter.
|
|
//
|
|
|
|
if (ndisAdap->Multiprocessor &&
|
|
adapter_record[ndisAdap->FtkAdapterHandle]->mc32_config ==
|
|
TRN_PCIT_BROKEN_DMA)
|
|
{
|
|
MadgePrint1("Using MP sfae PIO because of PCIT DMA.\n");
|
|
ndisAdap->UseMPSafePIO = TRUE;
|
|
}
|
|
|
|
//
|
|
// Note that we MUST start the receive process, even if we are NOT using
|
|
// auto-open, because FastmacPlus ignores SRBs (including OPEN SRBs) if
|
|
// this has not been done.
|
|
//
|
|
|
|
driver_start_receive_process(ndisAdap->FtkAdapterHandle);
|
|
|
|
//
|
|
// We now need to set the product instance ID. The product instance
|
|
// ID will be set to the contents of ftk_product_inst_id[] if we
|
|
// issue an open SRB, but since Miniports always auto-open we
|
|
// need to generate a set product instance SRB to set it.
|
|
//
|
|
|
|
//
|
|
// Note that we are generating a private SRB (not to be treated
|
|
// as a normal NDIS request), generate the SRB and then wait
|
|
// for it to finish.
|
|
//
|
|
|
|
ndisAdap->PrivateSrbInProgress = TRUE;
|
|
|
|
MadgePrint1("Calling driver_set_product_instance_id\n");
|
|
|
|
driver_set_product_instance_id(
|
|
ndisAdap->FtkAdapterHandle,
|
|
NT_PRODUCT_INSTANCE_ID
|
|
);
|
|
|
|
MadgePrint1("Waiting for SRB to complete\n");
|
|
|
|
while (FlagIsTrue(&ndisAdap->PrivateSrbInProgress))
|
|
NdisMSleep(100);
|
|
|
|
MadgePrint1("MadgeInitAdapter finished\n");
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------
|
|
|
|
|
| Function - MadgeCleanupAdapter
|
|
|
|
|
| Parameters - ndisAdap -> Pointer to an NDIS3 level adapter structure.
|
|
|
|
|
| Purpose - Deallocate the resources associated with an adapter.
|
|
|
|
|
| Returns - Nothing.
|
|
|
|
|
|--------------------------------------------------------------------------*/
|
|
|
|
STATIC VOID
|
|
MadgeCleanupAdapter(PMADGE_ADAPTER ndisAdap)
|
|
{
|
|
BOOLEAN timerOutstanding;
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 1\n");
|
|
|
|
if (ndisAdap->TimerInitialized)
|
|
{
|
|
NdisMCancelTimer(&ndisAdap->WakeUpTimer, &timerOutstanding);
|
|
NdisMCancelTimer(&ndisAdap->CompletionTimer, &timerOutstanding);
|
|
ndisAdap->TimerInitialized = FALSE;
|
|
}
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 2\n");
|
|
|
|
if (ndisAdap->FtkInitialized)
|
|
{
|
|
rxtx_await_empty_tx_slots(ndisAdap->FtkAdapterHandle);
|
|
driver_remove_adapter(ndisAdap->FtkAdapterHandle);
|
|
ndisAdap->FtkInitialized = FALSE;
|
|
}
|
|
|
|
if (ndisAdap->MapRegistersAllocated > 0)
|
|
{
|
|
NdisMFreeMapRegisters(ndisAdap->UsedInISR.MiniportHandle);
|
|
ndisAdap->MapRegistersAllocated = 0;
|
|
}
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 3\n");
|
|
|
|
if (ndisAdap->MmioMapped)
|
|
{
|
|
NdisMUnmapIoSpace(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap->MmioVirtualAddress,
|
|
PCI_MMIO_SIZE
|
|
);
|
|
ndisAdap->MmioMapped = FALSE;
|
|
}
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 4\n");
|
|
|
|
if (ndisAdap->IORange1Initialized)
|
|
{
|
|
NdisMDeregisterIoPortRange(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap->IoLocation1 + ndisAdap->IoLocationBase,
|
|
ndisAdap->IORange1,
|
|
ndisAdap->MappedIOLocation1
|
|
);
|
|
ndisAdap->IORange1Initialized = FALSE;
|
|
}
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 5\n");
|
|
|
|
if (ndisAdap->IORange2Initialized)
|
|
{
|
|
NdisMDeregisterIoPortRange(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
ndisAdap->IoLocation2 + ndisAdap->IoLocationBase,
|
|
ndisAdap->IORange2,
|
|
ndisAdap->MappedIOLocation2
|
|
);
|
|
ndisAdap->IORange2Initialized = FALSE;
|
|
}
|
|
|
|
MadgePrint1("MadgeCleanupAdapter 6\n");
|
|
|
|
if (ndisAdap->ShutdownHandlerRegistered)
|
|
{
|
|
NdisMDeregisterAdapterShutdownHandler(
|
|
ndisAdap->UsedInISR.MiniportHandle
|
|
);
|
|
ndisAdap->ShutdownHandlerRegistered = FALSE;
|
|
|
|
MadgePrint1("De-registered shutdown handler\n");
|
|
}
|
|
|
|
MADGE_FREE_MEMORY(ndisAdap, sizeof(MADGE_ADAPTER));
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - MadgeHalt
|
|
*
|
|
* Parameters - adapterContext -> Pointer to our NDIS level adapter
|
|
* structure.
|
|
*
|
|
* Purpose - Process a call from the NDIS3 wrapper to remove an
|
|
* adapter instance.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID
|
|
MadgeHalt(NDIS_HANDLE adapterContext)
|
|
{
|
|
PMADGE_ADAPTER ndisAdap;
|
|
|
|
MadgePrint1("MadgeHalt started\n");
|
|
|
|
ndisAdap = PMADGE_ADAPTER_FROM_CONTEXT(adapterContext);
|
|
|
|
//
|
|
// The NDIS interface guarantees that all bindings are closed, i.e. all
|
|
// MadgeCloseAdapter calls have completed successfully.
|
|
//
|
|
|
|
ndisAdap->HardwareStatus = NdisHardwareStatusClosing;
|
|
|
|
MadgeCleanupAdapter(ndisAdap);
|
|
|
|
MadgePrint1("MadgeHalt finished\n");
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Function - MadgeTxCompletion
|
|
*
|
|
* Parameters - systemSpecific1 -> Unused.
|
|
* context -> Actually a pointer to our NDIS3 level
|
|
* adapter structure.
|
|
* systemSpecific2 -> Unused.
|
|
* systemSpecific3 -> Unused.
|
|
*
|
|
* Purpose - Call our TX competion routine as a result of a timer.
|
|
*
|
|
* Returns - Nothing.
|
|
*
|
|
****************************************************************************/
|
|
|
|
VOID
|
|
MadgeTxCompletion(
|
|
PVOID systemSpecific1,
|
|
PVOID context,
|
|
PVOID systemSpecific2,
|
|
PVOID systemSpecific3
|
|
)
|
|
{
|
|
PMADGE_ADAPTER ndisAdap = (PMADGE_ADAPTER) context;
|
|
|
|
//
|
|
// Call the TX completion function.
|
|
//
|
|
|
|
rxtx_irq_tx_completion_check(
|
|
ndisAdap->FtkAdapterHandle,
|
|
adapter_record[ndisAdap->FtkAdapterHandle]
|
|
);
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - MadgeInitialise
|
|
*
|
|
* Parameters - openErrorStatus -> Pointer to a holder for an open
|
|
* error status.
|
|
* selectedMediumIndex -> Pointer to a holder for the index
|
|
* of the medium selected.
|
|
* mediumArray -> Array of media types.
|
|
* mediumArraySize -> Size of the media array.
|
|
* miniportHandle -> Miniport adapter handle.
|
|
* wrapperConfigContext -> Handle used when querying the
|
|
* registry.
|
|
*
|
|
* Purpose - Carry out adapter instance initialisation.
|
|
*
|
|
* Returns - An NDIS3 status code.
|
|
*
|
|
***************************************************************************/
|
|
|
|
NDIS_STATUS
|
|
MadgeInitialize(
|
|
PNDIS_STATUS openErrorStatus,
|
|
PUINT selectedMediumIndex,
|
|
PNDIS_MEDIUM mediumArray,
|
|
UINT mediumArraySize,
|
|
NDIS_HANDLE miniportHandle,
|
|
NDIS_HANDLE wrapperConfigContext
|
|
);
|
|
|
|
#pragma FTK_INIT_FUNCTION(MadgeInitialize)
|
|
|
|
NDIS_STATUS
|
|
MadgeInitialize(
|
|
PNDIS_STATUS openErrorStatus,
|
|
PUINT selectedMediumIndex,
|
|
PNDIS_MEDIUM mediumArray,
|
|
UINT mediumArraySize,
|
|
NDIS_HANDLE miniportHandle,
|
|
NDIS_HANDLE wrapperConfigContext
|
|
)
|
|
{
|
|
NDIS_STATUS status;
|
|
PMADGE_ADAPTER ndisAdap;
|
|
NDIS_HANDLE configHandle;
|
|
UINT i;
|
|
|
|
MadgePrint1("MadgeInitialize started\n");
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// Check that the upper protocol knows about token ring and if
|
|
// it does set the index.
|
|
//
|
|
|
|
for (i = 0; i < mediumArraySize; i++)
|
|
{
|
|
if (mediumArray[i] == NdisMedium802_5)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == mediumArraySize)
|
|
{
|
|
return NDIS_STATUS_UNSUPPORTED_MEDIA;
|
|
}
|
|
|
|
*selectedMediumIndex = i;
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// Doing basic sanity checks and allocating some memory for our
|
|
// per-adapter structure.
|
|
//
|
|
|
|
if (wrapperConfigContext == NULL)
|
|
{
|
|
//
|
|
// No registry config. information found by NDIS library for us.
|
|
// We cannot proceed without it.
|
|
//
|
|
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
//
|
|
// Allocate memory for the adapter structure.
|
|
//
|
|
|
|
MADGE_ALLOC_MEMORY(&status, &ndisAdap, sizeof(MADGE_ADAPTER));
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// Failed to allocate adapter structure. Can't go on without it.
|
|
//
|
|
|
|
return status;
|
|
}
|
|
|
|
MADGE_ZERO_MEMORY(ndisAdap, sizeof(MADGE_ADAPTER));
|
|
|
|
MadgePrint2("ndisAdap = %x\n", ndisAdap);
|
|
|
|
//
|
|
// We need the mini port handle early on.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.MiniportHandle = miniportHandle;
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// Read the registry: open the registry, read the contents, and close it
|
|
// again. This will handle adapter parameters and LAAs, and also working
|
|
// out various values to do with interrupt modes.
|
|
//
|
|
|
|
MadgePrint1("NdisOpenConfiguration called\n");
|
|
|
|
NdisOpenConfiguration(
|
|
&status,
|
|
&configHandle,
|
|
wrapperConfigContext
|
|
);
|
|
|
|
MadgePrint1("NdisOpenConfiguration returned\n");
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
MadgePrint2("NdisOpenConfiguration failed rc=%x\n", status);
|
|
MADGE_FREE_MEMORY(ndisAdap, sizeof(MADGE_ADAPTER));
|
|
return status;
|
|
}
|
|
|
|
status = MadgeReadRegistry(
|
|
wrapperConfigContext,
|
|
configHandle,
|
|
ndisAdap
|
|
);
|
|
|
|
NdisCloseConfiguration(configHandle);
|
|
|
|
//
|
|
// We have gleaned all we can from the registry - was it all OK?
|
|
//
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// If Status is not success, it will be either NDIS_STATUS_FAILURE
|
|
// if a parameter was out of range, or it will be the error code
|
|
// returned by NdisReadConfiguration().
|
|
//
|
|
|
|
MadgePrint2("MadgeReadRegistry failed rc = %x\n", status);
|
|
MADGE_FREE_MEMORY(ndisAdap, sizeof(MADGE_ADAPTER));
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// Having read the registry, we can initialize the rest of the fields in
|
|
// the adapter structure.
|
|
//
|
|
|
|
#define I_DATA ActualValue.ParameterData.IntegerData
|
|
|
|
//
|
|
// Copy the values from the Parameter table into the per-adapter struct.
|
|
// This is necessary because the Parameter table will be used again for
|
|
// the next card that is added.
|
|
//
|
|
// Note that we handle the rx/tx slots configuration in a special way.
|
|
// The value of rx/tx slots is set by indexing into a table with the
|
|
// single paramter RxTxSlots, unless RxSlots or TxSlots have been set in
|
|
// which case these values override the values derived from RxTxSlots.
|
|
//
|
|
|
|
switch (MadgeParmTable.RxTxSlots.I_DATA)
|
|
{
|
|
case 0:
|
|
ndisAdap->FastmacTxSlots = 2;
|
|
ndisAdap->FastmacRxSlots = 2;
|
|
break;
|
|
case 1:
|
|
ndisAdap->FastmacTxSlots = 3;
|
|
ndisAdap->FastmacRxSlots = 3;
|
|
break;
|
|
case 2:
|
|
ndisAdap->FastmacTxSlots = 4;
|
|
ndisAdap->FastmacRxSlots = 4;
|
|
break;
|
|
case 3:
|
|
ndisAdap->FastmacTxSlots = 6;
|
|
ndisAdap->FastmacRxSlots = 6;
|
|
break;
|
|
case 4:
|
|
ndisAdap->FastmacTxSlots = 8;
|
|
ndisAdap->FastmacRxSlots = 8;
|
|
break;
|
|
case 5:
|
|
ndisAdap->FastmacTxSlots = 10;
|
|
ndisAdap->FastmacRxSlots = 10;
|
|
break;
|
|
default:
|
|
ndisAdap->FastmacTxSlots = 4;
|
|
ndisAdap->FastmacRxSlots = 4;
|
|
break;
|
|
}
|
|
|
|
if (MadgeParmTable.TxSlots.I_DATA != 0)
|
|
{
|
|
ndisAdap->FastmacTxSlots = MadgeParmTable.TxSlots.I_DATA;
|
|
}
|
|
|
|
if (MadgeParmTable.RxSlots.I_DATA != 0)
|
|
{
|
|
ndisAdap->FastmacRxSlots = MadgeParmTable.RxSlots.I_DATA;
|
|
}
|
|
|
|
MadgePrint3("TX slots = %d RX slots = %d\n",
|
|
ndisAdap->FastmacTxSlots,
|
|
ndisAdap->FastmacRxSlots
|
|
);
|
|
|
|
ndisAdap->MaxFrameSize = MadgeParmTable.MaxFrameSize.I_DATA;
|
|
ndisAdap->CardBufferSize = MadgeParmTable.CardBufferSize.I_DATA;
|
|
ndisAdap->PromiscuousMode = (MadgeParmTable.PromiscuousMode.I_DATA == 1);
|
|
ndisAdap->AlternateIo = (MadgeParmTable.AlternateIo.I_DATA == 1);
|
|
ndisAdap->TestAndXIDEnabled = (MadgeParmTable.TestAndXIDEnabled.I_DATA == 1);
|
|
ndisAdap->ForceOpen = (MadgeParmTable.ForceOpen.I_DATA == 1);
|
|
ndisAdap->Force4 = (MadgeParmTable.Force4.I_DATA == 1);
|
|
ndisAdap->Force16 = (MadgeParmTable.Force16.I_DATA == 1);
|
|
ndisAdap->Multiprocessor = (NdisSystemProcessorCount() > 1);
|
|
|
|
if (ndisAdap->TransferMode != DMA_DATA_TRANSFER_MODE &&
|
|
ndisAdap->Multiprocessor)
|
|
{
|
|
ndisAdap->UseMPSafePIO = TRUE;
|
|
}
|
|
|
|
//
|
|
// If the RingSpeed parameter is present then this overrides the
|
|
// Force4 and Force16 parameters. RingSpeed == 0 means either not
|
|
// present or don't care. RingSpeed == 1 means 4MBits. RingSpeed == 2
|
|
// means 16MBits.
|
|
//
|
|
|
|
switch (MadgeParmTable.RingSpeed.I_DATA)
|
|
{
|
|
case 1:
|
|
ndisAdap->Force4 = TRUE;
|
|
ndisAdap->Force16 = FALSE;
|
|
break;
|
|
|
|
case 2:
|
|
ndisAdap->Force4 = FALSE;
|
|
ndisAdap->Force16 = TRUE;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Initialize the rest of the Adapter structure.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.MiniportHandle = miniportHandle;
|
|
ndisAdap->CurrentLookahead = ndisAdap->MaxFrameSize - FRAME_HEADER_SIZE;
|
|
ndisAdap->CurrentRingState = NdisRingStateClosed;
|
|
ndisAdap->HardwareStatus = NdisHardwareStatusNotReady;
|
|
|
|
//
|
|
// These next few lines are strictly unnecessary because their fields in
|
|
// the structure are already zero from our earlier ZERO_MEMORY() call.
|
|
//
|
|
|
|
ndisAdap->UsedInISR.SrbRequestCompleted = FALSE;
|
|
ndisAdap->UsedInISR.SrbRequestStatus = FALSE;
|
|
ndisAdap->DprInProgress = FALSE;
|
|
|
|
//
|
|
// One nasty piece of hackery for Smart16 cards, whereby we must add to
|
|
// the IoLocation 0x1000 if the Alternate switch is true.
|
|
//
|
|
|
|
if (ndisAdap->NTCardBusType == NdisInterfaceIsa &&
|
|
ndisAdap->IoLocation1 > 0x3a20 &&
|
|
ndisAdap->AlternateIo)
|
|
{
|
|
ndisAdap->IoLocation1 += 0x1000;
|
|
}
|
|
|
|
//
|
|
// We need to know where the end of the first range of IO locations
|
|
// we use is.
|
|
//
|
|
|
|
ndisAdap->IORange1End = ndisAdap->IoLocation1 + ndisAdap->IORange1 - 1;
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// We can now try to register the adapter. This involves filling in the
|
|
// AdapterInformation structure and calling NdisRegisterAdapter(). See
|
|
// the function MadgeRegisterAdapter for details.
|
|
//
|
|
|
|
if ((status = MadgeRegisterAdapter(
|
|
ndisAdap,
|
|
wrapperConfigContext
|
|
)) != NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// Either we failed to allocate memory for the adapter information
|
|
// structure, or the NdisRegisterAdapter() call failed.
|
|
//
|
|
|
|
MadgePrint2("MadgeRegisterAdapter failed rc = %x\n", status);
|
|
MADGE_FREE_MEMORY(ndisAdap, sizeof(MADGE_ADAPTER));
|
|
return status;
|
|
}
|
|
|
|
//
|
|
// ---------------------------------------------------------------------
|
|
// We are now into the last stages of initialization. This is going to
|
|
// cause to be allocated several more resources (in the form of kernel
|
|
// objects, filter databases, FTK structures, interrupt channels, ...)
|
|
// so from here on we have to be a lot more careful about cleaning up.
|
|
//
|
|
|
|
ndisAdap->HardwareStatus = NdisHardwareStatusInitializing;
|
|
|
|
//
|
|
// Call the FTK to download the MAC code to the card and initialize it.
|
|
//
|
|
|
|
status = MadgeInitAdapter(ndisAdap);
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
//
|
|
// If it was an FTK generated error then log an appropriate event.
|
|
//
|
|
|
|
if (status == NDIS_STATUS_FAILURE)
|
|
{
|
|
BYTE error_type;
|
|
BYTE error_value;
|
|
char * error_message;
|
|
|
|
driver_explain_error(
|
|
ndisAdap->FtkAdapterHandle,
|
|
&error_type,
|
|
&error_value,
|
|
&error_message
|
|
);
|
|
|
|
MadgePrint3("FTK error %02x, %02x\n", error_type, error_value);
|
|
|
|
//
|
|
// To keep Microsoft happy we will generate special error
|
|
// messages for some of the more common error conditions.
|
|
//
|
|
|
|
//
|
|
// An open error is probably because the cable isn't plugged in.
|
|
//
|
|
|
|
if (error_type == ERROR_TYPE_OPEN ||
|
|
error_type == ERROR_TYPE_AUTO_OPEN)
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER,
|
|
4,
|
|
madgeInitialize,
|
|
MADGE_ERRMSG_INITIAL_INIT,
|
|
(ULONG) error_type,
|
|
(ULONG) error_value
|
|
);
|
|
}
|
|
else
|
|
{
|
|
NdisWriteErrorLogEntry(
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
NDIS_ERROR_CODE_HARDWARE_FAILURE,
|
|
4,
|
|
madgeInitialize,
|
|
MADGE_ERRMSG_INITIAL_INIT,
|
|
(ULONG) error_type,
|
|
(ULONG) error_value
|
|
);
|
|
}
|
|
}
|
|
|
|
//
|
|
// In any case, tidy up the adapter and abort.
|
|
//
|
|
|
|
MadgeCleanupAdapter(ndisAdap);
|
|
return status;
|
|
}
|
|
|
|
ndisAdap->HardwareStatus = NdisHardwareStatusReady;
|
|
|
|
//
|
|
// Set up the ring status monitor function.
|
|
//
|
|
|
|
NdisMInitializeTimer(
|
|
&ndisAdap->WakeUpTimer,
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
(PVOID) MadgeGetAdapterStatus,
|
|
ndisAdap
|
|
);
|
|
|
|
NdisMSetTimer(&ndisAdap->WakeUpTimer, EVERY_2_SECONDS);
|
|
|
|
NdisMInitializeTimer(
|
|
&ndisAdap->CompletionTimer,
|
|
ndisAdap->UsedInISR.MiniportHandle,
|
|
(PVOID) MadgeTxCompletion,
|
|
ndisAdap
|
|
);
|
|
|
|
ndisAdap->TimerInitialized = TRUE;
|
|
|
|
MadgePrint1("MadgeInitialize finished\n");
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* Function - DriverEntry
|
|
*
|
|
* Parameters - driverObject -> Pointer to a driver object.
|
|
* registryPath -> Path to our configuration information in
|
|
* the registry.
|
|
*
|
|
* Purpose - Carry out the driver (as opposed to adapter instance)
|
|
* initialisation. This is the main entry point.
|
|
*
|
|
* Returns - An NDIS3 status code.
|
|
*
|
|
***************************************************************************/
|
|
|
|
NDIS_STATUS
|
|
DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath);
|
|
|
|
#pragma FTK_INIT_FUNCTION(DriverEntry)
|
|
|
|
NDIS_STATUS
|
|
DriverEntry(PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath)
|
|
{
|
|
NDIS_HANDLE ndisWrapperHandle;
|
|
NDIS_STATUS status;
|
|
NDIS_MINIPORT_CHARACTERISTICS madgeChar;
|
|
UINT i;
|
|
|
|
MadgePrint1("DriverEntry starting\n");
|
|
|
|
//
|
|
// We are obliged first of all to initialize the NDIS wrapper.
|
|
//
|
|
|
|
MadgePrint1("NdisMInitializeWrapper called\n");
|
|
|
|
NdisMInitializeWrapper(
|
|
&ndisWrapperHandle,
|
|
driverObject,
|
|
registryPath,
|
|
NULL
|
|
);
|
|
|
|
MadgePrint1("NdisMInitializeWrapper returned\n");
|
|
|
|
//
|
|
// Decode any hidden strings here, for use later in MacAddAdapter. This
|
|
// only applies to PromiscuousMode support at the moment.
|
|
//
|
|
|
|
for (i = 0;
|
|
i < MadgeParmTable.PromiscuousMode.Keyword.Length /
|
|
sizeof(*(MadgeParmTable.PromiscuousMode.Keyword.Buffer));
|
|
i++)
|
|
{
|
|
MadgeParmTable.PromiscuousMode.Keyword.Buffer[i] -= HIDDEN_OFFS;
|
|
}
|
|
|
|
//
|
|
// Fill in the characteristics table - this lists all the driver entry
|
|
// points that may be called by the NDIS wrapper.
|
|
//
|
|
|
|
madgeChar.MajorNdisVersion = MADGE_NDIS_MAJOR_VERSION;
|
|
madgeChar.MinorNdisVersion = MADGE_NDIS_MINOR_VERSION;
|
|
madgeChar.CheckForHangHandler = MadgeCheckForHang;
|
|
madgeChar.DisableInterruptHandler = MadgeDisableInterrupts;
|
|
madgeChar.EnableInterruptHandler = MadgeEnableInterrupts;
|
|
madgeChar.HaltHandler = MadgeHalt;
|
|
madgeChar.HandleInterruptHandler = MadgeHandleInterrupt;
|
|
madgeChar.InitializeHandler = MadgeInitialize;
|
|
madgeChar.ISRHandler = MadgeISR;
|
|
madgeChar.QueryInformationHandler = MadgeQueryInformation;
|
|
madgeChar.ReconfigureHandler = NULL;
|
|
madgeChar.ResetHandler = MadgeReset;
|
|
madgeChar.SendHandler = MadgeSend;
|
|
madgeChar.SetInformationHandler = MadgeSetInformation;
|
|
madgeChar.TransferDataHandler = MadgeTransferData;
|
|
|
|
//
|
|
// Register the miniport driver with NDIS library.
|
|
//
|
|
|
|
MadgePrint1("NdisMRegisterMiniport called\n");
|
|
|
|
status = NdisMRegisterMiniport(
|
|
ndisWrapperHandle,
|
|
&madgeChar,
|
|
sizeof(madgeChar)
|
|
);
|
|
|
|
MadgePrint1("NdisMRegisterMiniport returned\n");
|
|
|
|
if (status != NDIS_STATUS_SUCCESS)
|
|
{
|
|
MadgePrint2("NdisMRegisterMiniport failed rc=%x\n", status);
|
|
NdisTerminateWrapper(ndisWrapperHandle, NULL);
|
|
return NDIS_STATUS_FAILURE;
|
|
}
|
|
|
|
MadgePrint1("DriverEntry finished\n");
|
|
|
|
return NDIS_STATUS_SUCCESS;
|
|
}
|
|
|
|
|
|
/******** End of MADGE.C ***************************************************/
|
|
|