Windows NT 4.0 source code leak
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
send.c
Abstract:
This file contains the code for putting a packet through the staged allocation for transmission.
This is a process of
1) Calculating the what would need to be done to the packet so that the packet can be transmitted on the hardware.
2) Potentially allocating adapter buffers and copying user data to those buffers so that the packet data is transmitted under the hardware constraints.
3) Allocating enough hardware ring entries so that the packet can be transmitted.
4) Relinquish thos ring entries to the hardware.
The overall structure and most of the code is taken from the Lance driver by Tony Ercolano.
Author:
Anthony V. Ercolano (Tonye) 12-Sept-1990 Adam Barr (adamba) 16-Nov-1990
Environment:
Kernel Mode - Or whatever is the equivalent.
Revision History:
--*/
#include <ndis.h>
#include <tfilter.h>
#include <tokhrd.h>
#include <toksft.h>
#if DEVL
#define STATIC
#else
#define STATIC static
#endif
#if DBG
extern INT IbmtokDbg;
extern UCHAR Packets[5][64]; extern UCHAR NextPacket; #endif
#ifdef CHECK_DUP_SENDS
//
// CHECK_DUP_SENDS enables checking ownership of packets, to
// make sure we are not given the same packet twice, or
// complete the same packet twice.
//
#define PACKET_LIST_SIZE 50
PNDIS_PACKET IbmtokPacketList[PACKET_LIST_SIZE]; IbmtokPacketListSize = 0; IbmtokPacketsAdded = 0; IbmtokPacketsRemoved = 0;
VOID IbmtokAddPacketToList( PIBMTOK_ADAPTER Adapter, PNDIS_PACKET NewPacket ) { INT i;
++IbmtokPacketsAdded;
for (i=0; i<IbmtokPacketListSize; i++) {
if (IbmtokPacketList[i] == NewPacket) {
DbgPrint("IBMTOK: dup send of %lx\n", NewPacket);
}
}
IbmtokPacketList[IbmtokPacketListSize] = NewPacket; ++IbmtokPacketListSize;
}
VOID IbmtokRemovePacketFromList( PIBMTOK_ADAPTER Adapter, PNDIS_PACKET OldPacket ) { INT i;
++IbmtokPacketsRemoved;
for (i=0; i<IbmtokPacketListSize; i++) {
if (IbmtokPacketList[i] == OldPacket) {
break;
}
}
if (i == IbmtokPacketListSize) {
DbgPrint("IBMTOK: bad remove of %lx\n", OldPacket);
} else {
--IbmtokPacketListSize; IbmtokPacketList[i] = IbmtokPacketList[IbmtokPacketListSize];
}
} #endif // CHECK_DUP_SENDS
extern NDIS_STATUS IbmtokSend( IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet )
/*++
Routine Description:
The IbmtokSend request instructs a MAC to transmit a packet through the adapter onto the medium.
Arguments:
MacBindingHandle - The context value returned by the MAC when the adapter was opened. In reality, it is a pointer to IBMTOK_OPEN.
Packet - A pointer to a descriptor for the packet that is to be transmitted.
Return Value:
The function value is the status of the operation.
--*/
{
//
// Holds the status that should be returned to the caller.
//
NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
//
// Pointer to the adapter.
//
PIBMTOK_ADAPTER Adapter;
ULONG PacketLength;
Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
NdisQueryPacket( Packet, NULL, NULL, NULL, &PacketLength );
//
// Check that the packet will go on the wire. Note: I do not
// check that we have enough receive space to receive a packet
// of this size -- it is up to a protocol to work this out.
//
if ((PacketLength < 14) || (PacketLength > Adapter->MaxTransmittablePacket)) {
return(NDIS_STATUS_INVALID_PACKET);
}
NdisAcquireSpinLock(&Adapter->Lock);
Adapter->References++;
if (Adapter->Unplugged) {
StatusToReturn = NDIS_STATUS_DEVICE_FAILED;
} else if (!Adapter->NotAcceptingRequests) {
PIBMTOK_OPEN Open; PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(Packet);
Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
if (!Open->BindingShuttingDown) {
//
// We do not have to increment the open count. Since we hold
// the lock for the entire function we cannot have the open
// removed out from under us.
//
//
// NOTE NOTE NOTE !!!!!!
//
// There is an assumption in the code that no pointer
// (which are really handles) to an ndis packet will have
// its low bit set. (Always have even byte alignment.)
//
ASSERT(!((UINT)Packet & 1));
//
// ALL packets go on the wire (loopback is done
// by the card).
//
#ifdef CHECK_DUP_SENDS
IbmtokAddPacketToList(Adapter, Packet); #endif
Reserved->MacBindingHandle = MacBindingHandle; Reserved->Packet = Packet;
if (Adapter->FirstTransmit == NULL) {
Adapter->FirstTransmit = Packet;
} else {
PIBMTOK_RESERVED_FROM_PACKET(Adapter->LastTransmit)->Next = Packet;
}
Adapter->LastTransmit = Packet;
Reserved->Next = NULL;
//
// Increment the reference on the open since it
// will be leaving this packet around on the transmit
// queues.
//
Open->References++;
//
// This will send the transmit SRB command
// if the SRB is available.
//
IbmtokProcessSrbRequests( Adapter );
} else {
StatusToReturn = NDIS_STATUS_CLOSING;
}
} else {
if (Adapter->ResetInProgress) {
StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
} else if (Adapter->AdapterNotOpen) {
StatusToReturn = NDIS_STATUS_FAILURE;
} else {
NdisWriteErrorLogEntry( Adapter->NdisAdapterHandle, NDIS_ERROR_CODE_DRIVER_FAILURE, 2, IBMTOK_ERRMSG_INVALID_STATE, 2 );
}
}
//
// This macro assumes it is called with the lock held,
// and releases it.
//
IBMTOK_DO_DEFERRED(Adapter); return StatusToReturn; }
|