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

📄 interrup.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
            {
                ASSERT(SwRfd->Status & RFD_STATUS_OK);
                ASSERT((Rfd->RfdActualCount & 0xc000) == 0xc000);
                
                // Adjust our buffer length for this swrfd
                NdisAdjustBufferLength((PNDIS_BUFFER) SwRfd->ReceiveBuffer,
                    (UINT) SwRfd->FrameLength);
                ASSERT(SwRfd->FrameLength == (UINT)(Rfd->RfdActualCount & 0x3fff));
                
                // we dont do recalculatepacketcounts because we only 
                // have one buffer and its count is always correct
                // we could, however, do it if we were paranoid
                // or supported multiple receive buffers per packet
                //  NdisRecalculatePacketCounts(SwRfd->ReceivePacket);

                PacketArray[PacketArrayCount] = SwRfd->ReceivePacket;
                
                // keep track of how many we've used
                Adapter->UsedRfdCount++;
                ASSERT(Adapter->UsedRfdCount <= Adapter->NumRfd);
                
                // set the status on the packet, either resources or success
                if (Adapter->UsedRfdCount < Adapter->NumRfd - MIN_NUM_RFD)
                {
                    NDIS_SET_PACKET_STATUS(PacketArray[PacketArrayCount],NDIS_STATUS_SUCCESS);
                    // Keep track of the highest array index in which a packet
                    // with status NDIS_STATUS_SUCCESS is found. Once we hit the low
                    // resource condition, all further packets will be marked with status
                    // NDIS_STATUS_RESOURCES. This is because we hold the adapter lock
                    // here which prevents UsedRfdCount/NumRfd from being modified
                    // elsewhere.
                }
                else
                {
                    NDIS_SET_PACKET_STATUS(PacketArray[PacketArrayCount],
                        NDIS_STATUS_RESOURCES);
                        
                    PacketFreeCount++;
                    
                    // okay, we ran low on resources so allocate a bunch more
                    if ((Adapter->Last_RMD_used != (NUM_RMD - 1))
                        && (Adapter->AsynchronousAllocationPending == FALSE))
                    {
                        NDIS_STATUS     AllocationStatus;
                        
                        AllocationStatus = NdisMAllocateSharedMemoryAsync(
                            Adapter->D100AdapterHandle, 
                            packet_count[Adapter->Last_RMD_used] * sizeof(RFD_STRUC),
                            FALSE,
                            (PVOID) Adapter->Last_RMD_used);            
                        
                        if (AllocationStatus != NDIS_STATUS_PENDING)
                        {
                            INITSTR(("Async memory allocation not possible at this time!!!"));
                        }
                        else
                        {
                            // set this state variable so if we keep on receiving
                            // before our new memory is set up, we wont repeatedly
                            // call our allocate function
                            Adapter->AsynchronousAllocationPending = TRUE;
                        }
                        
                    }
                }
                
                // have to increment our packetcount
                PacketArrayCount++;
                
                // this limits the number of packets that we will indicate
                // to MAX_ARRAY_RECEIVE_PACKETS or the available number of RFDS
                if (( PacketArrayCount >= MAX_ARRAY_RECEIVE_PACKETS) ||
                    ( Adapter->UsedRfdCount == Adapter->NumRfd))
                {
                    ContinueToCheckRFDs = TRUE;
                    break; 
                }
                
            }
            
        }// end while 1
        
        // if we didn't process any receives, just return from here
        if (0 == PacketArrayCount)
        {
            DEBUGCHAR(Adapter,'g');
            return(FALSE);
        }
        
    #if DBG
        Adapter->IndicateReceivePacketCounter++;
        Adapter->PacketsIndicated+=PacketArrayCount;
    #endif    
        ////////////////////////////////////////////////////////////////
        // Indicate the packets and return the completed ones to our
        // receive list. If the packet is pended NDIS gets to keep it
        // and will return it with D100GetReturnedPackets.
        // NDIS should always leave us at least MIN_NUM_RFD packets
        // because we set Status_resources on our last MIN_NUM_RFD packets
        ////////////////////////////////////////////////////////////////
        if(PacketArrayCount)
        {
            NdisReleaseSpinLock(&Adapter->Lock);
            NdisMIndicateReceivePacket(Adapter->D100AdapterHandle,
                PacketArray,
                PacketArrayCount);
            
            NdisAcquireSpinLock(&Adapter->Lock);
            
        }

        //
        // NDIS will call our ReturnPackets handler for each packet
        // that was *not* marked NDIS_STATUS_RESOURCES. For those
        // that were marked with the resources status, the miniport
        // should assume that they are immediately returned.
        // Go through the packets that were marked NDIS_STATUS_RESOURCES
        // and reclaim them.
        //
        
        for (i=PacketArrayCount-PacketFreeCount;i<PacketArrayCount ;i++ )
        {
            // get the SwRfd associated with this packet
            SwRfd = *(D100SwRfd **)(PacketArray[i]->MiniportReserved);
            
            InitAndChainPacket(Adapter,SwRfd);
            Adapter->UsedRfdCount--;
            ASSERT(Adapter->UsedRfdCount <= Adapter->NumRfd);
        } // end for 
    } while (ContinueToCheckRFDs);
    
    // check to see if we came out of this routine with the correct amount of 
    // receive buffers left over
    ASSERT(Adapter->UsedRfdCount <= (Adapter->NumRfd - MIN_NUM_RFD));
    
    DEBUGCHAR(Adapter,'r');
    return (TRUE);
}

//-----------------------------------------------------------------------------
// Procedure:   StartReceiveUnit
//
// Description: This routine checks the status of the 82557's receive unit(RU),
//              and starts the RU if it was not already active.  However,
//              before restarting the RU, the driver cleans up any recent
//              pending receives (this is very important).
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:
//      TRUE - If we indicated any receives during this function call
//      FALSE - If we didn't indicate any receives
//-----------------------------------------------------------------------------

BOOLEAN
StartReceiveUnit(
                 IN PD100_ADAPTER Adapter
                 )

{
    PD100SwRfd      SwRfd;
    BOOLEAN         Status;
    UINT            WaitCount = 80000;

#if DBG
    UINT            i;
#endif

    DEBUGFUNC("StartReceiveUnit");

    TRACE2(Adapter, ("\n"));

    Status = FALSE;

    DEBUGCHAR(Adapter,'>');
    // If the receiver is ready, then don't try to restart.
    if ((Adapter->CSRAddress->ScbStatus & SCB_RUS_MASK) == SCB_RUS_READY)
        return Status;

    TRACE2(Adapter, ("Re-starting the RU!!!\n"));

    SwRfd = (PD100SwRfd) QueueGetHead(&Adapter->RfdList);

    // Check to make sure that our RFD head is available.  If its not, then
    // we should process the rest of our receives
    if ((SwRfd == NULL) || (SwRfd->Rfd->RfdCbHeader.CbStatus))
    {
        Status = ProcessRXInterrupt(Adapter);

        // Get the new RFD "head" after processing the pending receives.
        SwRfd = (PD100SwRfd) QueueGetHead(&Adapter->RfdList);
    }

#if DBG
    if ((Adapter->CSRAddress->ScbStatus & SCB_RUS_MASK) == SCB_RUS_READY)
    {
        TRACESTR(Adapter, ("RU is active!!!\n"));
    }

    // Big hack to check to make sure that all of the RFDs are indeed clear.
    // If they are not then we'll generate a break point.
    for (i=0; i< (Adapter->NumRfd - Adapter->UsedRfdCount); i++)
    {
        SwRfd = (PD100SwRfd) QueuePopHead(&Adapter->RfdList);
        if (SwRfd->Rfd->RfdCbHeader.CbStatus & RFD_STATUS_COMPLETE)
        {
            TRACESTR(Adapter,("RFD NOT PROCESSED!!!\n"));
//            DbgBreakPoint();
        }
        QueuePutTail(&Adapter->RfdList, &SwRfd->Link);
    }

    SwRfd = (PD100SwRfd) QueueGetHead(&Adapter->RfdList);
#endif //DBG


    // Wait for the SCB to clear before we set the general pointer
    if (WaitScb(Adapter) == FALSE)
        ASSERT(0);

    if (SwRfd != NULL)
    {
        // Set the SCB General Pointer to point the current Rfd
        Adapter->CSRAddress->ScbGeneralPointer = SwRfd->RfdPhys;
    }

    // Issue the SCB RU start command
    (void) D100IssueScbCommand(Adapter, SCB_RUC_START, FALSE);

    // wait for the command to be accepted
    WaitScb(Adapter);

    // wait for RUS to be Ready
    while (WaitCount !=0)
    {
        if ((Adapter->CSRAddress->ScbStatus & SCB_RUS_MASK) == SCB_RUS_READY)
            break;

        NdisStallExecution(10);
        WaitCount--;
    }
    if (!WaitCount)
    {
        HARDWARE_NOT_RESPONDING (Adapter);
    }

#if DBG
    // If we fall through, we have a problem.
    if (WaitCount == 0)
        TRACESTR(Adapter, ("Failed, RU won't ready -- ScbStatus %08x\n",
        Adapter->CSRAddress->ScbStatus));
#endif

    return Status;
}

⌨️ 快捷键说明

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