コード例 #1
0
void CParaNdisTX::Send(PNET_BUFFER_LIST NBL)
{
    PNET_BUFFER_LIST nextNBL = nullptr;

    for(auto currNBL = NBL; currNBL != nullptr; currNBL = nextNBL)
    {
        nextNBL = NET_BUFFER_LIST_NEXT_NBL(currNBL);
        NET_BUFFER_LIST_NEXT_NBL(currNBL) = nullptr;

        auto NBLHolder = new (m_Context->MiniportHandle) CNBL(currNBL, m_Context, *this);

        if (NBLHolder == nullptr)
        {
            CNBL OnStack(currNBL, m_Context, *this);
            OnStack.SetStatus(NDIS_STATUS_RESOURCES);
            DPrintf(0, ("ERROR: Failed to allocate CNBL instance\n"));
            continue;
        }

        if(NBLHolder->Prepare() &&
           ParaNdis_IsSendPossible(m_Context))
        {
            NBLHolder->StartMapping();
        }
        else
        {
            NBLHolder->SetStatus(ParaNdis_ExactSendFailureStatus(m_Context));
            NBLHolder->Release();
        }
    }
}
コード例 #2
0
void CParaNdisTX::Send(PNET_BUFFER_LIST NBL)
{
    PNET_BUFFER_LIST nextNBL = nullptr;
    NDIS_STATUS RejectionStatus = NDIS_STATUS_FAILURE;

    if (!m_StateMachine.RegisterOutstandingItems(ParaNdis_CountNBLs(NBL), &RejectionStatus))
    {
        ParaNdis_CompleteNBLChainWithStatus(m_Context->MiniportHandle, NBL, RejectionStatus);
        return;
    }

    for(auto currNBL = NBL; currNBL != nullptr; currNBL = nextNBL)
    {
        nextNBL = NET_BUFFER_LIST_NEXT_NBL(currNBL);
        NET_BUFFER_LIST_NEXT_NBL(currNBL) = nullptr;

        auto NBLHolder = new (m_Context->MiniportHandle) CNBL(currNBL, m_Context, *this);

        if (NBLHolder == nullptr)
        {
            currNBL->Status = NDIS_STATUS_RESOURCES;
            CompleteOutstandingNBLChain(currNBL);
            DPrintf(0, ("ERROR: Failed to allocate CNBL instance\n"));
            continue;
        }

        if(NBLHolder->Prepare() &&
           ParaNdis_IsSendPossible(m_Context))
        {
            NBLHolder->StartMapping();
        }
        else
        {
            NBLHolder->SetStatus(ParaNdis_ExactSendFailureStatus(m_Context));
            NBLHolder->Release();
        }
    }
}
コード例 #3
0
bool CParaNdisTX::SendMapped(bool IsInterrupt, PNET_BUFFER_LIST &NBLFailNow)
{
    if(!ParaNdis_IsSendPossible(m_Context))
    {
        NBLFailNow = RemoveAllNonWaitingNBLs();
        if (NBLFailNow)
        {
            DPrintf(0, (__FUNCTION__ " Failing send"));
        }
    }
    else
    {
        bool SentOutSomeBuffers = false;
        auto HaveBuffers = true;

        while (HaveBuffers && HaveMappedNBLs())
        {
            auto NBLHolder = PopMappedNBL();

            if (NBLHolder->HaveMappedBuffers())
            {
                auto NBHolder = NBLHolder->PopMappedNB();
                auto result = m_VirtQueue.SubmitPacket(*NBHolder);

                switch (result)
                {
                case SUBMIT_NO_PLACE_IN_QUEUE:
                    NBLHolder->PushMappedNB(NBHolder);
                    PushMappedNBL(NBLHolder);
                    HaveBuffers = false;
                    // break the loop, allow to kick and free some buffers
                    break;

                case SUBMIT_FAILURE:
                case SUBMIT_SUCCESS:
                case SUBMIT_PACKET_TOO_LARGE:
                    // if this NBL finished?
                    if (!NBLHolder->HaveMappedBuffers())
                    {
                        m_WaitingList.Push(NBLHolder);
                    }
                    else
                    {
                        // no, insert it back to the queue
                        PushMappedNBL(NBLHolder);
                    }

                    if (result == SUBMIT_SUCCESS)
                    {
                        SentOutSomeBuffers = true;
                    }
                    else
                    {
                        NBHolder->SendComplete();
                        CNB::Destroy(NBHolder, m_Context->MiniportHandle);
                    }
                    break;
                default:
                    ASSERT(false);
                    break;
                }
            }
            else
            {

                //TODO: Refactoring needed
                //This is a case when pause called, mapped list cleared but NBL is still in the send list
                m_WaitingList.Push(NBLHolder);
            }
        }

        if (SentOutSomeBuffers)
        {
            DPrintf(2, ("[%s] sent down\n", __FUNCTION__, SentOutSomeBuffers));
            if (IsInterrupt)
            {
                return true;
            }
            else
            {
                m_VirtQueue.Kick();
            }
        }
    }

    return false;
}