186 lines
4.0 KiB
C
186 lines
4.0 KiB
C
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ltloop.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the loopback queue processing routines.
|
|
|
|
Author:
|
|
|
|
Stephen Hou (stephh@microsoft.com)
|
|
Nikhil Kamkolkar (nikhilk@microsoft.com)
|
|
|
|
Revision History:
|
|
19 Jun 1992 Initial Version (dch@pacvax.pacersoft.com)
|
|
|
|
Notes: Tab stop: 4
|
|
--*/
|
|
|
|
#include "ltmain.h"
|
|
|
|
// Define file id for errorlogging
|
|
#define FILENUM LTLOOP
|
|
|
|
|
|
VOID
|
|
LtLoopProcessQueue(
|
|
IN PLT_ADAPTER Adapter
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is responsible for indicating *one* packet on
|
|
the loopback queue either completing it or moving on to the
|
|
finish send queue.
|
|
|
|
Arguments:
|
|
|
|
Adapter - The adapter whose loopback queue we are processing.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
// Packet at the head of the loopback list.
|
|
PNDIS_PACKET Packet;
|
|
|
|
// The reserved portion of the above packet.
|
|
PLT_PACKET_RESERVED Reserved;
|
|
|
|
// Buffer for loopback.
|
|
CHAR Loopback[LT_MAX_INDICATE_SIZE];
|
|
|
|
// The first buffer in the ndis packet to be loopedback.
|
|
PNDIS_BUFFER FirstBuffer;
|
|
|
|
// The total amount of user data in the packet to be
|
|
// loopedback.
|
|
UINT PacketLength;
|
|
|
|
// Eventually the address of the data to be indicated
|
|
// to the transport.
|
|
PCHAR BufferAddress, LinkAddress;
|
|
|
|
// Eventually the length of the data to be indicated
|
|
// to the transport.
|
|
UINT BufferLength;
|
|
PLIST_ENTRY p;
|
|
PLT_OPEN Binding;
|
|
|
|
|
|
NdisAcquireSpinLock(&Adapter->Lock);
|
|
while((!IsListEmpty(&Adapter->LoopBack)) &&
|
|
((Adapter->Flags & ADAPTER_RESET_IN_PROGRESS) == 0))
|
|
{
|
|
p = RemoveHeadList(&Adapter->LoopBack);
|
|
Packet = CONTAINING_RECORD(
|
|
p,
|
|
NDIS_PACKET,
|
|
MacReserved);
|
|
|
|
Reserved = (PLT_PACKET_RESERVED)Packet->MacReserved;
|
|
|
|
// Remember this in CurrentLoopbackPacket in Adapter.
|
|
// Used by Transfer data.
|
|
Adapter->CurrentLoopbackPacket = Packet;
|
|
NdisReleaseSpinLock(&Adapter->Lock);
|
|
|
|
DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
|
|
("LtLoopProcessLoopback: Dequeued %lx \n", Packet));
|
|
|
|
// See if we need to copy the data from the packet
|
|
// into the loopback buffer.
|
|
//
|
|
// We need to copy to the local loopback buffer if
|
|
// the first buffer of the packet is less than the
|
|
// minimum loopback size AND the first buffer isn't
|
|
// the total packet.
|
|
NdisQueryPacket(
|
|
Packet,
|
|
NULL,
|
|
NULL,
|
|
&FirstBuffer,
|
|
&PacketLength);
|
|
|
|
NdisQueryBuffer(
|
|
FirstBuffer,
|
|
&BufferAddress,
|
|
&BufferLength);
|
|
|
|
LinkAddress = BufferAddress;
|
|
if (BufferLength != PacketLength)
|
|
{
|
|
// !!!BUGBUG: What do the sizes mean?
|
|
LtUtilsCopyFromPacketToBuffer(
|
|
Packet,
|
|
LT_DGRAM_OFFSET,
|
|
LT_MAX_INDICATE_SIZE,
|
|
Loopback,
|
|
&BufferLength);
|
|
|
|
BufferAddress = Loopback;
|
|
|
|
}
|
|
else
|
|
{
|
|
// Adjust the buffer to account for the link header
|
|
// which is not part of the lookahead.
|
|
BufferAddress += LT_DGRAM_OFFSET;
|
|
BufferLength -= LT_LINK_HEADER_LENGTH;
|
|
}
|
|
|
|
// Indicate the packet to every open binding
|
|
// that could want it. Since loopback indications
|
|
// are seralized, we use a NULL handle to indicate that it
|
|
// is for a loopback packet. TransferData always gets the
|
|
// first packet off the loopback queue.
|
|
|
|
// Since we do not have an complicated filtering to do.
|
|
// Just walk the list of Open bindings and Indicate the packet
|
|
|
|
NdisAcquireSpinLock(&Adapter->Lock);
|
|
LtRecvIndicatePacket(
|
|
Adapter,
|
|
LinkAddress,
|
|
BufferAddress,
|
|
BufferLength,
|
|
PacketLength - LT_LINK_HEADER_LENGTH,
|
|
(NDIS_HANDLE)NULL);
|
|
NdisReleaseSpinLock(&Adapter->Lock);
|
|
|
|
|
|
// We have indicated the packet to all the binding. Now we just
|
|
// need to call send completion.
|
|
|
|
DBGPRINT(DBG_COMP_LOOP, DBG_LEVEL_WARN,
|
|
("LtLoopProcessLoopback: NdisSendComplete Packet = %p\n", Packet ));
|
|
|
|
|
|
Binding = (PLT_OPEN)(Reserved->MacBindingHandle);
|
|
NdisCompleteSend(
|
|
Binding->NdisBindingContext,
|
|
Packet,
|
|
NDIS_STATUS_SUCCESS);
|
|
|
|
// Dereference the adapter and the binding for this completed
|
|
// send.
|
|
LtDeReferenceBinding(Binding);
|
|
LtDeReferenceAdapter(Adapter);
|
|
|
|
NdisAcquireSpinLock(&Adapter->Lock);
|
|
}
|
|
NdisReleaseSpinLock(&Adapter->Lock);
|
|
|
|
return;
|
|
}
|
|
|
|
|