Net 링으로 네트워크 데이터 취소

NetAdapterCx 클라이언트 드라이버는 프레임워크가 패킷 큐에 대한 EvtPacketQueueCancel 콜백 함수를 호출할 때 네트워크 데이터를 취소합니다. 이 콜백은 프레임워크가 패킷 큐를 삭제하기 전에 클라이언트 드라이버가 필요한 모든 처리를 수행하는 위치입니다.

전송 큐 취소

전송 큐 에 대한 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로 반환해야 합니다. 다음 코드 예제와 같이 표시될 수 있습니다.

참고

이 예제에서는 수신을 나타내는 세부 정보를 제외합니다. 데이터를 수신하는 코드 샘플은 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;
}