Propagating the Completion of an I/O Operation
[The TCP chimney offload feature is deprecated and should not be used.]
The following figure shows the propagation of the completion of a TCP chimney I/O operation through an intermediate driver.
An offload target completes a TCP chimney I/O operation asynchronously by calling one of the following NDIS functions:
Note that an offload target does not asynchronously complete a call to its MiniportTcpOffloadReceiveReturn function.
When calling an NdisOffloadTcpXxxComplete function, an offload target passes:
An NdisMiniportHandle parameter, which is a handle that uniquely identifies the driver.
A pointer to a NET_BUFFER_LIST structure. This structure can be a stand-alone structure or the first structure in a linked list of such structures. Each NET_BUFFER_LIST structure in the list describes one NET_BUFFER structure. The NET_BUFFER structure maps to a chain of memory descriptor lists (MDLs).
In response to an offload target's call to an NdisOffloadTcpXxxComplete function, NDIS calls the intermediate driver's corresponding ProtocolTcpOffloadXxxComplete function:
To the intermediate driver's ProtocolTcpOffloadXxxComplete function, NDIS passes:
A ProtocolBindingContext parameter, which is a handle that references the intermediate driver's context for its binding to the offload target.
The same PNET_BUFFER_LIST pointer that the offload target passed to the NdisOffloadTcpXxxComplete function.
To propagate the completion of the I/O operation to the host stack, the intermediate driver calls the same NdisOffloadTcpXxxComplete function that the offload target called to complete the I/O operation. To the NdisOffloadTcpXxxComplete function, the intermediate driver passes the following:
An NdisMiniportHandle parameter, which is a handle that uniquely identifies the intermediate driver.
The same PNET_BUFFER_LIST pointer that NDIS passed to the intermediate driver's ProtocolTcpOffloadXxxComplete function.
In response, NDIS calls the host stack's ProtocolTcpOffloadXxxComplete function, passing a ProtocolBindingContext parameter and the same PNET_BUFFER_LIST pointer that was supplied by the intermediate driver to the NdisOffloadTcp*Xxx* function.
The intermediate driver then frees the memory for the IM call entry that it used to keep track of resources for the call. For more information about the IM Call Entry, see Reusing an NDIS_MINIPORT_OFFLOAD_BLOCK_LIST Structure.