Freigeben über


Abbrechen von Netzwerkdaten mit Netzringen

NetAdapterCx-Clienttreiber brechen Netzwerkdaten ab, wenn das Framework ihre EvtPacketQueueCancel-Rückruffunktion für eine Paketwarteschlange aufruft. In diesem Rückruf führen Clienttreiber alle erforderlichen Verarbeitungen aus, bevor das Framework die Paketwarteschlangen löscht.

Abbrechen einer Übertragungswarteschlange

In Ihrer EvtPacketQueueCancel-Rückruffunktion für eine Übertragungswarteschlange haben Sie die Möglichkeit, alle ausstehenden Übertragungspakete abzuschließen. Im Gegensatz zu einer Empfangswarteschlange müssen Sie dies nicht tun. Wenn Sie ausstehende Pakete verlassen, ruft NetAdapterCx Ihre EvtPacketQueueAdvance für die Übertragungswarteschlange auf, wo Sie sie im Rahmen Ihres regulären Vorgangs verarbeiten.

Wenn Ihre Hardware das Abbrechen von Übertragungen im Flug unterstützt, sollten Sie auch den Post-Paket-Iterator des Net-Rings über alle abgebrochenen Pakete hinaus verschieben. Dies könnte wie im folgenden Beispiel aussehen:

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;
}

Wenn Ihre Hardware den Abbruch nicht unterstützt, kann dieser Rückruf ohne Aktion zurückgegeben werden.

Abbrechen einer Empfangswarteschlange

In Ihrer EvtPacketQueueCancel-Rückruffunktion für eine Empfangswarteschlange müssen Sie alle ausstehenden Empfangspakete abschließen. Wenn Sie nicht alle Pakete zurückgeben, löscht das Betriebssystem die Warteschlange nicht, und NetAdapterCx beendet den Aufruf Ihrer Rückrufe für die Warteschlange.

Um Pakete zurückzugeben, sollten Sie zuerst versuchen, alle Empfang anzugeben, die möglicherweise angegeben wurden, während der Empfangspfad deaktiviert wurde. Legen Sie dann alle Pakete so fest, dass sie ignoriert werden, und geben Sie alle Fragmente an das Betriebssystem zurück. Dies könnte wie im folgenden Codebeispiel aussehen.

Hinweis

In diesem Beispiel werden Details zum Angeben von Empfangsdaten nicht angegeben. Ein Codebeispiel zum Empfangen von Daten finden Sie unter Empfangen von Netzwerkdaten mit Netzringen.

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;
}