1123 lines
24 KiB
C
1123 lines
24 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
adapter.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This contains routines related to the adapter (Initialize,
|
||
|
Deinitialize, bind, unbind, open, close etc.)
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Anil Francis Thomas (10/98)
|
||
|
|
||
|
Environment:
|
||
|
|
||
|
Kernel
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
|
||
|
#define MODULE_ID MODULE_ADAPTER
|
||
|
|
||
|
NDIS_STATUS
|
||
|
AtmSmAllocateAdapter(
|
||
|
PATMSM_ADAPTER *ppAdapter
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
AtmSmDeallocateAdapter(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
AtmSmOpenAdapterComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_STATUS OpenStatus
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
AtmSmCloseAdapterComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_STATUS Status
|
||
|
);
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmBindAdapter(
|
||
|
OUT PNDIS_STATUS pStatus,
|
||
|
IN NDIS_HANDLE BindContext,
|
||
|
IN PNDIS_STRING pDeviceName,
|
||
|
IN PVOID SystemSpecific1,
|
||
|
IN PVOID SystemSpecific2
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
This is called by NDIS when it has an adapter for which there is a
|
||
|
binding to the AtmSm client.
|
||
|
|
||
|
We first allocate an Adapter structure. Then we open our configuration
|
||
|
section for this adapter and save the handle in the Adapter structure.
|
||
|
Finally, we open the adapter.
|
||
|
|
||
|
We don't do anything more for this adapter until NDIS notifies us of
|
||
|
the presence of a Call manager (via our AfRegisterNotify handler).
|
||
|
|
||
|
Arguments:
|
||
|
pStatus - Place to return status of this call
|
||
|
BindContext - Not used, because we don't pend this call
|
||
|
pDeviceName - The name of the adapter we are requested to bind to
|
||
|
SystemSpecific1 - Opaque to us; to be used to access configuration info
|
||
|
SystemSpecific2 - Opaque to us; not used.
|
||
|
|
||
|
Return Value:
|
||
|
None. We set *pStatus to an error code if something goes wrong before we
|
||
|
call NdisOpenAdapter, otherwise NDIS_STATUS_PENDING.
|
||
|
--*/
|
||
|
{
|
||
|
PATMSM_ADAPTER pAdapt = NULL; // Pointer to new adapter structure
|
||
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
||
|
NDIS_STATUS OpenStatus;
|
||
|
UINT MediumIndex;
|
||
|
NDIS_MEDIUM MediumArray[] = {NdisMediumAtm};
|
||
|
ULONG Length;
|
||
|
|
||
|
TraceIn(AtmSmBindAdapter);
|
||
|
|
||
|
DbgLoud(("BindAdapter: Context 0x%x, pDevName 0x%x, SS1 0x%x, SS2 0x%x\n",
|
||
|
BindContext, pDeviceName, SystemSpecific1, SystemSpecific2));
|
||
|
|
||
|
|
||
|
do {
|
||
|
|
||
|
//
|
||
|
// Allocate and initialize the Adapter structure.
|
||
|
//
|
||
|
Status = AtmSmAllocateAdapter(&pAdapt);
|
||
|
|
||
|
if(NDIS_STATUS_SUCCESS != Status)
|
||
|
break;
|
||
|
|
||
|
pAdapt->NdisBindContext = BindContext;
|
||
|
|
||
|
// Status = AtmSmReadAdapterConfiguration(pAdapt);
|
||
|
|
||
|
if(NDIS_STATUS_SUCCESS != Status)
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// Now open the adapter below and complete the initialization
|
||
|
//
|
||
|
NdisOpenAdapter(&Status,
|
||
|
&OpenStatus,
|
||
|
&pAdapt->NdisBindingHandle,
|
||
|
&MediumIndex,
|
||
|
MediumArray,
|
||
|
1,
|
||
|
AtmSmGlobal.ProtHandle,
|
||
|
pAdapt,
|
||
|
pDeviceName,
|
||
|
0,
|
||
|
NULL);
|
||
|
|
||
|
if(NDIS_STATUS_PENDING != Status){
|
||
|
|
||
|
AtmSmOpenAdapterComplete((NDIS_HANDLE)pAdapt,
|
||
|
Status,
|
||
|
OpenStatus);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Return pending since we are bound to call (or have already
|
||
|
// called) NdisCompleteBindAdapter.
|
||
|
//
|
||
|
Status = NDIS_STATUS_PENDING;
|
||
|
pAdapt->Medium = MediumArray[MediumIndex];
|
||
|
|
||
|
} while (FALSE);
|
||
|
|
||
|
|
||
|
if ((NDIS_STATUS_SUCCESS != Status) &&
|
||
|
(NDIS_STATUS_PENDING != Status)) {
|
||
|
|
||
|
DbgErr(("Failed to Open Adapter. Error - 0x%X \n", Status));
|
||
|
|
||
|
if (NULL != pAdapt){
|
||
|
|
||
|
AtmSmDereferenceAdapter(pAdapt);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
TraceOut(AtmSmBindAdapter);
|
||
|
|
||
|
|
||
|
*pStatus = Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmOpenAdapterComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_STATUS Status,
|
||
|
IN NDIS_STATUS OpenStatus
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Upcall from NDIS to signal completion of a NdisOpenAdapter() call.
|
||
|
Or we called it from BindAdapter to complete the call.
|
||
|
|
||
|
Arguments:
|
||
|
ProtocolBindingContext Pointer to the pAdapt
|
||
|
Status Status of NdisOpenAdapter
|
||
|
OpenStatus OpenAdapter's code
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolBindingContext;
|
||
|
|
||
|
TraceIn(AtmSmOpenAdapterComplete);
|
||
|
|
||
|
// First complete the pending bind call.
|
||
|
NdisCompleteBindAdapter(pAdapt->NdisBindContext,
|
||
|
Status,
|
||
|
OpenStatus);
|
||
|
|
||
|
pAdapt->NdisBindContext = NULL; // we don't need the context anymore
|
||
|
|
||
|
if (NDIS_STATUS_SUCCESS != Status)
|
||
|
{
|
||
|
//
|
||
|
// NdisOpenAdapter() failed - log an error and exit
|
||
|
//
|
||
|
DbgErr(("Failed to open adapter. Status - 0x%X \n", Status));
|
||
|
|
||
|
AtmSmCloseAdapterComplete(pAdapt, Status);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pAdapt->ulFlags |= ADAPT_OPENED;
|
||
|
|
||
|
AtmSmQueryAdapter(pAdapt);
|
||
|
|
||
|
NdisQueryAdapterInstanceName(
|
||
|
&pAdapt->BoundToAdapterName,
|
||
|
pAdapt->NdisBindingHandle);
|
||
|
|
||
|
}
|
||
|
|
||
|
TraceOut(AtmSmOpenAdapterComplete);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmUnbindAdapter(
|
||
|
OUT PNDIS_STATUS pStatus,
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_HANDLE UnbindContext
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called by NDIS when it wants us to unbind
|
||
|
from an adapter. Or, this may be called from within our Unload
|
||
|
handler. We undo the sequence of operations we performed
|
||
|
in our BindAdapter handler.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pStatus - Place to return status of this operation
|
||
|
ProtocolBindingContext - Our context for this adapter binding, which
|
||
|
is a pointer to an ATMSM Adapter structure.
|
||
|
UnbindContext - This is NULL if this routine is called from
|
||
|
within our Unload handler. Otherwise (i.e.
|
||
|
NDIS called us), we retain this for later use
|
||
|
when calling NdisCompleteUnbindAdapter.
|
||
|
Return Value:
|
||
|
|
||
|
NDIS_STATUS_PENDING or NDIS_STATUS_SUCCESS.
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolBindingContext;
|
||
|
NDIS_EVENT CleanupEvent; // Used to wait for Close Adapter
|
||
|
#if DBG
|
||
|
KIRQL EntryIrql, ExitIrql;
|
||
|
#endif
|
||
|
|
||
|
TraceIn(AtmSmUnBindAdapter);
|
||
|
|
||
|
ATMSM_GET_ENTRY_IRQL(EntryIrql);
|
||
|
|
||
|
DbgInfo(("UnbindAdapter: pAdapter 0x%x, UnbindContext 0x%X\n",
|
||
|
pAdapt, UnbindContext));
|
||
|
|
||
|
NdisInitializeEvent(&CleanupEvent);
|
||
|
|
||
|
pAdapt->pCleanupEvent = &CleanupEvent;
|
||
|
|
||
|
//
|
||
|
// Save the unbind context for a later call to
|
||
|
// NdisCompleteUnbindAdapter.
|
||
|
pAdapt->UnbindContext = UnbindContext;
|
||
|
|
||
|
|
||
|
// ask the adapter to shutdown
|
||
|
AtmSmShutdownAdapter(pAdapt);
|
||
|
|
||
|
//
|
||
|
// Wait for the cleanup to complete
|
||
|
//
|
||
|
NdisWaitEvent(&CleanupEvent, 0);
|
||
|
|
||
|
//
|
||
|
// Return pending since we always call NdisCompleteUnbindAdapter.
|
||
|
//
|
||
|
*pStatus = NDIS_STATUS_PENDING;
|
||
|
|
||
|
ATMSM_CHECK_EXIT_IRQL(EntryIrql, ExitIrql);
|
||
|
|
||
|
TraceOut(AtmSmUnBindAdapter);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
AtmSmShutdownAdapter(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine is called to Shutdown an adapter.
|
||
|
|
||
|
Arguments:
|
||
|
pAdapt - Pointer to the adapter
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
NDIS_STATUS_PENDING or NDIS_STATUS_SUCCESS
|
||
|
--*/
|
||
|
{
|
||
|
NDIS_STATUS Status;
|
||
|
#if DBG
|
||
|
KIRQL EntryIrql, ExitIrql;
|
||
|
#endif
|
||
|
|
||
|
TraceIn(AtmSmShutdownAdapter);
|
||
|
|
||
|
ATMSM_GET_ENTRY_IRQL(EntryIrql);
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
pAdapt->ulFlags |= ADAPT_SHUTTING_DOWN;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Degister SAP
|
||
|
//
|
||
|
if(pAdapt->ulFlags & ADAPT_SAP_REGISTERED){
|
||
|
|
||
|
pAdapt->ulFlags &= ~ADAPT_SAP_REGISTERED;
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
Status = NdisClDeregisterSap(pAdapt->NdisSapHandle);
|
||
|
|
||
|
if (NDIS_STATUS_PENDING != Status) {
|
||
|
|
||
|
AtmSmDeregisterSapComplete(Status, pAdapt);
|
||
|
}
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Remove all VC's.
|
||
|
//
|
||
|
while (!IsListEmpty(&pAdapt->ActiveVcHead)) {
|
||
|
|
||
|
PATMSM_VC pVc;
|
||
|
|
||
|
pVc = CONTAINING_RECORD(pAdapt->ActiveVcHead.Flink, ATMSM_VC, List);
|
||
|
|
||
|
RemoveEntryList(&pVc->List);
|
||
|
InsertHeadList(&pAdapt->InactiveVcHead, &pVc->List);
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
// this will result in it getting removed
|
||
|
AtmSmDisconnectVc(pVc);
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Close Address Family
|
||
|
//
|
||
|
|
||
|
if(pAdapt->ulFlags & ADAPT_AF_OPENED){
|
||
|
|
||
|
pAdapt->ulFlags &= ~ADAPT_AF_OPENED;
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
Status = NdisClCloseAddressFamily(pAdapt->NdisAfHandle);
|
||
|
|
||
|
if (NDIS_STATUS_PENDING != Status){
|
||
|
|
||
|
AtmSmCloseAfComplete(Status, pAdapt);
|
||
|
}
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
}
|
||
|
|
||
|
if(pAdapt->pRecvIrp){
|
||
|
|
||
|
PIRP pRecvIrp = pAdapt->pRecvIrp;
|
||
|
|
||
|
// there is an Irp pending, complete it
|
||
|
pRecvIrp->IoStatus.Status = STATUS_CANCELLED;
|
||
|
pRecvIrp->Cancel = TRUE;
|
||
|
pRecvIrp->IoStatus.Information = 0;
|
||
|
IoCompleteRequest(pRecvIrp, IO_NETWORK_INCREMENT);
|
||
|
|
||
|
pAdapt->pRecvIrp = NULL;
|
||
|
}
|
||
|
|
||
|
pAdapt->fAdapterOpenedForRecv = FALSE;
|
||
|
|
||
|
//
|
||
|
// Set the interface to closing
|
||
|
//
|
||
|
ASSERT ((pAdapt->ulFlags & ADAPT_CLOSING) == 0);
|
||
|
pAdapt->ulFlags |= ADAPT_CLOSING;
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Close the adapter
|
||
|
//
|
||
|
NdisCloseAdapter(
|
||
|
&Status,
|
||
|
pAdapt->NdisBindingHandle
|
||
|
);
|
||
|
|
||
|
if (Status != NDIS_STATUS_PENDING) {
|
||
|
|
||
|
AtmSmCloseAdapterComplete(
|
||
|
(NDIS_HANDLE) pAdapt,
|
||
|
Status
|
||
|
);
|
||
|
}
|
||
|
|
||
|
ATMSM_CHECK_EXIT_IRQL(EntryIrql, ExitIrql);
|
||
|
|
||
|
TraceOut(AtmSmShutdownAdapter);
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmCloseAdapterComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_STATUS Status
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Called by NDIS or us to complete CloseAdapter call.
|
||
|
|
||
|
Arguments:
|
||
|
ProtocolBindingContext - Pointer to the adapter
|
||
|
Status - Status of our close adapter
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
PATMSM_ADAPTER pAdapt = (PATMSM_ADAPTER)ProtocolBindingContext;
|
||
|
NDIS_HANDLE UnbindContext = pAdapt->UnbindContext;
|
||
|
#if DBG
|
||
|
KIRQL EntryIrql, ExitIrql;
|
||
|
#endif
|
||
|
|
||
|
TraceIn(AtmSmCloseAdapterComplete);
|
||
|
|
||
|
ATMSM_GET_ENTRY_IRQL(EntryIrql);
|
||
|
|
||
|
pAdapt->NdisBindingHandle = NULL;
|
||
|
|
||
|
//
|
||
|
// Finally dereference it
|
||
|
//
|
||
|
AtmSmDereferenceAdapter(pAdapt);
|
||
|
|
||
|
if (UnbindContext != (NDIS_HANDLE)NULL) {
|
||
|
|
||
|
NdisCompleteUnbindAdapter(
|
||
|
UnbindContext,
|
||
|
NDIS_STATUS_SUCCESS
|
||
|
);
|
||
|
}
|
||
|
|
||
|
ATMSM_CHECK_EXIT_IRQL(EntryIrql, ExitIrql);
|
||
|
|
||
|
TraceOut(AtmSmCloseAdapterComplete);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
AtmSmAllocateAdapter(
|
||
|
PATMSM_ADAPTER *ppAdapter
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Called for initializing an Adapter structure.
|
||
|
|
||
|
Arguments:
|
||
|
ppAdapter - newly allocated adapter
|
||
|
|
||
|
Return Value:
|
||
|
NDIS_STATUS_SUCCESS - If successful
|
||
|
Others - failure
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PATMSM_ADAPTER pAdapt;
|
||
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
||
|
|
||
|
TraceIn(AtmSmAllocateAdapter);
|
||
|
|
||
|
do {
|
||
|
|
||
|
AtmSmAllocMem(&pAdapt, PATMSM_ADAPTER, sizeof(ATMSM_ADAPTER));
|
||
|
|
||
|
if (NULL == pAdapt){
|
||
|
|
||
|
Status = NDIS_STATUS_RESOURCES;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Initialize the adapter structure
|
||
|
//
|
||
|
NdisZeroMemory(pAdapt, sizeof(ATMSM_ADAPTER));
|
||
|
|
||
|
pAdapt->ulSignature = atmsm_adapter_signature;
|
||
|
|
||
|
//
|
||
|
// Put a reference on the adapter
|
||
|
//
|
||
|
AtmSmReferenceAdapter(pAdapt);
|
||
|
|
||
|
|
||
|
// the address is invalid now
|
||
|
pAdapt->ulFlags |= ADAPT_ADDRESS_INVALID;
|
||
|
|
||
|
|
||
|
// Hard-code the selector Byte
|
||
|
pAdapt->SelByte = (UCHAR) 0x5;
|
||
|
|
||
|
INIT_BLOCK_STRUCT(&pAdapt->RequestBlock);
|
||
|
|
||
|
InitializeListHead(&pAdapt->InactiveVcHead);
|
||
|
InitializeListHead(&pAdapt->ActiveVcHead);
|
||
|
|
||
|
NdisAllocateSpinLock(&pAdapt->AdapterLock);
|
||
|
|
||
|
NdisInitializeTimer(
|
||
|
&pAdapt->RecvTimerOb,
|
||
|
AtmSmRecvReturnTimerFunction,
|
||
|
pAdapt
|
||
|
);
|
||
|
|
||
|
//
|
||
|
// Fill in some defaults.
|
||
|
//
|
||
|
pAdapt->MaxPacketSize = DEFAULT_MAX_PACKET_SIZE;
|
||
|
pAdapt->LinkSpeed.Inbound = pAdapt->LinkSpeed.Outbound
|
||
|
= DEFAULT_SEND_BANDWIDTH;
|
||
|
|
||
|
pAdapt->VCFlowSpec = AtmSmDefaultVCFlowSpec;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Allocate a Buffer Pool
|
||
|
//
|
||
|
NdisAllocateBufferPool(&Status,
|
||
|
&pAdapt->BufferPoolHandle,
|
||
|
0xFFFFFFFF);
|
||
|
|
||
|
if (NDIS_STATUS_SUCCESS != Status)
|
||
|
break;
|
||
|
|
||
|
//
|
||
|
// Allocate a packet pool. We need this to pass sends down. We cannot
|
||
|
// use the same packet descriptor that came down to our send handler
|
||
|
//
|
||
|
NdisAllocatePacketPoolEx(&Status,
|
||
|
&pAdapt->PacketPoolHandle,
|
||
|
DEFAULT_NUM_PKTS_IN_POOL,
|
||
|
(0xFFFF - DEFAULT_NUM_PKTS_IN_POOL),
|
||
|
sizeof(PROTO_RSVD));
|
||
|
|
||
|
if (NDIS_STATUS_SUCCESS != Status)
|
||
|
break;
|
||
|
|
||
|
}while(FALSE);
|
||
|
|
||
|
|
||
|
if(Status == NDIS_STATUS_SUCCESS){
|
||
|
|
||
|
pAdapt->ulFlags |= ADAPT_CREATED;
|
||
|
|
||
|
// queue it in the Global list of adapters
|
||
|
ACQUIRE_GLOBAL_LOCK();
|
||
|
|
||
|
pAdapt->pAdapterNext = AtmSmGlobal.pAdapterList;
|
||
|
AtmSmGlobal.pAdapterList = pAdapt;
|
||
|
AtmSmGlobal.ulAdapterCount++;
|
||
|
|
||
|
RELEASE_GLOBAL_LOCK();
|
||
|
|
||
|
} else {
|
||
|
|
||
|
// Failed, so cleanup
|
||
|
LONG lRet = AtmSmDereferenceAdapter(pAdapt);
|
||
|
|
||
|
ASSERT(0 == lRet);
|
||
|
|
||
|
if(0 == lRet)
|
||
|
pAdapt = NULL;
|
||
|
}
|
||
|
|
||
|
*ppAdapter = pAdapt;
|
||
|
|
||
|
TraceOut(AtmSmAllocateAdapter);
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmDeallocateAdapter(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Called for cleaning up an Adapter structure, when it is not needed anymore.
|
||
|
We don't get here unless the reference count drops to zero, that means all
|
||
|
VC's, SAP etc are removed by now.
|
||
|
|
||
|
Arguments:
|
||
|
pAdapt - newly allocated adapter
|
||
|
|
||
|
Return Value:
|
||
|
None
|
||
|
--*/
|
||
|
{
|
||
|
PPROTO_RSVD pPRsvd;
|
||
|
PNDIS_PACKET pPkt;
|
||
|
PATMSM_ADAPTER pTmpAdapt, pPrevAdapt;
|
||
|
BOOLEAN fTimerCancelled;
|
||
|
|
||
|
TraceIn(AtmSmDeallocateAdapter);
|
||
|
|
||
|
if(!pAdapt)
|
||
|
return;
|
||
|
|
||
|
ASSERT(0 == pAdapt->ulRefCount);
|
||
|
|
||
|
// remove the adapter from the Global list of adapters
|
||
|
ACQUIRE_GLOBAL_LOCK();
|
||
|
|
||
|
pPrevAdapt = NULL;
|
||
|
pTmpAdapt = AtmSmGlobal.pAdapterList;
|
||
|
|
||
|
while(pTmpAdapt &&
|
||
|
pTmpAdapt != pAdapt){
|
||
|
|
||
|
pPrevAdapt = pTmpAdapt;
|
||
|
pTmpAdapt = pTmpAdapt->pAdapterNext;
|
||
|
}
|
||
|
|
||
|
ASSERT(pTmpAdapt);
|
||
|
|
||
|
if(pPrevAdapt)
|
||
|
pPrevAdapt->pAdapterNext = pAdapt->pAdapterNext;
|
||
|
else
|
||
|
AtmSmGlobal.pAdapterList = pAdapt->pAdapterNext;
|
||
|
|
||
|
AtmSmGlobal.ulAdapterCount--;
|
||
|
|
||
|
RELEASE_GLOBAL_LOCK();
|
||
|
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
// cancel any recv timer on the adapter
|
||
|
if(pAdapt->fRecvTimerQueued)
|
||
|
CANCEL_ADAPTER_RECV_TIMER(pAdapt, &fTimerCancelled);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Remove any packets still in the recv queue
|
||
|
//
|
||
|
while(pAdapt->pRecvPktNext){
|
||
|
|
||
|
pPkt = pAdapt->pRecvPktNext;
|
||
|
pPRsvd = GET_PROTO_RSVD(pPkt);
|
||
|
pAdapt->pRecvPktNext = pPRsvd->pPktNext;
|
||
|
|
||
|
pAdapt->ulRecvPktsCount--;
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
NdisReturnPackets(&pPkt, 1);
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
}
|
||
|
|
||
|
pAdapt->pRecvLastPkt = NULL;
|
||
|
|
||
|
// free the buffer pool
|
||
|
if(pAdapt->BufferPoolHandle)
|
||
|
NdisFreeBufferPool(pAdapt->BufferPoolHandle);
|
||
|
|
||
|
// free the pool handle
|
||
|
if(pAdapt->PacketPoolHandle)
|
||
|
NdisFreePacketPool(pAdapt->PacketPoolHandle);
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
|
||
|
// Free the bound to Adapter Name
|
||
|
if(pAdapt->BoundToAdapterName.Buffer)
|
||
|
NdisFreeString(pAdapt->BoundToAdapterName);
|
||
|
|
||
|
// Free all spinlocks
|
||
|
NdisFreeSpinLock(&pAdapt->AdapterLock);
|
||
|
|
||
|
//
|
||
|
// Signal anyone waiting for this to happen
|
||
|
//
|
||
|
if (pAdapt->pCleanupEvent) {
|
||
|
NdisSetEvent(pAdapt->pCleanupEvent);
|
||
|
}
|
||
|
|
||
|
// since memory is not cleared
|
||
|
pAdapt->ulSignature = atmsm_dead_adapter_signature;
|
||
|
|
||
|
// free the adapter itself
|
||
|
AtmSmFreeMem(pAdapt);
|
||
|
|
||
|
TraceOut(AtmSmDeallocateAdapter);
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOLEAN
|
||
|
AtmSmReferenceAdapter(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
To keep a refcount on the adapter.
|
||
|
|
||
|
Arguments:
|
||
|
pAdapt - adapter
|
||
|
|
||
|
Return Value:
|
||
|
TRUE - if the adapter is valid and not closing
|
||
|
FALSE - adapter is closing
|
||
|
--*/
|
||
|
{
|
||
|
BOOLEAN rc = FALSE;
|
||
|
|
||
|
ASSERT(pAdapt);
|
||
|
|
||
|
DbgInfo(("AtmSmReferenceAdapter - pAdapt - 0x%X\n", pAdapt));
|
||
|
|
||
|
if(!pAdapt)
|
||
|
return FALSE;
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
if(0 == (pAdapt->ulFlags & ADAPT_CLOSING)){
|
||
|
|
||
|
pAdapt->ulRefCount++;
|
||
|
rc = TRUE;
|
||
|
}
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
LONG
|
||
|
AtmSmDereferenceAdapter(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
To keep a refcount on the adapter. If the reference drops to 0
|
||
|
we free the adapter.
|
||
|
|
||
|
Arguments:
|
||
|
pAdapt - adapter
|
||
|
|
||
|
Return Value:
|
||
|
The new Refcount
|
||
|
--*/
|
||
|
{
|
||
|
ULONG ulRet;
|
||
|
|
||
|
TraceIn(AtmSmDereferenceAdapter);
|
||
|
|
||
|
DbgInfo(("AtmSmDereferenceAdapter - pAdapt - 0x%X\n", pAdapt));
|
||
|
|
||
|
ASSERT(pAdapt);
|
||
|
|
||
|
if(pAdapt){
|
||
|
|
||
|
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
ulRet = --pAdapt->ulRefCount;
|
||
|
|
||
|
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
|
||
|
|
||
|
// There are no more references on this adapter
|
||
|
// hence free it
|
||
|
if(0 == ulRet)
|
||
|
AtmSmDeallocateAdapter(pAdapt);
|
||
|
|
||
|
} else
|
||
|
ulRet = 0;
|
||
|
|
||
|
TraceOut(AtmSmDereferenceAdapter);
|
||
|
|
||
|
return ulRet;
|
||
|
}
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
AtmSmQueryAdapterATMAddresses(
|
||
|
PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
Send a request to the Call Manager to retrieve the ATM address
|
||
|
registered with the switch on the given interface.
|
||
|
|
||
|
Arguments:
|
||
|
pAdapt - adapter
|
||
|
|
||
|
Return Value:
|
||
|
--*/
|
||
|
{
|
||
|
PNDIS_REQUEST pNdisRequest;
|
||
|
PCO_ADDRESS pCoAddr;
|
||
|
NDIS_STATUS Status;
|
||
|
UINT Size;
|
||
|
|
||
|
TraceIn(AtmSmQueryAdapterATMAddresses);
|
||
|
|
||
|
//
|
||
|
// Allocate a request to query the configured address
|
||
|
//
|
||
|
Size = sizeof(NDIS_REQUEST) + sizeof(CO_ADDRESS_LIST) + sizeof(CO_ADDRESS)
|
||
|
+ sizeof(ATM_ADDRESS);
|
||
|
AtmSmAllocMem(&pNdisRequest, PNDIS_REQUEST, Size);
|
||
|
|
||
|
if (NULL == pNdisRequest){
|
||
|
DbgErr(("Failed to get Adapter ATM Address - STATUS_RESOURCES\n"));
|
||
|
return NDIS_STATUS_RESOURCES;
|
||
|
}
|
||
|
|
||
|
NdisZeroMemory(pNdisRequest, Size);
|
||
|
|
||
|
pNdisRequest->RequestType = NdisRequestQueryInformation;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.Oid = OID_CO_GET_ADDRESSES;
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.InformationBuffer =
|
||
|
((PUCHAR)pNdisRequest + sizeof(NDIS_REQUEST));
|
||
|
|
||
|
pNdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength =
|
||
|
Size - sizeof(NDIS_REQUEST);
|
||
|
|
||
|
Status = NdisCoRequest(pAdapt->NdisBindingHandle,
|
||
|
pAdapt->NdisAfHandle,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
pNdisRequest);
|
||
|
|
||
|
if (NDIS_STATUS_PENDING != Status) {
|
||
|
|
||
|
AtmSmCoRequestComplete(Status, pAdapt, NULL, NULL, pNdisRequest);
|
||
|
|
||
|
}
|
||
|
|
||
|
TraceOut(AtmSmQueryAdapterATMAddresses);
|
||
|
|
||
|
return Status;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmQueryAdapter(
|
||
|
IN PATMSM_ADAPTER pAdapt
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
Query the miniport we are bound to for the following info:
|
||
|
1. Line rate
|
||
|
2. Max packet size
|
||
|
|
||
|
These will overwrite the defaults we set up when creating the
|
||
|
adapter.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
pAdapt Pointer to the adapter
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
|
||
|
TraceIn(AtmSmQueryAdapter);
|
||
|
|
||
|
AtmSmSendAdapterNdisRequest(
|
||
|
pAdapt,
|
||
|
OID_GEN_CO_LINK_SPEED,
|
||
|
(PVOID)&(pAdapt->LinkSpeed),
|
||
|
sizeof(NDIS_CO_LINK_SPEED));
|
||
|
|
||
|
AtmSmSendAdapterNdisRequest(
|
||
|
pAdapt,
|
||
|
OID_ATM_MAX_AAL5_PACKET_SIZE,
|
||
|
(PVOID)&(pAdapt->MaxPacketSize),
|
||
|
sizeof(ULONG));
|
||
|
|
||
|
TraceOut(AtmSmQueryAdapter);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
NDIS_STATUS
|
||
|
AtmSmPnPEvent(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN PNET_PNP_EVENT pNetPnPEvent
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This is the NDIS entry point called when NDIS wants to inform
|
||
|
us about a PNP/PM event happening on an adapter.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
ProtocolBindingContext - Our context for this adapter binding, which
|
||
|
is a pointer to an ATMSM Adapter structure.
|
||
|
|
||
|
pNetPnPEvent - Pointer to the event.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PATMSM_ADAPTER pAdapt =
|
||
|
(PATMSM_ADAPTER)ProtocolBindingContext;
|
||
|
PNET_DEVICE_POWER_STATE pPowerState =
|
||
|
(PNET_DEVICE_POWER_STATE)pNetPnPEvent->Buffer;
|
||
|
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
|
||
|
|
||
|
|
||
|
TraceIn(AtmSmPnPEvent);
|
||
|
|
||
|
do {
|
||
|
|
||
|
switch (pNetPnPEvent->NetEvent) {
|
||
|
|
||
|
case NetEventSetPower:
|
||
|
|
||
|
switch (*pPowerState) {
|
||
|
case NetDeviceStateD0:
|
||
|
Status = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
//
|
||
|
// We can't suspend, so we ask NDIS to Unbind us by
|
||
|
// returning this status:
|
||
|
//
|
||
|
Status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case NetEventQueryPower: // FALLTHRU
|
||
|
case NetEventQueryRemoveDevice: // FALLTHRU
|
||
|
case NetEventCancelRemoveDevice:
|
||
|
Status = NDIS_STATUS_SUCCESS;
|
||
|
break;
|
||
|
|
||
|
case NetEventReconfigure:
|
||
|
|
||
|
if (pAdapt) {
|
||
|
|
||
|
// Status = AtmSmReadAdapterConfiguration(pAdapt);
|
||
|
|
||
|
} else {
|
||
|
//
|
||
|
// Global changes
|
||
|
//
|
||
|
Status = NDIS_STATUS_SUCCESS;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case NetEventBindList:
|
||
|
default:
|
||
|
Status = NDIS_STATUS_NOT_SUPPORTED;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
while (FALSE);
|
||
|
|
||
|
TraceOut(AtmSmPnPEvent);
|
||
|
|
||
|
return (Status);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmStatus(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_STATUS GeneralStatus,
|
||
|
IN PVOID StatusBuffer,
|
||
|
IN UINT StatusBufferSize
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DbgWarn(("StatusIndication: Ignored\n"));
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmReceiveComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmStatusComplete(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DbgWarn(("StatusComplete: Ignored\n"));
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AtmSmCoStatus(
|
||
|
IN NDIS_HANDLE ProtocolBindingContext,
|
||
|
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
|
||
|
IN NDIS_STATUS GeneralStatus,
|
||
|
IN PVOID StatusBuffer,
|
||
|
IN UINT StatusBufferSize
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
DbgWarn(("CoStatus: Ignored\n"));
|
||
|
}
|
||
|
|