summaryrefslogtreecommitdiffstats
path: root/private/ntos/ndis/lt200/ltinit.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/lt200/ltinit.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/lt200/ltinit.c')
-rw-r--r--private/ntos/ndis/lt200/ltinit.c738
1 files changed, 738 insertions, 0 deletions
diff --git a/private/ntos/ndis/lt200/ltinit.c b/private/ntos/ndis/lt200/ltinit.c
new file mode 100644
index 000000000..69cdc1ba4
--- /dev/null
+++ b/private/ntos/ndis/lt200/ltinit.c
@@ -0,0 +1,738 @@
+/*++
+
+Copyright (c) 1992 Microsoft Corporation
+
+Module Name:
+
+ ltinit.c
+
+Abstract:
+
+ This module contains the main processing routines.
+
+Author:
+
+ Stephen Hou (stephh@microsoft.com)
+ Nikhil Kamkolkar (nikhilk@microsoft.com)
+
+Revision History:
+ 19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com)
+
+Notes: Tab stop: 4
+--*/
+
+#define _GLOBALS_
+#include "ltmain.h"
+#include "ltreg.h"
+#include "ltreq.h"
+#include "ltfirm.h"
+#include "lttimer.h"
+#include "ltreset.h"
+
+// Define file id for errorlogging
+#define FILENUM LTINIT
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+ This is the entry routine for the localtalk driver.
+
+Arguments:
+
+ DriverObject: The IO driver object for this driver object.
+ RegistryPath: The path to the registry config for this driver.
+
+Return Value:
+
+ STATUS_SUCCESS: If load was successful
+ Error : Otherwise
+
+--*/
+{
+ NDIS_STATUS Status;
+ NDIS_MAC_CHARACTERISTICS LtChar;
+ static const NDIS_STRING MacName = NDIS_STRING_CONST("LT200");
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("Debugging breakpoint, Hit G <cr> to continue\n"));
+
+ DBGBREAK(DBG_LEVEL_INFO);
+
+ // Initialize the NDIS Wrapper.
+ NdisInitializeWrapper(
+ &LtNdisWrapperHandle,
+ DriverObject,
+ RegistryPath,
+ NULL);
+
+ // Setup the MAC Characteristics
+ LtChar.MajorNdisVersion = NDIS_MAJOR_VERSION;
+ LtChar.MinorNdisVersion = NDIS_MINOR_VERSION;
+ LtChar.OpenAdapterHandler = LtInitOpenAdapter;
+ LtChar.CloseAdapterHandler = LtInitCloseAdapter;
+ LtChar.SendHandler = LtSend;
+ LtChar.RequestHandler = LtRequest;
+ LtChar.TransferDataHandler = LtRecvTransferData;
+ LtChar.ResetHandler = LtReset;
+ LtChar.QueryGlobalStatisticsHandler = LtReqQueryGlobalStatistics;
+ LtChar.UnloadMacHandler = LtInitUnload;
+ LtChar.AddAdapterHandler = LtInitAddAdapter;
+ LtChar.RemoveAdapterHandler = LtInitRemoveAdapter;
+ LtChar.Name = MacName;
+
+ NdisRegisterMac(
+ &Status,
+ &LtMacHandle,
+ LtNdisWrapperHandle,
+ NULL, // Context for AddAdapter/Unload
+ &LtChar,
+ sizeof(LtChar));
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ // Can only get here if something went wrong registering the MAC or
+ // all of the adapters
+ NdisTerminateWrapper(LtNdisWrapperHandle, DriverObject);
+ }
+
+ return Status;
+}
+
+
+
+
+NDIS_STATUS
+LtInitAddAdapter(
+ IN NDIS_HANDLE MacMacContext,
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN PNDIS_STRING AdapterName
+ )
+/*++
+
+Routine Description:
+
+ This is called by NDIS when we do a register adapter.
+
+Arguments:
+
+ MacMacContext : Context passed to Add/Unload. NULL in our case.
+ ConfigurationHandle : Handle to configuration info.
+ AdapterName : Name to use to register the adapter.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS : If successful, error otherwise
+
+--*/
+{
+ NDIS_HANDLE ConfigHandle;
+ UCHAR SuggestedNodeId;
+ UINT BusNumber, IoBaseAddress;
+ NDIS_INTERFACE_TYPE BusType;
+ BOOLEAN configHandleOpen = FALSE;
+ NDIS_STATUS Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
+
+ if (ConfigurationHandle == NULL)
+ {
+ return(Status);
+ }
+
+
+ do
+ {
+ NdisOpenConfiguration(
+ &Status,
+ &ConfigHandle,
+ ConfigurationHandle);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ break;
+ }
+
+ configHandleOpen = TRUE;
+
+ // The following functions return the parameter as specified in the
+ // Configuration database or the default. If the database has an
+ // incorrect value, then the default is returned and an Error Event
+ // is logged.
+
+ BusNumber = LtRegGetBusNumber(ConfigHandle);
+
+ Status = LtRegGetBusType(ConfigHandle, &BusType);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ break;
+ }
+
+ // Get the io base address
+ Status = LtRegGetIoBaseAddr(
+ &IoBaseAddress,
+ ConfigurationHandle,
+ ConfigHandle,
+ BusType);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ break;
+ }
+
+ // Get default id or pram node id to try.
+ SuggestedNodeId = LtRegGetNodeId(ConfigHandle);
+
+ } while (FALSE);
+
+ // We have to register the adapter to log an error if that happened.
+ Status = LtInitRegisterAdapter(
+ LtMacHandle,
+ ConfigurationHandle,
+ AdapterName,
+ BusType,
+ SuggestedNodeId,
+ IoBaseAddress,
+ LT_MAX_ADAPTERS,
+ Status);
+
+ if (configHandleOpen)
+ {
+ NdisCloseConfiguration(ConfigHandle);
+ }
+
+ return Status;
+}
+
+
+
+
+VOID
+LtInitRemoveAdapter(
+ IN NDIS_HANDLE MacAdapterContext
+ )
+/*++
+
+Routine Description:
+
+ Called to remove an adapter. This is only called after all bindings
+ are closed.
+
+Arguments:
+
+ MacAdapterContext : Context value passed to NdisRegister. Adapter
+
+Return Value:
+
+ None.
+
+--*/
+{
+ BOOLEAN Cancelled, TimerQueued, Closing;
+ PLT_ADAPTER Adapter = (PLT_ADAPTER)MacAdapterContext;
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+ Closing = ((Adapter->Flags & ADAPTER_CLOSING) != 0);
+
+ Adapter->Flags |= ADAPTER_CLOSING;
+ TimerQueued = ((Adapter->Flags & ADAPTER_TIMER_QUEUED) != 0);
+ Adapter->Flags &= ~ADAPTER_TIMER_QUEUED;
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ if (Closing)
+ {
+ ASSERTMSG("LtInitRemoveAdapter: Removing twice!\n", 0);
+ return;
+ }
+
+ // Acording to Adam, this routine will NEVER be called with
+ // outstanding opens.
+ ASSERTMSG("LtRemoveAdapter: OpenCount is not zero!\n",
+ (Adapter->OpenCount == 0));
+
+ // There are no opens left so remove ourselves.
+ if (TimerQueued)
+ {
+ NdisCancelTimer(&Adapter->PollingTimer, &Cancelled);
+ if (Cancelled)
+ {
+ // Remove the timer reference
+ LtDeReferenceAdapter(Adapter);
+ }
+ }
+
+ ASSERTMSG("LtRemoveAdapter: RefCount not correct!\n", (Adapter->RefCount == 1));
+
+ // Remove the creation reference
+ LtDeReferenceAdapter(Adapter);
+ return;
+}
+
+
+
+
+NDIS_STATUS
+LtInitOpenAdapter(
+ OUT PNDIS_STATUS OperErrorStatus,
+ OUT NDIS_HANDLE *MacBindingHandle,
+ OUT PUINT SelectedMediumIndex,
+ IN PNDIS_MEDIUM MediumArray,
+ IN UINT MediumArraySize,
+ IN NDIS_HANDLE NdisBindingContext,
+ IN NDIS_HANDLE MacAdapterContext,
+ IN UINT OpenOptions,
+ IN PSTRING AddressingInformation
+ )
+/*++
+
+Routine Description:
+
+ Called by ndis when a protocol attempts to bind to us.
+
+Arguments:
+
+ As described in the NDIS 3.0 Spec.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESSFUL : If ok, error otherwise
+
+--*/
+{
+
+ UINT i;
+ PLT_OPEN NewOpen;
+
+ PLT_ADAPTER Adapter = (PLT_ADAPTER)MacAdapterContext;
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
+
+ // if the adapter is being closed, then do not allow the open
+ LtReferenceAdapter(Adapter, &StatusToReturn);
+ if (StatusToReturn != NDIS_STATUS_SUCCESS)
+ {
+ ASSERTMSG("LtInitOpenAdapter: Adapter is closing down!\n", 0);
+ return(StatusToReturn);
+ }
+
+ do
+ {
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("LtInitOpenAdapter Entered:\n"));
+
+ // Search thru the supplied MediumArray for NdisMediumLocalTalk
+ for (i = 0; i < MediumArraySize; i++)
+ {
+ if (MediumArray[i] == NdisMediumLocalTalk)
+ {
+ break;
+ }
+ }
+
+ if (i == MediumArraySize)
+ {
+ StatusToReturn = NDIS_STATUS_UNSUPPORTED_MEDIA;
+ break;
+ }
+
+ *SelectedMediumIndex = i;
+
+ // Allocate some space for the open binding.
+ NdisAllocateMemory(
+ (PVOID)&NewOpen,
+ (UINT)sizeof(LT_OPEN),
+ (UINT)0,
+ LtNdisPhyAddr);
+
+ if (NewOpen == NULL)
+ {
+ StatusToReturn = NDIS_STATUS_RESOURCES;
+
+ // NdisWriteErrorLogEntry();
+ TMPLOGERR();
+ break;
+ }
+
+ NdisZeroMemory(
+ NewOpen,
+ sizeof(LT_OPEN));
+
+ *MacBindingHandle = (NDIS_HANDLE)NewOpen;
+ NewOpen->NdisBindingContext = NdisBindingContext;
+ NewOpen->Flags |= BINDING_OPEN;
+ NewOpen->LtAdapter = Adapter;
+
+ // Set the creation reference
+ NewOpen->RefCount = 1;
+ InitializeListHead(&NewOpen->Linkage);
+
+ // Insert into adapter list and increment adapter open count.
+ NdisAcquireSpinLock(&Adapter->Lock);
+ InsertTailList(&Adapter->OpenBindings, &NewOpen->Linkage);
+ Adapter->OpenCount++;
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+ } while (FALSE);
+
+ if (StatusToReturn != NDIS_STATUS_SUCCESS)
+ {
+ LtDeReferenceAdapter(Adapter);
+ }
+
+ return StatusToReturn;
+}
+
+
+
+
+NDIS_STATUS
+LtInitCloseAdapter(
+ IN NDIS_HANDLE MacBindingHandle
+ )
+/*++
+
+Routine Description:
+
+ Called by NDIS to close a binding.
+
+Arguments:
+
+ MacBindingHandle : Context passed back in OpenAdapter.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS : If successful, error otherwise.
+ NDIS_STATUS_PENDING : If pending.
+
+--*/
+{
+
+ PLT_ADAPTER Adapter;
+ PLT_OPEN Open;
+
+ NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
+ BOOLEAN Closing = FALSE;
+
+ Open = (PLT_OPEN)MacBindingHandle;
+ Adapter = Open->LtAdapter;
+
+
+ NdisAcquireSpinLock(&Adapter->Lock);
+
+ // Do not do any thing if already closing.
+ if (Open->Flags & BINDING_CLOSING)
+ {
+ StatusToReturn = NDIS_STATUS_CLOSING;
+ }
+ else
+ {
+ // This flag prevents further requests on this binding.
+ Open->Flags |= BINDING_CLOSING;
+ Closing = TRUE;
+ }
+
+ NdisReleaseSpinLock(&Adapter->Lock);
+
+
+ if (Closing)
+ {
+ // Remove the creation reference
+ LtDeReferenceBinding(Open);
+ }
+
+ return StatusToReturn;
+}
+
+
+
+
+VOID
+LtInitUnload(
+ IN NDIS_HANDLE MacMacContext
+ )
+/*++
+
+Routine Description:
+
+ Called when the driver is to be unloaded.
+
+Arguments:
+
+ MacMacContext : Context passed to RegisterMac.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ NDIS_STATUS Status;
+ UNREFERENCED_PARAMETER(MacMacContext);
+
+ ASSERT(MacMacContext == (NDIS_HANDLE)NULL);
+
+ NdisDeregisterMac(
+ &Status,
+ LtMacHandle);
+
+ NdisTerminateWrapper(
+ LtNdisWrapperHandle,
+ NULL);
+
+ return;
+}
+
+
+
+
+NDIS_STATUS
+LtInitRegisterAdapter(
+ IN NDIS_HANDLE LtMacHandle,
+ IN NDIS_HANDLE WrapperConfigurationContext,
+ IN PNDIS_STRING AdapterName,
+ IN NDIS_INTERFACE_TYPE BusType,
+ IN UCHAR SuggestedNodeId,
+ IN UINT IoBaseAddress,
+ IN UINT MaxAdapters,
+ IN NDIS_STATUS ConfigError
+ )
+/*++
+
+Routine Description:
+
+ This routine (and its interface) are not portable. They are
+ defined by the OS, the architecture, and the particular Lt
+ implementation.
+
+ This routine is responsible for the allocation of the datastructures
+ for the driver as well as any hardware specific details necessary
+ to talk with the device.
+
+Arguments:
+
+ LtMacHandle : The handle given back to the mac from ndis when
+ the mac registered itself.
+
+ WrapperConfigurationContext
+ : configuration context passed in by NDIS in the AddAdapter
+ call.
+
+ AdapterName : The string containing the name to give to the device adapter.
+ BusType : The type of bus in use. (MCA, ISA, EISA ...)
+ IoBaseAddress : The base IO address of the card.
+ MaxAdapters : The maximum number of opens at any one time.
+ ConfigError : Error with the Config parameters if any.
+
+Return Value:
+
+ NDIS_STATUS_SUCCESS : If successful, error otherwise.
+
+--*/
+{
+ // Pointer for the adapter root.
+ PLT_ADAPTER Adapter;
+ NDIS_STATUS Status, RefStatus;
+ NDIS_ERROR_CODE LogErrorCode;
+
+ // Holds information needed when registering the adapter.
+ NDIS_ADAPTER_INFORMATION AdapterInformation;
+
+ // Allocate the Adapter block.
+ NdisAllocateMemory(
+ (PVOID)&Adapter,
+ sizeof(LT_ADAPTER),
+ 0,
+ LtNdisPhyAddr);
+
+ if (Adapter == NULL)
+ {
+ return(NDIS_STATUS_RESOURCES);
+ }
+
+ NdisZeroMemory(
+ Adapter,
+ sizeof(LT_ADAPTER));
+
+ Adapter->NdisMacHandle = LtMacHandle;
+
+ // Set up the AdapterInformation structure.
+ NdisZeroMemory (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));
+
+ AdapterInformation.DmaChannel = 0;
+ AdapterInformation.Master = FALSE ;
+ AdapterInformation.Dma32BitAddresses = FALSE ;
+ AdapterInformation.AdapterType = BusType ;
+ AdapterInformation.PhysicalMapRegistersNeeded = 0;
+ AdapterInformation.MaximumPhysicalMapping = 0;
+ AdapterInformation.NumberOfPortDescriptors = 1 ;
+ AdapterInformation.PortDescriptors[0].InitialPort = IoBaseAddress;
+ AdapterInformation.PortDescriptors[0].NumberOfPorts = 4;
+ AdapterInformation.PortDescriptors[0].PortOffset = (PVOID *)(&(Adapter->MappedIoBaseAddr));
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("LtInitRegisterAdapter: IoBaseAddr %lx\n", IoBaseAddress));
+
+ // Register the adapter with NDIS.
+ if ((Status = NdisRegisterAdapter(
+ &Adapter->NdisAdapterHandle,
+ Adapter->NdisMacHandle,
+ Adapter,
+ WrapperConfigurationContext,
+ AdapterName,
+ &AdapterInformation)) != NDIS_STATUS_SUCCESS)
+ {
+ // Could not register the adapter, so we cannot log any errors
+ // either.
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL,
+ ("LtInitRegisterAdapter: Failed %lx\n", Status));
+
+ // Free up the memory allocated.
+ NdisFreeMemory(
+ Adapter,
+ sizeof(LT_ADAPTER),
+ 0);
+
+ return(Status);
+ }
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR,
+ ("LtInitRegisterAdapter: MappedIoBaseAddr %lx\n", Adapter->MappedIoBaseAddr));
+
+ do
+ {
+ // Ok. We are all set.
+ Adapter->BusType = BusType;
+
+ InitializeListHead(&Adapter->Request);
+ InitializeListHead(&Adapter->OpenBindings);
+
+ InitializeListHead(&Adapter->LoopBack);
+ InitializeListHead(&Adapter->Transmit);
+ InitializeListHead(&Adapter->Receive);
+
+ NdisAllocateSpinLock(&Adapter->Lock);
+
+ Adapter->OpenCount = 0;
+
+ // Set refcount to 1 - creation
+ Adapter->RefCount = 1;
+
+ NdisInitializeTimer(
+ &Adapter->PollingTimer,
+ LtTimerPoll,
+ (PVOID)Adapter);
+
+ // If there were no configuration errors, then go ahead with the
+ // initialize.
+
+ if (ConfigError == NDIS_STATUS_SUCCESS)
+ {
+ // Start the card up. This writes an error
+ // log entry if it fails.
+ if (LtFirmInitialize(Adapter, SuggestedNodeId))
+ {
+ // Ok, the firmware code has been downloaded to the card.
+ // Start the poll timer. We should do this before we call
+ // GetAddress. Add a reference for the timer.
+ NdisAcquireSpinLock(&Adapter->Lock);
+ LtReferenceAdapterNonInterlock(Adapter, &RefStatus);
+
+ ASSERTMSG("LtInitRegisterAdapter: RefAdater Failed!\n",
+ (RefStatus == NDIS_STATUS_SUCCESS));
+
+ Adapter->Flags |= ADAPTER_TIMER_QUEUED;
+ NdisSetTimer(&Adapter->PollingTimer, LT_POLLING_TIME);
+ NdisReleaseSpinLock(&Adapter->Lock);
+ break;
+ }
+
+ LogErrorCode = NDIS_ERROR_CODE_HARDWARE_FAILURE;
+
+ }
+ else
+ {
+ LogErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER;
+ }
+
+
+ // We either could not initialize the hardware or get the node
+ // address. OR there was a config error. Log it and deregister
+ // the adapter.
+ LOGERROR(Adapter->NdisAdapterHandle, LogErrorCode);
+
+ // Deregister the adapter. This calls LtInitRemoveAdapter which
+ // will do all necessary cleanup.
+ NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
+
+ Status = NDIS_STATUS_FAILURE;
+ break;
+
+ } while (FALSE);
+
+ return(Status);
+}
+
+
+
+
+BOOLEAN
+LtInitGetAddressSetPoll(
+ IN PLT_ADAPTER Adapter,
+ IN UCHAR SuggestedNodeId
+ )
+/*++
+
+Routine Description:
+
+ This gets the node id from the card (starts it off actually) and
+ sets the card to be in polling mode.
+
+Arguments:
+
+ Adapter : Pointer to the adapter structure
+ SuggestedNodeId : Pram node id or 0
+
+Return Value:
+
+ TRUE : if success, FALSE otherwise
+
+--*/
+{
+ ULONG Seed, Random;
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("LtGetAddress: Getting a node address for lt adapter...\n"));
+
+ if (SuggestedNodeId == 0)
+ {
+ Seed = (ULONG)Adapter;
+ Random = RtlRandom(&Seed);
+ SuggestedNodeId =
+ (UCHAR)((Random % LT_MAX_CLIENT_NODE_ID) + LT_MIN_SERVER_NODE_ID);
+ }
+
+ DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO,
+ ("LtGetAddress: Suggested Node Id = %lx\n", SuggestedNodeId));
+
+ // Command Length LSB
+ NdisRawWritePortUchar(XFER_PORT, 2);
+
+ // Command Length MSB
+ NdisRawWritePortUchar(XFER_PORT, 0);
+
+ NdisRawWritePortUchar(XFER_PORT, (UCHAR)LT_CMD_LAP_INIT);
+
+ NdisRawWritePortUchar(XFER_PORT, SuggestedNodeId);
+
+ // Use 0xFF for the interrupt if this card is to be polled.
+ // We *ONLY* support polling.
+ NdisRawWritePortUchar(XFER_PORT, LT_ADAPTER_POLLED_MODE);
+
+ return TRUE;
+}
+
+
+