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

📄 d100.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
** COPYRIGHT (C) 1994-1997 INTEL CORPORATION                               **
** DEVELOPED FOR MICROSOFT BY INTEL CORP., HILLSBORO, OREGON               **
** HTTP://WWW.INTEL.COM/                                                   **
** THIS FILE IS PART OF THE INTEL ETHEREXPRESS PRO/100B(TM) AND            **
** ETHEREXPRESS PRO/100+(TM) NDIS 5.0 MINIPORT SAMPLE DRIVER               **
****************************************************************************/

/****************************************************************************
Module Name:
    d100.c

This driver runs on the following hardware:
    - 82557/82558 based PCI 10/100Mb ethernet adapters
    (aka Intel EtherExpress(TM) PRO Adapters)

Environment:
    Kernel Mode - Or whatever is the equivalent on WinNT

Revision History
    - JCB 8/14/97 Example Driver Created
*****************************************************************************/

#include "precomp.h"

#pragma hdrstop
#pragma warning (disable: 4244 4514 4706)

//-----------------------------------------------------------------------------
// Procedure:   DeleteSharedAdapterMemory
//
// Description: This routine is responsible for the deallocation of the
//              shared memory data structures for the Adapter structure.  This
//              includes the both the cached and uncached memory allocations.
//              We also free any allocated map registers in this routine.
//
// Arguments:
//      Adapter - Ptr to the Adapter structure
//
// Returns:     (none)
//-----------------------------------------------------------------------------

VOID
DeleteSharedAdapterMemory(PD100_ADAPTER Adapter)

{
#if DBG
    UINT RfdNum;
#endif
    UINT count;
    D100SwRfd *SwRfdPtr;
    DEBUGFUNC("DeleteSharedAdapterMemory");

    INITSTR(("\n"));

    // Free memory for receive packetpool and bufferpool
    if (Adapter->ReceivePacketPool)
    {
        TRACESTR(Adapter,("Freeing Packet Pool resources\n"));
        // get the first one to free
        SwRfdPtr = (D100SwRfd *) QueuePopHead(&Adapter->RfdList);     // cached RFDs logical

#if DBG
        count = 0;
#endif
        while (SwRfdPtr != (PD100SwRfd) 0)
        {

            FreeSwRfd(Adapter,SwRfdPtr);

            // walk our list of receive packets
            SwRfdPtr = (PD100SwRfd) QueuePopHead(&Adapter->RfdList);
#if DBG
            ++count;
#endif
        }

#if DBG
        // assert if we didnt free the full number of Rfds
        ASSERT(count == Adapter->NumRfd);
        // assert if our pool isnt empty
//        RfdNum = NdisPacketPoolUsage(Adapter->ReceivePacketPool);
//        ASSERT(!RfdNum);
#endif

        NdisFreeBufferPool(Adapter->ReceiveBufferPool);
        NdisFreePacketPool(Adapter->ReceivePacketPool);

    }

    // go through each element in our array and free the memory
    // pointed to by the element
    for (count = 0; count < NUM_RMD ; ++count)
    {
        // the packets and buffers should have already been freed

        // if a virtual address exists, we have to free the unit
        if (Adapter->ReceiveMemoryDescArray[count].CachedMem.VirtualAddress)
        {
            FreeRMD(Adapter,&Adapter->ReceiveMemoryDescArray[count]);
        }

    }

    // Free any memory allocated for the Original Software
    // receive structures (SwRfds)
    if (Adapter->RecvCached)
    {
        TRACESTR(Adapter, ("Freeing %d bytes RecvCached\n", Adapter->RecvCachedSize));
        NdisFreeMemory((PVOID) Adapter->RecvCached, Adapter->RecvCachedSize, 0);
        Adapter->RecvCached = (PUCHAR) 0;
    }

    // Free any memory allocated for the shared receive structures (RFDs)
    // the original ones...
    if (Adapter->RecvUnCached)
    {
        TRACESTR(Adapter, ("Freeing %d bytes RecvUnCached\n", Adapter->RecvUnCachedSize));
        // Now free the shared memory that was used for the receive buffers.
        NdisMFreeSharedMemory(
            Adapter->D100AdapterHandle,
            Adapter->RecvUnCachedSize,
            FALSE,
            (PVOID) Adapter->RecvUnCached,
            Adapter->RecvUnCachedPhys);
        Adapter->RecvUnCached = (PUCHAR) 0;
    }

    // Free any memory allocated for the Software transmit structures (SwTcbs)
    if (Adapter->XmitCached)
    {
        TRACESTR(Adapter, ("Freeing %d bytes XmitCached\n", Adapter->XmitCachedSize));
        NdisFreeMemory((PVOID) Adapter->XmitCached, Adapter->XmitCachedSize, 0);
        Adapter->XmitCached = (PUCHAR) 0;
    }

    // Free any memory allocated for the shared transmit structures (TCBs,
    // TBDs, non transmit command blocks, etc.)
    if (Adapter->CbUnCached)
    {
        TRACESTR(Adapter, ("Freeing %d bytes XmitUnCached\n", Adapter->CbUnCachedSize));


        // Now free the shared memory that was used for the command blocks and
        // transmit buffers.

        NdisMFreeSharedMemory(
            Adapter->D100AdapterHandle,
            Adapter->CbUnCachedSize,
            FALSE,
            (PVOID) Adapter->CbUnCached,
            Adapter->CbUnCachedPhys
            );
        Adapter->CbUnCached = (PUCHAR) 0;
        Adapter->XmitUnCached = (PUCHAR) 0;
    }

    // If this is a miniport driver we must free our allocated map registers
    if (Adapter->NumMapRegisters)
    {
        NdisMFreeMapRegisters(Adapter->D100AdapterHandle);
    }
}


//-----------------------------------------------------------------------------
// Procedure:   FreeAdapterObject
//
// Description: This routine releases all resources defined in the ADAPTER
//              object and returns the ADAPTER object memory to the free pool.
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:     (none)
//-----------------------------------------------------------------------------

VOID
FreeAdapterObject(PD100_ADAPTER Adapter)

{

    DEBUGFUNC("FreeAdapterObject");
    INITSTR(("\n"));

    // Free the transmit, receive, and SCB structures
    DeleteSharedAdapterMemory(Adapter);

    // we must delete any IO mappings that we have registered

    if (Adapter->MappedIoBase)
    {
        NdisMDeregisterIoPortRange(
            Adapter->D100AdapterHandle,
            (UINT) Adapter->AiBaseIo,
            Adapter->MappedIoRange,
            (PVOID) Adapter->MappedIoBase);
    }

    // free the adapter object itself
    D100_FREE_MEM(Adapter, sizeof(D100_ADAPTER));

}


//-----------------------------------------------------------------------------
// Procedure:   SoftwareReset
//
// Description: This routine is called by SelfTestHardware and InitializeD100.
//              It resets the D100 by issuing a PORT SOFTWARE RESET.
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:
//      (none)
//-----------------------------------------------------------------------------

VOID
SoftwareReset(PD100_ADAPTER Adapter)

{
    DEBUGFUNC("SoftWareReset");
    INITSTR(("\n"));

    DEBUGCHAR(Adapter,'W');

    // Issue a PORT command with a data word of 0
    Adapter->CSRAddress->Port = PORT_SOFTWARE_RESET;

    // wait 20 milliseconds for the reset to take effect
    D100StallExecution(20);

    // Mask off our interrupt line -- its unmasked after reset
    D100DisableInterrupt(Adapter);
}


//-----------------------------------------------------------------------------
// Procedure:   DriverEntry
//
// Description: This is the primary initialization routine for the D100
//              driver. It is simply responsible for the intializing the
//              wrapper and registering the adapter driver.  The routine gets
//              called once per driver, but D100Initialize(miniport) or
//              AddAdapter (mac) will get called multiple times if there are
//              multiple adapters.
//
// Arguments:
//      DriverObject - Pointer to driver object created by the system.
//      RegistryPath - The registry path of this driver
//
// Returns:
//  The status of the operation, normally this will be NDIS_STATUS_SUCCESS
//-----------------------------------------------------------------------------

NTSTATUS
DriverEntry(PDRIVER_OBJECT DriverObject,
            PUNICODE_STRING RegistryPath)

{

    NDIS_STATUS         Status;
    NDIS_HANDLE         NdisWrapperHandle;

    NDIS_MINIPORT_CHARACTERISTICS D100Char;

    DEBUGFUNC("D100DriverEntry");
    INITSTR(("\n"));

    // Now we must initialize the wrapper, and then register the Miniport
    NdisMInitializeWrapper( &NdisWrapperHandle,
        DriverObject,
        RegistryPath,
        NULL
        );

    NdisZeroMemory(&D100Char, sizeof(D100Char));

    // Initialize the Miniport characteristics for the call to
    // NdisMRegisterMiniport.
    D100Char.MajorNdisVersion       = D100_NDIS_MAJOR_VERSION;
    D100Char.MinorNdisVersion       = D100_NDIS_MINOR_VERSION;
    D100Char.CheckForHangHandler    = D100CheckForHang;
    D100Char.DisableInterruptHandler= D100DisableInterrupt;
    D100Char.EnableInterruptHandler = D100EnableInterrupt;
    D100Char.HaltHandler            = D100Halt;
    D100Char.HandleInterruptHandler = D100HandleInterrupt;
    D100Char.InitializeHandler      = D100Initialize;
    D100Char.ISRHandler             = D100Isr;
    D100Char.QueryInformationHandler= D100QueryInformation;
    D100Char.ReconfigureHandler     = NULL;
    D100Char.ResetHandler           = D100Reset;
    D100Char.SetInformationHandler  = D100SetInformation;
    D100Char.SendHandler            = NULL;
    D100Char.SendPacketsHandler     = D100MultipleSend;
    D100Char.ReturnPacketHandler    = D100GetReturnedPackets;
    D100Char.TransferDataHandler    = NULL;
    D100Char.AllocateCompleteHandler = D100AllocateComplete;


    DEBUGSTR(("DriverEntry: About to call NdisMRegisterMiniport\n"));

    // Register this driver with the NDIS wrapper
    //   This will cause D100Initialize to be called before returning
    Status = NdisMRegisterMiniport(
        NdisWrapperHandle,
        &D100Char,
        sizeof(NDIS_MINIPORT_CHARACTERISTICS));

    DEBUGSTR(("DriverEntry: NdisMRegisterMiniport returns %X\n", Status));

    if (Status == NDIS_STATUS_SUCCESS)
        return STATUS_SUCCESS;

    DEBUGSTR(("NdisMRegisterMiniport failed (Status = 0x%x)\n", Status));
    return Status;
}


//-----------------------------------------------------------------------------
// D100GetReturnedPackets
//
// PARAMETERS: IN NDIS_HANDLE MiniportAdapterContext
//                 - a context version of our Adapter pointer
//             IN NDIS_PACKET Packet
//                 - the packet that is being freed
//
// DESCRIPTION: This function attempts to return to the receive free list the
//              packet passed to us by NDIS
//
// RETURNS: nothing
//
//-----------------------------------------------------------------------------

VOID
D100GetReturnedPackets(NDIS_HANDLE  MiniportAdapterContext,
                       PNDIS_PACKET Packet)
{
    PD100_ADAPTER   Adapter;
    PD100SwRfd      SwRfd;

    DEBUGFUNC("D100GetReturnedPackets");
    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    NdisAcquireSpinLock(&Adapter->Lock);
    TRACE2(Adapter, ("\n"));

    ASSERT(Packet);

    DEBUGCHAR(Adapter,'G');
    SwRfd = *(D100SwRfd **)(Packet->MiniportReserved);
    ASSERT(SwRfd);

    InitAndChainPacket(Adapter, SwRfd);

    --Adapter->UsedRfdCount;
    ASSERT(Adapter->UsedRfdCount <= Adapter->NumRfd);

    NdisReleaseSpinLock(&Adapter->Lock);

    return;
}

//-----------------------------------------------------------------------------
// PROCEDURE: InitAndChainPacket
//
// PARAMETERS: Adapter structure Pointer

⌨️ 快捷键说明

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