📄 interrup.c
字号:
}
return(TRUE);
}
INDICATE_STATUS
RTL8139IndicatePacket(
IN PRTL8139_ADAPTER Adapter
)
/*++
Routine Description:
Indicates the first packet on the card to the protocols.
NOTE: For MP, non-x86 architectures, this assumes that the packet has been
read from the card and into Adapter->PacketHeader and Adapter->Lookahead.
NOTE: For UP x86 systems this assumes that the packet header has been
read into Adapter->PacketHeader and the minimal lookahead stored in
Adapter->Lookahead
Arguments:
Adapter - pointer to the adapter block.
Return Value:
CARD_BAD if the card should be reset;
INDICATE_OK otherwise.
--*/
{
//
// Length of the packet
//
UINT PacketLen;
//
// Length of the lookahead buffer
//
UINT IndicateLen;
//
// Variables for checking if the packet header looks valid
//
UCHAR PossibleNextPacket1, PossibleNextPacket2;
//
// Check if the next packet byte agress with the length, as
// described on p. A-3 of the Etherlink II Technical Reference.
// The start of the packet plus the MSB of the length must
// be equal to the start of the next packet minus one or two.
// Otherwise the header is considered corrupted, and the
// card must be reset.
//
PossibleNextPacket1 =
Adapter->NicNextPacket + Adapter->PacketHeader[3] + (UCHAR)1;
if (PossibleNextPacket1 >= Adapter->NicPageStop) {
PossibleNextPacket1 -= (Adapter->NicPageStop - Adapter->NicPageStart);
}
if (PossibleNextPacket1 != Adapter->PacketHeader[1]) {
PossibleNextPacket2 = PossibleNextPacket1+(UCHAR)1;
if (PossibleNextPacket2 == Adapter->NicPageStop) {
PossibleNextPacket2 = Adapter->NicPageStart;
}
if (PossibleNextPacket2 != Adapter->PacketHeader[1]) {
IF_LOUD( DbgPrint("First CARD_BAD check failed\n"); )
return SKIPPED;
}
}
//
// Check that the Next is valid
//
if ((Adapter->PacketHeader[1] < Adapter->NicPageStart) ||
(Adapter->PacketHeader[1] > Adapter->NicPageStop)) {
IF_LOUD( DbgPrint("Second CARD_BAD check failed\n"); )
return(SKIPPED);
}
//
// Sanity check the length
//
PacketLen = Adapter->PacketHeader[2] + Adapter->PacketHeader[3]*256 - 4;
if (PacketLen > 1514) {
IF_LOUD( DbgPrint("Third CARD_BAD check failed\n"); )
return(SKIPPED);
}
#if DBG
IF_RTL8139DEBUG( RTL8139_DEBUG_WORKAROUND1 ) {
//
// Now check for the high order 2 bits being set, as described
// on page A-2 of the Etherlink II Technical Reference. If either
// of the two high order bits is set in the receive status byte
// in the packet header, the packet should be skipped (but
// the adapter does not need to be reset).
//
if (Adapter->PacketHeader[0] & (RSR_DISABLED|RSR_DEFERRING)) {
IF_LOUD (DbgPrint("H");)
return SKIPPED;
}
}
#endif
//
// Lookahead amount to indicate
//
IndicateLen = (PacketLen > (Adapter->MaxLookAhead + RTL8139_HEADER_SIZE)) ?
(Adapter->MaxLookAhead + RTL8139_HEADER_SIZE) :
PacketLen;
//
// Indicate packet
//
Adapter->PacketLen = PacketLen;
if (IndicateLen < RTL8139_HEADER_SIZE) {
//
// Runt Packet
//
NdisMEthIndicateReceive(
Adapter->MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
(PCHAR)(Adapter->Lookahead),
IndicateLen,
NULL,
0,
0
);
} else {
NdisMEthIndicateReceive(
Adapter->MiniportAdapterHandle,
(NDIS_HANDLE)Adapter,
(PCHAR)(Adapter->Lookahead),
RTL8139_HEADER_SIZE,
(PCHAR)(Adapter->Lookahead) + RTL8139_HEADER_SIZE,
IndicateLen - RTL8139_HEADER_SIZE,
PacketLen - RTL8139_HEADER_SIZE
);
}
Adapter->IndicateReceiveDone = TRUE;
return INDICATE_OK;
}
NDIS_STATUS
RTL8139TransferData(
OUT PNDIS_PACKET Packet,
OUT PUINT BytesTransferred,
IN NDIS_HANDLE MiniportAdapterContext,
IN NDIS_HANDLE MiniportReceiveContext,
IN UINT ByteOffset,
IN UINT BytesToTransfer
)
/*++
Routine Description:
A protocol calls the RTL8139TransferData request (indirectly via
NdisTransferData) from within its Receive event handler
to instruct the driver to copy the contents of the received packet
a specified packet buffer.
Arguments:
MiniportAdapterContext - Context registered with the wrapper, really
a pointer to the adapter.
MiniportReceiveContext - The context value passed by the driver on its call
to NdisMEthIndicateReceive. The driver can use this value to determine
which packet, on which adapter, is being received.
ByteOffset - An unsigned integer specifying the offset within the
received packet at which the copy is to begin. If the entire packet
is to be copied, ByteOffset must be zero.
BytesToTransfer - An unsigned integer specifying the number of bytes
to copy. It is legal to transfer zero bytes; this has no effect. If
the sum of ByteOffset and BytesToTransfer is greater than the size
of the received packet, then the remainder of the packet (starting from
ByteOffset) is transferred, and the trailing portion of the receive
buffer is not modified.
Packet - A pointer to a descriptor for the packet storage into which
the MAC is to copy the received packet.
BytesTransfered - A pointer to an unsigned integer. The MAC writes
the actual number of bytes transferred into this location. This value
is not valid if the return status is STATUS_PENDING.
Notes:
- The MacReceiveContext will be a pointer to the open block for
the packet.
--*/
{
//
// Variables for the number of bytes to copy, how much can be
// copied at this moment, and the total number of bytes to copy.
//
UINT BytesLeft, BytesNow, BytesWanted;
//
// Current NDIS_BUFFER to copy into
//
PNDIS_BUFFER CurBuffer;
//
// Virtual address of the buffer.
//
XMIT_BUF NextBufToXmit;
PUCHAR BufStart;
//
// Length and offset into the buffer.
//
UINT BufLen, BufOff;
//
// The adapter to transfer from.
//
PRTL8139_ADAPTER Adapter = ((PRTL8139_ADAPTER)MiniportReceiveContext);
IF_LOG( RTL8139Log('t');)
//
// Add the packet header onto the offset.
//
ByteOffset += RTL8139_HEADER_SIZE;
//
// See how much data there is to transfer.
//
if (ByteOffset+BytesToTransfer > Adapter->PacketLen) {
if (Adapter->PacketLen < ByteOffset) {
*BytesTransferred = 0;
IF_LOG( RTL8139Log('T');)
return(NDIS_STATUS_FAILURE);
}
BytesWanted = Adapter->PacketLen - ByteOffset;
} else {
BytesWanted = BytesToTransfer;
}
//
// Set the number of bytes left to transfer
//
BytesLeft = BytesWanted;
{
//
// Address on the adapter to copy from
//
PUCHAR CurCardLoc;
//
// Copy data from the card -- it is not completely stored in the
// adapter structure.
//
// Determine where the copying should start.
//
CurCardLoc = Adapter->PacketHeaderLoc + ByteOffset;
if (CurCardLoc > Adapter->PageStop) {
CurCardLoc = CurCardLoc - (Adapter->PageStop - Adapter->PageStart);
}
//
// Get location to copy into
//
NdisQueryPacket(Packet, NULL, NULL, &CurBuffer, NULL);
NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);
BufOff = 0;
//
// Loop, filling each buffer in the packet until there
// are no more buffers or the data has all been copied.
//
while (BytesLeft > 0) {
//
// See how much data to read into this buffer.
//
if ((BufLen-BufOff) > BytesLeft) {
BytesNow = BytesLeft;
} else {
BytesNow = (BufLen - BufOff);
}
//
// See if the data for this buffer wraps around the end
// of the receive buffers (if so filling this buffer
// will use two iterations of the loop).
//
if (CurCardLoc + BytesNow > Adapter->PageStop) {
BytesNow = (UINT)(Adapter->PageStop - CurCardLoc);
}
//
// Copy up the data.
//
if (!CardCopyUp(Adapter, BufStart+BufOff, CurCardLoc, BytesNow)) {
*BytesTransferred = BytesWanted - BytesLeft;
NdisWriteErrorLogEntry(
Adapter->MiniportAdapterHandle,
NDIS_ERROR_CODE_HARDWARE_FAILURE,
1,
0x2
);
return(NDIS_STATUS_FAILURE);
}
//
// Update offsets and counts
//
CurCardLoc += BytesNow;
BytesLeft -= BytesNow;
//
// Is the transfer done now?
//
if (BytesLeft == 0) {
break;
}
//
// Wrap around the end of the receive buffers?
//
if (CurCardLoc == Adapter->PageStop) {
CurCardLoc = Adapter->PageStart;
}
//
// Was the end of this packet buffer reached?
//
BufOff += BytesNow;
if (BufOff == BufLen) {
NdisGetNextBuffer(CurBuffer, &CurBuffer);
if (CurBuffer == (PNDIS_BUFFER)NULL) {
break;
}
NdisQueryBuffer(CurBuffer, (PVOID *)&BufStart, &BufLen);
BufOff = 0;
}
}
*BytesTransferred = BytesWanted - BytesLeft;
//
// Did a transmit complete while we were doing what we were doing?
//
if (!Adapter->BufferOverflow && Adapter->CurBufXmitting != -1) {
ULONG Len;
UINT i;
UCHAR Status;
PNDIS_PACKET Packet;
NDIS_STATUS NdisStatus;
//
// Check if it completed
//
CardGetInterruptStatus(Adapter, &Status);
if (Status & ISR_XMIT_ERR) {
OctogmetusceratorRevisited(Adapter);
Adapter->InterruptStatus &= ~ISR_XMIT_ERR;
NdisRawWritePortUchar(Adapter->IoAddr+NIC_INTR_STATUS, (ISR_XMIT_ERR));
Status &= ~ISR_XMIT_ERR;
}
if (Status & (ISR_XMIT)) {
IF_LOG( RTL8139Log('*'); )
//
// Update NextBufToXmit
//
Len = (Adapter->PacketLens[Adapter->CurBufXmitting] + 255) >> 8;
NextBufToXmit = Adapter->NextBufToXmit + Len;
// Adapter->NextBufToXmit += Len;
if (NextBufToXmit == MAX_XMIT_BUFS) {
NextBufToXmit = 0;
}
if (Adapter->BufferStatus[NextBufToXmit] == EMPTY &&
Adapter->NextBufToFill != NextBufToXmit) {
NextBufToXmit = 0;
}
//
// If the next packet is ready to go, start it.
//
if (Adapter->BufferStatus[NextBufToXmit] == FULL) {
//
// Ack the transmit
//
//
// Remove the packet from the packet list.
//
Adapter->NextBufToXmit = NextBufToXmit;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -