📄 miniport.c
字号:
}
}
#endif // NDIS51
//
// We are either not using packet stacks, or there isn't stack space
// in the original packet passed down to us. Allocate a new packet
// to wrap the data with.
//
//
// If the below miniport is going to low power state, stop sending down any packet.
//
NdisAcquireSpinLock(&pAdapt->Lock);
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
NdisReleaseSpinLock(&pAdapt->Lock);
return NDIS_STATUS_FAILURE;
}
pAdapt->OutstandingSends++;
NdisReleaseSpinLock(&pAdapt->Lock);
NdisAllocatePacket(&Status,
&MyPacket,
pAdapt->SendPacketPoolHandle);
if (Status == NDIS_STATUS_SUCCESS)
{
PSEND_RSVD SendRsvd;
//
// Save a pointer to the original packet in our reserved
// area in the new packet. This is needed so that we can
// get back to the original packet when the new packet's send
// is completed.
//
SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
SendRsvd->OriginalPkt = Packet;
MyPacket->Private.Flags = Flags;
//
// Set up the new packet so that it describes the same
// data as the original packet.
//
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;
#ifdef WIN9X
//
// Work around the fact that NDIS does not initialize this
// to FALSE on Win9x.
//
MyPacket->Private.ValidCounts = FALSE;
#endif
//
// Copy the OOB Offset from the original packet to the new
// packet.
//
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
NDIS_OOB_DATA_FROM_PACKET(Packet),
sizeof(NDIS_PACKET_OOB_DATA));
#ifndef WIN9X
//
// Copy the right parts of per packet info into the new packet.
// This API is not available on Win9x since task offload is
// not supported on that platform.
//
NdisIMCopySendPerPacketInfo(MyPacket, Packet);
#endif
//
// Copy the Media specific information
//
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
&MediaSpecificInfo,
&MediaSpecificInfoSize);
if (MediaSpecificInfo || MediaSpecificInfoSize)
{
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
MediaSpecificInfo,
MediaSpecificInfoSize);
}
NdisSend(&Status,
pAdapt->BindingHandle,
MyPacket);
if (Status != NDIS_STATUS_PENDING)
{
#ifndef WIN9X
NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
#endif
NdisFreePacket(MyPacket);
ADAPT_DECR_PENDING_SENDS(pAdapt);
}
}
else
{
ADAPT_DECR_PENDING_SENDS(pAdapt);
//
// We are out of packets. Silently drop it. Alternatively we can deal with it:
// - By keeping separate send and receive pools
// - Dynamically allocate more pools as needed and free them when not needed
//
}
return(Status);
}
VOID
MPSendPackets(
IN NDIS_HANDLE MiniportAdapterContext,
IN PPNDIS_PACKET PacketArray,
IN UINT NumberOfPackets
)
/*++
Routine Description:
Send Packet Array handler. Either this or our SendPacket handler is called
based on which one is enabled in our Miniport Characteristics.
Arguments:
MiniportAdapterContext Pointer to our adapter
PacketArray Set of packets to send
NumberOfPackets Self-explanatory
Return Value:
None
--*/
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
NDIS_STATUS Status;
UINT i;
PVOID MediaSpecificInfo = NULL;
UINT MediaSpecificInfoSize = 0;
// Bump entry count. ja, 02.10.2003.
NdisInterlockedIncrement(&pAdapt->PassThruStats.MPSendPktsSeen);
// DBGPRINT(("MPSendPackets: pAdapt = 0x%08x, MPSendPktsCt = %d\n", pAdapt, pAdapt->PassThruStats.MPSendPktsSeen));
for (i = 0; i < NumberOfPackets; i++)
{
BOOLEAN bDecision; // ja, 02.10.2003
PNDIS_PACKET Packet, MyPacket;
Packet = PacketArray[i];
//
// The driver should fail the send if the virtual miniport is in low
// power state
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0)
{
NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
Packet,
NDIS_STATUS_FAILURE);
continue;
}
#ifdef NDIS51
//
// Use NDIS 5.1 packet stacking:
//
{
PNDIS_PACKET_STACK pStack;
BOOLEAN Remaining;
//
// Packet stacks: Check if we can use the same packet for sending down.
//
pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);
if (Remaining)
{
//
// We can reuse "Packet".
//
// NOTE: if we needed to keep per-packet information in packets
// sent down, we can use pStack->IMReserved[].
//
ASSERT(pStack);
//
// If the below miniport is going to low power state, stop sending down any packet.
//
NdisAcquireSpinLock(&pAdapt->Lock);
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
NdisReleaseSpinLock(&pAdapt->Lock);
NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
Packet,
NDIS_STATUS_FAILURE);
}
else
{
//........................................ // ja, 02.10.2003.
//DBGPRINT(("MPSendPackets(): In packet stacking\n"));
Status = FilterPacket( // See if packet to be dropped.
pAdapt,
Packet,
NULL,
TRUE, // Send action.
&bDecision
);
if (
NDIS_STATUS_SUCCESS==Status // Everything OK?
&&
TRUE==bDecision // Packet to be dropped?
)
{
// Bump dropped-packet count.
NdisInterlockedIncrement(&pAdapt->PassThruStats.MPSendPktsDropped);
NdisReleaseSpinLock(&pAdapt->Lock);
break; // Leave 'do' group, without sending down packet. (Packet completion indicated after group.)
}
//........................................ // ja, 02.10.2003.
pAdapt->OutstandingSends++;
NdisReleaseSpinLock(&pAdapt->Lock);
NdisSend(&Status,
pAdapt->BindingHandle,
Packet);
if (Status != NDIS_STATUS_PENDING)
{
NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),
Packet,
Status);
ADAPT_DECR_PENDING_SENDS(pAdapt);
}
}
continue; // Skip to bottom of 'for' loop. ja, 04.10.2003.
}
}
#endif
do
{
NdisAcquireSpinLock(&pAdapt->Lock);
//
// If the below miniport is going to low power state, stop sending down any packet.
//
if (pAdapt->PTDeviceState > NdisDeviceStateD0)
{
NdisReleaseSpinLock(&pAdapt->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
//........................................ // ja, 02.10.2003.
Status = FilterPacket( // See if packet to be dropped.
pAdapt,
Packet,
NULL,
TRUE, // Send action.
&bDecision
);
if (
NDIS_STATUS_SUCCESS==Status // Everything OK?
&&
TRUE==bDecision // Packet to be dropped?
)
{
// DBGPRINT(("MPSendPackets(): Dropping packet\n"));
// Bump dropped-packet count.
NdisInterlockedIncrement(&pAdapt->PassThruStats.MPSendPktsDropped);
NdisReleaseSpinLock(&pAdapt->Lock);
break; // Leave 'do' group, without sending down packet. (Packet completion indicated after group.)
}
//........................................ // ja, 02.10.2003.
pAdapt->OutstandingSends++;
NdisReleaseSpinLock(&pAdapt->Lock);
NdisAllocatePacket(&Status,
&MyPacket,
pAdapt->SendPacketPoolHandle);
if (Status == NDIS_STATUS_SUCCESS)
{
PSEND_RSVD SendRsvd;
SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);
SendRsvd->OriginalPkt = Packet;
MyPacket->Private.Flags = NdisGetPacketFlags(Packet);
MyPacket->Private.Head = Packet->Private.Head;
MyPacket->Private.Tail = Packet->Private.Tail;
#ifdef WIN9X
//
// Work around the fact that NDIS does not initialize this
// to FALSE on Win9x.
//
MyPacket->Private.ValidCounts = FALSE;
#endif // WIN9X
//
// Copy the OOB data from the original packet to the new
// packet.
//
NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),
NDIS_OOB_DATA_FROM_PACKET(Packet),
sizeof(NDIS_PACKET_OOB_DATA));
//
// Copy relevant parts of the per packet info into the new packet
//
#ifndef WIN9X
NdisIMCopySendPerPacketInfo(MyPacket, Packet);
#endif
//
// Copy the Media specific information
//
NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,
&MediaSpecificInfo,
&MediaSpecificInfoSize);
if (MediaSpecificInfo || MediaSpecificInfoSize)
{
NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,
MediaSpecificInfo,
MediaSpecificInfoSize);
}
NdisSend(&Status,
pAdapt->BindingHandle,
MyPacket);
if (Status != NDIS_STATUS_PENDING)
{
#ifndef WIN9X
NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);
#endif
NdisFreePacket(MyPacket);
ADAPT_DECR_PENDING_SENDS(pAdapt);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -