You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
761 lines
25 KiB
761 lines
25 KiB
/*
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
(C) Copyright 1998
|
|
All rights reserved.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
Portions of this software are:
|
|
|
|
(C) Copyright 1995, 1999 TriplePoint, Inc. -- http://www.TriplePoint.com
|
|
License to use this software is granted under the terms outlined in
|
|
the TriplePoint Software Services Agreement.
|
|
|
|
(C) Copyright 1992 Microsoft Corp. -- http://www.Microsoft.com
|
|
License to use this software is granted under the terms outlined in
|
|
the Microsoft Windows Device Driver Development Kit.
|
|
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@doc INTERNAL Adapter Adapter_c
|
|
|
|
@module Adapter.c |
|
|
|
|
This module implements the interface to the <t MINIPORT_ADAPTER_OBJECT>.
|
|
Supports the high-level adapter control functions used by the NDIS WAN
|
|
Minport driver. This module isolates most the NDIS specific logical
|
|
adapter interfaces. It should require very little change if you follow
|
|
this same overall architecture. You should try to isolate your changes
|
|
to the <t CARD_OBJECT> that is contained within the logical adapter
|
|
<t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
@head3 Contents |
|
|
@index class,mfunc,func,msg,mdata,struct,enum | Adapter_c
|
|
|
|
@end
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
*/
|
|
|
|
#define __FILEID__ MINIPORT_ADAPTER_OBJECT_TYPE
|
|
// Unique file ID for error logging
|
|
|
|
#include "Miniport.h" // Defines all the miniport objects
|
|
|
|
#if defined(NDIS_LCODE)
|
|
# pragma NDIS_LCODE // Windows 95 wants this code locked down!
|
|
# pragma NDIS_LDATA
|
|
#endif
|
|
|
|
|
|
PMINIPORT_ADAPTER_OBJECT g_Adapters[MAX_ADAPTERS] // @globalv
|
|
// Keeps track of all the <t MINIPORT_ADAPTER_OBJECT>s created by the driver.
|
|
= { 0 };
|
|
|
|
DBG_STATIC ULONG g_AdapterInstanceCounter // @globalv
|
|
// Keeps track of how many <t MINIPORT_ADAPTER_OBJECT>s are created and
|
|
// stored in the <p g_Adapters> array.
|
|
= 0;
|
|
|
|
DBG_STATIC UCHAR g_AnsiDriverName[] // @globalv
|
|
// ANSI string used to identify the driver to the system; usually defined
|
|
// as VER_PRODUCT_STR.
|
|
= VER_PRODUCT_STR;
|
|
|
|
DBG_STATIC UCHAR g_AnsiVendorDescription[] // @globalv
|
|
// ANSI string used to identify the vendor's device to the system; usually
|
|
// defined as VER_DEVICE_STR " Adapter".
|
|
= VER_DEVICE_STR " Adapter";
|
|
|
|
|
|
/* @doc INTERNAL EXTERNAL Adapter Adapter_c g_AdapterParameters
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@topic 5.1 Adapter Parameters |
|
|
|
|
This section describes the registry parameters read into the
|
|
<t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
@globalv DBG_STATIC <t PARAM_TABLE> | g_AdapterParameters |
|
|
|
|
This table defines the registry based parameters to be assigned to data
|
|
members of the <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
<f Note>:
|
|
If you add any registry based data members to <t MINIPORT_ADAPTER_OBJECT>
|
|
you will need to modify <f AdapterReadParameters> and add the parameter
|
|
definitions to the <f g_AdapterParameters> table.
|
|
|
|
*/
|
|
|
|
DBG_STATIC NDIS_STRING g_DefaultAddressList // @globalv
|
|
// Default value to be used for AddressList if it's not in the registry.
|
|
= INIT_STRING_CONST(VER_DEFAULT_ADDRESSLIST);
|
|
|
|
DBG_STATIC NDIS_STRING g_DefaultDeviceName // @globalv
|
|
// Default value to be used for DeviceName if it's not in the registry.
|
|
= INIT_STRING_CONST(VER_PRODUCT_STR);
|
|
|
|
DBG_STATIC NDIS_STRING g_DefaultMediaType // @globalv
|
|
// Default value to be used for MediaType if it's not in the registry.
|
|
= INIT_STRING_CONST(VER_DEFAULT_MEDIATYPE);
|
|
|
|
DBG_STATIC PARAM_TABLE g_AdapterParameters[] =
|
|
{
|
|
#if !defined(NDIS50_MINIPORT)
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
BusNumber, PARAM_BusNumber,
|
|
TRUE, NdisParameterInteger, 0,
|
|
0, 0, 15),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
BusType, PARAM_BusType,
|
|
TRUE, NdisParameterInteger, 0,
|
|
0, Internal, MaximumInterfaceType),
|
|
#endif // NDIS50_MINIPORT
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
TapiAddressList, PARAM_AddressList,
|
|
FALSE, NdisParameterMultiString, 0,
|
|
&g_DefaultAddressList, 0, 0),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
DeviceName, PARAM_DeviceName,
|
|
FALSE, NdisParameterString, 0,
|
|
&g_DefaultDeviceName, 0, 0),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
MediaType, PARAM_MediaType,
|
|
FALSE, NdisParameterString, 0,
|
|
&g_DefaultMediaType, 0, 0),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
NoAnswerTimeOut, PARAM_NoAnswerTimeOut,
|
|
FALSE, NdisParameterHexInteger, 0,
|
|
CARD_NO_ANSWER_TIMEOUT, 5000, 120000),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
NoAcceptTimeOut, PARAM_NoAcceptTimeOut,
|
|
FALSE, NdisParameterHexInteger, 0,
|
|
CARD_NO_ACCEPT_TIMEOUT, 1000, 60000),
|
|
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
RunningWin95, PARAM_RunningWin95,
|
|
FALSE, NdisParameterInteger, 0,
|
|
0, 0, 1),
|
|
|
|
#if DBG
|
|
PARAM_ENTRY(MINIPORT_ADAPTER_OBJECT,
|
|
DbgFlags, PARAM_DebugFlags,
|
|
FALSE, NdisParameterHexInteger, 0,
|
|
DBG_DEFAULTS | DBG_TAPICALL_ON, 0, 0xffffffff),
|
|
// TODO: Change the debug flags to meet your needs.
|
|
#endif
|
|
/* The last entry must be an empty string! */
|
|
{ { 0 } }
|
|
};
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterReadParameters
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterReadParameters> reads the adapter parameters from the registry
|
|
and initializes the associated data members. This should only be called
|
|
by <f AdapterCreate>.
|
|
|
|
<f Note>:
|
|
If you add any registry based data members to <t MINIPORT_ADAPTER_OBJECT>
|
|
you will need to modify <f AdapterReadParameters> and add the parameter
|
|
definitions to the <f g_AdapterParameters> table.
|
|
|
|
@rdesc
|
|
|
|
<f AdapterReadParameters> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
DBG_STATIC NDIS_STATUS AdapterReadParameters(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterReadParameters")
|
|
|
|
NDIS_STATUS Result;
|
|
// Holds the result code returned by this function.
|
|
|
|
ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
|
|
DBG_ENTER(DbgInfo);
|
|
|
|
/*
|
|
// Parse the registry parameters.
|
|
*/
|
|
Result = ParamParseRegistry(
|
|
pAdapter->MiniportAdapterHandle,
|
|
pAdapter->WrapperConfigurationContext,
|
|
(PUCHAR)pAdapter,
|
|
g_AdapterParameters
|
|
);
|
|
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// Make sure the parameters are valid.
|
|
*/
|
|
if (pAdapter->TODO)
|
|
{
|
|
DBG_ERROR(DbgInfo,("Invalid value 'TODO'\n",
|
|
pAdapter->TODO));
|
|
NdisWriteErrorLogEntry(
|
|
pAdapter->MiniportAdapterHandle,
|
|
NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
|
|
3,
|
|
pAdapter->TODO,
|
|
__FILEID__,
|
|
__LINE__
|
|
);
|
|
Result = NDIS_STATUS_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
// Construct the "MediaType\0DeviceName" string for use by TAPI
|
|
// on Windows NT.
|
|
*/
|
|
strcpy(pAdapter->ProviderInfo, pAdapter->MediaType.Buffer);
|
|
strcpy(pAdapter->ProviderInfo + pAdapter->MediaType.Length + 1,
|
|
pAdapter->DeviceName.Buffer);
|
|
pAdapter->ProviderInfoSize = pAdapter->MediaType.Length + 1 +
|
|
pAdapter->DeviceName.Length + 1;
|
|
|
|
DBG_NOTICE(DbgInfo,("ProviderInfoMedia='%s\\0%s'\n",
|
|
&pAdapter->ProviderInfo[0],
|
|
&pAdapter->ProviderInfo[pAdapter->MediaType.Length + 1]
|
|
));
|
|
}
|
|
}
|
|
|
|
DBG_RETURN(DbgInfo, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterCreateObjects
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterCreateObjects> calls the create routines for all the objects
|
|
contained in <t MINIPORT_ADAPTER_OBJECT>. This should only be called
|
|
by <f AdapterCreate>.
|
|
|
|
<f Note>:
|
|
If you add any new objects to <t MINIPORT_ADAPTER_OBJECT> you will need
|
|
to modify <f AdapterCreateObjects> and <f AdapterDestroyObjects> so they
|
|
will get created and destroyed properly.
|
|
|
|
@rdesc
|
|
|
|
<f AdapterCreateObjects> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
DBG_STATIC NDIS_STATUS AdapterCreateObjects(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterCreateObjects")
|
|
|
|
NDIS_STATUS Result;
|
|
// Holds the result code returned by this function.
|
|
|
|
ULONG Index;
|
|
// Loop counter.
|
|
|
|
ULONG NumBChannels;
|
|
// The number of BChannels supported by the NIC.
|
|
|
|
PANSI_STRING pTapiAddressList;
|
|
// MultiString of RAS address strings.
|
|
|
|
PUCHAR pTapiLineAddress;
|
|
// A pointer to the RAS/TAPI line address assigned to each RAS line.
|
|
|
|
ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
|
|
DBG_ENTER(DbgInfo);
|
|
|
|
/*
|
|
// Create the Card object.
|
|
*/
|
|
Result = CardCreate(&pAdapter->pCard, pAdapter);
|
|
|
|
/*
|
|
// Create the DChannel object.
|
|
*/
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
Result = DChannelCreate(&pAdapter->pDChannel, pAdapter);
|
|
}
|
|
|
|
/*
|
|
// Allocate space for the BChannels.
|
|
*/
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
NumBChannels = CardNumChannels(pAdapter->pCard);
|
|
|
|
Result = ALLOCATE_MEMORY(pAdapter->pBChannelArray,
|
|
sizeof(PVOID) * NumBChannels,
|
|
pAdapter->MiniportAdapterHandle);
|
|
}
|
|
|
|
/*
|
|
// Create the BChannel objects.
|
|
*/
|
|
pTapiAddressList = &pAdapter->TapiAddressList;
|
|
pTapiLineAddress = pTapiAddressList->Buffer;
|
|
|
|
for (Index = 0; Result == NDIS_STATUS_SUCCESS &&
|
|
Index < NumBChannels; Index++)
|
|
{
|
|
Result = BChannelCreate(&pAdapter->pBChannelArray[Index],
|
|
Index,
|
|
pTapiLineAddress,
|
|
pAdapter);
|
|
|
|
/*
|
|
// If we run off the end of the address list, we just point at the
|
|
// null terminator for the other addresses. This might happen if
|
|
// some of the lines were not configured for use with RAS/TAPI.
|
|
*/
|
|
pTapiLineAddress += strlen(pTapiLineAddress) + 1;
|
|
if ((pTapiLineAddress - pTapiAddressList->Buffer) >=
|
|
pTapiAddressList->Length)
|
|
{
|
|
--pTapiLineAddress;
|
|
}
|
|
|
|
/*
|
|
// Keep track of how many are created.
|
|
*/
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
pAdapter->NumBChannels++;
|
|
}
|
|
}
|
|
|
|
DBG_RETURN(DbgInfo, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterCreate
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterCreate> allocates memory for a <t MINIPORT_ADAPTER_OBJECT> and
|
|
then initializes the data members to their starting state.
|
|
If successful, <p ppAdapter> will be set to point to the newly created
|
|
<t MINIPORT_ADAPTER_OBJECT>. Otherwise, <p ppAdapter> will be set to
|
|
NULL.
|
|
|
|
@comm
|
|
|
|
This function should be called only once when the Miniport is loaded.
|
|
Before the Miniport is unloaded, <f AdapterDestroy> must be called to
|
|
release the <t MINIPORT_ADAPTER_OBJECT> created by this function.
|
|
|
|
@rdesc
|
|
|
|
<f AdapterCreate> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
NDIS_STATUS AdapterCreate(
|
|
OUT PMINIPORT_ADAPTER_OBJECT *ppAdapter, // @parm
|
|
// Points to a caller-defined memory location to which this function
|
|
// writes the virtual address of the allocated <t MINIPORT_ADAPTER_OBJECT>.
|
|
|
|
IN NDIS_HANDLE MiniportAdapterHandle, // @parm
|
|
// Specifies a handle identifying the miniport's NIC, which is assigned
|
|
// by the NDIS library. MiniportInitialize should save this handle; it
|
|
// is a required parameter in subsequent calls to NdisXxx functions.
|
|
|
|
IN NDIS_HANDLE WrapperConfigurationContext // @parm
|
|
// Specifies a handle used only during initialization for calls to
|
|
// NdisXxx configuration and initialization functions. For example,
|
|
// this handle is a required parameter to NdisOpenConfiguration and
|
|
// the NdisImmediateReadXxx and NdisImmediateWriteXxx functions.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterCreate")
|
|
|
|
NDIS_STATUS Result;
|
|
// Holds the result code returned by this function.
|
|
|
|
PMINIPORT_ADAPTER_OBJECT pAdapter;
|
|
// Pointer to our newly allocated object.
|
|
|
|
DBG_ENTER(DbgInfo);
|
|
|
|
/*
|
|
// Make sure the caller's object pointer is NULL to begin with.
|
|
// It will be set later only if everything is successful.
|
|
*/
|
|
*ppAdapter = NULL;
|
|
|
|
/*
|
|
// Allocate memory for the object.
|
|
*/
|
|
Result = ALLOCATE_OBJECT(pAdapter, MiniportAdapterHandle);
|
|
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// Zero everything to begin with.
|
|
// Then set the object type and assign a unique ID .
|
|
*/
|
|
pAdapter->ObjectType = MINIPORT_ADAPTER_OBJECT_TYPE;
|
|
pAdapter->ObjectID = ++g_AdapterInstanceCounter;
|
|
ASSERT(g_AdapterInstanceCounter <= MAX_ADAPTERS);
|
|
if (g_AdapterInstanceCounter <= MAX_ADAPTERS)
|
|
{
|
|
g_Adapters[g_AdapterInstanceCounter-1] = pAdapter;
|
|
}
|
|
|
|
/*
|
|
// We use the instance number in debug messages to help when debugging
|
|
// with multiple adapters.
|
|
*/
|
|
#if DBG
|
|
pAdapter->DbgID[0] = (UCHAR) ((pAdapter->ObjectID & 0x0F) + '0');
|
|
pAdapter->DbgID[1] = ':';
|
|
ASSERT (sizeof(VER_TARGET_STR) <= sizeof(pAdapter->DbgID)-2);
|
|
memcpy(&pAdapter->DbgID[2], VER_TARGET_STR, sizeof(VER_TARGET_STR));
|
|
#endif
|
|
/*
|
|
// Initialize the member variables to their default settings.
|
|
*/
|
|
pAdapter->MiniportAdapterHandle = MiniportAdapterHandle;
|
|
pAdapter->WrapperConfigurationContext = WrapperConfigurationContext;
|
|
|
|
/*
|
|
// Allocate spin locks to use for MUTEX queue protection.
|
|
*/
|
|
NdisAllocateSpinLock(&pAdapter->EventLock);
|
|
NdisAllocateSpinLock(&pAdapter->TransmitLock);
|
|
NdisAllocateSpinLock(&pAdapter->ReceiveLock);
|
|
|
|
/*
|
|
// Parse the registry parameters.
|
|
*/
|
|
Result = AdapterReadParameters(pAdapter);
|
|
#if DBG
|
|
DbgInfo->DbgFlags = pAdapter->DbgFlags;
|
|
#endif // DBG
|
|
DBG_DISPLAY(("NOTICE: Adapter#%d=0x%X DbgFlags=0x%X\n",
|
|
pAdapter->ObjectID, pAdapter, pAdapter->DbgFlags));
|
|
|
|
/*
|
|
// If all goes well, we are ready to create the sub-components.
|
|
*/
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
Result = AdapterCreateObjects(pAdapter);
|
|
}
|
|
|
|
if (Result == NDIS_STATUS_SUCCESS)
|
|
{
|
|
/*
|
|
// All is well, so return the object pointer to the caller.
|
|
*/
|
|
*ppAdapter = pAdapter;
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
// Something went wrong, so let's make sure everything is
|
|
// cleaned up.
|
|
*/
|
|
AdapterDestroy(pAdapter);
|
|
}
|
|
}
|
|
|
|
DBG_RETURN(DbgInfo, Result);
|
|
return (Result);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterDestroyObjects
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterDestroyObjects> calls the destroy routines for all the objects
|
|
contained in <t MINIPORT_ADAPTER_OBJECT>. This should only be called
|
|
by <f AdapterDestroy>.
|
|
|
|
<f Note>:
|
|
If you add any new objects to <t MINIPORT_ADAPTER_OBJECT> you will need
|
|
to modify <f AdapterCreateObjects> and <f AdapterDestroyObjects> so they
|
|
will get created and destroyed properly.
|
|
|
|
*/
|
|
|
|
DBG_STATIC void AdapterDestroyObjects(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterDestroyObjects")
|
|
|
|
UINT NumBChannels;
|
|
// The number of BChannels supported by the NIC.
|
|
|
|
ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
|
|
DBG_ENTER(DbgInfo);
|
|
|
|
/*
|
|
// Destroy the BChannel objects.
|
|
*/
|
|
NumBChannels = pAdapter->NumBChannels;
|
|
while (NumBChannels--)
|
|
{
|
|
BChannelDestroy(pAdapter->pBChannelArray[NumBChannels]);
|
|
}
|
|
pAdapter->NumBChannels = 0;
|
|
|
|
/*
|
|
// Free space for the BChannels.
|
|
*/
|
|
if (pAdapter->pBChannelArray)
|
|
{
|
|
NumBChannels = CardNumChannels(pAdapter->pCard);
|
|
FREE_MEMORY(pAdapter->pBChannelArray, sizeof(PVOID) * NumBChannels);
|
|
}
|
|
|
|
/*
|
|
// Destroy the DChannel object.
|
|
*/
|
|
DChannelDestroy(pAdapter->pDChannel);
|
|
|
|
/*
|
|
// Destroy the Card object.
|
|
*/
|
|
CardDestroy(pAdapter->pCard);
|
|
|
|
DBG_LEAVE(DbgInfo);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterDestroy
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterDestroy> frees the memory for this <t MINIPORT_ADAPTER_OBJECT>.
|
|
All memory allocated by <f AdapterCreate> will be released back to the OS.
|
|
|
|
*/
|
|
|
|
void AdapterDestroy(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterDestroy")
|
|
|
|
DBG_ENTER(DbgInfo);
|
|
|
|
if (pAdapter)
|
|
{
|
|
ASSERT(pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
|
|
|
|
/*
|
|
// Release all objects allocated within this object.
|
|
*/
|
|
AdapterDestroyObjects(pAdapter);
|
|
|
|
/*
|
|
// Destroy any string parameter buffers created by ParamParseRegistry.
|
|
*/
|
|
if (pAdapter->MediaType.Length)
|
|
{
|
|
FREE_NDISSTRING(pAdapter->MediaType);
|
|
}
|
|
if (pAdapter->DeviceName.Length)
|
|
{
|
|
FREE_NDISSTRING(pAdapter->DeviceName);
|
|
}
|
|
if (pAdapter->TapiAddressList.Length)
|
|
{
|
|
FREE_NDISSTRING(pAdapter->TapiAddressList);
|
|
}
|
|
|
|
if (pAdapter->EventLock.SpinLock)
|
|
{
|
|
NdisFreeSpinLock(&pAdapter->EventLock);
|
|
}
|
|
|
|
if (pAdapter->TransmitLock.SpinLock)
|
|
{
|
|
NdisFreeSpinLock(&pAdapter->TransmitLock);
|
|
}
|
|
|
|
if (pAdapter->ReceiveLock.SpinLock)
|
|
{
|
|
NdisFreeSpinLock(&pAdapter->ReceiveLock);
|
|
}
|
|
|
|
/*
|
|
// Make sure we fail the ASSERT if we see this object again.
|
|
*/
|
|
if (pAdapter->ObjectType <= MAX_ADAPTERS)
|
|
{
|
|
g_Adapters[pAdapter->ObjectType-1] = NULL;
|
|
}
|
|
pAdapter->ObjectType = 0;
|
|
FREE_OBJECT(pAdapter);
|
|
}
|
|
|
|
DBG_LEAVE(DbgInfo);
|
|
}
|
|
|
|
|
|
/* @doc INTERNAL Adapter Adapter_c AdapterInitialize
|
|
ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
|
|
|
|
@func
|
|
|
|
<f AdapterInitialize> prepares the <t MINIPORT_ADAPTER_OBJECT> and all
|
|
its sub-components for use by the NDIS wrapper. Upon successful
|
|
completion of this routine, the NIC will be ready to accept requests
|
|
from the NDIS wrapper.
|
|
|
|
@rdesc
|
|
|
|
<f AdapterInitialize> returns zero if it is successful.<nl>
|
|
Otherwise, a non-zero return value indicates an error condition.
|
|
|
|
*/
|
|
|
|
NDIS_STATUS AdapterInitialize(
|
|
IN PMINIPORT_ADAPTER_OBJECT pAdapter // @parm
|
|
// A pointer to the <t MINIPORT_ADAPTER_OBJECT> instance.
|
|
)
|
|
{
|
|
DBG_FUNC("AdapterInitialize")
|
|
|
|
NDIS_STATUS Result;
|
|
// Holds the result code returned by this function.
|
|
|
|
PBCHANNEL_OBJECT pBChannel;
|
|
// A Pointer to one of our <t BCHANNEL_OBJECT>'s.
|
|
|
|
ULONG Index;
|
|
// Loop counter.
|
|
|
|
ASSERT(pAdapter && pAdapter->ObjectType == MINIPORT_ADAPTER_OBJECT_TYPE);
|
|
DBG_ENTER(pAdapter);
|
|
|
|
/*
|
|
// Initialize the WAN information structure to match the capabilities of
|
|
// the adapter.
|
|
*/
|
|
pAdapter->WanInfo.MaxFrameSize = pAdapter->pCard->BufferSize - NDISWAN_EXTRA_SIZE;
|
|
pAdapter->WanInfo.MaxTransmit = pAdapter->pCard->TransmitBuffersPerLink;
|
|
|
|
/*
|
|
// Since we copy the packets to/from adapter RAM, no padding information is
|
|
// needed in the WAN packets we get. We can just use adapter RAM as needed.
|
|
*/
|
|
pAdapter->WanInfo.HeaderPadding = 0;
|
|
pAdapter->WanInfo.TailPadding = 0;
|
|
|
|
/*
|
|
// Transmits and received are copied to/from adapter RAM so cached memory
|
|
// can be used for packet allocation and we don't really care if it's
|
|
// physically contiguous or not, as long as it's virtually contiguous.
|
|
*/
|
|
pAdapter->WanInfo.MemoryFlags = 0;
|
|
pAdapter->WanInfo.HighestAcceptableAddress = g_HighestAcceptableAddress;
|
|
|
|
/*
|
|
// We only support point to point framing, and we don't need to see the
|
|
// address or control fields. The TAPI_PROVIDER bit is set to indicate
|
|
// that we can accept the TAPI OID requests.
|
|
*/
|
|
pAdapter->WanInfo.FramingBits = PPP_FRAMING | TAPI_PROVIDER |
|
|
PPP_MULTILINK_FRAMING;
|
|
|
|
/*
|
|
// This value is ignored by this driver, but its default behavior is such
|
|
// that all these control bytes would appear to be handled transparently.
|
|
*/
|
|
pAdapter->WanInfo.DesiredACCM = 0;
|
|
|
|
/*
|
|
// This value indicates how many point to point connections are allowed
|
|
// per adapter. Currently, the WAN wrapper only supports 1 connection
|
|
// per NDIS link.
|
|
*/
|
|
pAdapter->WanInfo.Endpoints = pAdapter->NumBChannels;
|
|
|
|
/*
|
|
// Setyup the default call parameters.
|
|
*/
|
|
pAdapter->DefaultLineCallParams.ulTotalSize = sizeof(pAdapter->DefaultLineCallParams);
|
|
pAdapter->DefaultLineCallParams.ulBearerMode = LINEBEARERMODE_DATA;
|
|
pAdapter->DefaultLineCallParams.ulMinRate = _56KBPS;
|
|
pAdapter->DefaultLineCallParams.ulMaxRate = _64KBPS;
|
|
pAdapter->DefaultLineCallParams.ulMediaMode = LINEMEDIAMODE_DIGITALDATA;
|
|
pAdapter->DefaultLineCallParams.ulCallParamFlags = 0;
|
|
pAdapter->DefaultLineCallParams.ulAddressMode = LINEADDRESSMODE_ADDRESSID;
|
|
pAdapter->DefaultLineCallParams.ulAddressID = TSPI_ADDRESS_ID;
|
|
|
|
/*
|
|
// Initialize the packet management queues to empty.
|
|
*/
|
|
InitializeListHead(&pAdapter->EventList);
|
|
InitializeListHead(&pAdapter->TransmitPendingList);
|
|
InitializeListHead(&pAdapter->TransmitCompleteList);
|
|
InitializeListHead(&pAdapter->ReceiveCompleteList);
|
|
|
|
/*
|
|
// Setup the timer event handler.
|
|
*/
|
|
NdisMInitializeTimer(&pAdapter->EventTimer,
|
|
pAdapter->MiniportAdapterHandle,
|
|
MiniportTimer,
|
|
pAdapter);
|
|
|
|
/*
|
|
// Initialize the DChannel object.
|
|
*/
|
|
DChannelInitialize(pAdapter->pDChannel);
|
|
|
|
/*
|
|
// Initialize all the BChannel objects.
|
|
*/
|
|
for (Index = 0; Index < pAdapter->NumBChannels; ++Index)
|
|
{
|
|
pBChannel = GET_BCHANNEL_FROM_INDEX(pAdapter, Index);
|
|
BChannelInitialize(pBChannel);
|
|
}
|
|
|
|
/*
|
|
// Now, we can initialize the Card object.
|
|
*/
|
|
Result = CardInitialize(pAdapter->pCard);
|
|
|
|
DBG_RETURN(pAdapter, Result);
|
|
return (Result);
|
|
}
|
|
|