ProtocolSendComplete

VOID
    ProtocolSendComplete(

        IN NDIS_HANDLE  ProtocolBindingContext,
        IN PNDIS_PACKET  Packet,
        IN NDIS_STATUS Status
        );

ProtocolSendComplete is a required driver function that completes the processing of a protocol-initiated send previously passed to NdisSendPackets or NdisSend, which returned NDIS_STATUS_PENDING.

Parameters

ProtocolBindingContext
Specifies the handle to a protocol-allocated context area in which the protocol driver maintains per-binding runtime state. The driver supplied this handle when it called NdisOpenAdapter.
Packet
Points to the protocol-supplied packet descriptor for the completed send.
Status
Specifies the final status of the send operation.

Comments

ProtocolSendComplete performs whatever postprocessing is necessary for a completed transmit operation, such as notifying the client that originally requested the protocol to send data over the network.

Completion of a send operation usually implies that the underlying NIC driver actually has transmitted the given packet over the network. However, the driver of a so-called intelligent NIC can consider a send complete as soon as it downloads the net packet to its NIC. The underlying driver’s call to NdisMSendComplete or NdisMWanSendComplete causes NDIS to call the ProtocolSendComplete function.

When ProtocolSendComplete is called, the driver regains ownership of the following protocol-allocated resources:

Consequently, ProtocolSendComplete can either release these resources or prepare them for reuse in a subsequent call to NdisSendPackets or NdisSend. As a general rule, reusing such resources yields better performance than releasing them except, possibly, in periods of low network traffic if the protocol previously allocated a surplus of these resources to handle a period of heavy I/O demand.

To prepare the buffer and packet descriptors for reuse, ProtocolSendComplete should follow these guidelines:

Until ProtocolSendComplete is called, the current status of a protocol-initiated send is volatile. A protocol temporarily releases ownership of all resources it allocated for a send when it calls NdisSendPackets or NdisSend, even if the protocol supplies out-of-band information with the packet descriptors it allocates for sends. In particular, a protocol should never attempt to examine the Status member of the associated out-of-band data block when NdisSendPackets or NdisSend returns control.

Although NDIS always submits protocol-supplied packet arrays to the underlying miniport in the protocol-determined order passed in calls to NdisSendPackets, the underlying driver can complete the given packets in random order. That is, every bound protocol can rely on NDIS to submit the packets the protocol passes to NdisSendPackets or NdisSend in FIFO order to the underlying driver, but no protocol can rely on that underlying driver to call NdisMSendComplete with those packets in the same order.

The ProtocolSendComplete function of an NDIS intermediate driver cannot simply forward completion indications to still higher-level protocols. Such an attempt can cause a deadlock. Instead, such a driver must call NdisIMSwitchToMiniport to forward the indication from the appropriate context. If NdisIMSwitchToMiniport returns FALSE, the driver must call NdisIMQueueMiniportCallback and forward the indication from the protocol-supplied MiniportCallback function.

By default, ProtocolSendComplete runs at IRQL DISPATCH_LEVEL in an arbitrary thread context.

See Also

MiniportSend, MiniportSendPackets, MiniportWanSend, NdisAllocateBuffer, NdisAllocatePacket, NdisFreeBuffer, NdisFreePacket, NdisIMQueueMiniportCallback, NdisIMSwitchToMiniport, NdisMSendComplete, NDIS_OOB_DATA_FROM_PACKET, NDIS_PACKET_OOB_DATA, NdisReinitializePacket, NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO, NDIS_SET_PACKET_TIME_TO_SEND, NdisUnchainBufferAtBack, NdisUnchainBufferAtFront, NdisZeroMemory