📄 vc.c
字号:
/*++
Copyright (c) 2000 Microsoft Corporation. All rights reserved.
File: vc.c
Developed for Toshiba by Elisa Research Inc., CA
http://www.elisaresearch.com
(510) 770-4920
Abstract:
This module contains the routines that allow for the creation, deletion,
activation and deactivation of virtual circuits.
Author:
A. Wang
Environment:
Kernel mode
Revision History:
09/23/96 kyleb Cleanup.
Added support for NdisAllocateMemoryWithTag
Fixed/cleanup transmit segment allocation code.
Insert the VC_BLOCK in the hash table before
the receiver is activated for the VC.
10/01/96 kyleb Added async VC completion and async receive
buffer allocation.
01/07/97 awang Initial of Toshiba ATM 155 Device Driver.
02/16/99 hhan Use synchronize mode to allocate xmit buffer.
03/04/99 hhan Added support for MAX_AAL5_
--*/
#include "precomp.h"
#pragma hdrstop
#define MODULE_NUMBER MODULE_VC
NDIS_STATUS
TbAtm155CreateVc(
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE NdisVcHandle,
OUT PNDIS_HANDLE MiniportVcContext
)
/*++
Routine Description:
This is the NDIS 4.1 handler to create a VC. This will allocate necessary
system resources for the VC.
Arguments:
MiniportAdapterContext - Pointer to our ADAPTER_BLOCK.
NdisVcHandle - Handle that NDIS uses to identify the VC that
is about to be created.
MiniportVcContext - Storage to hold context information about
the newly created VC.
Return Value:
NDIS_STATUS_SUCCESS if we successfully create the new VC.
NDIS_STATUS_RESOURCES if we are unable to allocate system memory for
driver use.
--*/
{
PADAPTER_BLOCK pAdapter = (PADAPTER_BLOCK)MiniportAdapterContext;
PVC_BLOCK pVc;
NDIS_STATUS Status;
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("==>TbAtm155CreateVc\n"));
//
// I'm paranoid.
//
*MiniportVcContext = NULL;
//
// Allocate memory for the VC.
//
ALLOCATE_MEMORY(&Status, &pVc, sizeof(VC_BLOCK), '90DA');
if (NDIS_STATUS_SUCCESS != Status)
{
return(NDIS_STATUS_RESOURCES);
}
//
// Initialize memory.
//
ZERO_MEMORY(pVc, sizeof(VC_BLOCK));
//
// Attempt to allocate storage for the debug logs.
//
dbgInitializeDebugInformation(&pVc->DebugInfo);
//
// Save a pointer to the adapter block with the vc.
//
pVc->Adapter = pAdapter;
pVc->HwInfo = pAdapter->HardwareInfo;
pVc->NdisVcHandle = NdisVcHandle;
pVc->Sar = pAdapter->HardwareInfo->SarInfo;
pVc->XmitDmaQ = &pAdapter->HardwareInfo->SarInfo->XmitDmaQ;
pVc->RecvDmaQ = &pAdapter->HardwareInfo->SarInfo->RecvDmaQ;
pVc->References = 1;
NdisAllocateSpinLock(&pVc->lock);
NdisAcquireSpinLock(&pAdapter->lock);
//
// Add the VC to the adapter's inactive list.
//
InsertHeadList(&pAdapter->InactiveVcList, &pVc->Link);
//
// This adapter has another reference...
//
tbAtm155ReferenceAdapter(pAdapter);
NdisReleaseSpinLock(&pAdapter->lock);
//
// Return the pointer to the new VC as the context.
//
*MiniportVcContext = (PNDIS_HANDLE)pVc;
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("<==TbAtm155CreateVc (Status: 0x%lx)\n", Status));
return(Status);
}
NDIS_STATUS
TbAtm155DeleteVc(
IN NDIS_HANDLE MiniportVcContext
)
/*++
Routine Description:
This is the NDIS 4.1 handler to delete a given VC. This routine will
free any resources that are associated with the VC. For the VC to
be deleted it MUST be deactivated first.
Arguments:
MiniportVcContext - Pointer to the VC_BLOCK describing the VC that
is to be deleted.
Return Value:
NDIS_STATUS_SUCCESS if the VC is successfully deleted.
--*/
{
PVC_BLOCK pVc = (PVC_BLOCK)MiniportVcContext;
PADAPTER_BLOCK pAdapter = pVc->Adapter;
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("==>TbAtm155DeleteVc, Vc=(%lx)\n", pVc->VpiVci.Vci));
NdisAcquireSpinLock(&pAdapter->lock);
NdisDprAcquireSpinLock(&pVc->lock);
//
// Verify that this VC is inactive.
//
if (VC_TEST_FLAG(pVc, fVC_ACTIVE) || VC_TEST_FLAG(pVc, fVC_DEACTIVATING))
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("DeleteVc: Vc is either active [%u] or is deactivating [%u]\n",
VC_TEST_FLAG(pVc, fVC_ACTIVE), VC_TEST_FLAG(pVc, fVC_DEACTIVATING)));
// Cannot delete a VC that is still active.
//
NdisDprReleaseSpinLock(&pVc->lock);
NdisReleaseSpinLock(&pAdapter->lock);
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("<==TbAtm155DeleteVc (NDIS_STATUS_FAILURE)\n"));
return(NDIS_STATUS_FAILURE);
}
//
// If a VC is deactive then it had better have only the creation
// reference count on it!
//
ASSERT(1 == pVc->References);
//
// Remove the VC from the inactive list.
//
RemoveEntryList(&pVc->Link);
NdisDprReleaseSpinLock(&pVc->lock);
//
// Dereference the adapter.
//
tbAtm155DereferenceAdapter(pAdapter);
NdisReleaseSpinLock(&pAdapter->lock);
//
// Free any logs that were allocated.
//
dbgFreeDebugInformation(pVc->DebugInfo);
//
// Clean up the resources that were allocated on behalf of the
// VC_BLOCK.
//
NdisFreeSpinLock(&pVc->lock);
#if DBG
if (VC_TEST_FLAG(pVc, fVC_ALLOCATING_TXBUF))
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("FREE_MEMORY: pVc(%lx) of VC(0x%lx) Flags(0x%lx)\n",
pVc, pVc->VpiVci.Vci, pVc->Flags));
DBGBREAK(DBG_COMP_VC, DBG_LEVEL_ERR);
}
#endif // end of DBG
//
// Free the memory that was taken by the vc.
//
FREE_MEMORY(pVc, sizeof(VC_BLOCK));
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("<==TbAtm155DeleteVc (NDIS_STATUS_SUCCESS)\n"));
return(NDIS_STATUS_SUCCESS);
}
ULONG
tbAtm155NextPowerOf2(
ULONG RequestedSize
)
/*++
Routine Description:
If the RequestedSize is not a power of 2 then this routine will find the
next highest...
Arguments:
RequestedSize - Value to find the power of 2 for.
Return Value:
--*/
{
ULONG Value;
if ((RequestedSize > 0) && (RequestedSize <= BLOCK_1K))
{
Value = BLOCK_1K;
}
else if ((RequestedSize > BLOCK_1K) && (RequestedSize <= BLOCK_2K))
{
Value = BLOCK_2K;
}
else if ((RequestedSize > BLOCK_2K) && (RequestedSize <= BLOCK_4K))
{
Value = BLOCK_4K;
}
else if ((RequestedSize > BLOCK_4K) && (RequestedSize <= BLOCK_8K))
{
Value = BLOCK_8K;
}
else if ((RequestedSize > BLOCK_8K) && (RequestedSize <= BLOCK_10K))
{
Value = BLOCK_10K;
}
else
{
Value = BLOCK_16K;
}
return(Value);
}
NDIS_STATUS
tbAtm155WriteEntryOfTheSramTbl(
IN PADAPTER_BLOCK pAdapter,
IN ULONG Dest,
IN PUSHORT pPhData,
IN USHORT LengthOfEntry
)
/*++
Routine Description:
This routine will write data to the entry to the specified table
on on-board SRAM.
Arguments:
pAdapter - Pointer to the adapter to program.
Dest - Point to the entry of the table on SRAM
pPhData - Point to the starting address of data array
to be written onto SRAM.
LengthOfEntry - Number of words to be written to the table.
Return Value:
NDIS_STATUS_SUCCESS if the entry of VC state table is opened
successfully.
--*/
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
//
// DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
// ("==>tbAtm155WriteEntryOfTheSramTbl\n"));
//
//
// DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
// ("Dest=0x%lx, pPhData=0x%lx, LengthOfEntry=%d\n",
// Dest, pPhData, LengthOfEntry));
//
for (
;
(LengthOfEntry > 0) && (NDIS_STATUS_SUCCESS == Status);
LengthOfEntry--, Dest++, pPhData++)
{
TBATM155_PH_WRITE_SRAM(pAdapter, Dest, *pPhData, &Status);
if (NDIS_STATUS_SUCCESS != Status)
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("Failed to open the entry of the Vc state table.\n") );
break;
}
}
//
// DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
// ("<==tbAtm155WriteEntryOfTheSramTbl.\n"));
//
return (Status);
}
NDIS_STATUS
tbAtm155AdjustTrafficParameters(
IN PADAPTER_BLOCK pAdapter,
IN PATM_FLOW_PARAMETERS pFlow,
IN BOOLEAN fRoundFlowUp,
OUT PULONG pPreScaleVal,
OUT PULONG pNumOfEntries
)
/*++
Routine Description:
Arguments:
Return Value:
NDIS_STATUS_SUCCESS if we successfully allocate the bandwidth.
NDIS_STATUS_FAILURE if we are unable to allocate bandwidth for
the flow parameters.
--*/
{
PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
ULONG PreScale_Val;
ULONG NumOfEntriesNeeded;
ULONG ActualPeakCellRate;
BOOLEAN fDone;
ULONG c;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_INFO,
("==>tbAtm155AdjustTrafficParameters\n"));
do
{
#if AW_QOS
//
// The Number of available CBR VCs
// 9/17/97 - Please read the note where declares this
// variable (in SW.H).
//
if (pAdapter->NumOfAvailableCbrVc == 0)
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("There is not enough remaining bandwidth to support even the minimum required bandwidth\n"));
Status = NDIS_STATUS_FAILURE;
break;
}
#endif // end of AW_QOS
//
// Verify the low end of the bandwidth
//
if (pAdapter->RemainingTransmitBandwidth < pAdapter->MinimumCbrBandwidth)
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("There is not enough remaining bandwidth to support even the minimum required bandwidth\n"));
Status = NDIS_STATUS_FAILURE;
break;
}
//
// Make sure we can satisfy the peak cell rate.
//
if (pFlow->PeakCellRate < pAdapter->MinimumCbrBandwidth)
pFlow->PeakCellRate = pAdapter->MinimumCbrBandwidth;
if ((pFlow->PeakCellRate > pAdapter->RemainingTransmitBandwidth) ||
(pFlow->PeakCellRate < pAdapter->MinimumCbrBandwidth))
{
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("PeakCellRate is not within remaining and minimum\n"));
DBGPRINT(DBG_COMP_VC, DBG_LEVEL_ERR,
("PeakCellRate %u, RemainingBW %u\n", pFlow->PeakCellRate, pAdapter->RemainingTransmitBandwidth));
Status = NDIS_STATUS_FAILURE;
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -