📄 receive.c
字号:
RECV_PACKET_RESERVED_FROM_PACKET(Packet)->RecvHeader = pRecvBufHead;
//
// Chain the first buffer to the packet.
//
NdisChainBufferAtBack(Packet, pRecvBufHead->NdisBuffer);
}
if (pEntryOfRxReportQ->RxReportQDWord1.Eop)
{
//
// Need to Adjust the last receive buffer size.
// LongWord size.
//
LastBufferLength = pEntryOfRxReportQ->RxReportQDWord1.Size;
if (LastBufferLength)
{
//
// Convert to Byte length.
//
LastBufferLength <<= 2;
}
else
{
//
// The value 0 is used to represent exactly 16KB
// of valid data.
//
#if DBG
DbgPrint("TBATM155: tbAtm155RxInterruptOnCompletion: pEntry %p, LastBufLen zero\n",
pEntryOfRxReportQ);
#endif // DBG
LastBufferLength = BLOCK_16K;
}
ASSERT (LastBufferLength >= sizeof(AAL5_PDU_TRAILER));
if (pEntryOfRxReportQ->RxReportQDWord1.Sop)
{
//
// If there is only 1 buffer for this packet,
// adjust the length of NdisBuffer.
//
NdisAdjustBufferLength(
pRecvBufHead->NdisBuffer,
LastBufferLength);
}
else
{
//
// If there are more than 1 buffer for this packet,
// adjust the length of FlushBuffer.
//
NdisAdjustBufferLength(
pRecvBufHead->FlushBuffer,
LastBufferLength);
}
}
tbAtm155InsertRecvBufferAtTail(pSegCompleting, pRecvBufHead, FALSE);
//
// Get the descriptor for this packet.
//
Packet = pSegCompleting->BufListHead->Packet;
pSegCompleting->BufListHead->Last = pRecvBufHead;
if (pEntryOfRxReportQ->RxReportQDWord1.Sop == 0)
{
//
// Chain the buffer to the packet.
//
NdisChainBufferAtBack(Packet, pRecvBufHead->FlushBuffer);
}
if (pEntryOfRxReportQ->RxReportQDWord1.Eop == 0)
{
continue;
}
//
// We support AAL5 only
//
//
// Get the packet information.
// (09/15/97)
// WARNING: the returned PhysicalBufferCount is not
// the "real" buffer count for the requested packet.
// DO NOT use PhysicalBufferCount.
//
NdisQueryPacket(
Packet,
&PhysicalBufferCount,
NULL,
NULL,
&PacketLength);
dbgLogRecvPacket(
pVc->DebugInfo,
Packet,
PhysicalBufferCount,
PacketLength,
'nikp');
Reserved = RECV_PACKET_RESERVED_FROM_PACKET(Packet);
//
// The BufferCount field is actually the number of buffers
// that were allocated to receive the packet. If it is
// greater than one then the AAL5 PDU trailer and/or padding
// may be split between buffers. We first optimize for
// packets that contain only one buffer.
//
do
{
NdisZeroMemory (&Trailer, sizeof(AAL5_PDU_TRAILER));
if (1 == pSegCompleting->BufferCount)
{
PUCHAR BufferVa;
UINT BufferLength;
dbgLogRecvPacket(pVc->DebugInfo, Packet, (ULONG)pRecvBuf, 1, ' 1');
//
// Get the virtual address and length of the first buffer.
//
#if BUILD_W2K
NdisQueryBuffer(
pRecvBufHead->NdisBuffer,
&BufferVa,
&BufferLength);
#else
NdisQueryBufferSafe(
pRecvBufHead->NdisBuffer,
&BufferVa,
&BufferLength,
NormalPagePriority);
#endif
if (BufferVa == NULL)
{
//
// If we cannot get BufferVa due to low resources, just return the packet
//
fQueryBufferFail = TRUE;
break;
}
dbgLogRecvPacket(pVc->DebugInfo, Packet, BufferLength, 0, ' 2');
//
// Copy the AAL5 PDU trailer from the end of the buffer.
//
NdisMoveMemory(
&Trailer,
BufferVa + BufferLength - sizeof(AAL5_PDU_TRAILER),
sizeof(AAL5_PDU_TRAILER));
//
// Need to convert the length into a readable form.
//
Trailer.Length = TBATM155_SWAP_USHORT(Trailer.Length);
Trailer.CRC = TBATM155_SWAP_ULONG(Trailer.CRC);
//
// Check if we get a corrupted packet.
//
if ((LastBufferLength < (UINT)Trailer.Length) ||
(LastBufferLength > (UINT)(Trailer.Length + MAX_APPEND_BYTES)))
{
fCorruptedPacket = TRUE;
}
//
// Now we need to determine the packet size with out the
// trailer and padding. This is the value that is in
// the Trailer.Length.
//
NdisAdjustBufferLength(
pRecvBufHead->NdisBuffer,
Trailer.Length);
dbgLogRecvPacket(pVc->DebugInfo, Packet, Trailer.Length, 0, ' lt');
}
else
{
///
// Things are a little more complicated....
// Since there is more than one buffer it means that the
// padding and/or AAL5 pdu trailer can be split between
// them.
///
LastBuffer = pSegCompleting->BufListTail->FlushBuffer;
//
// First look for a packet that has a last buffer that is
// large enough for the AAL5_PDU_TRAILER.
//
#if BUILD_W2K
NdisQueryBuffer(
LastBuffer,
&LastBufferVa,
&LastBufferLength);
#else
NdisQueryBufferSafe(
LastBuffer,
&LastBufferVa,
&LastBufferLength,
NormalPagePriority);
#endif
if (LastBufferVa == NULL)
{
//
// Cannot get BufferVa due to low resources
//
fQueryBufferFail = TRUE;
break;
}
if (LastBufferLength >= sizeof(AAL5_PDU_TRAILER))
{
dbgLogRecvPacket(pVc->DebugInfo, Packet, LastBufferLength, 0, ' 2');
//
// The last buffer has all of the AAL5 pdu trailer.
// Copy it in at once.
//
NdisMoveMemory(
&Trailer,
(LastBufferVa + LastBufferLength) - sizeof(AAL5_PDU_TRAILER),
sizeof(AAL5_PDU_TRAILER));
}
else
{
dbgLogRecvPacket(pVc->DebugInfo, Packet, LastBufferLength, 0, ' 3');
//
// First grab whatever is in the last buffer and copy
// it to our local trailer.
//
NdisMoveMemory(
(PUCHAR)&Trailer + (sizeof(AAL5_PDU_TRAILER) - LastBufferLength),
LastBufferVa,
LastBufferLength);
//
// We need to get remaining trailer from the next to last
// buffer... but the next to last buffer can either be
// represented by the NdisBuffer or FlushBuffer. If
// the PhysicalBufferCount is 2 then it's the NdisBuffer,
// if not it's the FlushBuffer.
//
if (2 == pSegCompleting->BufferCount)
{
prevLastBuffer = pSegCompleting->BufListTail->Prev->NdisBuffer;
}
else
{
prevLastBuffer = pSegCompleting->BufListTail->Prev->FlushBuffer;
}
//
// Get the next to last buffers virtual address and
// length.
//
#if BUILD_W2K
NdisQueryBuffer(
prevLastBuffer,
&prevLastBufferVa,
&prevLastBufferLength);
#else
NdisQueryBufferSafe(
prevLastBuffer,
&prevLastBufferVa,
&prevLastBufferLength,
NormalPagePriority);
#endif
if (prevLastBufferVa == NULL)
{
//
// If cannot get preLastBufferVa due to low resources
//
fQueryBufferFail = TRUE;
break;
}
//
// Copy the first part of the trailer from this buffer
// into our local.
//
NdisMoveMemory(
&Trailer,
(PUCHAR)((prevLastBufferVa + prevLastBufferLength) -
(sizeof(AAL5_PDU_TRAILER) - LastBufferLength)),
sizeof(AAL5_PDU_TRAILER) - LastBufferLength);
}
//
// Need to convert the length into a readable form.
//
Trailer.Length = TBATM155_SWAP_USHORT(Trailer.Length);
Trailer.CRC = TBATM155_SWAP_ULONG(Trailer.CRC);
dbgLogRecvPacket(pVc->DebugInfo, Packet, Trailer.Length, 0, ' lt');
//
// Determine the amount of packet data that needs to be
// dumped before we indicate it up.
//
#if DBG
if (PacketLength < Trailer.Length)
{
DBGPRINT(DBG_COMP_SPECIAL, DBG_LEVEL_ERR,
("tbAtm155RxIOC: PacketLength (%x), Trailer.Length (%x).\n",
PacketLength, Trailer.Length));
DBGBREAK(DBG_COMP_SPECIAL, DBG_LEVEL_ERR);
}
#endif
TrimAmount = PacketLength - Trailer.Length;
dbgLogRecvPacket(pVc->DebugInfo, Packet, TrimAmount, 0, ' at');
//
// See if the last buffer contains all the data that
// needs to be trimmed.
//
if (TrimAmount < LastBufferLength)
{
//
// Adjust the last packet.
//
NdisAdjustBufferLength(
LastBuffer,
LastBufferLength - TrimAmount);
dbgLogRecvPacket(
pVc->DebugInfo,
Packet,
LastBufferLength - TrimAmount,
0,
'blat');
}
else
{
//
// Drop the last buffer from the packet.
// This is safe and we don't need to do anything with
// the buffer since it is saved in the RECV_BUFFER_HEADER.
//
NdisUnchainBufferAtBack(Packet, &LastBuffer);
//
// Determine how much data needs to be trimmed from
// the next to last.
//
TrimAmount -= LastBufferLength;
//
// If there were only two buffers then we need to
// adjust the NdisBuffer since this is the one that
// is chained to the Packet. If there are more than
// two buffers in the Packet then we need to adjust
// the FlushBuffer.
//
if (2 == pSegCompleting->BufferCount)
{
prevLastBuffer = pSegCompleting->BufListTail->Prev->NdisBuffer;
}
else
{
prevLastBuffer = pSegCompleting->BufListTail->Prev->FlushBuffer;
}
//
// Get the next to last buffers virtual address and length.
//
#if BUILD_W2K
NdisQueryBuffer(
prevLastBuffer,
NULL,
&prevLastBufferLength);
#else
NdisQueryBufferSafe(
prevLastBuffer,
NULL,
&prevLastBufferLength,
NormalPagePriority);
#endif
//
// Adjust the next to last (now the last) buffer
// in the packet.
//
NdisAdjustBufferLength(
prevLastBuffer,
prevLastBufferLength - TrimAmount);
dbgLogRecvPacket(pVc->DebugInfo, Packet, LastBufferLength - TrimAmount, 0, 'atbl');
}
} // end of if (1 == pSegCompleting->BufferCount)
}
while (FALSE);
//
// Save the traile
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -