使用網路通道取消網路資料
當架構針對封包佇列叫用 EvtPacketQueueCancel 回呼函式時,NetAdapterCx 用戶端驅動程式會取消網路資料。 此回呼是用戶端驅動程式在架構刪除封包佇列之前執行所需的任何處理。
取消傳輸佇列
在傳輸佇列的 EvtPacketQueueCancel 回呼函式中,您有機會完成任何未處理的傳輸封包。 不同于接收佇列,您不需要這麼做。 如果您離開未處理的封包,NetAdapterCx 會呼叫傳輸佇列的 EvtPacketQueueAdvance ,您可以在其中處理它們作為一般作業的一部分。
如果您的硬體支援取消即時傳輸,您也應該將 net ring 的封包後反覆運算器前進到所有已取消的封包。 這看起來可能如下列範例所示:
void
MyEvtTxQueueCancel(
NETPACKETQUEUE TxQueue
)
{
// Get the transmit queue's context to retrieve the net ring collection
PMY_TX_QUEUE_CONTEXT txQueueContext = MyGetTxQueueContext(TxQueue);
NET_RING_COLLECTION const * ringCollection = txQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
while (currentPacketIndex != packetEndIndex)
{
// Mark this packet as canceled with the scratch field, then move past it
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Scratch = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
}
如果您的硬體不支援取消,此回呼可以傳回而不採取動作。
取消接收佇列
在接收佇列的 EvtPacketQueueCancel 回呼函式中,您必須完成任何未處理的接收封包。 如果您未傳回所有封包,作業系統不會刪除佇列,而 NetAdapterCx 會停止呼叫佇列的回呼。
若要傳回封包,您應該先嘗試指出在停用接收路徑時可能已指出的任何接收,然後將所有封包設定為忽略,並將所有片段傳回 OS。 這看起來可能如下列程式碼範例所示。
注意
此範例會排除指出接收的詳細資料。 如需接收資料的程式碼範例,請參閱 使用 net 通道接收網路資料。
void
MyEvtRxQueueCancel(
NETPACKETQUEUE RxQueue
)
{
// Get the receive queue's context to retrieve the net ring collection
PMY_RX_QUEUE_CONTEXT rxQueueContext = MyGetRxQueueContext(RxQueue);
NET_RING_COLLECTION const * ringCollection = rxQueueContext->RingCollection;
NET_RING * packetRing = ringCollection->Rings[NET_RING_TYPE_PACKET];
NET_RING * fragmentRing = ringCollection->Rings[NET_RING_TYPE_FRAGMENT];
UINT32 currentPacketIndex = packetRing->BeginIndex;
UINT32 packetEndIndex = packetRing->EndIndex;
// Set hardware register for cancellation
...
//
// Indicate receives
...
//
// Get all packets and mark them for ignoring
currentPacketIndex = packetRing->BeginIndex;
while(currentPacketIndex != packetEndIndex)
{
NET_PACKET * packet = NetRingGetPacketAtIndex(packetRing, currentPacketIndex);
packet->Ignore = 1;
currentPacketIndex = NetRingIncrementIndex(packetRing, currentPacketIndex);
}
packetRing->BeginIndex = packetRing->EndIndex;
// Return all fragments to the OS
fragmentRing->BeginIndex = fragmentRing->EndIndex;
}