📄 adapter.c
字号:
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;
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"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -