Annullamento dei dati di rete con anelli di rete
I driver client NetAdapterCx annullano i dati di rete quando il framework richiama la funzione di callback EvtPacketQueueCancel per una coda di pacchetti. Questo callback è la posizione in cui i driver client eseguono qualsiasi elaborazione necessaria prima che il framework elimini le code di pacchetti.
Annullamento di una coda di trasmissione
Nella funzione di callback EvtPacketQueueCancel per una coda di trasmissione è possibile completare eventuali pacchetti di trasmissione in sospeso. A differenza di una coda di ricezione, non è necessario farlo. Se si lasciano pacchetti in sospeso, NetAdapterCx chiama EvtPacketQueueAdvance per la coda di trasmissione, in cui vengono elaborati come parte della normale operazione.
Se l'hardware supporta l'annullamento delle trasmissioni in anteprima, è necessario anche avanzare l'iteratore post-pacchetto del circuito net oltre tutti i pacchetti annullati. L'esempio potrebbe essere simile al seguente:
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;
}
Se l'hardware non supporta l'annullamento, questo callback può essere restituito senza intervenire.
Annullamento di una coda di ricezione
Nella funzione di callback EvtPacketQueueCancel per una coda di ricezione è necessario completare tutti i pacchetti di ricezione in sospeso. Se non si restituiscono tutti i pacchetti, il sistema operativo non elimina la coda e NetAdapterCx smette di chiamare i callback per la coda.
Per restituire pacchetti, è prima necessario tentare di indicare eventuali ricevute che potrebbero essere state indicate durante la disabilitazione del percorso di ricezione, quindi impostare tutti i pacchetti da ignorare e restituire tutti i frammenti al sistema operativo. L'esempio di codice seguente potrebbe essere simile al seguente.
Nota
In questo esempio vengono visualizzati i dettagli per indicare le ricevute. Per un esempio di codice di ricezione dei dati, vedere Ricezione di dati di rete con anelli di rete.
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;
}