📄 support.c
字号:
}
//
// If this buffer is not the last one in the queue,
// set pBufferQ->BufListTail->Next to NULL.
//
if (NULL != pBufferQ->BufListTail)
{
//
// This buffer is at the end of queue.
//
pBufferQ->BufListTail->Next = NULL;
}
}
else
{
//
// The receive is at the Beginning of the list.
// Update the BufListHead
//
pBufferQ->BufListHead = ptmpRecvHeader->Next;
pBufferQ->BufListHead->Prev = NULL;
}
ptmpRecvHeader->Next = NULL;
ptmpRecvHeader->Prev = NULL;
pBufferQ->BufferCount--;
BufferIsFound = TRUE;
break;
}
}
if (BufferIsFound == TRUE)
{
*pRecvHeader = ptmpRecvHeader;
}
else
{
*pRecvHeader = NULL;
}
NdisDprReleaseSpinLock(&pBufferQ->lock);
}
VOID
tbAtm155MergeRecvBuffers2FreeBufferQueue(
IN PADAPTER_BLOCK pAdapter,
IN PRECV_BUFFER_QUEUE pFreeBufferQ,
IN PRECV_BUFFER_QUEUE pReturnBufferQ
)
/*++
Routine Description:
This routine will merge pRetrunBufferQ into pFreeBufferQ and
put the buffers back to their pools if the pools are being
freed.
Arguments:
Return Value:
--*/
{
NdisAcquireSpinLock(&pFreeBufferQ->lock);
if (NULL != pReturnBufferQ->BufListHead)
{
if (NULL == pFreeBufferQ->BufListHead)
{
pFreeBufferQ->BufListHead = pReturnBufferQ->BufListHead;
pFreeBufferQ->BufListTail = pReturnBufferQ->BufListTail;
}
else
{
//
// Chain the first buffer in the returned queue with the
// current tail of the free buffer list.
//
pReturnBufferQ->BufListTail->Prev = pFreeBufferQ->BufListTail;
pFreeBufferQ->BufListTail->Next = pReturnBufferQ->BufListHead;
//
// Setup the new tail of the free buffer list.
//
pFreeBufferQ->BufListTail = pReturnBufferQ->BufListTail;
pFreeBufferQ->BufListTail->Next = NULL;
}
//
// Increment the receive information's free buffer count.
// This is the total number of returned headers minus the
// ones that were freed back to their pools.
//
pFreeBufferQ->BufferCount += pReturnBufferQ->BufferCount;
DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
("tbAtm155MergeRecvBuffers2FreeBufferQueue: %lu\n", pFreeBufferQ->BufferCount));
DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
("AllocatedBigRecvBuffers: %lu\n", pAdapter->HardwareInfo->SarInfo->AllocatedBigRecvBuffers));
DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
("AllocatedSmallRecvBuffers: %lu\n", pAdapter->HardwareInfo->SarInfo->AllocatedSmallRecvBuffers));
// initialize the pReturnBufferQ for re-use.
pReturnBufferQ->BufListHead = NULL;
pReturnBufferQ->BufListTail = NULL;
pReturnBufferQ->BufferCount = 0;
}
NdisReleaseSpinLock(&pFreeBufferQ->lock);
}
VOID
tbAtm155HashVc(
IN PADAPTER_BLOCK pAdapter,
IN PVC_BLOCK pVc
)
/*++
Routine Description:
This routine will save the VC pointer in a hash table.
This table is used to find the VC in a quick manner given only
it's VC number.
Arguments:
pAdapter - Adapter block to hash the VC to.
pVc - Pointer to the VC to hash.
Return Value:
None.
--*/
{
ULONG HashIndex;
//
// Get the bucket in the hash table where this VC will be placed.
//
HashIndex = pVc->VpiVci.Vci % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;
//
// Just store this vc at the head.
//
NdisAcquireSpinLock(&pAdapter->VcHashLock);
pVc->NextVcHash = pAdapter->VcHashList[HashIndex];
pAdapter->VcHashList[HashIndex] = pVc;
NdisReleaseSpinLock(&pAdapter->VcHashLock);
}
PVC_BLOCK
tbAtm155UnHashVc(
IN PADAPTER_BLOCK pAdapter,
IN ULONG Vc
)
/*++
Routine Description:
This routine will return the pointer to the VC_BLOCK that is
represented by the VC number.
Arguments:
pAdapter - Pointer to the adapter block that the VC belongs to.
Vc - The number of the VC that we want to retreive.
Return Value:
PVC_BLOCK if successful. NULL if the VC has not been created or
activated on this adapter.
--*/
{
ULONG HashIndex;
PVC_BLOCK pVc;
//
// Get the hash bucket that the VC is in.
//
HashIndex = Vc % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;
NdisAcquireSpinLock(&pAdapter->VcHashLock);
pVc = pAdapter->VcHashList[HashIndex];
while ((pVc != NULL) && (pVc->VpiVci.Vci != Vc))
{
pVc = pVc->NextVcHash;
}
NdisReleaseSpinLock(&pAdapter->VcHashLock);
return(pVc);
}
VOID
tbAtm155RemoveHash(
IN PADAPTER_BLOCK pAdapter,
IN PVC_BLOCK pVc
)
/*++
Routine Description:
This routine will remove VC from the hash table.
Arguments:
pAdapter - Pointer to the ADAPTER_BLOCK.
pVc - Pointer to the VC_BLOCK
Return Value:
None.
--*/
{
ULONG HashIndex;
PVC_BLOCK ptmpVc;
PVC_BLOCK pPrevVc = NULL;
//
// Get the hash table index.
//
HashIndex = pVc->VpiVci.Vci % pAdapter->RegistryParameters[TbAtm155VcHashTableSize].Value;
NdisAcquireSpinLock(&pAdapter->VcHashLock);
//
// Get a temp list pointer to manipulate.
//
ptmpVc = pAdapter->VcHashList[HashIndex];
//
// Walk the list looking for the VC that we need to remove.
//
while ((NULL != ptmpVc) && (pVc != ptmpVc))
{
//
// Save the previous hashed VC_BLOCK.
//
pPrevVc = ptmpVc;
//
// Get a pointer to the next hashed VC_BLOCK.
//
ptmpVc = ptmpVc->NextVcHash;
}
//
// Make sure that the VC was hashed.
// If it wasn't then ignore the call.
//
if (NULL != ptmpVc)
{
//
// Was the VC_BLOCK the head of the hash list?
//
if (NULL == pPrevVc)
{
pAdapter->VcHashList[HashIndex] = ptmpVc->NextVcHash;
}
else
{
pPrevVc->NextVcHash = ptmpVc->NextVcHash;
}
}
NdisReleaseSpinLock(&pAdapter->VcHashLock);
}
VOID
tbAtm155InitializePacketQueue(
IN OUT PPACKET_QUEUE PacketQ
)
/*++
Routine Description:
This routine will initialize a PACKET_QUEUE structure for use.
Arguments:
PacketQ - Pointer to the PACKET_QUEUE to initialize.
Return Value:
None.
--*/
{
PacketQ->Head = NULL;
PacketQ->Tail = NULL;
NdisAllocateSpinLock(&PacketQ->lock);
}
VOID
tbAtm155FreePacketQueue(
IN OUT PPACKET_QUEUE PacketQ
)
/*++
Routine Description:
This routine will free a PACKET_QUEUE structure from use.
Arguments:
PacketQ - Pointer to the PACKET_QUEUE to free.
Return Value:
None.
--*/
{
ASSERT(NULL == PacketQ->Head);
NdisFreeSpinLock(&PacketQ->lock);
}
VOID
tbAtm155InitializeReceiveBufferQueue(
IN OUT PRECV_BUFFER_QUEUE RecvBufferQ
)
/*++
Routine Description:
This routine will initialize a RECV_BUFFER_QUEUE structure for use.
Arguments:
RecvBufferQ - Pointer to the RECV_BUFFER_QUEUE to initialize.
Return Value:
None.
--*/
{
RecvBufferQ->BufListHead = NULL;
RecvBufferQ->BufListTail = NULL;
RecvBufferQ->BufferCount = 0;
NdisAllocateSpinLock(&RecvBufferQ->lock);
}
VOID
tbAtm155FreeReceiveBufferQueue(
IN PADAPTER_BLOCK pAdapter,
IN OUT PRECV_BUFFER_QUEUE RecvBufferQ
)
/*++
Routine Description:
This routine will free a RECV_BUFFER_QUEUE structure for use.
Arguments:
RecvBufferQ - Pointer to the RECV_BUFFER_QUEUE to free.
Return Value:
None.
--*/
{
PRECV_BUFFER_HEADER *ppRecvHeaderHead;
for (ppRecvHeaderHead = &RecvBufferQ->BufListHead;
NULL != *ppRecvHeaderHead; )
{
//
// Free the buffer pool when all of the buffers has been freed
// into the pool.
//
tbAtm155FreeReceiveBuffer(ppRecvHeaderHead, pAdapter, *ppRecvHeaderHead);
RecvBufferQ->BufferCount--;
}
ASSERT(0 == RecvBufferQ->BufferCount);
if (NULL == RecvBufferQ->BufListHead)
{
// Reset the Pointer
RecvBufferQ->BufListTail = NULL;
}
ASSERT(NULL == RecvBufferQ->BufListHead);
ASSERT(NULL == RecvBufferQ->BufListTail);
ASSERT(0 == RecvBufferQ->BufferCount);
NdisFreeSpinLock(&RecvBufferQ->lock);
}
ULONG Exp_Tbl[24] = {
1L, 2L, 4L, 8L, // exp 0
16L, 32L, 64L, 128L, // exp 4
256L, 512L, 1024L, 2048L, // exp 8
4096L, 8192L, 16386L, 32678L, // exp 12
65536L, 131072L, 262144L, 524288L, // exp 16
1048576L, 2097152L, 4194394L, 8288608L // exp 20
};
void
tbAtm155ConvertToFP(
IN OUT PULONG pRate,
OUT PUSHORT pRateInFP
)
/*++
Routine Description:
This routine will convert from rate, PCR, into a binary floating
point representation. The Equate is
Rate = [2^e (1 + m/512)] * nz
reserved bit -> Bit 15
nz -> Bit 14
0 the rate is zero
1 the rate is as given by the fields e and m.
e -> Bit 13 through 9
range from 0 to 31. The exponent is a 5 bit unsigned
m -> Bit 9 through 0
The mantissa is a 5 bit unsigned
Arguments:
Rate - The rate needs to be converted.
pRateInFP - point to the variable to write
Return Value:
None.
--*/
{
ULONG i_rate = *pRate;
ULONG temp;
TBATM155_RATE_IN_FP rate_FP;
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
do {
//
// Just initialize
//
rate_FP.reg = 0; // default nz to be 0.
rate_FP.nz = 1; // default nz to be 1.
if (i_rate == 0)
{
//
// Detected input rate is 0, set nz and return ot caller.
//
rate_FP.nz = 0;
break;
}
for (temp = 0; temp < 24; temp++)
{
if (i_rate <= Exp_Tbl[temp])
{
if (i_rate != Exp_Tbl[temp])
{
//
// i_rate cannot be less than 1 and not equal to 0
//
ASSERT(temp > 0);
temp--;
}
rate_FP.exp = (USHORT)temp;
temp = Exp_Tbl[temp];
Status = NDIS_STATUS_SUCCESS;
break;
}
}
if (Status == NDIS_STATUS_FAILURE)
{
//
// If there are trouble, give the lowest rate of transfer
//
i_rate = Exp_Tbl[3];
temp = i_rate;
*pRate = i_rate;
}
rate_FP.mant = (USHORT)(((i_rate - temp) * 512) / temp);
} while (FALSE);
*pRateInFP = rate_FP.reg;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -