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

📄 mp_main.c

📁 Intel EtherExpressTM PRO/100+ Ethernet 网卡在Windows2000/xp下的PCI驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    // Get the packets from SendCancelQueue and complete them if any
    //
    while (!IsQueueEmpty(&Adapter->SendCancelQueue))
    {
        pEntry = RemoveHeadQueue(&Adapter->SendCancelQueue); 

        NdisReleaseSpinLock(&Adapter->SendLock);

        ASSERT(pEntry);
        Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);

        NdisMSendComplete(
            MP_GET_ADAPTER_HANDLE(Adapter),
            Packet,
            NDIS_STATUS_REQUEST_ABORTED);
        
        NdisAcquireSpinLock(&Adapter->SendLock);
    } 

    NdisReleaseSpinLock(&Adapter->SendLock);

    DBGPRINT(MP_TRACE, ("<==== MPCancelSendPackets\n"));

}

VOID MPPnPEventNotify(
    IN  NDIS_HANDLE             MiniportAdapterContext,
    IN  NDIS_DEVICE_PNP_EVENT   PnPEvent,
    IN  PVOID                   InformationBuffer,
    IN  ULONG                   InformationBufferLength
    )
/*++

Routine Description:
    
    MiniportPnPEventNotify handler - NDIS51 and later
    
Arguments:

    MiniportAdapterContext      Pointer to our adapter
    PnPEvent                    Self-explanatory 
    InformationBuffer           Self-explanatory 
    InformationBufferLength     Self-explanatory 

Return Value:

    None
    
--*/
{
    PMP_ADAPTER     Adapter = (PMP_ADAPTER)MiniportAdapterContext;

    //
    // Turn off the warings.
    //
    UNREFERENCED_PARAMETER(InformationBuffer);
    UNREFERENCED_PARAMETER(InformationBufferLength);
    UNREFERENCED_PARAMETER(Adapter);

    DBGPRINT(MP_TRACE, ("====> MPPnPEventNotify\n"));

    switch (PnPEvent)
    {
        case NdisDevicePnPEventQueryRemoved:
            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventQueryRemoved\n"));
            break;

        case NdisDevicePnPEventRemoved:
            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventRemoved\n"));
            break;       

        case NdisDevicePnPEventSurpriseRemoved:

            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventSurpriseRemoved\n"));
            break;

        case NdisDevicePnPEventQueryStopped:
            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventQueryStopped\n"));
            break;

        case NdisDevicePnPEventStopped:
            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventStopped\n"));
            break;      
            
        case NdisDevicePnPEventPowerProfileChanged:
            DBGPRINT(MP_WARN, ("MPPnPEventNotify: NdisDevicePnPEventPowerProfileChanged\n"));
            break;      
            
        default:
            DBGPRINT(MP_ERROR, ("MPPnPEventNotify: unknown PnP event %x \n", PnPEvent));
            break;         
    }

    DBGPRINT(MP_TRACE, ("<==== MPPnPEventNotify\n"));

}


#if LBFO
VOID MPUnload(
    IN  PDRIVER_OBJECT  DriverObject
    )
/*++

Routine Description:
    
    The Unload handler
    This handler is registered through NdisMRegisterUnloadHandler
    
Arguments:

    DriverObject        Not used

Return Value:

    None
    
--*/
{
    ASSERT(IsListEmpty(&g_AdapterList));

    NdisFreeSpinLock(&g_Lock);      
}

VOID MpAddAdapterToList(
    IN  PMP_ADAPTER  Adapter
    )
/*++

Routine Description:
    
    This function adds a new adapter to the global adapter list
    1. Not part of bundle (primary) if BundleId string is empty
    2. Primary if no adapter with the same BundleId
    3. Secondary if there is already one adapter with the same BundleId  
    
Arguments:

    MiniportAdapterContext      Pointer to our adapter

Return Value:

    None
    
--*/
{
    NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
    PMP_ADAPTER     ThisAdapter;
    PMP_ADAPTER     PrimaryAdapter = NULL;

    DBGPRINT(MP_WARN, ("Add adapter "PTR_FORMAT" ...", Adapter));

    //
    // Set the primary adapter to itself by default
    //
    Adapter->PrimaryAdapter = Adapter;

    //
    // Is this adapter part of a bundle? Just insert it in the list if not
    //
    if (Adapter->BundleId.Length == 0)
    {
        DBGPRINT_RAW(MP_WARN, ("not in a bundle\n"));
        NdisInterlockedInsertTailList(&g_AdapterList, &Adapter->List, &g_Lock);
        return;   
    }

    NdisAllocateSpinLock(&Adapter->LockLBFO);

    do
    {
        NdisAcquireSpinLock(&g_Lock);

        //
        // Search for the primary adapter if it exists. 
        // Skip searching if the list is empty 
        //
        if (IsListEmpty(&g_AdapterList))
        {
            DBGPRINT_RAW(MP_WARN, ("Primary\n"));
            break;
        }

        ThisAdapter = (PMP_ADAPTER)GetListHeadEntry(&g_AdapterList);

        while ((PLIST_ENTRY)ThisAdapter != &g_AdapterList)
        {
            if (!MP_TEST_FLAG(ThisAdapter, fMP_ADAPTER_SECONDARY) && 
                ThisAdapter->BundleId.Length == Adapter->BundleId.Length)
            {
                if (NdisEqualMemory(ThisAdapter->BundleId.Buffer, 
                    Adapter->BundleId.Buffer, Adapter->BundleId.Length))
                {
                    PrimaryAdapter = ThisAdapter;
                    break;
                }
            }

            ThisAdapter = (PMP_ADAPTER)GetListFLink((PLIST_ENTRY)ThisAdapter);   
        }

        //
        // Does a primary adapter exist? If not, this adapter will be primary.
        //
        if (PrimaryAdapter == NULL)
        {
            DBGPRINT_RAW(MP_WARN, ("Primary\n"));
            break;
        }

        //
        // Found the primary adapter, so set this adapter as secondary
        // Put a ref on the primary adapter so it won't go away while 
        // we are calling NdisMSetMiniportSecondary.
        //
        MP_LBFO_INC_REF(PrimaryAdapter);        

        NdisReleaseSpinLock(&g_Lock);

        //
        // We found the primary adapter with the same BundleIdentifier string
        // Set this adapter as scondary
        //
        Status = NdisMSetMiniportSecondary(
                     Adapter->AdapterHandle,
                     PrimaryAdapter->AdapterHandle);

        ASSERT(Status == NDIS_STATUS_SUCCESS);

        NdisAcquireSpinLock(&g_Lock);

        if (Status == NDIS_STATUS_SUCCESS)
        {
            MP_SET_FLAG(Adapter, fMP_ADAPTER_SECONDARY);
            Adapter->PrimaryAdapter = PrimaryAdapter; 

            DBGPRINT_RAW(MP_WARN, ("Secondary, use primary adapter "PTR_FORMAT"\n", 
                PrimaryAdapter));

            //
            // Add this to the end of primary's secondary miniport list
            //
            NdisAcquireSpinLock(&PrimaryAdapter->LockLBFO);

            PrimaryAdapter->NumSecondary++;   
            ThisAdapter = PrimaryAdapter; 
            while (ThisAdapter->NextSecondary)
            {
                ThisAdapter = ThisAdapter->NextSecondary;
            }
            ThisAdapter->NextSecondary = Adapter;

            NdisReleaseSpinLock(&PrimaryAdapter->LockLBFO);
        }

        MP_LBFO_DEC_REF(PrimaryAdapter);        

    } while (FALSE);

    InsertTailList(&g_AdapterList, &Adapter->List);

    NdisReleaseSpinLock(&g_Lock);

    return;      
}

VOID MpRemoveAdapterFromList(
    IN  PMP_ADAPTER  Adapter
    )
/*++

Routine Description:
    
    This function removes the adapter from the global adapter list
    1. Not part of bundle (primary) if BundleId string is empty
    2. Secondary - Remove it from primary's secondary adapter list
    3. Primary - If a secondary adapter exists, promote the secondary
    
Arguments:

    MiniportAdapterContext      Pointer to our adapter

Return Value:

    None
    
--*/
{
    PMP_ADAPTER     PrimaryAdapter;
    PMP_ADAPTER     ThisAdapter;

    DBGPRINT(MP_WARN, ("Remove adapter "PTR_FORMAT" ...", Adapter));

    ASSERT(!IsListEmpty(&g_AdapterList));

    //
    // Is this adapter part of a bundle? Just remove it if not
    //
    if (Adapter->BundleId.Length == 0)
    {
        DBGPRINT_RAW(MP_WARN, ("not in a bundle\n"));

        NdisAcquireSpinLock(&g_Lock);
        RemoveEntryList(&Adapter->List);
        NdisReleaseSpinLock(&g_Lock);
        return;
    }

    NdisAcquireSpinLock(&g_Lock);

    //
    // Check to see if it's secondary adapter, need to remove it from primary 
    // adapter's secondary list so the primary adapter won't pass more packets 
    // to this adapter
    //
    if (MP_TEST_FLAG(Adapter, fMP_ADAPTER_SECONDARY))
    {
        //
        // This is a secondary adapter
        //
        PrimaryAdapter = Adapter->PrimaryAdapter;

        DBGPRINT_RAW(MP_WARN, ("Secondary, primary adapter = "PTR_FORMAT"\n", 
            PrimaryAdapter));

        NdisAcquireSpinLock(&PrimaryAdapter->LockLBFO);

        //
        // Remove it from the primary's secondary miniport list
        //
        ThisAdapter = PrimaryAdapter; 
        while (ThisAdapter)
        {
            if (ThisAdapter->NextSecondary == Adapter)
            {
                ThisAdapter->NextSecondary = Adapter->NextSecondary;
                PrimaryAdapter->NumSecondary--;   
                break;
            }

            ThisAdapter = ThisAdapter->NextSecondary;
        }
        
        NdisReleaseSpinLock(&PrimaryAdapter->LockLBFO);

        //
        // Remove this adapter from the list
        //
        RemoveEntryList(&Adapter->List);
    }

    //
    // Need to wait for the ref count to be zero ...
    // For a primary adapter, non-zero ref count means one or more adapters are 
    // trying to become this adapter's secondary adapters    
    // For a secondary adapter, non-zero ref count means the primary is actively 
    // sending some packets on this adapter
    //
    while (TRUE)
    {
        if (MP_LBFO_GET_REF(Adapter) == 0)
        {
            break;
        }
        
        NdisReleaseSpinLock(&g_Lock);
        NdisMSleep(100);
        NdisAcquireSpinLock(&g_Lock);
    }  
    
    if (!MP_TEST_FLAG(Adapter, fMP_ADAPTER_SECONDARY))
    {
        //
        // Remove this adapter from the list
        //
        RemoveEntryList(&Adapter->List);
    
        DBGPRINT_RAW(MP_WARN, ("Primary\n"));
        if (Adapter->NumSecondary > 0)
        {
            //
            // Promote a secondary adapter
            //
            MpPromoteSecondary(Adapter);
        }
    }

    NdisReleaseSpinLock(&g_Lock);

    NdisFreeSpinLock(&Adapter->LockLBFO);
}

VOID MpPromoteSecondary(
    IN  PMP_ADAPTER     Adapter)
/*++

Routine Description:
    
    This function promotes a secondary miniport and sets up this new primary's
    secondary adapter list
    
Arguments:

    MiniportAdapterContext      Pointer to our adapter

Return Value:

    None
    
--*/
{
    NDIS_STATUS     Status;
    PMP_ADAPTER     ThisAdapter;
    PMP_ADAPTER     PromoteAdapter = NULL;

    //
    // Promote a secondary adapter
    //
    ThisAdapter = Adapter->NextSecondary; 
    while (ThisAdapter)
    {
        DBGPRINT(MP_WARN, ("Promote adapter "PTR_FORMAT"\n", ThisAdapter));

        Status = NdisMPromoteMiniport(ThisAdapter->AdapterHandle);
        ASSERT(Status == NDIS_STATUS_SUCCESS);
        if (Status == NDIS_STATUS_SUCCESS)
        {
            PromoteAdapter = ThisAdapter;
            MP_CLEAR_FLAG(PromoteAdapter, fMP_ADAPTER_SECONDARY);
            break;
        }

        ThisAdapter = ThisAdapter->NextSecondary;
    }

    if (PromoteAdapter)
    {
        //
        // Remove the new primary from old primary's secondary miniport list
        //
        NdisAcquireSpinLock(&Adapter->LockLBFO);
        ThisAdapter = Adapter; 
        while (ThisAdapter)
        {
            if (ThisAdapter->NextSecondary == PromoteAdapter)
            {
                ThisAdapter->NextSecondary = PromoteAdapter->NextSecondary;
                Adapter->NumSecondary--;   
                break;
            }

            ThisAdapter = ThisAdapter->NextSecondary;
        }
        NdisReleaseSpinLock(&Adapter->LockLBFO);

        //
        // Set all adapters in the bundle to use the new primary
        //
        PromoteAdapter->PrimaryAdapter = PromoteAdapter;
        while (ThisAdapter)
        {
            ThisAdapter->PrimaryAdapter = PromoteAdapter;
            ThisAdapter = ThisAdapter->NextSecondary;
        }

        //
        // Set the new primary's secondary miniport list
        //
        NdisAcquireSpinLock(&PromoteAdapter->LockLBFO);
        PromoteAdapter->NextSecondary = Adapter->NextSecondary;
        PromoteAdapter->NumSecondary = Adapter->NumSecondary;
        NdisReleaseSpinLock(&PromoteAdapter->LockLBFO);
    }
    else
    {
        //
        // This shouldn't happen! 
        // Set each secondary's primary to point to itself
        //
        DBGPRINT(MP_ERROR, ("Failed to promote any seconday adapter\n"));
        ASSERT(FALSE);

        ThisAdapter = Adapter->NextSecondary; 
        while (ThisAdapter)
        {
            ThisAdapter->PrimaryAdapter = ThisAdapter;
            ThisAdapter = ThisAdapter->NextSecondary;
        }
    }
}

#endif

⌨️ 快捷键说明

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