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

📄 miniport.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
    CheckForHang handler is called in the context of a timer DPC. 
    take advantage of this fact when acquiring/releasing spinlocks

--*/
{
    DEBUGP(MP_LOUD, ("---> MPCheckForHang\n"));
    DEBUGP(MP_LOUD, ("<--- MPCheckForHang\n"));
    return(FALSE);
}


VOID 
MPHandleInterrupt(
    IN NDIS_HANDLE MiniportAdapterContext
    )
/*++

Routine Description:
    
    MiniportHandleInterrupt is a DPC function called to do deferred 
    processing of all outstanding interrupt operations. When a NIC 
    generates an interrupt, a miniport's MiniportISR or 
    MiniportDisableInterrupt function dismisses the interrupt on the 
    NIC, saves any necessary state about the operation, and returns 
    control as quickly as possible, thereby deferring most 
    interrupt-driven I/O operations to MiniportHandleInterrupt. This
    handler is called only if the MiniportISR function returned 
    QueueMiniportHandleInterrupt set to TRUE.

    MiniportHandleInterrupt then re-enables interrupts on the NIC, 
    either by letting NDIS call the miniport driver's 
    MiniportEnableInterrupt function after MiniportHandleInterrupt 
    returns control or by enabling the interrupt from within
    MiniportHandleInterrupt, which is faster. 

    Note that more than one instance of this function can execute 
    concurrently in SMP machines.
    
    Runs at IRQL = DISPATCH_LEVEL    
    
Arguments:

    MiniportAdapterContext  Pointer to our adapter

Return Value:

    None
    
--*/
{
    DEBUGP(MP_TRACE, ("---> MPHandleInterrupt\n"));
    DEBUGP(MP_TRACE, ("<--- MPHandleInterrupt\n"));
}

VOID 
MPIsr(
    OUT PBOOLEAN InterruptRecognized,
    OUT PBOOLEAN QueueMiniportHandleInterrupt,
    IN NDIS_HANDLE MiniportAdapterContext
    )
/*++

Routine Description:
    
    MiniportIsr handler is called to when the device asserts an interrupt.
    MiniportISR dismisses the interrupt on the NIC, saves whatever state
    it must about the interrupt, and defers as much of the I/O processing
    for each interrupt as possible to the MiniportHandleInterrupt function. 
    
    MiniportISR is not re-entrant, although two instantiations of this 
    function can execute concurrently in SMP machines, particularly if 
    the miniport driver supports full-duplex sends and receives. A driver
    writer should not rely on a one-to-one correspondence between the 
    execution of MiniportISR and MiniportHandleInterrupt. 

    If the NIC shares an IRQ with other devices (check NdisMRegisterInterrupt), 
    this function should determine whether the NIC generated the interrupt. 
    If the NIC did not generated the interrupt, MiniportISR should return FALSE 
    immediately so that the driver of the device that generated the interrupt
    is called quickly. 

    Runs at IRQL = DIRQL assigned when the NIC driver's MiniportInitialize
    function called NdisMRegisterInterrupt.   

Arguments:

    InterruptRecognized             TRUE on return if the interrupt comes 
                                    from this NIC    
    QueueMiniportHandleInterrupt    TRUE on return if MiniportHandleInterrupt 
                                    should be called
    MiniportAdapterContext          Pointer to our adapter

Return Value:

    None
    
--*/
{

    DEBUGP(MP_TRACE, ("---> MPIsr\n"));
    DEBUGP(MP_TRACE, ("<--- MPIsr\n"));
}

VOID 
MPDisableInterrupt(
    IN PVOID MiniportAdapterContext
    )
/*++

Routine Description:
    
    MiniportDisableInterrupt typically disables interrupts by writing 
    a mask to the NIC. If a driver does not have this function, typically
    its MiniportISR disables interrupts on the NIC.

    This handler is required by drivers of NICs that support dynamic 
    enabling and disabling of interrupts but do not share an IRQ.

    Runs at IRQL = DIRQL    
    
Arguments:

    MiniportAdapterContext          Pointer to our adapter

Return Value:

    None
    
--*/
{
    DEBUGP(MP_TRACE, ("---> MPDisableInterrupt\n"));
    DEBUGP(MP_TRACE, ("<--- MPDisableInterrupt\n"));

}

VOID 
MPEnableInterrupt(
    IN PVOID MiniportAdapterContext
    )
/*++

Routine Description:
    
    MiniportEnableInterrupt typically enables interrupts by writing a mask
    to the NIC. A NIC driver that exports a MiniportDisableInterrupt function
    need not have a reciprocal MiniportEnableInterrupt function. 
    Such a driver's MiniportHandleInterrupt function is responsible for 
    re-enabling interrupts on the NIC. 

    Runs at IRQL = DIRQL    
    
Arguments:

    MiniportAdapterContext          Pointer to our adapter

Return Value:

    None
    
--*/
{
    DEBUGP(MP_TRACE, ("---> MPEnableInterrupt\n"));
    DEBUGP(MP_TRACE, ("<--- MPEnableInterrupt\n"));

}

VOID 
MPAllocateComplete(
    NDIS_HANDLE MiniportAdapterContext,
    IN PVOID VirtualAddress,
    IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
    IN ULONG Length,
    IN PVOID Context
    )
/*++

Routine Description:
    
    This handler is needed if the driver makes calls to 
    NdisMAllocateSharedMemoryAsync. Drivers of bus-master DMA NICs call 
    NdisMAllocateSharedMemoryAsync to dynamically allocate shared memory
    for transfer operations when high network traffic places excessive 
    demands on the shared memory space that the driver allocated during 
    initialization. 

    Runs at IRQL = DISPATCH_LEVEL.
    
Arguments:

    MiniportAdapterContext  Pointer to our adapter
    VirtualAddress          Pointer to the allocated memory block 
    PhysicalAddress         Physical address of the memory block       
    Length                  Length of the memory block                
    Context                 Context in NdisMAllocateSharedMemoryAsync              

Return Value:

    None
    
--*/
{
    DEBUGP(MP_TRACE, ("---> MPAllocateComplete\n"));
}

#ifdef NDIS51_MINIPORT
VOID 
MPCancelSendPackets(
    IN  NDIS_HANDLE     MiniportAdapterContext,
    IN  PVOID           CancelId
    )
/*++

Routine Description:
    
    MiniportCancelSendPackets cancels the transmission of all packets that
    are marked with a specified cancellation identifier. Miniport drivers
    that queue send packets for more than one second should export this
    handler. When a protocol driver or intermediate driver calls the
    NdisCancelSendPackets function, NDIS calls the MiniportCancelSendPackets 
    function of the appropriate lower-level driver (miniport driver or 
    intermediate driver) on the binding.

    Runs at IRQL <= DISPATCH_LEVEL.
  
    Available - NDIS5.1 (WinXP) and later.
    
Arguments:

    MiniportAdapterContext      Pointer to our adapter
    CancelId                    All the packets with this Id should be cancelled

Return Value:

    None
    
--*/
{
    PNDIS_PACKET    Packet;
    PVOID           PacketId;
    PLIST_ENTRY     thisEntry, nextEntry, listHead;
    SINGLE_LIST_ENTRY SendCancelList;
    PSINGLE_LIST_ENTRY entry;
    
    PMP_ADAPTER     Adapter = (PMP_ADAPTER)MiniportAdapterContext;

#define MP_GET_PACKET_MR(_p)    (PSINGLE_LIST_ENTRY)(&(_p)->MiniportReserved[0]) 

    DEBUGP(MP_TRACE, ("---> MPCancelSendPackets\n"));

    SendCancelList.Next = NULL;
    
    NdisAcquireSpinLock(&Adapter->SendLock);

    //
    // Walk through the send wait queue and complete the sends with matching Id
    //
    listHead = &Adapter->SendWaitList;
    
    for(thisEntry = listHead->Flink,nextEntry = thisEntry->Flink;
       thisEntry != listHead;
       thisEntry = nextEntry,nextEntry = thisEntry->Flink) {
        Packet = CONTAINING_RECORD(thisEntry, NDIS_PACKET, MiniportReserved);

        PacketId = NdisGetPacketCancelId(Packet);
        if (PacketId == CancelId)
        {       
            //
            // This packet has the right CancelId
            //
            RemoveEntryList(thisEntry);
            //
            // Put this packet on SendCancelList
            //
            PushEntryList(&SendCancelList, MP_GET_PACKET_MR(Packet));
        }
    }
       
    NdisReleaseSpinLock(&Adapter->SendLock);

    //
    // Get the packets from SendCancelList and complete them if any
    //

    entry = PopEntryList(&SendCancelList);
    
    while (entry)
    {
        Packet = CONTAINING_RECORD(entry, NDIS_PACKET, MiniportReserved);

        NdisMSendComplete(
            Adapter->AdapterHandle,
            Packet,
            NDIS_STATUS_REQUEST_ABORTED);
        
        entry = PopEntryList(&SendCancelList);        
    }

    DEBUGP(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 is to handle PnP notification messages.
    All NDIS 5.1 miniport drivers must export a MiniportPnPEventNotify
    function. Miniport drivers that have a WDM lower edge should export
    a MiniportPnPEventNotify function.

    Runs at IRQL = PASSIVE_LEVEL in the context of system thread.

    Available - NDIS5.1 (WinXP) 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;
    PNDIS_POWER_PROFILE NdisPowerProfile;
    
    //
    // Turn off the warings.
    //
    UNREFERENCED_PARAMETER(Adapter);

    DEBUGP(MP_TRACE, ("---> MPPnPEventNotify\n"));

    switch (PnPEvent)
    {
        case NdisDevicePnPEventQueryRemoved:
            //
            // Called when NDIS receives IRP_MN_QUERY_REMOVE_DEVICE.
            //
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventQueryRemoved\n"));
            break;

        case NdisDevicePnPEventRemoved:
            //
            // Called when NDIS receives IRP_MN_REMOVE_DEVICE.
            // NDIS calls MiniportHalt function after this call returns.
            //
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventRemoved\n"));
            break;       

        case NdisDevicePnPEventSurpriseRemoved:
            //
            // Called when NDIS receives IRP_MN_SUPRISE_REMOVAL. 
            // NDIS calls MiniportHalt function after this call returns.
            //
            MP_SET_FLAG(Adapter, fMP_ADAPTER_SURPRISE_REMOVED);
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventSurpriseRemoved\n"));
            break;

        case NdisDevicePnPEventQueryStopped:
            //
            // Called when NDIS receives IRP_MN_QUERY_STOP_DEVICE. ??
            //
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventQueryStopped\n"));
            break;

        case NdisDevicePnPEventStopped:
            //
            // Called when NDIS receives IRP_MN_STOP_DEVICE.
            // NDIS calls MiniportHalt function after this call returns.
            // 
            //
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventStopped\n"));
            break;      
            
        case NdisDevicePnPEventPowerProfileChanged:
            //
            // After initializing a miniport driver and after miniport driver
            // receives an OID_PNP_SET_POWER notification that specifies 
            // a device power state of NdisDeviceStateD0 (the powered-on state), 
            // NDIS calls the miniport's MiniportPnPEventNotify function with 
            // PnPEvent set to NdisDevicePnPEventPowerProfileChanged. 
            //            
            DEBUGP(MP_INFO, ("MPPnPEventNotify: NdisDevicePnPEventPowerProfileChanged\n"));
            
            if(InformationBufferLength == sizeof(NDIS_POWER_PROFILE)) {
                NdisPowerProfile = (PNDIS_POWER_PROFILE)InformationBuffer;
                if(*NdisPowerProfile == NdisPowerProfileBattery) {
                    DEBUGP(MP_INFO, 
                        ("The host system is running on battery power\n"));
                }
                if(*NdisPowerProfile == NdisPowerProfileAcOnLine) {
                    DEBUGP(MP_INFO, 
                        ("The host system is running on AC power\n"));
               }
            }
            break;      
            
        default:
            DEBUGP(MP_ERROR, ("MPPnPEventNotify: unknown PnP event %x \n", PnPEvent));
            break;         
    }

    DEBUGP(MP_TRACE, ("<--- MPPnPEventNotify\n"));

}

#endif

⌨️ 快捷键说明

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