summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/digi/pcimac/pcimac.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/ndis/digi/pcimac/pcimac.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/ndis/digi/pcimac/pcimac.c')
-rw-r--r--private/ntos/ndis/digi/pcimac/pcimac.c2385
1 files changed, 2385 insertions, 0 deletions
diff --git a/private/ntos/ndis/digi/pcimac/pcimac.c b/private/ntos/ndis/digi/pcimac/pcimac.c
new file mode 100644
index 000000000..74b56788c
--- /dev/null
+++ b/private/ntos/ndis/digi/pcimac/pcimac.c
@@ -0,0 +1,2385 @@
+//
+// 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
+
+
+