⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 send.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
    PLIST_ENTRY         pEntry = NULL;
    PNDIS_PACKET        Packet = NULL;
    PTCB                pTCB = NULL;
    
    DEBUGP(MP_TRACE, ("--> NICFreeBusySendPackets\n"));

    if(!MP_TEST_FLAG(Adapter, fMP_SEND_SIDE_RESOURCE_ALLOCATED)){
        return;
    }        

    NdisAcquireSpinLock(&Adapter->SendLock);
    
    while(!IsListEmpty(&Adapter->SendBusyList))
    {
        pEntry = (PLIST_ENTRY)RemoveHeadList(&Adapter->SendBusyList);

        pTCB = CONTAINING_RECORD(pEntry, TCB, List);
        NdisInitializeListHead(&pTCB->List);

        NdisReleaseSpinLock(&Adapter->SendLock); 
        
        if (InterlockedExchange((PVOID)&pTCB->IrpLock, IRPLOCK_CANCEL_STARTED) 
                                        == IRPLOCK_CANCELABLE) {

            // 
            // we got it to the IRP before it was completed. We can cancel
            // the IRP without fear of losing it, as the completion routine
            // will not let go of the IRP until we say so.
            // 
            IoCancelIrp(pTCB->Irp);
            // 
            // Release the completion routine. If it already got there,
            // then we need to free it yourself. Otherwise, we got
            // through IoCancelIrp before the IRP completed entirely.
            // 
            if (InterlockedExchange((PVOID)&pTCB->IrpLock, IRPLOCK_CANCEL_COMPLETE)
                                        == IRPLOCK_COMPLETED) {
                                        
                if(NdisInterlockedDecrement(&pTCB->Ref) == 0) {
                    
                    DEBUGP(MP_VERY_LOUD, ("Calling NdisMSendComplete \n"));

                    NdisMSendComplete(Adapter->AdapterHandle,
                                        pTCB->OrgSendPacket,
                                        NDIS_STATUS_SUCCESS); 
                    //
                    // Initialize the head so that we don't barf in NICFreeSendTCB
                    // while doing RemoveEntryList.
                    //
                    NdisInitializeListHead(&pTCB->List);                    
                    
                    NICFreeSendTCB(Adapter, pTCB);        
                }else {
                    ASSERTMSG("Only we have the right to free TCB\n", FALSE);                
                }
            }

        }

        NdisAcquireSpinLock(&Adapter->SendLock);
        
    }

    NdisReleaseSpinLock(&Adapter->SendLock); 

    DEBUGP(MP_TRACE, ("<-- NICFreeBusySendPackets\n"));
     
    return ;
}



VOID 
NICFreeSendTCB(
    IN PMP_ADAPTER Adapter,
    IN PTCB pTCB)
/*++

Routine Description:

    Adapter    - pointer to the adapter structure
    pTCB      - pointer to TCB block
        
Arguments:

    This routine reinitializes the TCB block and puts it back
    into the SendFreeList for reuse.
    

Return Value:

    VOID

--*/
{
    DEBUGP(MP_TRACE, ("--> NICFreeSendTCB %p\n", pTCB));
    
    pTCB->OrgSendPacket = NULL;
    pTCB->Buffer->Next = NULL;
    pTCB->Mdl = NULL;
    
    ASSERT(pTCB->Irp);    
    ASSERT(!pTCB->Ref);

    //
    // Reinitialize the IRP for reuse.
    //
    IoReuseIrp(pTCB->Irp, STATUS_SUCCESS);    

    // 
    // Set the MDL field to NULL so that we don't end up free the
    // MDL in our call to IoFreeIrp.
    // 
      
    pTCB->Irp->MdlAddress = NULL;
    
    //
    // Re adjust the length to the originl size
    //
    NdisAdjustBufferLength(pTCB->Buffer, NIC_BUFFER_SIZE);

    //
    // Insert the TCB back in the send free list     
    //
    NdisAcquireSpinLock(&Adapter->SendLock);
    
    RemoveEntryList(&pTCB->List);
    
    InsertTailList(&Adapter->SendFreeList, &pTCB->List);

    NdisInterlockedDecrement(&Adapter->nBusySend);
    ASSERT(Adapter->nBusySend >= 0);
    
    NdisReleaseSpinLock(&Adapter->SendLock); 


    DEBUGP(MP_TRACE, ("<-- NICFreeSendTCB\n"));
    
}



VOID 
NICFreeQueuedSendPackets(
    PMP_ADAPTER Adapter
    )
/*++

Routine Description:

    This routine is called by the Halt handler to fail all
    the queued up SendPackets because the device is either
    gone, being stopped for resource rebalance.
    
Arguments:

    Adapter    - pointer to the adapter structure

Return Value:

    VOID

--*/
{
    PLIST_ENTRY       pEntry = NULL;
    PNDIS_PACKET      Packet = NULL;

    DEBUGP(MP_TRACE, ("--> NICFreeQueuedSendPackets\n"));
 
    while(MP_TEST_FLAG(Adapter, fMP_SEND_SIDE_RESOURCE_ALLOCATED))
    {
        pEntry = (PLIST_ENTRY) NdisInterlockedRemoveHeadList(
                        &Adapter->SendWaitList, 
                        &Adapter->SendLock);
        if(!pEntry)
        {
            break;
        }

        Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);
        NdisMSendComplete(
            Adapter->AdapterHandle,
            Packet,
            NDIS_STATUS_FAILURE);
    }

    DEBUGP(MP_TRACE, ("<-- NICFreeQueuedSendPackets\n"));

}

BOOLEAN
NICCopyPacket(
    PMP_ADAPTER Adapter,
    PTCB pTCB, 
    PNDIS_PACKET Packet)
/*++

Routine Description:

    This routine copies the packet data into the TCB data block and
    inserts the TCB in the SendBusyList.
        
Arguments:

    Adapter    - pointer to the MP_ADAPTER structure
    pTCB      - pointer to TCB block
    Packet    - packet to be transfered.


Return Value:

    VOID

--*/
{
    PNDIS_BUFFER   CurrentBuffer = NULL;
    PVOID          VirtualAddress = NULL;
    UINT           CurrentLength;
    UINT           BytesToCopy;
    UINT           BytesCopied = 0;
    UINT           PacketLength;      
    PUCHAR         pDest = pTCB->pData;
    BOOLEAN        bResult = TRUE, bPadding = FALSE;
    PETH_HEADER    pEthHeader;
    UINT           DestBufferSize = NIC_BUFFER_SIZE;        
        
    DEBUGP(MP_TRACE, ("--> NICCopyPacket\n"));

    //
    // Initialize TCB structure
    //
    pTCB->OrgSendPacket = Packet;
    pTCB->Ref = 1;
    NdisInitializeListHead(&pTCB->List);

    //
    // Query the packet to get length and pointer to the first buffer.
    //    
    NdisQueryPacket(Packet,
                    NULL,
                    NULL,
                    &CurrentBuffer,
                    &PacketLength);

    ASSERT(PacketLength <= NIC_BUFFER_SIZE);

    PacketLength = min(PacketLength, NIC_BUFFER_SIZE); 
    
    if(PacketLength < ETH_MIN_PACKET_SIZE)
    {
        PacketLength = ETH_MIN_PACKET_SIZE;   // padding
        bPadding = TRUE;
    }

    if(Adapter->TargetSupportsChainedMdls 
                    && bPadding == FALSE) {
        //
        // If the lower driver supports chained MDLs, we will 
        // assign the MDL to the request and send it down. However if
        // the packet is less than 60 bytes, we need to pad zero to
        // make it atleast 60bytes long. In that case we will just use
        // our preallocated flat buffer. If this driver is adapted for
        // a real device, the user should only preallocate 60 bytes TCB
        // Buffer instead of NIC_BUFFER_SIZE.
        //
        pTCB->Mdl = (PMDL)CurrentBuffer;
        pTCB->ulSize = PacketLength;
        Adapter->nBytesArrived += PacketLength;
        
    } else {

        BytesToCopy = PacketLength;
        
        //
        // Copy the data from chained buffers to our TCB flat buffer.
        //
        while(CurrentBuffer)
        {
            NdisQueryBufferSafe(
                CurrentBuffer,
                &VirtualAddress,
                &CurrentLength,
                NormalPagePriority);
            
            if(!VirtualAddress) {
                bResult = FALSE;
                break;                
            }

            CurrentLength = min(CurrentLength, DestBufferSize);         
            
            if(CurrentLength)
            {
                // Copy the data.
                NdisMoveMemory(pDest, VirtualAddress, CurrentLength);
                BytesCopied += CurrentLength;
                DestBufferSize -= CurrentLength;            
                pDest += CurrentLength;
            }

            NdisGetNextBuffer(
                CurrentBuffer,
                &CurrentBuffer);
        }


        if(bResult) {

            Adapter->nBytesArrived += BytesCopied;
            
            //
            // If the packet size is less than ETH_MIN_PACKET_SIZE. Pad the buffer
            // up to ETH_MIN_PACKET_SIZE with zero bytes for security reason.
            //
            if(BytesCopied < BytesToCopy)
            {
                NdisZeroMemory(pDest, BytesToCopy-BytesCopied);
                BytesCopied = BytesToCopy;
            }

            //
            // Adjust the buffer length to reflect the new length
            //
            NdisAdjustBufferLength(pTCB->Buffer, BytesCopied);       
            pTCB->ulSize = BytesCopied;

            pTCB->Mdl = pTCB->Buffer;
            
            if(PacketLength >= sizeof(ETH_HEADER)) {
                
                pEthHeader = (PETH_HEADER)pTCB->pData;
                
                //memcpy(pEthHeader->SrcAddr, Adapter->PhyNicMacAddress, 
                //                ETH_LENGTH_OF_ADDRESS);  
                
                DEBUGP(MP_LOUD, ("Src Address = %02x-%02x-%02x-%02x-%02x-%02x", 
                    pEthHeader->SrcAddr[0],
                    pEthHeader->SrcAddr[1],
                    pEthHeader->SrcAddr[2],
                    pEthHeader->SrcAddr[3],
                    pEthHeader->SrcAddr[4],
                    pEthHeader->SrcAddr[5]));

                DEBUGP(MP_LOUD, ("  Dest Address = %02x-%02x-%02x-%02x-%02x-%02x\n", 
                    pEthHeader->DstAddr[0],
                    pEthHeader->DstAddr[1],
                    pEthHeader->DstAddr[2],
                    pEthHeader->DstAddr[3],
                    pEthHeader->DstAddr[4],
                    pEthHeader->DstAddr[5]));
                    
            }else{
                ASSERTMSG("Packet length is less than ETH_HEADER\n", FALSE);
                bResult = FALSE;
            }
        }
    }
    
    if(bResult){
        
        NdisInterlockedInsertTailList(
                            &Adapter->SendBusyList, 
                            &pTCB->List, 
                            &Adapter->SendLock);

    }
    
    DEBUGP(MP_TRACE, ("<-- NICCopyPacket\n"));
    return bResult;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -