亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? mp_nic.c

?? Intel EtherExpressTM PRO/100+ Ethernet 網(wǎng)卡在Windows2000/xp下的PCI驅動程序源代碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/*++

Copyright (c) 1999  Microsoft Corporation

Module Name:
    mp_nic.c

Abstract:
    This module contains miniport send/receive routines

Revision History:
    Who         When        What
    --------    --------    ----------------------------------------------
    DChen       11-01-99    created

Notes:

--*/

#include "precomp.h"

#if DBG
#define _FILENUMBER     'CINM'
#endif

__inline VOID MP_FREE_SEND_PACKET(
    IN  PMP_ADAPTER Adapter,
    IN  PMP_TCB     pMpTcb
    )
/*++
Routine Description:

    Recycle a MP_TCB and complete the packet if necessary
    Assumption: Send spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter
    pMpTcb      Pointer to MP_TCB        

Return Value:

    None

--*/
{
    
    PNDIS_PACKET  Packet;
    PNDIS_BUFFER  CurrBuffer;

    ASSERT(MP_TEST_FLAG(pMpTcb, fMP_TCB_IN_USE));

    Packet = pMpTcb->Packet;
    pMpTcb->Packet = NULL;
    pMpTcb->Count = 0;

    if (pMpTcb->MpTxBuf)
    {
        ASSERT(MP_TEST_FLAG(pMpTcb, fMP_TCB_USE_LOCAL_BUF));

        PushEntryList(&Adapter->SendBufList, &pMpTcb->MpTxBuf->SList);
        pMpTcb->MpTxBuf = NULL;
    }
    MP_CLEAR_FLAGS(pMpTcb);

    Adapter->CurrSendHead = Adapter->CurrSendHead->Next;
    Adapter->nBusySend--;
    ASSERT(Adapter->nBusySend >= 0);

    if (Packet)
    {
        NdisReleaseSpinLock(&Adapter->SendLock);
        DBGPRINT(MP_TRACE, ("Calling NdisMSendComplete, Pkt= "PTR_FORMAT"\n", Packet));
        NdisMSendComplete(
            MP_GET_ADAPTER_HANDLE(Adapter),
            Packet,
            NDIS_STATUS_SUCCESS);

        NdisAcquireSpinLock(&Adapter->SendLock);
    }
}

NDIS_STATUS MpSendPacket(
    IN  PMP_ADAPTER   Adapter,
    IN  PNDIS_PACKET  Packet,
    IN  BOOLEAN       bFromQueue
    )
/*++
Routine Description:

    Do the work to send a packet
    Assumption: Send spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter
    Packet      The packet
    bFromQueue  TRUE if it's taken from the send wait queue

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_PENDING         Put into the send wait queue
    NDIS_STATUS_HARD_ERRORS

--*/
{
    NDIS_STATUS     Status = NDIS_STATUS_PENDING;
    PMP_TCB         pMpTcb = NULL;
    PMP_TXBUF       pMpTxBuf = NULL;
    ULONG           BytesCopied;
    
    // Mimiced frag list if the packet is too small or too fragmented.                                         
    MP_FRAG_LIST    FragList;
    
    // Pointer to either the scatter gather or the local mimiced frag list
    PMP_FRAG_LIST   pFragList;

    DBGPRINT(MP_TRACE, ("--> MpSendPacket, Pkt= "PTR_FORMAT"\n", Packet));

    pMpTcb = Adapter->CurrSendTail;
    ASSERT(!MP_TEST_FLAG(pMpTcb, fMP_TCB_IN_USE));

    NdisQueryPacket(
        Packet,
        (PUINT)&pMpTcb->PhysBufCount,
        (PUINT)&pMpTcb->BufferCount,
        &pMpTcb->FirstBuffer,
        (PUINT)&pMpTcb->PacketLength);

    ASSERT(pMpTcb->PhysBufCount);
    ASSERT(pMpTcb->FirstBuffer);
    ASSERT(pMpTcb->PacketLength);

    //
    // Check to see if we need to coalesce
    //
    if (pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE ||
        pMpTcb->PhysBufCount > NIC_MAX_PHYS_BUF_COUNT)
    {
        //
        // A local MP_TXBUF available (for local data copying)?
        //
        if (IsSListEmpty(&Adapter->SendBufList))
        {
            Adapter->nWaitSend++;
            if (bFromQueue)
            {
                InsertHeadQueue(&Adapter->SendWaitQueue, MP_GET_PACKET_MR(Packet));
            }
            else
            {
                InsertTailQueue(&Adapter->SendWaitQueue, MP_GET_PACKET_MR(Packet));
            }

            DBGPRINT(MP_TRACE, ("<-- MpSendPacket - queued, no buf\n"));
            return Status;
        }

        pMpTxBuf = (PMP_TXBUF) PopEntryList(&Adapter->SendBufList);   
        ASSERT(pMpTxBuf);

        //
        // Copy the buffers in this packet, enough to give the first buffer as they are linked
        //
        BytesCopied = MpCopyPacket(pMpTcb->FirstBuffer, pMpTxBuf);
        
        //
        // MpCopyPacket may return 0 if system resources are low or exhausted
        //
        if (BytesCopied == 0)
        {
            PushEntryList(&Adapter->SendBufList, &pMpTxBuf->SList);
        
            DBGPRINT(MP_ERROR, ("Calling NdisMSendComplete with NDIS_STATUS_RESOURCES, Pkt= "PTR_FORMAT"\n", Packet));
    
            NdisReleaseSpinLock(&Adapter->SendLock); 
            NdisMSendComplete(
                MP_GET_ADAPTER_HANDLE(Adapter),
                Packet,
                NDIS_STATUS_RESOURCES);
    
            NdisAcquireSpinLock(&Adapter->SendLock);  
            return NDIS_STATUS_RESOURCES;            
        }

        pMpTcb->MpTxBuf = pMpTxBuf; 

        //
        // Set up the frag list, only one fragment after it's coalesced
        //
        pFragList = &FragList;
        pFragList->NumberOfElements = 1;
        pFragList->Elements[0].Address = pMpTxBuf->BufferPa;
        pFragList->Elements[0].Length = (BytesCopied >= NIC_MIN_PACKET_SIZE) ? 
                                        BytesCopied : NIC_MIN_PACKET_SIZE;
        
        MP_SET_FLAG(pMpTcb, fMP_TCB_USE_LOCAL_BUF);
        //
        // Even the driver uses its local buffer, it has to wait the send complete interrupt to
        // complete the packet. Otherwise, the driver may run into the following situation:
        // before send complete interrupt happens, its halt handler is called and the halt handler 
        // deregisters the interrupt, so no send complete interrupt can happen, and the send 
        // complete interrupt handle routine will never be called to free some resources used 
        // by this send. 
        
    }
    else
    {
        ASSERT(MP_TEST_FLAG(Adapter, fMP_ADAPTER_SCATTER_GATHER));
        //
        // In scatter/gather case, use the frag list pointer saved 
        // in the packet info field
        //
        pFragList = (PMP_FRAG_LIST) NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, 
                                                           ScatterGatherListPacketInfo);

    }

    pMpTcb->Packet = Packet;
    MP_SET_FLAG(pMpTcb, fMP_TCB_IN_USE);

    //
    // Call the NIC specific send handler, it only needs to deal with the frag list
    //
    Status = NICSendPacket(Adapter, pMpTcb, pFragList);

    Adapter->nBusySend++;
    ASSERT(Adapter->nBusySend <= Adapter->NumTcb);
    Adapter->CurrSendTail = Adapter->CurrSendTail->Next;

    DBGPRINT(MP_TRACE, ("<-- MpSendPacket\n"));
    return Status;

}  

ULONG MpCopyPacket(
    IN  PNDIS_BUFFER  CurrBuffer,
    IN  PMP_TXBUF     pMpTxBuf
    ) 
/*++
Routine Description:

    Copy the packet data to a local buffer
    Either the packet is too small or it has too many fragments
    Assumption: Send spinlock has been acquired 

Arguments:

    CurrBuffer  Pointer to the first NDIS_BUFFER    
    pMpTxBuf    Pointer to the local buffer (MP_TXBUF)

Return Value:

    Bytes copied

--*/
{
    UINT    CurrLength;
    PUCHAR  pSrc;
    PUCHAR  pDest;
    UINT    BytesCopied = 0;

    DBGPRINT(MP_TRACE, ("--> MpCopyPacket\n"));

    pDest = pMpTxBuf->pBuffer;

    while ((CurrBuffer) && (BytesCopied < pMpTxBuf->BufferSize))
    {

        //
        // Support for the following API with NormalPagePrioirty was added for 
        // NDIS 5.0 and 5.1 miniports in Windows XP
        //
#if !BUILD_W2K
	NdisQueryBufferSafe( CurrBuffer, &pSrc, &CurrLength, NormalPagePriority );
#else
	NdisQueryBuffer( CurrBuffer, &pSrc, &CurrLength);	
#endif

        if (pSrc == NULL)
        {
            return 0;
        }

        
        if (pMpTxBuf->BufferSize - BytesCopied < CurrLength)
        {
            CurrLength = pMpTxBuf->BufferSize - BytesCopied;
        }
                    
        if (CurrLength)
        {
            //
            // Copy the data.
            //
            NdisMoveMemory(pDest, pSrc, CurrLength);
            BytesCopied += CurrLength;
            pDest += CurrLength;
        }

        NdisGetNextBuffer( CurrBuffer, &CurrBuffer);
    }
    //
    // Zero out the padding bytes
    // 
    if (BytesCopied < NIC_MIN_PACKET_SIZE)
    {
        NdisZeroMemory(pDest, NIC_MIN_PACKET_SIZE - BytesCopied);
    }

    NdisAdjustBufferLength(pMpTxBuf->NdisBuffer, BytesCopied);

    NdisFlushBuffer(pMpTxBuf->NdisBuffer, TRUE);

    ASSERT(BytesCopied <= pMpTxBuf->BufferSize);

    DBGPRINT(MP_TRACE, ("<-- MpCopyPacket\n"));

    return BytesCopied;
}


NDIS_STATUS NICSendPacket(
    IN  PMP_ADAPTER     Adapter,
    IN  PMP_TCB         pMpTcb,
    IN  PMP_FRAG_LIST   pFragList
    )
/*++
Routine Description:

    NIC specific send handler
    Assumption: Send spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter
    pMpTcb      Pointer to MP_TCB
    pFragList   The pointer to the frag list to be filled

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_HARD_ERRORS

--*/
{
    NDIS_STATUS  Status;
    ULONG        index;
    UCHAR        TbdCount = 0;

    PHW_TCB      pHwTcb = pMpTcb->HwTcb;
    PTBD_STRUC   pHwTbd = pMpTcb->HwTbd;

    DBGPRINT(MP_TRACE, ("--> NICSendPacket\n"));

    for (index = 0; index < pFragList->NumberOfElements; index++)
    {
        if (pFragList->Elements[index].Length)
        {
            pHwTbd->TbdBufferAddress = NdisGetPhysicalAddressLow(pFragList->Elements[index].Address);
            pHwTbd->TbdCount = pFragList->Elements[index].Length;

            pHwTbd++;                    
            TbdCount++;   
        }
    }

    pHwTcb->TxCbHeader.CbStatus = 0;
    pHwTcb->TxCbHeader.CbCommand = CB_S_BIT | CB_TRANSMIT | CB_TX_SF_BIT;

    pHwTcb->TxCbTbdPointer = pMpTcb->HwTbdPhys;
    pHwTcb->TxCbTbdNumber = TbdCount;
    pHwTcb->TxCbCount = 0;
    pHwTcb->TxCbThreshold = (UCHAR) Adapter->AiThreshold;

    Status = NICStartSend(Adapter, pMpTcb);

    DBGPRINT(MP_TRACE, ("<-- NICSendPacket\n"));

    return Status;
}

NDIS_STATUS NICStartSend(
    IN  PMP_ADAPTER  Adapter,
    IN  PMP_TCB      pMpTcb
    )
/*++
Routine Description:

    Issue a send command to the NIC
    Assumption: Send spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter
    pMpTcb      Pointer to MP_TCB

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_HARD_ERRORS

--*/
{
    NDIS_STATUS     Status;

    DBGPRINT(MP_TRACE, ("--> NICStartSend\n"));

    //
    // If the transmit unit is idle (very first transmit) then we must
    // setup the general pointer and issue a full CU-start
    //
    if (Adapter->TransmitIdle)
    {
        
        DBGPRINT(MP_INFO,  ("CU is idle -- First TCB added to Active List\n"));

        //
        // Wait for the SCB to clear before we set the general pointer
        //
        if (!WaitScb(Adapter))
        {
            Status = NDIS_STATUS_HARD_ERRORS;
            MP_EXIT;
        }

        //
        // Don't try to start the transmitter if the command unit is not
        // idle ((not idle) == (Cu-Suspended or Cu-Active)).
        //
        if ((Adapter->CSRAddress->ScbStatus & SCB_CUS_MASK) != SCB_CUS_IDLE)
        {
            DBGPRINT(MP_ERROR, ("Adapter = "PTR_FORMAT", CU Not IDLE\n", Adapter));
            MP_SET_HARDWARE_ERROR(Adapter);
            NdisStallExecution(25);
        }

        Adapter->CSRAddress->ScbGeneralPointer = pMpTcb->HwTcbPhys;

        Status = D100IssueScbCommand(Adapter, SCB_CUC_START, FALSE);

        Adapter->TransmitIdle = FALSE;
        Adapter->ResumeWait = TRUE;
    }
    else
    {
        //
        // If the command unit has already been started, then append this
        // TCB onto the end of the transmit chain, and issue a CU-Resume.
        //
        DBGPRINT(MP_LOUD, ("adding TCB to Active chain\n"));

        //
        // Clear the suspend bit on the previous packet.
        //
        pMpTcb->PrevHwTcb->TxCbHeader.CbCommand &= ~CB_S_BIT;

        //
        // Issue a CU-Resume command to the device.  We only need to do a
        // WaitScb if the last command was NOT a RESUME.
        //
        Status = D100IssueScbCommand(Adapter, SCB_CUC_RESUME, Adapter->ResumeWait);
    }

    exit:
                      
    DBGPRINT(MP_TRACE, ("<-- NICStartSend\n"));

    return Status;
}

NDIS_STATUS MpHandleSendInterrupt(
    IN  PMP_ADAPTER  Adapter
    )
/*++
Routine Description:

    Interrupt handler for sending processing
    Re-claim the send resources, complete sends and get more to send from the send wait queue
    Assumption: Send spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter

Return Value:

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91色九色蝌蚪| 韩国毛片一区二区三区| 91香蕉视频mp4| 最新日韩在线视频| 91福利视频在线| 五月天精品一区二区三区| 日韩一区二区三区在线观看| 另类的小说在线视频另类成人小视频在线| 亚洲另类色综合网站| 色综合天天综合在线视频| 亚洲自拍偷拍图区| 欧美美女一区二区在线观看| 久久电影网电视剧免费观看| 国产精品亲子乱子伦xxxx裸| 91成人免费网站| 免费一级欧美片在线观看| 久久色.com| 日本伦理一区二区| 久久激情综合网| 国产精品久久久久久久久果冻传媒| 色综合色狠狠综合色| 免费在线观看成人| 亚洲视频免费在线观看| 91.xcao| 风间由美一区二区三区在线观看 | 欧美精品久久99| 九九**精品视频免费播放| 日本一区免费视频| 欧美日韩激情一区二区| 国产成人在线影院| 香蕉加勒比综合久久| 久久蜜桃av一区二区天堂 | 91精品国产综合久久婷婷香蕉| 黄色日韩网站视频| 一区二区三区四区激情| 欧美大片在线观看| 色婷婷av一区二区三区大白胸| 久久69国产一区二区蜜臀| 亚洲欧美综合另类在线卡通| 日韩精品一区二区三区在线| 色婷婷综合久久久| 高清不卡一区二区| 麻豆国产91在线播放| 亚洲一二三级电影| 国产精品天美传媒沈樵| 日韩视频免费观看高清完整版在线观看 | 欧美午夜精品久久久久久超碰| 久久超碰97中文字幕| 一区二区三区四区蜜桃| 欧美激情一区二区三区在线| 91精品国产综合久久久蜜臀图片| a级精品国产片在线观看| 精品一区二区免费| 日本中文字幕一区二区视频| 亚洲精品国产精华液| 亚洲国产激情av| 久久影音资源网| 精品欧美黑人一区二区三区| 欧美亚洲日本国产| 色综合色狠狠综合色| 99久久婷婷国产综合精品电影| 91麻豆成人久久精品二区三区| 波波电影院一区二区三区| 日本一区二区不卡视频| 精品久久五月天| 欧美一区二区三区在线观看| 国产精品久久影院| 国产亚洲一区二区三区| 欧美一区永久视频免费观看| 欧美亚洲一区二区在线观看| 在线免费观看日本欧美| 99re8在线精品视频免费播放| 高清不卡一二三区| 成人av午夜影院| 成人av网站在线| 懂色av噜噜一区二区三区av| 粉嫩绯色av一区二区在线观看| 国产精品自在在线| 激情综合网最新| 国产美女娇喘av呻吟久久| 国产自产v一区二区三区c| 国产一区二区三区国产| 国产精华液一区二区三区| 国产精品综合一区二区三区| 国产精品一区免费视频| 成人综合婷婷国产精品久久蜜臀| 成人午夜私人影院| 91在线视频播放地址| 色综合久久久久久久久| 在线看国产日韩| 欧美久久久久久蜜桃| 日韩欧美一级二级三级久久久| 欧美va日韩va| 国产欧美精品在线观看| 国产精品国产三级国产| 亚洲一线二线三线视频| 婷婷一区二区三区| 国产一区二区三区蝌蚪| av激情综合网| 欧美人与性动xxxx| 精品对白一区国产伦| 中文字幕亚洲精品在线观看| 亚洲国产精品久久人人爱蜜臀| 蜜臀av性久久久久蜜臀aⅴ四虎 | 粉嫩aⅴ一区二区三区四区 | 91精品欧美一区二区三区综合在| 日韩免费在线观看| 国产精品久久久久久久久久久免费看| 亚洲欧美日韩小说| 久久精品久久99精品久久| 国产成人免费网站| 国产精品美女久久久久久久| 亚洲最新视频在线观看| 免费成人在线观看视频| 波多野结衣中文一区| 欧美三级视频在线| 欧美精品一区视频| 一区二区三区在线视频免费观看| 蜜芽一区二区三区| 色综合天天性综合| 精品噜噜噜噜久久久久久久久试看| 国产精品每日更新在线播放网址| 性久久久久久久久久久久| 国产成人久久精品77777最新版本| 色综合久久99| 久久久不卡网国产精品一区| 亚洲第一电影网| 成人app软件下载大全免费| 欧美日韩精品一区二区三区四区 | 国产精品免费视频网站| 亚洲高清中文字幕| 成人精品鲁一区一区二区| 在线播放日韩导航| 亚洲精选在线视频| 国产成人欧美日韩在线电影| 欧美日韩成人一区| 亚洲精品久久7777| 不卡一区二区中文字幕| ww亚洲ww在线观看国产| 亚洲成人免费av| 99免费精品在线| 国产日韩欧美a| 国产在线精品视频| 91精品福利在线一区二区三区 | 成人综合婷婷国产精品久久| 欧美一区二区三区免费| 一区二区免费在线播放| 91在线观看污| 国产在线精品免费| 欧美高清视频一二三区| 亚洲激情网站免费观看| 国产一区中文字幕| 日韩一区二区精品葵司在线| 亚洲国产精品嫩草影院| 欧美在线色视频| 亚洲乱码国产乱码精品精的特点 | 97精品久久久久中文字幕 | 亚洲三级电影网站| gogogo免费视频观看亚洲一| wwwwxxxxx欧美| 国产一区二区三区黄视频| 欧美哺乳videos| 久久se精品一区精品二区| 日韩三级免费观看| 蜜臀a∨国产成人精品| 91精品国产色综合久久ai换脸| 日韩在线一二三区| 91精品国产91久久综合桃花| 日韩国产一区二| 欧美一级搡bbbb搡bbbb| 美女www一区二区| 精品精品国产高清a毛片牛牛| 久久成人18免费观看| 国产欧美一区二区三区在线老狼| 国产suv精品一区二区三区| 欧美国产乱子伦| 91网站在线观看视频| 亚洲一区二区三区中文字幕在线| 在线观看视频欧美| 免费欧美日韩国产三级电影| 久久影院午夜论| 成人动漫一区二区| 亚洲一区在线观看免费 | 精品久久久久香蕉网| 精品一区二区三区在线视频| 精品国产91乱码一区二区三区| 国产麻豆精品视频| 亚洲日本va午夜在线影院| 在线亚洲人成电影网站色www| 亚洲高清免费观看| 日韩亚洲欧美在线| 国产乱人伦偷精品视频免下载| 国产精品久久一级| 精品婷婷伊人一区三区三| 美腿丝袜亚洲一区| 国产精品久久久久久久久久免费看| 色一情一伦一子一伦一区| 日韩国产精品大片| 国产精品久久久久影视| 欧美色大人视频|