windows-nt/Source/XPSP1/NT/net/tapi/rca/rcandis.c
2020-09-26 16:20:57 +08:00

1511 lines
53 KiB
C

#include <precomp.h>
#define MODULE_NUMBER MODULE_NDIS
#define _FILENUMBER 'SIDN'
RCA_PROTOCOL_CONTEXT GlobalContext;
NDIS_STATUS
RCACoNdisInitialize(
IN PRCA_CO_NDIS_HANDLERS pHandlers,
IN ULONG ulInitTimeout
)
/*++
Routine Description:
Initializes the Co-NDIS client.
Arguments:
pHandlers - Pointer to RCA_CO_NDIS_HANDLERS structure containing pointers
to functions that will be called in response to various events.
ulInitTimeout - Number of milliseconds to allow initialization to proceed. If
it has not completed in this time, it will abort.
Return value:
NDIS_STATUS_SUCCESS if all went OK, NDIS_STATUS_FAILURE in the case of a timeout,
or some other pertinent error code otherwise.
--*/
{
NDIS_STATUS Status;
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
RCADEBUGP(RCA_INFO, ("RCACoNdisInitialize: Enter\n"));
do {
NDIS_PROTOCOL_CHARACTERISTICS RCAProtocolCharacteristics;
RCADEBUGP(RCA_LOUD, ("RCACoNdisInitialize: Protocol context block is at 0x%x\n", pProtocolContext));
//
// Initialize the protocol context.
//
NdisZeroMemory(pProtocolContext, sizeof(RCA_PROTOCOL_CONTEXT));
#if DBG
pProtocolContext->rca_sig = rca_signature;
#endif
NdisAllocateSpinLock(&pProtocolContext->SpinLock);
RCAInitBlockStruc(&pProtocolContext->BindingInfo.Block);
//
// Copy the handlers passed to us.
//
RtlCopyMemory(&pProtocolContext->Handlers, pHandlers, sizeof(RCA_CO_NDIS_HANDLERS));
//
// Set up our protocol characteristics and register as an NDIS protocol.
//
NdisZeroMemory (&RCAProtocolCharacteristics, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
RCAProtocolCharacteristics.MajorNdisVersion = NDIS_MAJOR_VERSION;
RCAProtocolCharacteristics.MinorNdisVersion = NDIS_MINOR_VERSION;
RCAProtocolCharacteristics.Filler = 0;
RCAProtocolCharacteristics.Flags = NDIS_PROTOCOL_BIND_ALL_CO;
RCAProtocolCharacteristics.CoAfRegisterNotifyHandler = RCANotifyAfRegistration;
RCAProtocolCharacteristics.OpenAdapterCompleteHandler = RCAOpenAdapterComplete;
RCAProtocolCharacteristics.CloseAdapterCompleteHandler = RCACloseAdapterComplete;
RCAProtocolCharacteristics.TransferDataCompleteHandler = RCATransferDataComplete;
RCAProtocolCharacteristics.ResetCompleteHandler = RCAResetComplete;
RCAProtocolCharacteristics.SendCompleteHandler = RCASendComplete;
RCAProtocolCharacteristics.RequestCompleteHandler = RCARequestComplete;
RCAProtocolCharacteristics.ReceiveHandler = RCAReceive;
RCAProtocolCharacteristics.ReceiveCompleteHandler = RCAReceiveComplete;
RCAProtocolCharacteristics.ReceivePacketHandler = RCAReceivePacket;
RCAProtocolCharacteristics.StatusHandler = RCAStatus;
RCAProtocolCharacteristics.StatusCompleteHandler = RCAStatusComplete;
RCAProtocolCharacteristics.BindAdapterHandler = RCABindAdapter;
RCAProtocolCharacteristics.UnbindAdapterHandler = RCAUnbindAdapter;
RCAProtocolCharacteristics.PnPEventHandler = RCAPnPEventHandler;
RCAProtocolCharacteristics.UnloadHandler = NULL;
RCAProtocolCharacteristics.CoStatusHandler = RCACoStatus;
RCAProtocolCharacteristics.CoReceivePacketHandler = RCACoReceivePacket;
RCAProtocolCharacteristics.CoSendCompleteHandler = RCACoSendComplete;
NdisInitUnicodeString(&(RCAProtocolCharacteristics.Name), RCA_CL_NAME);
NdisRegisterProtocol(&Status,
&pProtocolContext->RCAClProtocolHandle,
&RCAProtocolCharacteristics,
sizeof(RCAProtocolCharacteristics));
if (Status != NDIS_STATUS_SUCCESS) {
RCADEBUGP(RCA_ERROR, ("RCACoNdisInitialize: "
"Failed to register as an NDIS Protocol - status == 0x%x\n",
Status));
break;
}
//
// Block waiting for indications/bindings to complete.
//
RCABlockTimeOut(&pProtocolContext->BindingInfo.Block, ulInitTimeout, &Status);
if (Status == STATUS_TIMEOUT) {
Status = NDIS_STATUS_FAILURE;
RCADEBUGP(RCA_ERROR, ("RCACoNdisInitialize: "
"Initialization timed out, setting Status = NDIS_STATUS_FAILURE\n"));
break;
}
} while (FALSE);
if (Status != NDIS_STATUS_SUCCESS) {
//
// Cleanup / bail out.
//
RCACoNdisUninitialize();
}
RCADEBUGP(RCA_INFO, ("RCACoNdisInitialize: Exit - Returning status 0x%x\n", Status));
return Status;
}
VOID
RCACoNdisUninitialize(
)
/*++
Routine Description:
Uninitializes the Co-NDIS client and frees up any resources used by it.
Arguments:
(None)
Return value:
(None)
--*/
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
NDIS_STATUS Status;
RCADEBUGP(RCA_INFO, ("RCACoNdisUninitialize: Enter\n"));
//
// Deregister our protocol.
//
if (pProtocolContext->RCAClProtocolHandle != (NDIS_HANDLE)NULL) {
NdisDeregisterProtocol(&Status, pProtocolContext->RCAClProtocolHandle);
}
RCADEBUGP(RCA_INFO, ("RCACoNdisUninitialize: Exit\n"));
}
NDIS_STATUS
RCAPnPSetPower(
IN PRCA_ADAPTER pAdapter,
IN PNET_PNP_EVENT NetPnPEvent
)
{
PNET_DEVICE_POWER_STATE pPowerState;
NDIS_STATUS Status;
RCADEBUGP(RCA_INFO, ("RCAPnPSetPower: enter\n"));
pPowerState = (PNET_DEVICE_POWER_STATE)NetPnPEvent->Buffer;
switch (*pPowerState) {
case NetDeviceStateD0:
Status = NDIS_STATUS_SUCCESS;
break;
default:
Status = NDIS_STATUS_NOT_SUPPORTED;
};
RCADEBUGP(RCA_INFO, ("RCAPnPSetPower: exit\n"));
return Status;
}
NDIS_STATUS
RCAPnPQueryPower(
IN PRCA_ADAPTER pAdapter,
IN PNET_PNP_EVENT NetPnPEvent
)
{
RCADEBUGP(RCA_INFO, ("RCAPnPQueryPower: enter\n"));
RCADEBUGP(RCA_INFO, ("RCAPnPQueryPower: exit\n"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
RCAPnPQueryRemoveDevice(
IN PRCA_ADAPTER pAdapter,
IN PNET_PNP_EVENT NetPnPEvent
)
{
RCADEBUGP(RCA_INFO, ("RCAPnPQueryRemoveDevice: enter\n"));
RCADEBUGP(RCA_INFO, ("RCAPnPQueryRemoveDevice: exit\n"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
RCAPnPCancelRemoveDevice(
IN PRCA_ADAPTER pAdapter,
IN PNET_PNP_EVENT NetPnPEvent
)
{
RCADEBUGP(RCA_INFO, ("RCAPnPCancelRemoveDevice: enter\n"));
RCADEBUGP(RCA_INFO, ("RCAPnPCancelRemoveDevice: exit\n"));
return (NDIS_STATUS_SUCCESS);
}
NDIS_STATUS
RCAPnPEventBindsComplete(
IN PRCA_ADAPTER pAdapter,
IN PNET_PNP_EVENT NetPnPEvent
)
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
RCADEBUGP(RCA_INFO, ("RCAPnPEventBindsComplete: enter\n"));
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAPnPEventBindsComplete: Acquired global protocol context lock\n"));
pProtocolContext->BindingInfo.BindingsComplete = TRUE;
if (pProtocolContext->BindingInfo.SAPCnt == pProtocolContext->BindingInfo.AdapterCnt) {
RCADEBUGP(RCA_INFO, ("RCAPnPEventBindsComplete: Unblocking RCACoNdisInitialize(), Counts == %d\n",
pProtocolContext->BindingInfo.AdapterCnt));
RCASignal(&pProtocolContext->BindingInfo.Block, Status);
} else {
RCADEBUGP(RCA_INFO, ("RCAPnPEventBindsComplete: "
"Not unblocking RCACoNdisInitialize()- SAPCnt == %d, AdapterCnt == %d\n",
pProtocolContext->BindingInfo.SAPCnt, pProtocolContext->BindingInfo.AdapterCnt));
}
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAPnPEventBindsComplete: Released global protocol context lock\n"));
RCADEBUGP(RCA_INFO, ("RCAPnPEventBindsComplete: exit\n"));
return NDIS_STATUS_SUCCESS;
}
NDIS_STATUS
RCAPnPEventHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT NetPnPEvent
)
/*++
Routine Description:
Called by NDIS in to indicate a PNP event.
Arguments:
ProtocolBindingContext - Actually a pointer to the adapter structure
NetPnPEvent - Pointer to the event
Return value:
NDIS_STATUS_SUCCESS for those events we support, NDIS_STATUS_NOT_SUPPORTED for those we don't.
--*/
{
NDIS_STATUS Status;
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_INFO, ("RCAPnPEventHandler: enter\n"));
pAdapter = (PRCA_ADAPTER)ProtocolBindingContext;
switch(NetPnPEvent->NetEvent) {
case NetEventSetPower:
Status = RCAPnPSetPower(pAdapter, NetPnPEvent);
break;
case NetEventQueryPower:
Status = RCAPnPQueryPower(pAdapter, NetPnPEvent);
break;
case NetEventQueryRemoveDevice:
Status = RCAPnPQueryRemoveDevice(pAdapter, NetPnPEvent);
break;
case NetEventCancelRemoveDevice:
Status = RCAPnPCancelRemoveDevice(pAdapter, NetPnPEvent);
break;
case NetEventBindsComplete:
Status = RCAPnPEventBindsComplete(pAdapter, NetPnPEvent);
break;
default:
Status = NDIS_STATUS_NOT_SUPPORTED;
};
RCADEBUGP(RCA_INFO, ("RCAPnPEventHandler: exit, returning %x\n", Status));
return Status;
}
VOID
RCABindAdapter(
OUT PNDIS_STATUS pStatus,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
IN PVOID SystemSpecific1,
IN PVOID SystemSpecific2
)
/*++
Routine Description:
Entry point that gets called by NDIS when an adapter appears on the
system.
Arguments:
pStatus - place for our Return Value
BindContext - to be used if we call NdisCompleteBindAdapter; we don't
DeviceName - Name of the adapter to be bound to
SystemSpecific1 - Name of the protocol-specific entry in this adapter's
registry section
SystemSpecific2 - Not used
Return Value:
None. We set *pStatus to NDIS_STATUS_SUCCESS if everything goes off well,
otherwise an NDIS error status.
--*/
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
PRCA_ADAPTER *ppNextAdapter;
NDIS_STATUS OpenError;
UINT SelectedIndex;
PRCA_ADAPTER pAdapter;
NDIS_MEDIUM Media[] = {NdisMediumAtm, NdisMediumCoWan}; // This should be more generic
NDIS_STATUS Status;
RCADEBUGP(RCA_INFO,("RCABindAdapter: Enter\n"));
do
{
//
// Allocate adapter structure.
//
RCAAllocMem(pAdapter, RCA_ADAPTER, sizeof(RCA_ADAPTER));
if (pAdapter == (PRCA_ADAPTER)NULL) {
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Could not allocate memory for adapter, "
"setting status to NDIS_STATUS_RESOURCES\n"));
Status = NDIS_STATUS_RESOURCES;
break;
}
RCADEBUGP(RCA_INFO, ("RCABindAdapter: New adapter allocated at 0x%x\n", pAdapter));
//
// Initialize the new adapter structure
//
NdisZeroMemory(pAdapter, sizeof(RCA_ADAPTER));
#if DBG
pAdapter->rca_sig = rca_signature;
#endif
RCAInitBlockStruc(&pAdapter->Block);
NdisAllocateSpinLock(&pAdapter->SpinLock);
NdisInitializeWorkItem(&pAdapter->DeactivateWorkItem,
RCADeactivateAdapterWorker,
(PVOID)pAdapter);
RCAInitBlockStruc(&pAdapter->DeactivateBlock);
//
// Link the adapter into the global list.
//
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Acquired global protocol spinlock\n"));
//
// Now ppNextAdapter points to the new adapter's would-be predecessor's
// Next pointer; chain the new adapter to follow this predecessor:
//
LinkDoubleAtHead(pProtocolContext->AdapterList, pAdapter, NextAdapter, PrevAdapter);
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Released global protocol spinlock\n"));
//
// Allocate send packet and buffer pools
//
NdisAllocatePacketPoolEx(&Status,
&pAdapter->SendPacketPool,
MIN_PACKETS_POOL,
MAX_PACKETS_POOL-MIN_PACKETS_POOL,
sizeof(PKT_RSVD));
if (Status == NDIS_STATUS_SUCCESS)
{
NdisAllocateBufferPool(&Status,
&pAdapter->SendBufferPool,
MAX_PACKETS_POOL);
if (Status != NDIS_STATUS_SUCCESS)
{
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: "
"Failed to allocate send buffer bool, freeing packet pool, status == 0x%x\n", Status));
NdisFreePacketPool(pAdapter->SendPacketPool);
}
} else {
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Failed to allocate send packet pool, status == 0x%x\n", Status));
}
if (Status == NDIS_STATUS_SUCCESS)
{
//
// Allocate receive packet and buffer pools
//
NdisAllocatePacketPoolEx(&Status,
&pAdapter->RecvPacketPool,
MIN_PACKETS_POOL,
MAX_PACKETS_POOL-MIN_PACKETS_POOL,
sizeof(PKT_RSVD));
if (Status == NDIS_STATUS_SUCCESS)
{
NdisAllocateBufferPool(&Status,
&pAdapter->RecvBufferPool,
MAX_PACKETS_POOL);
if (Status != NDIS_STATUS_SUCCESS)
{
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Failed to allocate receive buffer pool, freeing other pools, status == 0x%x\n", Status));
NdisFreePacketPool(pAdapter->SendPacketPool);
NdisFreeBufferPool(pAdapter->SendBufferPool);
NdisFreePacketPool(pAdapter->RecvPacketPool);
}
} else {
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Failed to allocate receive packet pool, freeing send pools, status == 0x%x\n", Status));
NdisFreePacketPool(pAdapter->SendPacketPool);
NdisFreeBufferPool(pAdapter->SendBufferPool);
}
}
if (Status == NDIS_STATUS_SUCCESS) {
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: About to open Adapter %ws\n", DeviceName));
NdisOpenAdapter(&Status,
&OpenError,
&pAdapter->NdisBindingHandle,
&SelectedIndex,
Media,
2,
pProtocolContext->RCAClProtocolHandle,
(NDIS_HANDLE)pAdapter,
DeviceName,
0,
NULL);
if (Status == NDIS_STATUS_PENDING) {
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: NdisOpenAdapter returned NDIS_STATUS_PENDING, "
"about to block\n"));
RCABlock(&pAdapter->Block, &Status);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Unblocked waiting for NdisOpenAdapter to complete\n"));
}
if (Status != NDIS_STATUS_SUCCESS) {
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Failed to open adapter - Status == 0x%x\n", Status));
NdisFreePacketPool(pAdapter->SendPacketPool);
NdisFreeBufferPool(pAdapter->SendBufferPool);
NdisFreePacketPool(pAdapter->RecvPacketPool);
NdisFreeBufferPool(pAdapter->RecvBufferPool);
}
}
} while (FALSE);
if (Status != NDIS_STATUS_SUCCESS) {
//
// We had some sort of error. Clean up and free up.
//
RCADEBUGP(RCA_ERROR, ("RCABindAdapter: Bad status - 0x%x\n", Status));
if (pAdapter != (PRCA_ADAPTER)NULL)
{
RCAInitBlockStruc(&pAdapter->Block);
if (pAdapter->NdisBindingHandle != (NDIS_HANDLE)NULL)
{
NdisCloseAdapter(&Status, pAdapter->NdisBindingHandle);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Acquired global protocol spinlock\n"));
pProtocolContext->BindingInfo.AdapterCnt--;
RCADEBUGP(RCA_INFO, ("RCABindAdapter: Decremented adapter count, current value == %d\n", pProtocolContext->BindingInfo.AdapterCnt));
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Released global protocol spinlock\n"));
}
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Acquired global protocol spinlock\n"));
UnlinkDouble(pAdapter, NextAdapter, PrevAdapter);
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCABindAdapter: Released global protocol spinlock\n"));
NdisFreeSpinLock(&pAdapter->Lock);
RCAFreeMem(pAdapter);
pAdapter = NULL;
}
Status = NDIS_STATUS_FAILURE;
}
*pStatus = Status;
}
VOID
RCAOpenAdaperComplete(
IN NDIS_HANDLE BindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
)
/*++
Routine Description
Our OpenAdapter completion handler. We signal whoever opened the
adapter.
Arguments
BindingContext - A pointer to a RCA_ADAPTER structure.
Status - Status of open attempt.
OpenErrorStatus - Additional status information.
Return Value:
None
--*/
{
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_INFO, ("RCAOpenAdapterComplete: Enter\n"));
pAdapter = (PRCA_ADAPTER)BindingContext;
RCAStructAssert(pAdapter, rca);
RCASignal(&pAdapter->Block, Status);
RCADEBUGP(RCA_INFO, ("RCAOpenAdapterComplete: Exit\n"));
}
VOID
RCADeactivateAdapterWorker(
IN PNDIS_WORK_ITEM pWorkItem,
IN PVOID Context
)
/*++
Routine Description:
This routine is called by a worker thread when a work item is scheduled to deactivate
an adapter.
Arguments:
pWorkItem - Pointer to the work item structure used to schedule this work item
Context - Actually a pointer to the RCA_ADAPTER structure for the adapter that
will be deactivated.
Return Value:
(None)
--*/
{
PRCA_ADAPTER pAdapter = (PRCA_ADAPTER) Context;
RCADEBUGP(RCA_INFO, ("RCADeactivateAdapterWorker: Enter - Context == 0x%x\n", Context));
//
// Wait for all AF registrations to complete. There is a window of opportunity for us
// to be here even though we may not be done in RCANotifyAfRegistration() i.e. between
// the call to NdisClOpenAddressFamily() and the end of the function.
//
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
while (pAdapter->AfRegisteringCount != 0) {
NDIS_STATUS DummyStatus;
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCABlock(&pAdapter->AfRegisterBlock, &DummyStatus);
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
}
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCADeactivateAdapter(pAdapter);
RCASignal(&pAdapter->DeactivateBlock, NDIS_STATUS_SUCCESS);
RCA_CLEAR_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_DEACTIVATE_IN_PROGRESS);
RCADEBUGP(RCA_INFO, ("RCADeactivateAdapterWorker: Exit"));
}
VOID
RCADeactivateAdapter(
IN PRCA_ADAPTER pAdapter
)
/*++
Routine Description:
Free all VCs on this adapter.
Arguments:
pAdapter - points to the Adapter the VCs are listed off
Calling Seqence
Called from RCACmUnbindAdapter to ensure we're all clear
before deallocating an adapter structure
Return Value:
None
--*/
{
PRCA_VC pVc, pNextVc;
NDIS_STATUS Status;
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
RCADEBUGP(RCA_INFO, ("RCADeactivateAdapter: Enter - pAdapter 0x%x\n", pAdapter));
//
// Deregister Sap handle so we get no more incoming calls.
//
if (pAdapter->NdisSapHandle != NULL)
{
RCAInitBlockStruc(&pAdapter->Block);
Status = NdisClDeregisterSap(pAdapter->NdisSapHandle);
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_DEREG_SAP);
if (NDIS_STATUS_PENDING == Status)
{
RCABlock(&pAdapter->Block, &Status);
}
pAdapter->NdisSapHandle = NULL;
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_DEREG_SAP_COMPLETE);
}
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
if (pAdapter->VcList) {
pAdapter->BlockedOnClose = TRUE;
RCAInitBlockStruc(&pAdapter->CloseBlock);
}
for (pVc = pAdapter->VcList; pVc != NULL; pVc = pNextVc)
{
pNextVc = pVc->NextVcOnAdapter;
if (pVc->Flags & VC_ACTIVE)
{
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCACoNdisCloseCallOnVcNoWait((PVOID)pVc);
//
// Call the VC Close callback if necessary.
//
ACQUIRE_SPIN_LOCK(&pVc->SpinLock);
if ((pVc->ClientReceiveContext || pVc->ClientSendContext) &&
(pProtocolContext->Handlers.VcCloseCallback)) {
//
// Release the spin lock here because this callback will very likely
// call RCACoNdisReleaseXXxVcContext() etc which will want the lock.
//
// There is a teensy tiny race here - if someone releases the VC context
// between when we release the lock and when we call the callback, we
// could be in trouble.
//
RELEASE_SPIN_LOCK(&pVc->SpinLock);
pProtocolContext->Handlers.VcCloseCallback((PVOID)pVc,
pVc->ClientReceiveContext,
pVc->ClientSendContext);
} else {
RELEASE_SPIN_LOCK(&pVc->SpinLock);
}
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
}
}
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
//
// Deregister Af handle
//
if (pAdapter->NdisAfHandle)
{
RCAInitBlockStruc(&pAdapter->Block);
Status = NdisClCloseAddressFamily(pAdapter->NdisAfHandle);
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_CLOSE_AF);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
pAdapter->NdisAfHandle = NULL;
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_CLOSE_AF_COMPLETE);
}
//
// Block waiting for the actual VCs to be deleted, if any.
//
if (pAdapter->BlockedOnClose) {
RCABlock(&pAdapter->CloseBlock, &Status);
pAdapter->BlockedOnClose = FALSE;
}
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_DEACTIVATE_COMPLETE);
RCADEBUGP(RCA_LOUD, ("RCADeactivateAdapter: Exit\n"));
}
VOID
RCAUnbindAdapter(
OUT PNDIS_STATUS pStatus,
IN NDIS_HANDLE ProtocolBindContext,
IN PNDIS_HANDLE UnbindContext
)
/*++
Routine Description:
Our entry point called by NDIS when we need to destroy an existing
adapter binding.
Close and clean up the adapter.
Arguments:
pStatus - where we return the status of this call
ProtocolBindContext - actually a pointer to the Adapter structure
UnbindContext - we should pass this value in NdisCompleteUnbindAdapter
Return Value:
None; *pStatus contains the result code.
--*/
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
PRCA_ADAPTER *ppNextAdapter;
PRCA_ADAPTER pAdapter;
NDIS_STATUS Status;
pAdapter = (PRCA_ADAPTER)ProtocolBindContext;
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Enter - pAdapter 0x%x, UnbindContext 0x%x\n",
pAdapter, UnbindContext));
//
// Deactivate Adapter - This may already be in progress by a worker thread in response
// to an OID_CO_AF_CLOSE.
//
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
pAdapter->AdapterFlags |= RCA_ADAPTERFLAGS_UNBIND_IN_PROGRESS;
while (pAdapter->AfRegisteringCount != 0) {
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCABlock(&pAdapter->AfRegisterBlock, &Status);
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
}
if (pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_DEACTIVATE_IN_PROGRESS) {
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
//
// RCADeactivateAdapter() will be called by the worker thread,
// just wait for it to complete.
//
RCABlock(&pAdapter->DeactivateBlock, &Status);
} else if (pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_DEACTIVATE_COMPLETE) {
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
//
// Already deactivated, nothing to do.
//
} else {
pAdapter->AdapterFlags |= RCA_ADAPTERFLAGS_DEACTIVATE_IN_PROGRESS;
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
//
// Close Sap, Close Vcs and Close Af
//
RCADeactivateAdapter(pAdapter);
RCASignal(&pAdapter->DeactivateBlock, NDIS_STATUS_SUCCESS);
RCA_CLEAR_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_DEACTIVATE_IN_PROGRESS);
}
RCAInitBlockStruc (&pAdapter->Block);
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Calling NdisCloseAdapter\n"));
NdisCloseAdapter(&Status, pAdapter->NdisBindingHandle);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Acquired global protocol context lock\n"));
pProtocolContext->BindingInfo.AdapterCnt--;
RCADEBUGP(RCA_INFO, ("RCAUnbindAdapter: Decremented adapter count, current value == %d\n", pProtocolContext->BindingInfo.AdapterCnt));
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Released global protocol context lock\n"));
if (pAdapter->VcList != NULL) {
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: VcList not null, pAdapter is 0x%x\n", pAdapter));
DbgBreakPoint();
}
// Delist and free the adapters from our Global info
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Acquired global protocol context lock\n"));
UnlinkDouble(pAdapter, NextAdapter, PrevAdapter);
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAUnbindAdapter: Released global protocol context lock\n"));
if (pAdapter->SendPacketPool != NULL)
{
NdisFreePacketPool(pAdapter->SendPacketPool);
}
if (pAdapter->SendBufferPool != NULL)
{
NdisFreeBufferPool(pAdapter->SendBufferPool);
}
if (pAdapter->RecvPacketPool != NULL)
{
NdisFreePacketPool(pAdapter->RecvPacketPool);
}
if (pAdapter->RecvBufferPool != NULL)
{
NdisFreeBufferPool(pAdapter->RecvBufferPool);
}
RCA_SET_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_UNBIND_COMPLETE);
RCA_CLEAR_ADAPTER_FLAG_LOCKED(pAdapter, RCA_ADAPTERFLAGS_UNBIND_IN_PROGRESS);
RCAFreeMem(pAdapter);
RCADEBUGP(RCA_INFO, ("RCADeAllocateAdapter: exit\n"));
*pStatus = NDIS_STATUS_SUCCESS;
}
VOID
RCAOpenAdapterComplete(
IN NDIS_HANDLE BindingContext,
IN NDIS_STATUS Status,
IN NDIS_STATUS OpenErrorStatus
)
/*++
Routine Description
Our OpenAdapter completion handler. We signal whoever opened the
adapter.
Arguments
BindingContext - A pointer to a RCA_ADAPTER structure.
Status - Status of open attempt.
OpenErrorStatus - Additional status information.
Return Value:
None
--*/
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
PRCA_ADAPTER pAdapter;
pAdapter = (PRCA_ADAPTER)BindingContext;
RCAStructAssert(pAdapter, rca);
if (Status == NDIS_STATUS_SUCCESS) {
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAOpenAdapterComplete: Acquired global protocol context lock\n"));
pProtocolContext->BindingInfo.AdapterCnt++;
RCADEBUGP(RCA_INFO, ("RCAOpenAdapterComplete: Incremented adapter count, current value == %d\n", pProtocolContext->BindingInfo.AdapterCnt));
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCAOpenAdapterComplete: Released global protocol context lock\n"));
}
RCASignal(&pAdapter->Block, Status);
}
VOID
RCACloseAdapterComplete(
IN NDIS_HANDLE BindingContext,
IN NDIS_STATUS Status
)
/*++
Routine Description
Our CloseAdapter completion handler. We signal whoever closed the
adapter.
Arguments
BindingContext - A pointer to a RCA_ADAPTER structure.
Status - Status of close attempt.
Return Value:
None
--*/
{
PRCA_ADAPTER pAdapter;
pAdapter = (PRCA_ADAPTER)BindingContext;
RCAStructAssert(pAdapter, rca);
RCAAssert(Status == NDIS_STATUS_SUCCESS);
RCASignal(&pAdapter->Block, Status);
}
VOID
RCANotifyAfRegistration(
IN NDIS_HANDLE BindingContext,
IN PCO_ADDRESS_FAMILY pFamily
)
/*++
Routine Description:
We get called here each time a call manager registers an address family.
This is where we open the address family if it's the Proxy.
Arguments:
RCABindingContext - our pointer to an adapter
pFamily - The AF that's been registered
Return Value:
None
--*/
{
PRCA_PROTOCOL_CONTEXT pProtocolContext = &GlobalContext;
NDIS_CLIENT_CHARACTERISTICS RCAClientCharacteristics;
PRCA_ADAPTER pAdapter;
PCO_SAP Sap;
NDIS_STATUS Status;
UCHAR SapBuf[sizeof(CO_SAP) + sizeof(RCA_SAP_STRING)];
#if DBG
KIRQL EntryIrql;
#endif
RCA_GET_ENTRY_IRQL(EntryIrql);
RCADEBUGP(RCA_LOUD,("RCANotifyAfRegistration: Enter - Adapter 0x%x, AF 0x%x\n",
BindingContext, pFamily->AddressFamily));
pAdapter = (PRCA_ADAPTER)BindingContext;
if ((pFamily->AddressFamily != CO_ADDRESS_FAMILY_TAPI) ||
(pAdapter->NdisAfHandle != NULL))
{
//
// Not Proxy or already bound -- do nothing
//
return;
}
RCADEBUGP(RCA_LOUD, ("RCANotifyAfRegistration: Opening Proxy AF\n"));
//
// Check that the adapter is not being unbound.
//
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
if ((pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_UNBIND_IN_PROGRESS) ||
(pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_UNBIND_COMPLETE) ||
(pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_DEACTIVATE_IN_PROGRESS) ||
(pAdapter->AdapterFlags & RCA_ADAPTERFLAGS_DEACTIVATE_COMPLETE)) {
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCADEBUGP(RCA_INFO, ("RCANotifyAfRegistration: Adapter is being unbound - bailing\n"));
return;
}
if (pAdapter->AfRegisteringCount == 0) {
RCAInitBlockStruc(&pAdapter->AfRegisterBlock);
}
pAdapter->AfRegisteringCount++;
pAdapter->OldAdapterFlags = pAdapter->AdapterFlags;
pAdapter->AdapterFlags = 0;
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
do
{
//
// Do the client open on the address family
//
NdisZeroMemory (&RCAClientCharacteristics, sizeof(NDIS_CLIENT_CHARACTERISTICS));
RCAClientCharacteristics.MajorVersion = NDIS_MAJOR_VERSION;
RCAClientCharacteristics.MinorVersion = NDIS_MINOR_VERSION;
RCAClientCharacteristics.Reserved = 0;
RCAClientCharacteristics.ClCreateVcHandler = RCACreateVc;
RCAClientCharacteristics.ClDeleteVcHandler = RCADeleteVc;
RCAClientCharacteristics.ClRequestHandler = RCARequest;
RCAClientCharacteristics.ClRequestCompleteHandler = RCACoRequestComplete;
RCAClientCharacteristics.ClOpenAfCompleteHandler = RCAOpenAfComplete;
RCAClientCharacteristics.ClCloseAfCompleteHandler = RCACloseAfComplete;
RCAClientCharacteristics.ClRegisterSapCompleteHandler = RCARegisterSapComplete;
RCAClientCharacteristics.ClDeregisterSapCompleteHandler = RCADeregisterSapComplete;
RCAClientCharacteristics.ClCloseCallCompleteHandler = RCACloseCallComplete;
RCAClientCharacteristics.ClIncomingCallHandler = RCAIncomingCall;
RCAClientCharacteristics.ClIncomingCallQoSChangeHandler = RCAIncomingCallQosChange;
RCAClientCharacteristics.ClIncomingCloseCallHandler = RCAIncomingCloseCall;
RCAClientCharacteristics.ClCallConnectedHandler = RCACallConnected;
RCADEBUGP(RCA_INFO,(" NotifyAfRegistration -- NdisClOpenAddressFamily\n"));
RCAInitBlockStruc(&pAdapter->Block);
Status = NdisClOpenAddressFamily(pAdapter->NdisBindingHandle,
pFamily,
(NDIS_HANDLE)pAdapter,
&RCAClientCharacteristics,
sizeof(NDIS_CLIENT_CHARACTERISTICS),
&pAdapter->NdisAfHandle);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
if (Status != NDIS_STATUS_SUCCESS)
{
//
// Open AF failure.
//
RCADEBUGP(RCA_ERROR, ("RCANotifyAfRegistration -- open AF failure, status == 0x%x\n", Status));
break;
}
InterlockedIncrement(&pAdapter->AfOpenCount);
RCADEBUGP(RCA_LOUD, ("RCANotifyAfRegistration -- calling RCARegisterSap\n"));
RCAInitBlockStruc(&pAdapter->Block);
Sap = (PCO_SAP)SapBuf;
// Sap->SapType = SAP_TYPE_NSAP;
Sap->SapLength = sizeof(SapBuf);
RtlCopyMemory(&Sap->Sap, RCA_SAP_STRING, sizeof(RCA_SAP_STRING));
Status = NdisClRegisterSap(pAdapter->NdisAfHandle,
pAdapter,
Sap,
&pAdapter->NdisSapHandle);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
if (Status != NDIS_STATUS_SUCCESS)
{
//
// So we opned the AF, but the CM didn't let us register our SAP.
//
RCADEBUGP(RCA_ERROR, ("RCANotifyAfRegistration - "
"RCARegisterSap on NdisAfHandle 0x%x and pAdapter 0x%x "
"failed with status 0x%x\n",
pAdapter->NdisAfHandle, pAdapter, Status));
//
// Close AF
//
RCAInitBlockStruc(&pAdapter->Block);
Status = NdisClCloseAddressFamily(pAdapter->NdisAfHandle);
if (Status == NDIS_STATUS_PENDING)
{
RCABlock(&pAdapter->Block, &Status);
}
break;
}
ACQUIRE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCANotifyAfRegistration: Acquired global protocol context lock\n"));
pProtocolContext->BindingInfo.SAPCnt++;
RCADEBUGP(RCA_INFO, ("RCANotifyAfRegistration: "
"Incremented SAP count, current value == %d\n", pProtocolContext->BindingInfo.SAPCnt));
if (pProtocolContext->BindingInfo.BindingsComplete &&
(pProtocolContext->BindingInfo.SAPCnt == pProtocolContext->BindingInfo.AdapterCnt)) {
RCADEBUGP(RCA_INFO, ("RCANotifyAfRegistration: Unblocking RCACoNdisInitialize(), counts == %d\n",
pProtocolContext->BindingInfo.AdapterCnt));
RCASignal(&pProtocolContext->BindingInfo.Block, Status);
} else {
RCADEBUGP(RCA_INFO, ("RCANotifyAfRegistration: Not unblocking RCACoNdisInitialize() - SAPCnt == %d, AdapterCnt == %d\n",
pProtocolContext->BindingInfo.SAPCnt,
pProtocolContext->BindingInfo.AdapterCnt));
}
RELEASE_SPIN_LOCK(&pProtocolContext->SpinLock);
RCADEBUGP(RCA_LOUD, ("RCANotifyAfRegistration: Released global protocol context lock\n"));
} while (FALSE);
ACQUIRE_SPIN_LOCK(&pAdapter->SpinLock);
pAdapter->AfRegisteringCount--;
if (pAdapter->AfRegisteringCount == 0) {
RCASignal(&pAdapter->AfRegisterBlock, NDIS_STATUS_SUCCESS);
}
RELEASE_SPIN_LOCK(&pAdapter->SpinLock);
RCA_CHECK_EXIT_IRQL(EntryIrql);
RCADEBUGP(RCA_INFO, ("RCANotifyAfRegistration: Exit\n"));
}
VOID
RCAOpenAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE NdisAfHandle
)
{
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_INFO,("RCAOpenAfComplete: Enter - Status = 0X%x, AfHandle = 0X%x\n",
Status, NdisAfHandle));
pAdapter = (PRCA_ADAPTER)ProtocolAfContext;
RCAStructAssert(pAdapter, rca);
if (NDIS_STATUS_SUCCESS == Status)
{
pAdapter->NdisAfHandle = NdisAfHandle;
}
RCASignal(&pAdapter->Block, Status);
RCADEBUGP(RCA_INFO, ("RCAOpenAfComplete: Exit\n"));
}
VOID
RCACloseAfComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolAfContext
)
{
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_INFO, ("RCACloseAfComplete: Enter\n"));
pAdapter = (PRCA_ADAPTER)ProtocolAfContext;
pAdapter->NdisAfHandle = NULL;
RCASignal(&pAdapter->Block, Status);
RCADEBUGP(RCA_INFO, ("RCACloseAfComplete: Exit\n"));
}
VOID
RCARegisterSapComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolSapContext,
IN PCO_SAP pSap,
IN NDIS_HANDLE NdisSapHandle
)
/*++
Routine Description:
This routine is called to indicate completion of a call to
NdisClRegisterSap. If the call was successful, save the
allocated NdisSapHandle in our SAP structure.
Arguments:
Status - Status of Register SAP
ProtocolSapContext - Pointer to our SAP structure
pSap - SAP information we'd passed in the call
NdisSapHandle - SAP Handle
Return Value:
None
--*/
{
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_INFO, ("RCARegisterSapComplete: Enter\n"));
pAdapter = (PRCA_ADAPTER)ProtocolSapContext;
if (Status == NDIS_STATUS_SUCCESS)
{
pAdapter->NdisSapHandle = NdisSapHandle;
}
RCASignal(&pAdapter->Block, Status);
RCADEBUGP(RCA_INFO, ("RCARegisterSapComplete: Exit\n"));
}
VOID
RCADeregisterSapComplete(
IN NDIS_STATUS Status,
IN NDIS_HANDLE ProtocolSapContext
)
{
PRCA_ADAPTER pAdapter;
RCADEBUGP(RCA_LOUD,("RCADeregisterSapComplete: Enter\n"));
pAdapter = (PRCA_ADAPTER)ProtocolSapContext;
pAdapter->NdisSapHandle = NULL;
RCASignal(&pAdapter->Block, Status);
RCADEBUGP(RCA_LOUD,("RCADeregisterSapComplete: Exit\n"));
}
//
// Dummy NDIS functions
//
VOID
RCATransferDataComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status,
IN UINT BytesTransferred)
{
RCAAssert(FALSE);
}
VOID
RCAResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
)
{
RCAAssert(FALSE);
}
VOID
RCARequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
{
}
NDIS_STATUS
RCAReceive(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE MacReceiveContext,
IN PVOID HeaderBuffer,
IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer,
IN UINT LookAheadBufferSize,
IN UINT PacketSize
)
{
RCAAssert(FALSE);
return(NDIS_STATUS_FAILURE);
}
INT
RCAReceivePacket(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet
)
{
RCAAssert(FALSE);
return(0);
}
VOID
RCAStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize)
{
}
VOID
RCAStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
}
VOID
RCACoStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize)
{
RCADEBUGP(RCA_INFO, (" RCACoStatus: Bind Ctx 0x%x, Status 0x%x\n",
ProtocolBindingContext, GeneralStatus));
}
VOID
RCASendComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_PACKET Packet,
IN NDIS_STATUS Status
)
{
RCAAssert(TRUE);
}
VOID
RCAModifyCallQosComplete(
IN NDIS_STATUS status,
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS CallParameters
)
{
RCAAssert(TRUE);
}
VOID
RCAAddPartyComplete(
IN NDIS_STATUS status,
IN NDIS_HANDLE ProtocolPartyContext,
IN NDIS_HANDLE NdisPartyHandle,
IN PCO_CALL_PARAMETERS CallParameters
)
{
RCAAssert(FALSE);
}
VOID
RCADropPartyComplete(
IN NDIS_STATUS status,
IN NDIS_HANDLE ProtocolPartyContext
)
{
RCAAssert(FALSE);
}
VOID
RCAIncomingCallQosChange(
IN NDIS_HANDLE ProtocolVcContext,
IN PCO_CALL_PARAMETERS CallParameters
)
{
RCAAssert(TRUE);
}
VOID
RCAIncomingDropParty(
IN NDIS_STATUS DropStatus,
IN NDIS_HANDLE ProtocolPartyContext,
IN PVOID CloseData OPTIONAL,
IN UINT Size OPTIONAL)
{
RCAAssert(TRUE);
}
VOID
RCACoRequestComplete(
IN NDIS_STATUS NdisStatus,
IN NDIS_HANDLE ProtocolAfContext,
IN NDIS_HANDLE ProtocolVcContext OPTIONAL,
IN NDIS_HANDLE ProtocolPartyContext OPTIONAL,
IN OUT PNDIS_REQUEST NdisRequest
)
{
RCADEBUGP(RCA_INFO, ("RCACoRequestComplete: Enter\n"));
RCADEBUGP(RCA_INFO, ("RCACoRequestComplete: Exit\n"));
}