ネット リングを使用したネットワーク データの取り消し
NetAdapterCx クライアント ドライバーは、フレームワークがパケット キューの EvtPacketQueueAdvance コールバック関数を呼び出すときにネットワーク データを送信します。 このコールバックにより、フレームワークがパケット キューを削除する前に、クライアント ドライバーで必要な処理が実行されます。
送信キューの取り消し
送信キューの EvtPacketQueueCancel コールバック関数では、未処理の送信パケットを完了する機会があります。 受信キューとは異なり、そうする必要はありません。 未処理のパケットを残した場合、NetAdapterCx は送信キューの EvtPacketQueueAdvance を呼び出し、通常の操作の一部として処理します。
ハードウェアで実行中の送信のキャンセルがサポートされている場合は、キャンセルされたすべてのパケットを超えて、ネット リングのポスト パケット反復子も進める必要があります。 これは次の例のようになります。
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 に返す必要があります。 これは次のコード例のようになります。
Note
この例では、受信を示す詳細を示します。 データを受信するコード サンプルについては、「ネット リングを使用したネットワーク データの受信」を参照してください。
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;
}