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

📄 d100.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    // Allocate the Adapter Object, exit if error occurs
    Status = D100_ALLOC_MEM(&Adapter, sizeof(D100_ADAPTER));

    if (Status != NDIS_STATUS_SUCCESS)
    {
        DEBUGSTR(("ADAPTER Allocate Memory failed (Status = 0x%x)\n", Status));
        return Status;
    }

    //Zero out the adapter object space
    NdisZeroMemory(Adapter, sizeof(D100_ADAPTER));

    Adapter->D100AdapterHandle = MiniportAdapterHandle;

    INITSTR(("Adapter structure pointer is %08x\n", Adapter));

    // Open Registry, exit if error occurs.
    NdisOpenConfiguration(&Status,
        &ConfigHandle,
        WrapperConfigurationContext);

    if (Status != NDIS_STATUS_SUCCESS)
    {
        DEBUGSTR(("NdisOpenConfiguration failed (Status = 0x%x)\n", Status));
        FreeAdapterObject(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    // Parse all of our configuration parameters.
    Status = ParseRegistryParameters(Adapter, ConfigHandle);

    // If a required configuration parameter was not present, then error out
    if (Status != NDIS_STATUS_SUCCESS)
    {
        DEBUGSTR(("ParseRegistryParameters failed (Status = 0x%x)\n", Status));
        NdisCloseConfiguration(ConfigHandle);
        FreeAdapterObject(Adapter);
        return Status;
    }

    // initialize the number of Tcbs we will have in our queue
    // this is to work around limitations of the hardware and the S-bit
    Adapter->NumTcb = Adapter->RegNumTcb + 1;

    DEBUGSTR(("ParseRegistryParameters Completed successfully\n"));

    // Look for a Node Address (IA) override
    // this is where the registry parameter NodeAddress in
    // HKLM\System\CCS\Services\E100BX\Parameters

    NdisReadNetworkAddress(&Status,
        &OverrideNetAddress,
        (UINT *) &i,
        ConfigHandle);

    // If there is an IA override save it to the adapter object
    if ((i == ETH_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS))
        NdisMoveMemory(Adapter->AiNodeAddress,
        OverrideNetAddress,
        ETH_LENGTH_OF_ADDRESS);

    // We read out all of our config info, so close the gateway to the registry
    NdisCloseConfiguration(ConfigHandle);

    // register our adapter object with the OS as a PCI adapter
    IfType = NdisInterfacePci;

    // call NdisMSetAttributesEx in order to let NDIS know
    // what kind of driver and features we support
    NdisMSetAttributesEx(
        Adapter->D100AdapterHandle,
        (NDIS_HANDLE) Adapter,
        0,
        (ULONG)
        NDIS_ATTRIBUTE_DESERIALIZE |
        NDIS_ATTRIBUTE_BUS_MASTER,
        IfType
        );

    // Assign (Claim) a physical Adapter for this Adapter object
    // In this function is where we find our adapter on the PCI bus and
    // call NdisMPciAssignResources
    if (ClaimAdapter(Adapter) != NDIS_STATUS_SUCCESS)
    {
        DEBUGSTR(("No adapter detected\n"));
        FreeAdapterObject(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    // set up our Command Register's I/O mapping (the CSR)
    Status = SetupAdapterInfo(Adapter);

    if (Status != NDIS_STATUS_SUCCESS)
    {
        DEBUGSTR(("I/O Space allocation failed (Status = 0x%X)\n",Status));
        FreeAdapterObject(Adapter);
        return(NDIS_STATUS_FAILURE);
    }

    // allocate & Initialize the required 82557 (D100) Shared Memory areas
    Status = SetupSharedAdapterMemory(Adapter);

    // Check the status returned from SetupSharedAdapterMemory
    if (Status != NDIS_STATUS_SUCCESS)
    {
        // Since we couldn't allocate enough shared memory, free any resources
        // that we previously allocated and error out.
        D100LogError(Adapter, EVENT_10, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);
        DEBUGSTR(("Shared Memory Allocation failed (Status = 0x%x)\n", Status));

        // Free our adapter object
        FreeAdapterObject(Adapter);

        return NDIS_STATUS_FAILURE;
    }

    // Disable interrupts while we finish with the initialization
    // Must SetupSharedAdapterMemory() before you can do this
    // (fixed bug) must check for success of alloc sharedmem before
    // calling D100DisableInterrupt.
    D100DisableInterrupt(Adapter);

    // Next we'll register our interrupt with the NDIS wrapper.

    // Hook our interrupt vector.  We used level-triggered, shared interrupts
    // with our PCI adapters
    DEBUGSTR(("RegisterIrq: handl=%x, irq=%x, mode=%x\n",
        Adapter->D100AdapterHandle, Adapter->AiInterrupt,
        Adapter->InterruptMode));

    Status = NdisMRegisterInterrupt(&Adapter->Interrupt,
        Adapter->D100AdapterHandle,
        Adapter->AiInterrupt,
        Adapter->AiInterrupt,
        FALSE,
        TRUE, /* shared irq */
        Adapter->InterruptMode);

    if (Status != NDIS_STATUS_SUCCESS)
    {
        TRACESTR(Adapter,("Interrupt conflict, Status %08x, IRQ %d, %s Sensitive\n",
            Status,
            Adapter->AiInterrupt,
            (Adapter->InterruptMode==NdisInterruptLevelSensitive)?"Level":"Edge")
            );
        D100LogError(Adapter,
            EVENT_0,
            NDIS_ERROR_CODE_INTERRUPT_CONNECT,
            (ULONG) Adapter -> AiInterrupt);

        // Free the entire adapter object and error out
        FreeAdapterObject(Adapter);

        return NDIS_STATUS_FAILURE;
    }

    // Test our adapter hardware.  If the adapter is not seated in a bus
    // mastering slot, or if the master enable bit is not set in the adapter's
    // PCI configuration space, the self-test will fail.
    Status = SelfTestHardware(Adapter);

    if(Status != NDIS_STATUS_SUCCESS)
    {
        // Since the adapter failed the self-test, free any resources that
        // we previously allocated and error out.
        DEBUGSTR(("Adapter Self Test Failure.\n"));

        NdisMDeregisterInterrupt(&Adapter->Interrupt);
        FreeAdapterObject(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    // Setup and initialize the transmit structures.
    SetupTransmitQueues(Adapter, TRUE);

    // configure the 82557 (D100) chip.
    if (!InitializeAdapter(Adapter))
    {
        // Since the adapter failed to initialize, free any resources that
        // we previously allocated and error out.
        DEBUGSTR(("InitializeAdapter Failed.\n"));

        NdisMDeregisterInterrupt(&Adapter->Interrupt);
        FreeAdapterObject(Adapter);
        return NDIS_STATUS_FAILURE;
    }

    // allocate a spin lock for locking at all our entry points
    NdisAllocateSpinLock(&Adapter->Lock);
    //    DbgPrint ("E100B: Adapter->Lock address is %8X\n", (char *) &Adapter->Lock);
    //    DbgPrint ("E100B: Adapter->SendQueueListHead address is  0x%8X\n", (char *) &(Adapter->FirstTxQueue));

    // Setup and initialize the receive structures
    SetupReceiveQueues(Adapter);

    // Start the receive unit -- we can now receive packets off the wire
    StartReceiveUnit(Adapter);

    // register a shutdown handler...
    NdisMRegisterAdapterShutdownHandler(Adapter->D100AdapterHandle,
        (PVOID) Adapter,
        (ADAPTER_SHUTDOWN_HANDLER) D100ShutdownHandler);

    // Init a timer for use with our reset routine...
    NdisMInitializeTimer(&Adapter->D100AsyncResetTimer,
        Adapter->D100AdapterHandle,
        (PNDIS_TIMER_FUNCTION) D100ResetComplete,
        (PVOID) Adapter);

    // Enable board interrupts
    D100EnableInterrupt(Adapter);

    DEBUGSTR(("D100Initialize: Completed Init Successfully\n"));
    return NDIS_STATUS_SUCCESS;
}


//-----------------------------------------------------------------------------
// Procedure:   D100Reset
//
// Description: Instructs the Miniport to issue a hardware reset to the
//              network adapter.  The driver also resets its software state.
//              this function also resets the transmit queues.
//
// Arguments:
//      AddressingReset - TRUE if the wrapper needs to call
//                        MiniportSetInformation to restore the addressing
//                        information to the current values
//      MiniportAdapterContext - pointer to the adapter object data area.
//
// Returns:
//      NDIS_STATUS_PENDING - This function sets a timer to complete, so
//                            pending is always returned
//-----------------------------------------------------------------------------

NDIS_STATUS
D100Reset(PBOOLEAN AddressingReset,
          NDIS_HANDLE MiniportAdapterContext)
{
    PD100_ADAPTER Adapter;
    DEBUGFUNC("D100Reset");
    INITSTR(("\n"));

    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    NdisAcquireSpinLock(&Adapter->Lock);

    DEBUGCHAR(Adapter,'$');
    *AddressingReset = TRUE;

    // *** possible temporary code
    // *** NDIS may actually handle this
    Adapter->ResetInProgress = TRUE;

    // Disable interrupts while we re-init the transmit structures
    D100DisableInterrupt(Adapter);

    // The NDIS 5 support for deserialized miniports requires that
    // when reset is called, the driver de-queue and fail all uncompleted
    // sends, and complete any uncompleted sends. Essentially we must have
    // no pending send requests left when we leave this routine.


    // we will fail all sends that we have left right now.
    DEBUGSTR(("DeQing: "));
    while(Adapter->FirstTxQueue)
    {
        PNDIS_PACKET QueuePacket = Adapter->FirstTxQueue;

        Adapter->NumPacketsQueued--;
        DequeuePacket(Adapter->FirstTxQueue, Adapter->LastTxQueue);

        // we must release the lock here before returning control to ndis
        // (even temporarily like this)
        NdisReleaseSpinLock(&Adapter->Lock);
        NdisMSendComplete(
            Adapter->D100AdapterHandle,
            QueuePacket,
            NDIS_STATUS_FAILURE);

        NdisAcquireSpinLock(&Adapter->Lock);
    }
    DEBUGSTR(("\nDone!\n"));

    // clean up all the packets we have successfully TX'd
    ProcessTXInterrupt(Adapter);

    while (!(QueueEmpty(&Adapter->ActiveChainList)))
    {
        // here we have to fail any sends that haven't completed yet
        PD100SwTcb pSwTcb = (PD100SwTcb) QueuePopHead(&Adapter->ActiveChainList);

        // If this wasn't a multicast command, then we need to check to see
        // if we need to issue send complete
        if ((pSwTcb->Tcb->TxCbHeader.CbCommand & CB_CMD_MASK) != CB_MULTICAST)
        {
            DEBUGCHAR(Adapter,'-');
            NdisReleaseSpinLock(&Adapter->Lock);
            // Do a send Complete for this frame
            NdisMSendComplete(
                Adapter->D100AdapterHandle,
                pSwTcb->Packet,
                NDIS_STATUS_FAILURE);
            NdisAcquireSpinLock(&Adapter->Lock);
        }
    }

    // Issue a selective reset to make the CU idle.  This will also abort
    // the RU, and make the receive unit go idle.
    D100IssueSelectiveReset(Adapter);

    // since the d100/d101 both assert the interrupt line after reset,
    // lets try disabling ints here, because we don't handle
    // anything on a reset interrupt anyway.
    D100DisableInterrupt(Adapter);

    // Clear out our software transmit structures
    NdisZeroMemory((PVOID) Adapter->XmitCached, Adapter->XmitCachedSize);

    // re-init the map register related variables
    Adapter->NextFreeMapReg = 0;
    Adapter->OldestUsedMapReg = 0;

    // re-initialize the transmit structures
    DEBUGSTR(("D100Reset: Calling SetupTransmitQueues\n"));
    SetupTransmitQueues(Adapter, FALSE);

    // set a timer to call us back so
    // that we don't try to hold a spinlock too long
    // delay 500 ms
    NdisMSetTimer(&Adapter->D100AsyncResetTimer,500);

    NdisReleaseSpinLock(&Adapter->Lock);

    // return status_pending so that we can finish this later
    return(NDIS_STATUS_PENDING);
}

//-----------------------------------------------------------------------------
// D100ResetComplete
//
// PARAMETERS: NDIS_HANDLE MiniportAdapterContext
//
// DESCRIPTION: This function is called by a timer indicating our
//              reset is done (by way of .5 seconds expiring)
//
// RETURNS: nothing, but sets NdisMResetComplete, enables ints
//          and starts the receive unit
//
//-----------------------------------------------------------------------------

VOID
D100ResetComplete(PVOID sysspiff1,
                  NDIS_HANDLE MiniportAdapterContext,
                  PVOID sysspiff2, PVOID sysspiff3)
{
    PD100_ADAPTER Adapter;
    DEBUGFUNC("D100ResetComplete");

    INITSTR(("\n"));
    Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);

    DEBUGCHAR(Adapter,'@');

    NdisMResetComplete(Adapter->D100AdapterHandle,
        (NDIS_STATUS) NDIS_STATUS_SUCCESS,
        FALSE);

⌨️ 快捷键说明

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