1511 lines
53 KiB
C
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"));
|
|
}
|
|
|
|
|
|
|
|
|