?? adapter.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.
//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -