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

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

?? mp_nic.c

?? Intel EtherExpressTM PRO/100+ Ethernet 網卡在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一区二区三区免费野_久草精品视频
中文字幕第一页久久| 欧美亚洲综合一区| 97久久超碰精品国产| 精品国产一区二区在线观看| 亚洲图片一区二区| 日本乱人伦aⅴ精品| 亚洲婷婷综合久久一本伊一区| 日韩中文字幕1| 在线不卡免费av| 日韩中文字幕1| 在线欧美一区二区| 亚洲日本电影在线| 欧美日韩在线播放三区四区| 亚洲精品国产视频| 91精品国产品国语在线不卡| 蜜桃视频在线一区| 欧洲一区二区三区在线| 日本最新不卡在线| 精品少妇一区二区三区日产乱码 | 欧美性猛交xxxxxxxx| 亚洲图片有声小说| 67194成人在线观看| 亚洲天堂网中文字| 欧美一区二区三区在线电影| 男男gaygay亚洲| 国产精品传媒视频| 色成人在线视频| 亚洲成人av一区二区| 精品国产人成亚洲区| 国产米奇在线777精品观看| 国产尤物一区二区| 国产精品网站在线播放| 蜜臀久久99精品久久久久宅男| 26uuu国产在线精品一区二区| 国产精品一区在线| 亚洲第一主播视频| 久久综合狠狠综合久久综合88 | 国产一区激情在线| 亚洲激情欧美激情| 精品乱人伦小说| av在线播放成人| 久久91精品久久久久久秒播| 国产午夜亚洲精品羞羞网站| 色婷婷av久久久久久久| 麻豆精品国产91久久久久久| 久久欧美一区二区| 91精品国产一区二区三区香蕉| 精品在线观看免费| 一级日本不卡的影视| 欧美精品一区二区三区视频| www.欧美日韩| 精品一区二区国语对白| 成人欧美一区二区三区| 精品1区2区在线观看| 色综合久久中文综合久久97| 日韩av中文在线观看| 亚洲精品国产一区二区精华液| 日韩一级二级三级| 91精品国产综合久久婷婷香蕉 | 亚洲激情校园春色| 欧美国产97人人爽人人喊| 6080午夜不卡| 成人黄色小视频在线观看| 日韩国产精品大片| 中文字幕在线不卡视频| 国产日韩欧美高清| 日韩亚洲欧美综合| 在线播放91灌醉迷j高跟美女| 东方欧美亚洲色图在线| 无码av免费一区二区三区试看| 亚洲色图视频网站| 久久久青草青青国产亚洲免观| 欧美一区二区三区婷婷月色| 91视视频在线观看入口直接观看www | 精品美女一区二区三区| 欧美影院精品一区| 欧美在线你懂得| 国产凹凸在线观看一区二区| 国产揄拍国内精品对白| 秋霞电影网一区二区| 婷婷中文字幕综合| 亚洲一区视频在线| 亚洲图片你懂的| 亚洲欧美精品午睡沙发| 中文在线资源观看网站视频免费不卡| 久久精品一级爱片| 2024国产精品视频| 国产视频一区在线观看| 美女国产一区二区三区| 久久精品国产亚洲a| 免费精品视频最新在线| 亚洲免费在线观看| 亚洲综合图片区| 一区二区免费视频| 首页国产欧美久久| 香蕉av福利精品导航| 视频一区视频二区中文| 午夜精品久久久久久| 中文字幕亚洲一区二区va在线| 亚洲欧洲综合另类在线| 中文字幕亚洲成人| 偷拍自拍另类欧美| 日韩va欧美va亚洲va久久| 韩国v欧美v亚洲v日本v| 国产精品一区免费在线观看| 国产精品99久| 欧美性大战久久久久久久蜜臀| 91一区二区在线| 91黄色免费网站| 欧美日韩大陆在线| 欧美成人aa大片| 精品对白一区国产伦| 久久一区二区视频| 中文在线资源观看网站视频免费不卡| 国产精品污污网站在线观看| 亚洲va欧美va人人爽| 午夜电影一区二区三区| 麻豆成人av在线| 国产成人av电影在线观看| 99精品黄色片免费大全| 制服丝袜一区二区三区| 久久综合网色—综合色88| 亚洲你懂的在线视频| 亚洲成精国产精品女| 亚洲电影视频在线| 懂色av中文字幕一区二区三区| 95精品视频在线| 久久亚洲综合色| 亚洲欧美日韩综合aⅴ视频| 日韩成人伦理电影在线观看| 国产精品系列在线观看| 日本韩国视频一区二区| 日韩丝袜情趣美女图片| 国产精品久久久久永久免费观看 | 91精品久久久久久久99蜜桃 | 麻豆精品一二三| 91久久一区二区| 久久久精品日韩欧美| 一色屋精品亚洲香蕉网站| 免费不卡在线视频| av综合在线播放| ww亚洲ww在线观看国产| 亚洲成av人片观看| 一本色道久久综合狠狠躁的推荐| 884aa四虎影成人精品一区| 亚洲三级小视频| 久久99精品国产麻豆婷婷洗澡| 91尤物视频在线观看| 欧美va日韩va| 亚洲自拍偷拍网站| 91在线观看地址| 欧美精品一区二| 男人的天堂久久精品| 91网页版在线| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 日韩中文字幕91| 欧美日韩一区二区欧美激情| 国产欧美日韩麻豆91| 亚洲欧洲制服丝袜| 9久草视频在线视频精品| 日韩一级完整毛片| 日韩电影一区二区三区| 国产美女精品一区二区三区| 国产一区二区三区免费看| 国产一区二区美女| 日韩精品中文字幕在线不卡尤物| 亚洲视频网在线直播| 91在线观看下载| 日本一区二区三区国色天香| 国产美女在线精品| 精品免费日韩av| 国产美女精品人人做人人爽| 欧美一区午夜精品| 亚洲美女免费视频| 色综合中文字幕| 精品动漫一区二区三区在线观看| 久久精品二区亚洲w码| 欧美日韩久久久一区| 日本成人中文字幕| 欧美亚洲免费在线一区| 亚洲成av人片| 在线免费不卡电影| 亚洲成av人片观看| 欧美裸体一区二区三区| 亚洲人成小说网站色在线| 成人激情综合网站| 精品国产免费人成电影在线观看四季| 久久国产精品色婷婷| 91精品啪在线观看国产60岁| 精品一区二区国语对白| 精品国产免费一区二区三区香蕉| 福利91精品一区二区三区| 久久久蜜桃精品| 色综合网色综合| 亚洲综合一二区| 精品少妇一区二区三区视频免付费 | 精品理论电影在线| 久久99久久久欧美国产| 国产日韩视频一区二区三区| 成人视屏免费看|