當架構針對封包佇列叫用其 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 會停止呼叫佇列的回呼函式。
若要傳回封包,您應應先嘗試指出在停用接收路徑時可能已指示的任何接收,然後將所有封包設定為忽略,並將所有片段傳回作業系統。 這可能看起來像下列程式代碼範例。
備註
本範例省略了指出接收的細節。 如需接收數據的程式代碼範例,請參閱 使用 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;
}