2386 lines
65 KiB
C
Raw Normal View History

2001-01-01 00:00:00 +01:00
//
// Pcimac.c - Main file for pcimac miniport wan driver
//
//
//
//
#include <ndis.h>
#include <ndiswan.h>
#include <mytypes.h>
#include <mydefs.h>
#include <opcodes.h>
#include <disp.h>
#include <adapter.h>
#include <util.h>
#include <idd.h>
#include <mtl.h>
#include <cm.h>
#include <tapioid.h>
#include <res.h>
#include <trc.h>
#include <io.h>
#include <ansihelp.h>
/* driver global vars */
DRIVER_BLOCK Pcimac;
ULONG DigiDebugLevel = ( DIGIERRORS | DIGIBUGCHECK | DIGIINIT );
ULONG DigiDontLoadDriver = FALSE;
USHORT MCAIOAddressTable[] = { 0x108, 0x118,
0x128, 0x208,
0x228, 0x308,
0x328, 0 };
#if !BINARY_COMPATIBLE
/* store location for prev. ioctl handler */
NTSTATUS (*PrevIoctl)(DEVICE_OBJECT* DeviceObject, IRP* Irp) = NULL;
#endif
/* forward for external name manager */
VOID BindName(ADAPTER *Adapter, BOOL create);
//VOID RegistryInit (VOID);
//VOID NdisTapiRequest(PNDIS_STATUS, NDIS_HANDLE, PNDIS_REQUEST);
ULONG
GetBaseConfigParams(
CONFIGPARAM *ConfigParam,
CHAR *Key
);
ULONG
GetLineConfigParams(
CONFIGPARAM *ConfigParam,
ULONG LineNumber,
CHAR *Key
);
ULONG
GetLTermConfigParams(
CONFIGPARAM *ConfigParam,
ULONG LineNumber,
ULONG LTermNumber,
CHAR *Key
);
VOID
IdpGetEaddrFromNvram(
IDD *idd,
CM *cm,
USHORT Line,
USHORT LineIndex
);
VOID
AdpGetEaddrFromNvram(
IDD *idd,
CM *cm,
USHORT Line,
USHORT LineIndex
);
NTSTATUS PcimacInitMCA( NDIS_HANDLE AdapterHandle,
PULONG BaseIO,
PULONG BaseMemory,
ULONG SlotNumber );
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath );
/* driver entry point */
#pragma NDIS_INIT_FUNCTION( DriverEntry )
NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath )
/*++
Routine Description:
Entry point for loading driver.
Arguments:
DriverObject - Pointer to this drivers object.
RegistryPath - Pointer to a unicode string which points to this
drivers registry entry.
Return Value:
STATUS_SUCCESS - If the driver was successfully loaded, otherwise,
a value which indicates why it wasn't able to load.
--*/
{
ULONG RetVal, n, m;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_HANDLE NdisWrapperHandle;
NDIS_MINIPORT_CHARACTERISTICS MiniportChars;
PWCHAR path;
ULONG DebugLevel;
ULONG zero = 0;
ULONG shouldBreak = 0;
#if !BINARY_COMPATIBLE
ULONG defaultMemPrintFlags=MEM_PRINT_FLAG_FILE;
RTL_QUERY_REGISTRY_TABLE paramTable[5];
//
// First, read the registry to determine some initial information.
//
DigiInitMem( 'irbD' );
if( path = DigiAllocMem( PagedPool,
RegistryPath->Length+sizeof(WCHAR) ))
{
RtlZeroMemory( &paramTable[0], sizeof(paramTable) );
RtlZeroMemory( path, RegistryPath->Length+sizeof(WCHAR) );
RtlMoveMemory( path, RegistryPath->Buffer, RegistryPath->Length );
paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[0].Name = L"DigiBreakOnEntry";
paramTable[0].EntryContext = &shouldBreak;
paramTable[0].DefaultType = REG_DWORD;
paramTable[0].DefaultData = &zero;
paramTable[0].DefaultLength = sizeof(ULONG);
paramTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[1].Name = L"DigiDebugLevel";
paramTable[1].EntryContext = &DebugLevel;
paramTable[1].DefaultType = REG_DWORD;
paramTable[1].DefaultData = &DigiDebugLevel;
paramTable[1].DefaultLength = sizeof(ULONG);
paramTable[2].Flags = RTL_QUERY_REGISTRY_DIRECT;
paramTable[2].Name = L"DigiPrintFlags";
paramTable[2].EntryContext = &DigiPrintFlags;
paramTable[2].DefaultType = REG_DWORD;
paramTable[2].DefaultData = &defaultMemPrintFlags;
paramTable[2].DefaultLength = sizeof(ULONG);
if( !NT_SUCCESS(RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
path,
&paramTable[0],
NULL, NULL )))
{
// No, don't break on entry if there isn't anything to over-
// ride.
shouldBreak = 0;
// Set debug level to what ever was compiled into the driver.
DebugLevel = DigiDebugLevel;
}
}
DigiDebugLevel = DebugLevel;
if( shouldBreak )
{
DbgBreakPoint();
}
if( DigiDontLoadDriver )
return( STATUS_CANCELLED );
MemPrintPreInitSettings( "\\SystemRoot\\digibri.log",
(65536 * 8) );
MemPrintInitialize();
#endif
NdisZeroMemory(&Pcimac, sizeof(DRIVER_BLOCK));
/* initialize ndis wrapper */
NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
/* initialize debug support */
D_LOG(DIGIINIT, ("PCIMAC WanMiniport NT Driver, Copyright Digi Intl. Inc, 1992-1994\n"));
D_LOG(DIGIINIT, ("DriverObject: 0x%x\n", DriverObject));
D_LOG(DIGIINIT, ("RegisteryPath: 0x%x\n", RegistryPath));
D_LOG(DIGIINIT, ("WrapperHandle: 0x%x\n", NdisWrapperHandle));
Pcimac.NdisWrapperHandle = NdisWrapperHandle;
NdisAllocateSpinLock (&Pcimac.lock);
/* initialize classes */
if ((RetVal = idd_init()) != IDD_E_SUCC)
goto exit_idd_error;
if ((RetVal = cm_init()) != CM_E_SUCC)
goto exit_cm_error;
if ((RetVal = res_init()) != RES_E_SUCC)
goto exit_res_error;
NdisZeroMemory(&MiniportChars,
sizeof(NDIS_MINIPORT_CHARACTERISTICS));
MiniportChars.MajorNdisVersion = NDIS_MAJOR_VER;
MiniportChars.MinorNdisVersion = NDIS_MINOR_VER;
MiniportChars.Reserved = NDIS_USE_WAN_WRAPPER;
MiniportChars.CheckForHangHandler = PcimacCheckForHang;
MiniportChars.DisableInterruptHandler = NULL;
MiniportChars.EnableInterruptHandler = NULL;
MiniportChars.HaltHandler = PcimacHalt;
MiniportChars.HandleInterruptHandler = NULL;
MiniportChars.InitializeHandler = PcimacInitialize;
MiniportChars.ISRHandler = NULL;
MiniportChars.QueryInformationHandler = PcimacSetQueryInfo;
MiniportChars.ReconfigureHandler = PcimacReconfigure;
MiniportChars.ResetHandler = PcimacReset;
MiniportChars.WanSendHandler = PcimacSend;
MiniportChars.SetInformationHandler = PcimacSetQueryInfo;
MiniportChars.WanTransferDataHandler = NULL;
NdisMRegisterMiniport (NdisWrapperHandle,
(PNDIS_MINIPORT_CHARACTERISTICS)&MiniportChars,
sizeof(MiniportChars));
if (!EnumAdaptersInSystem())
goto exit_event_error;
/* initialize ioctl filter */
#if !BINARY_COMPATIBLE
PrevIoctl = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL];
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PcimacIoctl;
#endif
//
// get an adapter to create a binding I/O name binding to
//
for( n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++ )
{
ADAPTER *Adapter = Pcimac.AdapterTbl[n];
if (Adapter)
{
/* create external name binding */
BindName(Adapter, TRUE);
break;
}
}
//
// turn off the trace on all idd's in the system
//
for (n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++)
{
ADAPTER *Adapter = Pcimac.AdapterTbl[n];
IDD_MSG msg;
if (Adapter)
{
for (m = 0; m < MAX_IDD_PER_ADAPTER; m++)
{
IDD *idd = Adapter->IddTbl[m];
if (idd)
{
/* issue idd command to stop trace */
NdisZeroMemory(&msg, sizeof(msg));
msg.opcode = CMD_TRC_OFF;
idd_send_msg(idd, &msg, IDD_PORT_CMD_TX, NULL, NULL);
}
}
}
}
D_LOG(D_EXIT, ("DriverEntry: exit success!\n"));
/* if successful here, done */
return(STATUS_SUCCESS);
exit_event_error:
D_LOG(D_ALWAYS, ("EventError!\n"));
res_term();
exit_res_error:
D_LOG(D_ALWAYS, ("ResError!\n"));
cm_term();
exit_cm_error:
exit_idd_error:
D_LOG(D_ALWAYS, ("CmIddError!\n"));
NdisFreeSpinLock(&Pcimac.lock);
NdisTerminateWrapper(Pcimac.NdisWrapperHandle, NULL);
#if !BINARY_COMPATIBLE
if( path )
{
DigiFreeMem(path);
}
MemPrintQuit();
#endif
return(NDIS_STATUS_FAILURE);
}
BOOLEAN
PcimacCheckForHang(
NDIS_HANDLE AdapterContext
)
{
ULONG n, IdpCounter = 0;
ADAPTER *Adapter = (ADAPTER *)AdapterContext;
BOOLEAN ReturnStatus = FALSE;
D_LOG(D_ENTRY, ("PcimacCheckForHang: Adapter: 0x%lx\n", AdapterContext));
//
// for all idd's that belong to this adpater
//
for (n = 0; Adapter->IddTbl[n] && n < MAX_IDD_PER_ADAPTER; n++)
{
IDD *idd = Adapter->IddTbl[n];
//
// see if this idd is dead
//
if (!idd || idd->state == IDD_S_SHUTDOWN)
continue;
IdpCounter++;
}
//
// if there are no idps alive on this adapter tell the wrapper
//
if (!IdpCounter)
ReturnStatus = TRUE;
D_LOG(D_ALWAYS, ("PcimacCheckForHang: ReturnStatus: %d\n", ReturnStatus));
return(ReturnStatus);
}
VOID
PcimacHalt(
NDIS_HANDLE AdapterContext
)
{
ULONG n;
ADAPTER *Adapter = (ADAPTER*)AdapterContext;
D_LOG(D_ENTRY, ("PcimacHalt: Adapter: 0x%lx\n", AdapterContext));
DbgPrint("PcimacHalt: Adapter: 0x%lx\n", AdapterContext);
//
// destroy cm objects
//
for (n = 0; n < MAX_CM_PER_ADAPTER; n++)
{
CM *cm = Adapter->CmTbl[n];
Adapter->CmTbl[n] = NULL;
if (cm)
cm_destroy(cm);
}
//
// destroy mtl objects
//
for (n = 0; n < MAX_MTL_PER_ADAPTER; n++)
{
MTL *mtl = Adapter->MtlTbl[n];
Adapter->MtlTbl[n] = NULL;
if (mtl)
mtl_destroy(mtl);
}
//
// destroy idd objects
//
for (n = 0; n < MAX_IDD_PER_ADAPTER; n++)
{
IDD *idd = (IDD*)Adapter->IddTbl[n];
Adapter->IddTbl[n] = NULL;
if (idd)
idd_destroy(idd);
}
/* delete external name binding */
BindName(Adapter, FALSE);
//
// deregister adapter
//
AdapterDestroy(Adapter);
}
#pragma NDIS_INIT_FUNCTION(PcimacInitialize)
NDIS_STATUS PcimacInitialize( PNDIS_STATUS OpenErrorStatus,
PUINT SelectMediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE AdapterHandle,
NDIS_HANDLE WrapperConfigurationContext )
{
ADAPTER *Adapter;
USHORT BoardType, NumberOfLines, NumberOfLTerms, BoardNumber;
ULONG BaseMem, BaseIO, n, m, l, IddStarted = 0;
PVOID VBaseMem, VBaseIO;
ANSI_STRING AnsiStr;
NDIS_STRING NdisStr;
CHAR DefName[128];
NDIS_STATUS RetVal = NDIS_STATUS_SUCCESS;
CONFIGPARAM ConfigParam;
NDIS_INTERFACE_TYPE NdisInterfaceType = NdisInterfaceIsa;
NDIS_PHYSICAL_ADDRESS MemPhyAddr;
NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
D_LOG(D_ENTRY, ("PcimacInitialize: AdapterHandle: 0x%x\n", AdapterHandle));
for (n = 0; n < MediumArraySize; n++)
if (MediumArray[n] == NdisMediumWan)
break;
if (n == MediumArraySize)
return(NDIS_STATUS_UNSUPPORTED_MEDIA);
*SelectMediumIndex = n;
//
// allocate control block for this adapter
//
NdisAllocateMemory((PVOID*)&Adapter,
sizeof(ADAPTER),
0,
HighestAcceptableMax);
if ( !Adapter)
{
D_LOG(D_ALWAYS, ("PcimacInitiailize: Adapter memory allocate failed!\n"));
return (NDIS_STATUS_ADAPTER_NOT_FOUND);
}
D_LOG(D_ALWAYS, ("PcimacInitialize: Allocated an Adapter: 0x%lx\n", Adapter));
NdisZeroMemory(Adapter, sizeof(ADAPTER));
//
// store adapter in global structure
//
for (n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++)
{
if (!Pcimac.AdapterTbl[n])
{
Pcimac.AdapterTbl[n] = Adapter;
Pcimac.NumberOfAdaptersInSystem++;
BoardNumber = (USHORT)n;
break;
}
}
//
// if no room destroy and leave
//
if (n >= MAX_ADAPTERS_IN_SYSTEM)
{
D_LOG(D_ALWAYS, ("PcimacInitialize: No room in Adapter Table\n"));
NdisFreeMemory(Adapter, sizeof(ADAPTER), 0);
return (NDIS_STATUS_ADAPTER_NOT_FOUND);
}
//
// set in driver access lock
//
// NdisAllocateSpinLock (&Adapter->InDriverLock);
//
// store adapter handle
//
Adapter->Handle = AdapterHandle;
//
// initialize adapter specific timers
//
NdisMInitializeTimer(&Adapter->IddPollTimer, Adapter->Handle, IddPollFunction, Adapter);
NdisMSetTimer(&Adapter->IddPollTimer, IDD_POLL_T);
NdisMInitializeTimer(&Adapter->MtlPollTimer, Adapter->Handle, MtlPollFunction, Adapter);
NdisMSetTimer(&Adapter->MtlPollTimer, MTL_POLL_T);
NdisMInitializeTimer(&Adapter->CmPollTimer, Adapter->Handle, CmPollFunction, Adapter);
NdisMSetTimer(&Adapter->CmPollTimer, CM_POLL_T);
ConfigParam.AdapterHandle = AdapterHandle;
//
// Open registry
//
NdisOpenConfiguration(&RetVal, &ConfigParam.ConfigHandle, WrapperConfigurationContext);
if (RetVal != NDIS_STATUS_SUCCESS)
{
D_LOG(D_ALWAYS, ("PcimacInitialize: Error Opening Config: RetVal: 0x%x\n", RetVal));
NdisWriteErrorLogEntry (AdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
1,
0);
goto InitErrorExit;
}
//
// read registry board type
//
ConfigParam.StringLen = sizeof(ConfigParam.String);
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetBaseConfigParams(&ConfigParam, PCIMAC_KEY_BOARDTYPE))
goto InitErrorExit;
if (!__strncmp(ConfigParam.String, "PCIMAC4", 7))
BoardType = IDD_BT_PCIMAC4;
else if (!__strncmp(ConfigParam.String, "PCIMAC - ISA", 12))
BoardType = IDD_BT_PCIMAC;
else if (!__strncmp(ConfigParam.String, "PCIMAC - MC", 11))
{
NdisInterfaceType = NdisInterfaceMca;
BoardType = IDD_BT_MCIMAC;
}
else if (!__strncmp(ConfigParam.String, "DATAFIRE - ISA1U", 16))
BoardType = IDD_BT_DATAFIREU;
else if (!__strncmp(ConfigParam.String, "DATAFIRE - ISA1ST", 17))
BoardType = IDD_BT_DATAFIREST;
else if (!__strncmp(ConfigParam.String, "DATAFIRE - ISA4ST", 17))
BoardType = IDD_BT_DATAFIRE4ST;
else
{
D_LOG(D_ALWAYS, ("PcimacInitialize: Invalid BoardType: %s\n", ConfigParam.String));
goto InitErrorExit;
}
//
// save board type
//
Adapter->BoardType = BoardType;
//
// set miniport attributes (only isa for now)
//
NdisMSetAttributes( AdapterHandle, Adapter, FALSE, NdisInterfaceType );
//
// read registry base io
//
ConfigParam.StringLen = 0;
ConfigParam.ParamType = NdisParameterInteger;
ConfigParam.MustBePresent = TRUE;
if (!GetBaseConfigParams(&ConfigParam,PCIMAC_KEY_BASEIO))
goto InitErrorExit;
BaseIO = ConfigParam.Value;
if( NdisInterfaceType != NdisInterfaceMca )
{
//
// save base I/O for this adapter
//
Adapter->BaseIO = BaseIO;
}
else
{
//
// Must be a MCA adapter.
//
// Note, BaseIO should be the slot number for this adapter instance.
//
RetVal = PcimacInitMCA( AdapterHandle,
&Adapter->BaseIO,
&Adapter->BaseMem,
BaseIO );
BaseMem = Adapter->BaseMem;
BaseIO = Adapter->BaseIO;
if( RetVal != NDIS_STATUS_SUCCESS )
goto InitErrorExit;
}
//
// register I/O range
//
RetVal = NdisMRegisterIoPortRange(&VBaseIO,
AdapterHandle,
BaseIO,
8);
if (RetVal != NDIS_STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
0);
goto InitErrorExit;
}
Adapter->VBaseIO = VBaseIO;
if( (BoardType != IDD_BT_DATAFIREU) &&
(BoardType != IDD_BT_DATAFIREST) &&
(BoardType != IDD_BT_DATAFIRE4ST) )
{
//
// This is a PCIMAC family of adapters
//
//
// read registry base mem
//
if( NdisInterfaceType != NdisInterfaceMca )
{
ConfigParam.StringLen = 0;
ConfigParam.ParamType = NdisParameterInteger;
ConfigParam.MustBePresent = TRUE;
if( !GetBaseConfigParams(&ConfigParam, PCIMAC_KEY_BASEMEM) )
goto InitErrorExit;
BaseMem = ConfigParam.Value;
//
// save base memory for this adapter
//
Adapter->BaseMem = BaseMem;
}
//
// since our adapters can share the same base memory we need to
// see if we have already mapped this memory range. if we have already
// mapped the memory once then save that previous value
//
for (n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++)
{
ADAPTER *PreviousAdapter = Pcimac.AdapterTbl[n];
//
// if this is a valid adapter, this is not the current adapter, and
// this adapter has the same shared memory address as the current
// adapter, then use this adapters mapped memory for the current
// adpaters mapped memory
//
if (PreviousAdapter &&
(PreviousAdapter != Adapter) &&
(PreviousAdapter->BaseMem == Adapter->BaseMem))
{
VBaseMem = PreviousAdapter->VBaseMem;
break;
}
}
//
// if we did not find a previous adapter with this memory range
// we need to map this memory range
//
if (n >= MAX_ADAPTERS_IN_SYSTEM)
{
//
// map our physical memory into virtual memory
//
NdisSetPhysicalAddressHigh(MemPhyAddr, 0);
NdisSetPhysicalAddressLow(MemPhyAddr, BaseMem);
RetVal = NdisMMapIoSpace(&VBaseMem,
AdapterHandle,
MemPhyAddr,
0x4000);
if (RetVal != NDIS_STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_RESOURCE_CONFLICT,
0);
goto InitErrorExit;
}
Adapter->VBaseMem = VBaseMem;
}
}
//
// read registry name
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = sizeof(Adapter->Name);
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetBaseConfigParams(&ConfigParam, PCIMAC_KEY_BOARDNAME))
goto InitErrorExit;
NdisMoveMemory( Adapter->Name,
ConfigParam.String,
ConfigParam.StringLen );
//
// read the number of lines for this board
//
ConfigParam.StringLen = 0;
ConfigParam.ParamType = NdisParameterInteger;
ConfigParam.MustBePresent = TRUE;
if (!GetBaseConfigParams(&ConfigParam, PCIMAC_KEY_NUMLINES))
NumberOfLines = (BoardType == IDD_BT_PCIMAC4) ? 4 : 1;
else
NumberOfLines = (USHORT)ConfigParam.Value;
//
// for number of lines
//
for (n = 0; n < NumberOfLines; n++)
{
IDD *idd;
//
// Create idd object
//
if (idd_create(&idd, BoardType) != IDD_E_SUCC)
{
NdisWriteErrorLogEntry (AdapterHandle,
NDIS_ERROR_CODE_OUT_OF_RESOURCES,
0);
goto InitErrorExit;
}
//
// store idd in idd table
//
for (l = 0; l < MAX_IDD_PER_ADAPTER; l++)
{
if (!Adapter->IddTbl[l])
{
Adapter->IddTbl[l] = idd;
break;
}
}
Adapter->NumberOfIddOnAdapter++;
//
// set idd physical base i/o and memory
//
idd->phw.base_io = BaseIO;
idd->phw.base_mem = BaseMem;
//
// set idd virtual base i/o and memory
//
idd->vhw.vbase_io = (ULONG)VBaseIO;
idd->vhw.vmem = VBaseMem;
//
// create an i/o resource manager for this idd
//
idd->res_io = res_create(RES_CLASS_IO, (ULONG)BaseIO);
//
// create a memory resource manager for this idd
//
idd->res_mem = res_create(RES_CLASS_MEM, (ULONG)BaseMem);
res_set_data(idd->res_mem, (ULONG)VBaseMem);
//
// save adapter handle
//
idd->adapter_handle = AdapterHandle;
//
// save the board number of this idd
//
idd->bnumber = BoardNumber;
//
// save the line number of this idd
//
// idd->bline = (USHORT)NumberOfLines - 1 - n;
idd->bline = (USHORT)n;
//
// save the board type that this idd belongs to
//
idd->btype = BoardType;
if(idd->CheckIO(idd))
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
0);
goto InitErrorExit;
}
//
// read registry line name
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = sizeof(idd->name);
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetLineConfigParams(&ConfigParam, n, PCIMAC_KEY_LINENAME))
goto InitErrorExit;
sprintf(idd->name, "%s-%s", Adapter->Name, ConfigParam.String);
// NdisMoveMemory(idd->name,
// ConfigParam.String,
// ConfigParam.StringLen);
//
// read registry idp file name
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = sizeof(idd->phw.idp_bin);
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetLineConfigParams(&ConfigParam, n, PCIMAC_KEY_IDPFILENAME))
goto InitErrorExit;
NdisMoveMemory(idd->phw.idp_bin,
ConfigParam.String,
ConfigParam.StringLen);
//
// Try to open idp bin file
//
RtlInitAnsiString(&AnsiStr, idd->phw.idp_bin);
//
// allocate buffer and turn ansi to unicode
//
RtlAnsiStringToUnicodeString(&NdisStr, &AnsiStr, TRUE);
NdisOpenFile(&RetVal,
&idd->phw.fbin,
&idd->phw.fbin_len,
&NdisStr,
HighestAcceptableMax);
//
// free up unicode string buffer
//
RtlFreeUnicodeString(&NdisStr);
if (RetVal != NDIS_STATUS_SUCCESS)
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
0);
goto InitErrorExit;
}
//
// read registry switch style
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetLineConfigParams(&ConfigParam, n, PCIMAC_KEY_SWITCHSTYLE))
goto InitErrorExit;
//
// added to support the new switch styles
//
CmSetSwitchStyle(ConfigParam.String);
idd_add_def(idd, "q931.style", ConfigParam.String);
//
// read registry terminal management
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = TRUE;
if (!GetLineConfigParams(&ConfigParam, n,
PCIMAC_KEY_TERMINALMANAGEMENT))
goto InitErrorExit;
idd_add_def(idd, "q931.tm", ConfigParam.String);
//
// read WaitForL3 value
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = FALSE;
if (!GetLineConfigParams(&ConfigParam, n,
PCIMAC_KEY_WAITFORL3))
strcpy(ConfigParam.String, "5");
idd_add_def(idd, "q931.wait_l3", ConfigParam.String);
//
// read registry logical terminals
//
ConfigParam.StringLen = 0;
ConfigParam.ParamType = NdisParameterInteger;
ConfigParam.MustBePresent = TRUE;
if (!GetLineConfigParams(&ConfigParam, n, PCIMAC_KEY_NUMLTERMS))
goto InitErrorExit;
NumberOfLTerms = (USHORT)ConfigParam.Value;
if (NumberOfLTerms > 1)
idd_add_def(idd, "dual_q931", "any");
//
// store number of lterms that this idd has
//
idd->CallInfo.NumLTerms = NumberOfLTerms;
//
// for each logical terminal
//
for (l = 0; l < NumberOfLTerms; l++)
{
//
// read registry tei
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = FALSE;
if (!GetLTermConfigParams(&ConfigParam, n, l, PCIMAC_KEY_TEI))
__strcpy(ConfigParam.String, "127");
NdisZeroMemory(DefName, sizeof(DefName));
sprintf(DefName, "q931.%d.tei", l);
idd_add_def(idd, DefName, ConfigParam.String);
//
// read registry spid
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = FALSE;
if (GetLTermConfigParams(&ConfigParam, n, l, PCIMAC_KEY_SPID))
{
CHAR TempVal[64];
ULONG i, j;
//
// remove any non digits except # & *
//
NdisZeroMemory(TempVal, sizeof(TempVal));
for (i = 0, j = 0; i < ConfigParam.StringLen; i++)
{
if ((ConfigParam.String[i] >= '0' && ConfigParam.String[i] <= '9') ||
ConfigParam.String[i] == '*' ||
ConfigParam.String[i] == '#')
{
TempVal[j++] = ConfigParam.String[i];
}
}
NdisZeroMemory(DefName, sizeof(DefName));
sprintf(DefName, "q931.%d.spid", l);
idd_add_def(idd, DefName, TempVal);
idd_add_def(idd, "q931.multipoint", "any");
}
//
// read registry address
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = 128;
ConfigParam.ParamType = NdisParameterString;
ConfigParam.MustBePresent = FALSE;
if (GetLTermConfigParams(&ConfigParam, n, l, PCIMAC_KEY_ADDRESS))
{
CHAR TempVal[64];
ULONG i, j;
//
// remove any non digits except # & *
//
NdisZeroMemory(TempVal, sizeof(TempVal));
for (i = 0, j = 0; i < ConfigParam.StringLen; i++)
{
if ((ConfigParam.String[i] >= '0' && ConfigParam.String[i] <= '9') ||
ConfigParam.String[i] == '*' ||
ConfigParam.String[i] == '#')
{
TempVal[j++] = ConfigParam.String[i];
}
}
NdisZeroMemory(DefName, sizeof(DefName));
sprintf(DefName, "q931.%d.addr", l);
idd_add_def(idd, DefName, TempVal);
}
//
// add code to read generic multistring at the lterm level
// Key is "LTermDefinitions" these will be added to
// the enviornment database
// each string will look like "name=value\0" should
// remove "=" and replace with '\0'
//
}
//
// add code to read generic multistring at the board level
// Key is "GenericDefines"
// each string will look like "name=value\0" should
// remove "=" and replace with '\0'
//
NdisZeroMemory(ConfigParam.String, sizeof(ConfigParam.String));
ConfigParam.StringLen = sizeof(ConfigParam.String);
ConfigParam.ParamType = NdisParameterMultiString;
ConfigParam.MustBePresent = FALSE;
if (GetBaseConfigParams(&ConfigParam, PCIMAC_KEY_GENERICDEFINES))
{
CHAR Name[50] = {0};
CHAR Value[50] = {0};
CHAR *StringPointer = ConfigParam.String;
while (__strlen(StringPointer))
{
//
// copy the name part of the generic define
//
__strcpy(Name, StringPointer);
D_LOG(D_ALWAYS, ("PcimacInitialize: GenericDefines: Name: %s\n", Name));
//
// push pointer over the name
//
StringPointer += __strlen(StringPointer);
//
// get over the null character
//
StringPointer += 1;
//
// copy the value part of the generic define
//
__strcpy(Value, StringPointer);
D_LOG(D_ALWAYS, ("PcimacInitialize: GenericDefines: Value: %s\n", Value));
idd_add_def(idd, Name, Value);
//
// push pointer over the value
//
StringPointer += __strlen(StringPointer);
//
// get over the null character
//
StringPointer += 1;
}
}
//
// startup idd
//
if (idd_startup(idd) != IDD_E_SUCC)
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_HARDWARE_FAILURE,
2,
(ULONG)idd->bnumber,
(ULONG)idd->bline);
idd_destroy(idd);
for (m = 0; m < MAX_IDD_PER_ADAPTER; m++)
if (Adapter->IddTbl[m] == idd)
Adapter->IddTbl[m] = NULL;
Adapter->NumberOfIddOnAdapter--;
continue;
}
//
// register handlers for idd
//
cm_register_idd(idd);
IddStarted++;
}
if (!IddStarted)
goto InitErrorExit;
for (n = 0; n < IddStarted; n++)
{
CM *cm;
MTL *mtl;
IDD *idd;
idd = Adapter->IddTbl[n];
//
// build two cm's and two mtl's per line
//
for (l = 0; l < 2; l++)
{
ULONG m;
//
// Allocate memory for cm object
//
if (cm_create(&cm, AdapterHandle) != CM_E_SUCC)
goto InitErrorExit;
for (m = 0; m < MAX_CM_PER_ADAPTER; m++)
{
if (!Adapter->CmTbl[m])
{
Adapter->CmTbl[m] = cm;
break;
}
}
//
// back pointer to adapter structure
//
cm->Adapter = Adapter;
//
// pointer to idd that belongs to this cm
//
cm->idd = idd;
//
// name cm object format: AdapterName-LineName-chan#
//
sprintf(cm->name,"%s-%d", idd->name, l);
//
// set local address, format: NetCard#-idd#-chan#
//
#if !BINARY_COMPATIBLE
sprintf( cm->LocalAddress, "%d-%d-%d",
atoi( &Adapter->Name[6] ),
(idd->bline * 2) + l,
0 );
#else
sprintf(cm->LocalAddress, "1-%d-%d", (idd->bline * 2) + l, 0);
#endif
//
// get ethernet addresses for this cm
//
if( (idd->btype == IDD_BT_DATAFIREU) ||
(idd->btype == IDD_BT_DATAFIREST) ||
(idd->btype == IDD_BT_DATAFIRE4ST) )
AdpGetEaddrFromNvram(idd, cm, (USHORT)n, (USHORT)l);
else
IdpGetEaddrFromNvram(idd, cm, (USHORT)n, (USHORT)l);
//
// Allocate memory for mtl object
//
if (mtl_create(&mtl, AdapterHandle) != MTL_E_SUCC)
goto InitErrorExit;
for (m = 0; m < MAX_MTL_PER_ADAPTER; m++)
{
if (!Adapter->MtlTbl[m])
{
Adapter->MtlTbl[m] = mtl;
break;
}
}
//
// back pointer to adapter structure
//
mtl->Adapter = Adapter;
//
// link between cm and mtl
//
cm->mtl = mtl;
mtl->cm = cm;
}
}
NdisCloseConfiguration(ConfigParam.ConfigHandle);
NdisMRegisterAdapterShutdownHandler(
AdapterHandle,
Adapter,
(PVOID)PcimacHalt
);
return (NDIS_STATUS_SUCCESS);
InitErrorExit:
NdisCloseConfiguration(ConfigParam.ConfigHandle);
//
// clean up all idd's allocated
//
for (l = 0; l < MAX_IDD_PER_ADAPTER; l++)
{
IDD *idd = Adapter->IddTbl[l];
//
// if memory has been mapped release
//
if (idd)
{
idd_destroy(idd);
Adapter->IddTbl[l] = NULL;
}
}
//
// clean up all cm's allocated
//
for (l = 0; l < MAX_CM_PER_ADAPTER; l++)
{
CM *cm = Adapter->CmTbl[l];
if (cm)
{
cm_destroy(cm);
Adapter->CmTbl[l] = NULL;
}
}
//
// clean up all mtl's allocated
//
for (l = 0; l < MAX_MTL_PER_ADAPTER; l++)
{
MTL *mtl = Adapter->MtlTbl[l];
if (mtl)
{
mtl_destroy(mtl);
Adapter->MtlTbl[l] = NULL;
}
}
//
// clean up adapter block allocated
//
AdapterDestroy(Adapter);
return (NDIS_STATUS_ADAPTER_NOT_FOUND);
} // end PcimacInitialize
NDIS_STATUS
PcimacSetQueryInfo(
NDIS_HANDLE AdapterContext,
NDIS_OID Oid,
PVOID InfoBuffer,
ULONG InfoBufferLen,
PULONG BytesReadWritten,
PULONG BytesNeeded
)
{
ULONG OidType;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
D_LOG(D_ENTRY, ("PcimacSetQueryInfo: Adapter: 0x%lx, Oid: 0x%x\n", AdapterContext, Oid));
//
// get oid type
//
OidType = Oid & 0xFF000000;
switch (OidType)
{
case OID_WAN_INFO:
Status = WanOidProc(AdapterContext,
Oid,
InfoBuffer,
InfoBufferLen,
BytesReadWritten,
BytesNeeded);
break;
case OID_TAPI_INFO:
Status = TapiOidProc(AdapterContext,
Oid,
InfoBuffer,
InfoBufferLen,
BytesReadWritten,
BytesNeeded);
break;
case OID_GEN_INFO:
case OID_8023_INFO:
Status = LanOidProc(AdapterContext,
Oid,
InfoBuffer,
InfoBufferLen,
BytesReadWritten,
BytesNeeded);
break;
default:
Status = NDIS_STATUS_INVALID_OID;
break;
}
D_LOG(D_EXIT, ("PcimacSetQueryInfo: Status: 0x%x, BytesReadWritten: %d, BytesNeeded: %d\n", Status, *BytesReadWritten, *BytesNeeded));
return(Status);
}
NDIS_STATUS
PcimacReconfigure(
PNDIS_STATUS OpenErrorStatus,
NDIS_HANDLE AdapterContext,
NDIS_HANDLE WrapperConfigurationContext
)
{
D_LOG(D_ENTRY, ("PcimacReconfigure: Adapter: 0x%lx\n", AdapterContext));
//
// not supported for now
//
return(NDIS_STATUS_FAILURE);
}
NDIS_STATUS
PcimacReset(
PBOOLEAN AddressingReset,
NDIS_HANDLE AdapterContext
)
{
D_LOG(D_ENTRY, ("PcimacReset: Adapter: 0x%lx\n", AdapterContext));
return(NDIS_STATUS_HARD_ERRORS);
}
NDIS_STATUS
PcimacSend(
NDIS_HANDLE MacBindingHandle,
NDIS_HANDLE LinkContext,
PNDIS_WAN_PACKET WanPacket
)
{
MTL *mtl = (MTL*)LinkContext;
D_LOG(D_ENTRY, ("PcimacSend: Link: 0x%lx\n", mtl));
/* send packet */
mtl__tx_packet(mtl, WanPacket);
return(NDIS_STATUS_PENDING);
}
/* create/delete external name binding */
VOID
BindName(ADAPTER *Adapter, BOOL create)
{
#if !BINARY_COMPATIBLE
#define LINKNAME "\\DosDevices\\PCIMAC0"
UNICODE_STRING linkname, devname;
NTSTATUS stat;
CHAR name[128];
ANSI_STRING aname;
ANSI_STRING lname;
if (Adapter)
sprintf(name,"\\Device\\%s",Adapter->Name);
if ( !name )
sprintf(name,"\\Device\\Pcimac69");
D_LOG(D_ENTRY, ("BindName: LinkName: %s, NdisName: %s\n", LINKNAME, name));
/* convert to unicode string */
RtlInitAnsiString(&lname, LINKNAME);
stat = RtlAnsiStringToUnicodeString(&linkname, &lname, TRUE);
/* convert to unicode string */
RtlInitAnsiString(&aname, name);
stat = RtlAnsiStringToUnicodeString(&devname, &aname, TRUE);
/* create? */
if ( create )
{
UNICODE_STRING AtlasVName, AtlasVEntry;
RtlInitAnsiString( &aname, "DigiBRI" );
RtlAnsiStringToUnicodeString( &AtlasVName, &aname, TRUE );
RtlInitAnsiString( &aname, "DgBRIAtlas" );
RtlAnsiStringToUnicodeString( &AtlasVEntry, &aname, TRUE );
stat = DigiRegisterAtlasName( &devname,
&AtlasVName,
&AtlasVEntry );
if( NT_ERROR(stat) )
stat = IoCreateSymbolicLink (&linkname, &devname);
RtlFreeUnicodeString( &AtlasVName );
RtlFreeUnicodeString( &AtlasVEntry );
}
else /* delete */
stat = IoDeleteSymbolicLink (&linkname);
D_LOG(D_ENTRY, ("BindName: Operation: 0x%x, stat: 0x%x\n", create, stat));
RtlFreeUnicodeString(&devname);
RtlFreeUnicodeString(&linkname);
#endif
}
//
// Function commented out for change in how RAS picks up tapi name and address info
// This will help make the driver more portable.
//
//#pragma NDIS_INIT_FUNCTION(RegistryInit)
//
//VOID
//RegistryInit(VOID)
//{
// UNICODE_STRING AddressUnicodeString;
// UNICODE_STRING UnicodeString;
// ANSI_STRING AnsiString;
// PWCHAR AddressBuffer;
// NDIS_PHYSICAL_ADDRESS HighestAcceptableMax = NDIS_PHYSICAL_ADDRESS_CONST(-1, -1);
// ULONG l, m;
//
// NdisAllocateMemory((PVOID)&AddressBuffer,
// 1024,
// 0,
// HighestAcceptableMax);
//
// if (!AddressBuffer)
// {
// D_LOG(D_ALWAYS, ("RegistryInit: Memory Allocation Failed!\n"));
// return;
// }
//
// AddressUnicodeString.MaximumLength = 1024;
// AddressUnicodeString.Length = 0;
// NdisZeroMemory(AddressBuffer, 1024);
// AddressUnicodeString.Buffer = AddressBuffer;
//
// //
// // create tapi devices key
// //
// RtlCreateRegistryKey (RTL_REGISTRY_DEVICEMAP, L"Tapi Devices");
//
// //
// // create pcimac service provider key
// //
// RtlCreateRegistryKey (RTL_REGISTRY_DEVICEMAP, L"Tapi Devices\\PCIMAC");
//
// //
// // write media type - isdn for us
// //
// RtlInitAnsiString(&AnsiString, "ISDN");
//
// RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
//
// RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
// L"Tapi Devices\\PCIMAC",
// L"Media Type",
// REG_SZ,
// UnicodeString.Buffer,
// UnicodeString.Length);
//
// RtlFreeUnicodeString(&UnicodeString);
//
// for (l = 0; l < MAX_ADAPTERS_IN_SYSTEM; l++)
// {
// ADAPTER *Adapter = (ADAPTER*)Pcimac.AdapterTbl[l];
//
// if (Adapter)
// {
// for (m = 0; m < MAX_CM_PER_ADAPTER; m++)
// {
// CM *cm = Adapter->CmTbl[m];
//
// if (cm)
// {
// RtlInitAnsiString(&AnsiString, cm->LocalAddress);
//
// RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, TRUE);
//
// RtlAppendUnicodeStringToString(&AddressUnicodeString, &UnicodeString);
//
// AddressUnicodeString.Buffer[AddressUnicodeString.Length + 1] = '\0';
// AddressUnicodeString.Length += 2;
//
// RtlFreeUnicodeString(&UnicodeString);
// }
// }
// }
// }
//
// //
// // write value
// //
// RtlWriteRegistryValue(RTL_REGISTRY_DEVICEMAP,
// L"Tapi Devices\\PCIMAC",
// L"Address",
// REG_MULTI_SZ,
// AddressUnicodeString.Buffer,
// AddressUnicodeString.Length);
//
// NdisFreeMemory(AddressBuffer, 1024, 0);
//}
#pragma NDIS_INIT_FUNCTION(GetBaseConfigParams)
ULONG
GetBaseConfigParams(
CONFIGPARAM *RetParam,
CHAR *Key
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
NDIS_STRING KeyWord;
ANSI_STRING AnsiKey;
ULONG n;
PNDIS_CONFIGURATION_PARAMETER ConfigParam;
D_LOG(D_ALWAYS, ("GetBaseConfigParams: Key: %s\n", Key));
//
// turn passed in key to an ansi string
//
RtlInitAnsiString(&AnsiKey, Key);
//
// allocate buffer and turn ansi to unicode
//
RtlAnsiStringToUnicodeString(&KeyWord, &AnsiKey, TRUE);
NdisReadConfiguration(&Status,
&ConfigParam,
RetParam->ConfigHandle,
&KeyWord,
RetParam->ParamType);
D_LOG(D_ALWAYS, ("GetBaseConfigParams: Status: 0x%x\n", Status));
//
// free up unicode string buffer
//
RtlFreeUnicodeString(&KeyWord);
if (Status != NDIS_STATUS_SUCCESS)
{
D_LOG(D_ALWAYS, ("GetBaseConfigParams: Error Reading Config: RetVal: 0x%x\n", Status));
if (RetParam->MustBePresent)
NdisWriteErrorLogEntry (RetParam->AdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
0);
return(0);
}
D_LOG(D_ALWAYS, ("GetBaseConfigParams: StringLength: %d\n", ConfigParam->ParameterData.StringData.Length));
switch (ConfigParam->ParameterType)
{
case NdisParameterString:
{
#if !BINARY_COMPATIBLE
ANSI_STRING AnsiRet;
RtlUnicodeStringToAnsiString(&AnsiRet, &ConfigParam->ParameterData.StringData, TRUE);
__strncpy(RetParam->String, AnsiRet.Buffer, AnsiRet.Length);
RetParam->StringLen = AnsiRet.Length;
RtlFreeAnsiString(&AnsiRet);
#else
RetParam->StringLen = __strlen((PUCHAR)ConfigParam->ParameterData.StringData.Buffer);
__strncpy(RetParam->String, (PUCHAR) ConfigParam->ParameterData.StringData.Buffer, RetParam->StringLen);
#endif
D_LOG(D_ALWAYS, ("GetBaseConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
break;
}
case NdisParameterMultiString:
D_LOG(D_ALWAYS, ("GetBaseConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
#if !BINARY_COMPATIBLE
for (n = 0; n < RetParam->StringLen && n < ConfigParam->ParameterData.StringData.Length; n++)
RetParam->String[n] = (CHAR)ConfigParam->ParameterData.StringData.Buffer[n];
RetParam->StringLen = n/2;
#else
// Ansi
for (n = 0; n < RetParam->StringLen && n < ConfigParam->ParameterData.StringData.Length; n++)
RetParam->String[n] = ((PUCHAR)ConfigParam->ParameterData.StringData.Buffer)[n];
RetParam->StringLen = n;
#endif
for (n = 0; n < RetParam->StringLen; n++)
if (!__strnicmp((CHAR*)&RetParam->String[n], (CHAR*)"=", 1))
RetParam->String[n] = '\0';
break;
case NdisParameterInteger:
case NdisParameterHexInteger:
RetParam->Value = ConfigParam->ParameterData.IntegerData;
D_LOG(D_ALWAYS, ("GetBaseConfigParams: Integer: 0x%x\n", RetParam->Value));
break;
default:
return(0);
}
return(1);
}
#pragma NDIS_INIT_FUNCTION(GetLineConfigParams)
ULONG
GetLineConfigParams(
CONFIGPARAM *RetParam,
ULONG LineNumber,
CHAR *Key
)
{
ULONG n;
CHAR LinePath[64];
NDIS_STRING KeyWord;
ANSI_STRING AnsiKey;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNDIS_CONFIGURATION_PARAMETER ConfigParam;
sprintf(LinePath,
"%s%d.%s",
PCIMAC_KEY_LINE,
LineNumber,
Key);
D_LOG(D_ALWAYS, ("GetLineConfigParams: LineNumber: %d, Key: %s\n", LineNumber, Key));
//
// turn passed in key to an ansi string
//
RtlInitAnsiString(&AnsiKey, LinePath);
//
// allocate buffer and turn ansi to unicode
//
RtlAnsiStringToUnicodeString(&KeyWord, &AnsiKey, TRUE);
NdisReadConfiguration(&Status,
&ConfigParam,
RetParam->ConfigHandle,
&KeyWord,
RetParam->ParamType);
//
// free up unicode string buffer
//
RtlFreeUnicodeString(&KeyWord);
if (Status != NDIS_STATUS_SUCCESS)
{
D_LOG(D_ALWAYS, ("GetLineConfigParams: Error Reading Config: RetVal: 0x%x\n", Status));
if (RetParam->MustBePresent)
NdisWriteErrorLogEntry (RetParam->AdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
0);
return(0);
}
switch (ConfigParam->ParameterType)
{
case NdisParameterString:
{
#if !BINARY_COMPATIBLE
ANSI_STRING AnsiRet;
RtlUnicodeStringToAnsiString(&AnsiRet, &ConfigParam->ParameterData.StringData, TRUE);
__strncpy(RetParam->String, AnsiRet.Buffer, AnsiRet.Length);
RetParam->StringLen = AnsiRet.Length;
RtlFreeAnsiString(&AnsiRet);
#else
RetParam->StringLen = __strlen((PUCHAR)ConfigParam->ParameterData.StringData.Buffer);
__strncpy(RetParam->String, (PUCHAR) ConfigParam->ParameterData.StringData.Buffer, RetParam->StringLen);
#endif
D_LOG(D_ALWAYS, ("GetLineConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
break;
}
case NdisParameterMultiString:
for (n = 0; n < RetParam->StringLen && n < ConfigParam->ParameterData.StringData.Length; n++)
RetParam->String[n] = (CHAR)ConfigParam->ParameterData.StringData.Buffer[n];
RetParam->StringLen = n/2;
for (n = 0; n < RetParam->StringLen; n++)
if (!__strnicmp((CHAR*)&RetParam->String[n], (CHAR*)"=", 1))
RetParam->String[n] = '\0';
D_LOG(D_ALWAYS, ("GetBaseConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
break;
case NdisParameterInteger:
case NdisParameterHexInteger:
RetParam->Value = ConfigParam->ParameterData.IntegerData;
D_LOG(D_ALWAYS, ("GetLineConfigParams: Integer: 0x%x\n", RetParam->Value));
break;
default:
return(0);
}
return(1);
}
#pragma NDIS_INIT_FUNCTION(GetLTermConfigParams)
ULONG
GetLTermConfigParams(
CONFIGPARAM *RetParam,
ULONG LineNumber,
ULONG LTermNumber,
CHAR *Key
)
{
ULONG n;
CHAR LTermPath[64];
NDIS_STRING KeyWord;
ANSI_STRING AnsiKey;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
PNDIS_CONFIGURATION_PARAMETER ConfigParam;
D_LOG(D_ALWAYS, ("GetLTermConfigParams: LineNumber: %d, LTerm: %d, Key: %s\n", LineNumber, LTermNumber, Key));
sprintf(LTermPath,
"%s%d.%s%d.%s",
PCIMAC_KEY_LINE,
LineNumber,
PCIMAC_KEY_LTERM,
LTermNumber,
Key);
//
// turn passed in key to an ansi string
//
RtlInitAnsiString(&AnsiKey, LTermPath);
//
// allocate buffer and turn ansi to unicode
//
RtlAnsiStringToUnicodeString(&KeyWord, &AnsiKey, TRUE);
NdisReadConfiguration(&Status,
&ConfigParam,
RetParam->ConfigHandle,
&KeyWord,
RetParam->ParamType);
//
// free up unicode string buffer
//
RtlFreeUnicodeString(&KeyWord);
if (Status != NDIS_STATUS_SUCCESS)
{
D_LOG(D_ALWAYS, ("GetLTermConfigParams: Error Reading Config: RetVal: 0x%x\n", Status));
if (RetParam->MustBePresent)
NdisWriteErrorLogEntry (RetParam->AdapterHandle,
NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
0);
return(0);
}
switch (ConfigParam->ParameterType)
{
case NdisParameterString:
{
#if !BINARY_COMPATIBLE
ANSI_STRING AnsiRet;
RtlUnicodeStringToAnsiString(&AnsiRet, &ConfigParam->ParameterData.StringData, TRUE);
__strncpy(RetParam->String, AnsiRet.Buffer, AnsiRet.Length);
RetParam->StringLen = AnsiRet.Length;
RtlFreeAnsiString(&AnsiRet);
#else
RetParam->StringLen = __strlen((PUCHAR)ConfigParam->ParameterData.StringData.Buffer);
__strncpy(RetParam->String, (PUCHAR) ConfigParam->ParameterData.StringData.Buffer, RetParam->StringLen);
#endif
D_LOG(D_ALWAYS, ("GetLTermConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
break;
}
case NdisParameterMultiString:
for (n = 0; n < RetParam->StringLen && n < ConfigParam->ParameterData.StringData.Length; n++)
RetParam->String[n] = (CHAR)ConfigParam->ParameterData.StringData.Buffer[n];
RetParam->StringLen = n/2;
for (n = 0; n < RetParam->StringLen; n++)
if (!__strnicmp((CHAR*)&RetParam->String[n], (CHAR*)"=", 1))
RetParam->String[n] = '\0';
D_LOG(D_ALWAYS, ("GetLTermConfigParams: String: %s, Length: %d\n", RetParam->String, RetParam->StringLen));
break;
case NdisParameterInteger:
case NdisParameterHexInteger:
RetParam->Value = ConfigParam->ParameterData.IntegerData;
D_LOG(D_ALWAYS, ("GetLTermConfigParams: Integer: 0x%x\n", RetParam->Value));
break;
default:
return(0);
}
return(1);
}
VOID
SetInDriverFlag (
ADAPTER *Adapter
)
{
NdisAcquireSpinLock(&Pcimac.lock);
Pcimac.InDriverFlag = 1;
Pcimac.CurrentAdapter = Adapter;
Pcimac.NextAdapterToPoll++;
if (Pcimac.NextAdapterToPoll == Pcimac.NumberOfAdaptersInSystem)
Pcimac.NextAdapterToPoll = 0;
NdisReleaseSpinLock(&Pcimac.lock);
}
VOID
ClearInDriverFlag (
ADAPTER *Adapter
)
{
NdisAcquireSpinLock(&Pcimac.lock);
Pcimac.InDriverFlag = 0;
NdisReleaseSpinLock(&Pcimac.lock);
}
ULONG
CheckInDriverFlag (
ADAPTER *Adapter
)
{
ADAPTER *CurrentAdapter;
INT RetVal = 0;
NdisAcquireSpinLock(&Pcimac.lock);
//
// get the current in driver adapter
//
CurrentAdapter = (ADAPTER*)Pcimac.CurrentAdapter;
//
// if someone is in the driver and they are using the same
// shared memory window as the new prospective user send them
// away unhappy
//
if (Pcimac.InDriverFlag && CurrentAdapter && (Adapter->VBaseMem == CurrentAdapter->VBaseMem))
RetVal = 1;
NdisReleaseSpinLock(&Pcimac.lock);
return(RetVal);
}
#pragma NDIS_INIT_FUNCTION(IdpGetEaddrFromNvram)
/*
* get ethernet address(s) out on nvram & register
*
* note that line number inside board (bline) argument was added here.
* for each idd installed, this function is called to add two ethernet
* addresses associated with it (it's two B channels - or it's capability to
* handle two connections). All ethernet address are derived from the
* single address stored starting at nvram address 8. since the manufecturer
* code is the first 3 bytes, we must not modify these bytes. therefor,
* addresses are generated by indexing the 4'th byte by bline*2 (need two
* address - remember?).
*/
VOID
IdpGetEaddrFromNvram(
IDD *idd,
CM *cm,
USHORT Line,
USHORT LineIndex
)
{
UCHAR eaddr[6];
USHORT nvval;
/* extract original stored ethernet address */
idd_get_nvram(idd, (USHORT)(8), &nvval);
eaddr[0] = LOBYTE(nvval);
eaddr[1] = HIBYTE(nvval);
idd_get_nvram(idd, (USHORT)(9), &nvval);
eaddr[2] = LOBYTE(nvval);
eaddr[3] = HIBYTE(nvval);
idd_get_nvram(idd, (USHORT)(10), &nvval);
eaddr[4] = LOBYTE(nvval);
eaddr[5] = HIBYTE(nvval);
/* create derived address and store it */
eaddr[3] += (Line * 2) + LineIndex;
NdisMoveMemory(cm->SrcAddr, eaddr, sizeof(cm->SrcAddr));
} // end IdpGetEaddrFromNvram
#pragma NDIS_INIT_FUNCTION(AdpGetEaddrFromNvram)
/*
* get ethernet address(s) out on nvram & register
*
* note that line number inside board (bline) argument was added here.
* for each idd installed, this function is called to add two ethernet
* addresses associated with it (it's two B channels - or it's capability to
* handle two connections). All ethernet address are derived from the
* single address stored starting at nvram address 8. since the manufecturer
* code is the first 3 bytes, we must not modify these bytes. therefor,
* addresses are generated by indexing the 4'th byte by bline*2 (need two
* address - remember?).
*/
VOID
AdpGetEaddrFromNvram(
IDD *idd,
CM *cm,
USHORT Line,
USHORT LineIndex
)
{
UCHAR eaddr[6];
USHORT nvval;
//
// the MAC address lines at offset 0x950 in the onboard memory
// this is NVRAM_WINDOW 0x940 + 0x10
//
idd_get_nvram(idd, (USHORT)(0x10), &nvval);
eaddr[0] = LOBYTE(nvval);
eaddr[1] = HIBYTE(nvval);
idd_get_nvram(idd, (USHORT)(0x12), &nvval);
eaddr[2] = LOBYTE(nvval);
eaddr[3] = HIBYTE(nvval);
idd_get_nvram(idd, (USHORT)(0x14), &nvval);
eaddr[4] = LOBYTE(nvval);
eaddr[5] = HIBYTE(nvval);
/* create derived address and store it */
eaddr[3] += (Line * 2) + LineIndex;
NdisMoveMemory(cm->SrcAddr, eaddr, sizeof(cm->SrcAddr));
} // end AdpGetEaddrFromNvram
#ifdef OLD
ULONG
EnumAdaptersInSystem()
{
ULONG n, NumAdapters = 0;
for (n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++)
{
if (Pcimac.AdapterTbl[n])
NumAdapters++;
}
return(NumAdapters);
}
#endif
ULONG
EnumAdaptersInSystem()
{
ULONG NumAdapters;
NdisAcquireSpinLock(&Pcimac.lock);
NumAdapters = Pcimac.NumberOfAdaptersInSystem;
NdisReleaseSpinLock(&Pcimac.lock);
return(NumAdapters);
}
ADAPTER*
GetAdapterByIndex(
ULONG Index
)
{
ADAPTER *Adapter;
NdisAcquireSpinLock(&Pcimac.lock);
Adapter = Pcimac.AdapterTbl[Index];
NdisReleaseSpinLock(&Pcimac.lock);
return(Adapter);
}
INT
IoEnumAdapter(VOID *cmd_1)
{
IO_CMD *cmd = (IO_CMD*)cmd_1;
ULONG n, m, NumberOfAdapters;
NumberOfAdapters = cmd->val.enum_adapters.num = (USHORT)EnumAdaptersInSystem();
for (n = 0, m = 0; n < NumberOfAdapters; n++)
{
ADAPTER *Adapter = GetAdapterByIndex(n);
if (Adapter)
{
cmd->val.enum_adapters.BaseIO[m] = Adapter->BaseIO;
cmd->val.enum_adapters.BaseMem[m] = Adapter->BaseMem;
cmd->val.enum_adapters.BoardType[m] = Adapter->BoardType;
NdisMoveMemory (&cmd->val.enum_adapters.Name[m], Adapter->Name, sizeof(cmd->val.enum_adapters.Name[n]));
cmd->val.enum_adapters.tbl[m] = Adapter;
m++;
}
}
return(0);
}
VOID
AdapterDestroy(
ADAPTER *Adapter
)
{
ULONG n;
for (n = 0; n < MAX_ADAPTERS_IN_SYSTEM; n++)
{
if (Adapter == Pcimac.AdapterTbl[n])
break;
}
if (n == MAX_ADAPTERS_IN_SYSTEM)
return;
//
// stop idd timers
//
StopTimers(Adapter);
Pcimac.AdapterTbl[n] = NULL;
Pcimac.NumberOfAdaptersInSystem--;
//
// if we have successfully mapped our base i/o then we need to release
//
if (Adapter->VBaseIO)
{
//
// deregister adapters I/O and memory
//
NdisMDeregisterIoPortRange((NDIS_HANDLE)Adapter->Handle,
Adapter->BaseIO,
8,
Adapter->VBaseIO);
}
//
// if we have successfully mapped our base memory then we need to release
//
if (Adapter->VBaseMem)
{
NdisMUnmapIoSpace((NDIS_HANDLE)Adapter->Handle,
Adapter->VBaseMem,
0x4000);
}
// NdisFreeSpinLock(&Adapter->lock);
NdisFreeMemory(Adapter, sizeof(ADAPTER), 0);
}
#pragma NDIS_INIT_FUNCTION(StartTimers)
VOID
StartTimers(
ADAPTER *Adapter
)
{
NdisMSetTimer(&Adapter->IddPollTimer, IDD_POLL_T);
NdisMSetTimer(&Adapter->MtlPollTimer, MTL_POLL_T);
NdisMSetTimer(&Adapter->CmPollTimer, CM_POLL_T);
}
VOID
StopTimers(
ADAPTER *Adapter
)
{
BOOLEAN TimerCanceled;
NdisMCancelTimer(&Adapter->IddPollTimer, &TimerCanceled);
NdisMCancelTimer(&Adapter->MtlPollTimer, &TimerCanceled);
NdisMCancelTimer(&Adapter->CmPollTimer, &TimerCanceled);
}
#pragma NDIS_INIT_FUNCTION(IdpCheckIO)
ULONG
IdpCheckIO(IDD *idd)
{
ULONG ReturnValue = 1;
//
// check for board at this I/O address
//
if (idd->btype == IDD_BT_PCIMAC || idd->btype == IDD_BT_PCIMAC4)
{
UCHAR BoardID;
BoardID = (idd->InFromPort(idd, 5) & 0x0F);
if ( ((idd->btype == IDD_BT_PCIMAC) && (BoardID == 0x02)) ||
((idd->btype == IDD_BT_PCIMAC4) && (BoardID == 0x04)))
ReturnValue = 0;
}
else if( idd->btype == IDD_BT_MCIMAC )
ReturnValue = 0;
return(ReturnValue);
}
#pragma NDIS_INIT_FUNCTION(AdpCheckIO)
ULONG
AdpCheckIO(IDD *idd)
{
UCHAR BoardId = idd->InFromPort(idd, ADP_REG_ID);
D_LOG(D_ENTRY, ("AdpCheckIO: entry, idd: 0x%lx BoardType: %d\n", idd, idd->btype));
D_LOG(D_ALWAYS, ("AdpCheckIO: ADP_REG_ID: %d\n", BoardId));
switch( idd->btype )
{
case IDD_BT_DATAFIREU:
case IDD_BT_DATAFIREST:
if (BoardId != ADP_BT_ADP1)
return(1);
break;
case IDD_BT_DATAFIRE4ST:
if (BoardId != ADP_BT_ADP4)
return(1);
break;
}
return( 0 );
}
#pragma NDIS_INIT_FUNCTION(IdpCheckMem)
ULONG
IdpCheckMem(IDD *idd)
{
return(0);
}
#pragma NDIS_INIT_FUNCTION(AdpCheckMem)
ULONG
AdpCheckMem(IDD *idd)
{
return(0);
}
NTSTATUS PcimacInitMCA( NDIS_HANDLE AdapterHandle,
PULONG BaseIO,
PULONG BaseMemory,
ULONG SlotNumber )
/*++
Routine Description:
This routine will be called if it is determined the type of bus
is MCA. We verify that the controller is actually a DigiBoard
PCIMAC controller, read the POS to determine the I/O address and
Memory Mapped address, so the initialization process can continue.
Arguments:
AdapterHandle - Handle passed in the initialization routine. Required
so mapping of POS I/O ports can take place.
BaseIO - Pointer where the adapters base I/O address is passed back.
BaseMemory - Pointer where the adapters base memory address is passed back.
SlotNumber - Number indicating what slot this MCA adapter should be in.
Return Value:
STATUS_SUCCESS - If we were able to complete successfully
?? - We were not able to get the information required to continue.
--*/
{
#define PcimacPOSID 0x7F9E
#define MCA_BASE_POS_IO_PORT 0x96
#define MCA_INFO_POS_IO_PORT 0x100
#define MCA_IO_PORT_MASK 0x0070
USHORT ActualPosId, POSConfig;
USHORT IOPortOffset;
ULONG MemoryAddress;
PVOID VirtualPOSBaseAddress; // Virtual address
PVOID VirtualPOSInfoAddress; // Virtual address
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UCHAR OneByte;
//
// We need to read the POS Adapter ID and make sure the controller
// is one of ours. Use the Slot number and the POS ID we
// installed during configuration from the registry.
//
DigiDump( DIGIINIT, ("Pcimac: PcimacPOSID: 0x%x\n",
PcimacPOSID) );
DigiDump( DIGIINIT, ("--------- SlotNumber: 0x%x\n",
SlotNumber) );
*BaseIO = 0;
*BaseMemory = 0;
Status = NdisMRegisterIoPortRange( &VirtualPOSBaseAddress,
AdapterHandle,
MCA_BASE_POS_IO_PORT,
1 );
if( Status != NDIS_STATUS_SUCCESS )
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
0);
goto PcimacInitMCAExit;
}
Status = NdisMRegisterIoPortRange( &VirtualPOSInfoAddress,
AdapterHandle,
MCA_INFO_POS_IO_PORT,
1 );
if( Status != NDIS_STATUS_SUCCESS )
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
0);
goto PcimacInitMCAExit;
}
// Enable the POS information for the slot we are interested in.
NdisRawWritePortUchar( VirtualPOSBaseAddress, (UCHAR)(SlotNumber + 7) );
NdisRawReadPortUchar( (PVOID)((ULONG)VirtualPOSInfoAddress + 1),
(PUCHAR)&OneByte );
ActualPosId = ((USHORT)OneByte << 8);
NdisRawReadPortUchar( VirtualPOSInfoAddress, (PUCHAR)&OneByte );
ActualPosId |= OneByte;
DigiDump( DIGIINIT, ("POS Adapter ID = 0x%hx\n", ActualPosId) );
if( ActualPosId != PcimacPOSID )
{
NdisWriteErrorLogEntry(AdapterHandle,
NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
0);
Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
goto PcimacInitMCAError2;
}
//
// Clear the VPD.
//
NdisRawWritePortUchar( (ULONG)VirtualPOSInfoAddress + 6, 0 );
NdisRawReadPortUchar( (ULONG)VirtualPOSInfoAddress + 4,
(PUCHAR)&OneByte );
MemoryAddress = ((ULONG)OneByte << 22);
NdisRawReadPortUchar( (ULONG)VirtualPOSInfoAddress + 3,
(PUCHAR)&OneByte );
MemoryAddress |= ((ULONG)OneByte << 14);
NdisRawReadPortUchar( (ULONG)VirtualPOSInfoAddress + 2,
(PUCHAR)&OneByte );
POSConfig = OneByte;
IOPortOffset = (POSConfig & MCA_IO_PORT_MASK) >> 4;
DigiDump( DIGIINIT, ("POS config read = 0x%hx\n"
" IOPortOffset = 0x%hx, MemoryAddress = 0x%x,"
" IOPort = 0x%hx\n",
POSConfig, IOPortOffset, MemoryAddress,
MCAIOAddressTable[IOPortOffset]) );
*BaseIO = MCAIOAddressTable[IOPortOffset];
*BaseMemory = MemoryAddress;
// Disable the POS information.
NdisRawWritePortUchar( VirtualPOSBaseAddress, 0 );
//
// Unmap the POS register
//
PcimacInitMCAError2:;
NdisMDeregisterIoPortRange( AdapterHandle,
MCA_INFO_POS_IO_PORT,
1,
VirtualPOSInfoAddress );
NdisMDeregisterIoPortRange( AdapterHandle,
MCA_BASE_POS_IO_PORT,
1,
VirtualPOSBaseAddress );
PcimacInitMCAExit:;
return( Status );
} // end PcimacInitMCA