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

📄 ne2000adapter.cpp

📁 VC++ 6.0NDIS, NDIS Miniport NIC Drivers
💻 CPP
📖 第 1 页 / 共 5 页
字号:

                }
            }
        }

        return(NDIS_STATUS_SUCCESS);
    }
}




/*** end of Handlers ***/




/*++

Routine Description:
    Called when a new adapter should be registered. It allocates space for
    the adapter, initializes the adapter's block, registers resources
    with the wrapper and initializes the physical adapter.
Arguments:
    WrapperConfigurationContext - Handle passed by the Ndis
    ConfigError - Was there an error during configuration reading.
    ConfigErrorValue - Value to log if there is an error.
Return Value:
    Indicates the success or failure of the registration.
--*/
NDIS_STATUS KdNe2000Adapter::Register(NDIS_HANDLE WrapperConfigurationContext,     
                                      BOOLEAN ConfigError,
                                      ULONG ConfigErrorValue)

{

    // Temporary looping variable.
    UINT i;
    // General purpose return from NDIS calls
    NDIS_STATUS status;
    // check that NumBuffers <= MAX_XMIT_BUFS
    if (Info.NumBuffers > MAX_XMIT_BUFS)
        return(NDIS_STATUS_RESOURCES);
    // Check for a configuration error
    if (ConfigError)
    {
        // Log Error and exit.
        NdisWriteErrorLogEntry(
            GetMiniportAdapterHandle(),
            NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
            1,
            ConfigErrorValue
            );
        return(NDIS_STATUS_FAILURE);
    }

    // Set Attr was already called with default values - we dont take any chances and call SetAttr
    // with the values we want
    SetAttr(FALSE,Info.BusType);

    // Register the port addresses.
    status =  RegisterIoPortRange((PVOID *)(&(Info.IoPAddr)),(ULONG)Info.IoBaseAddr,0x20);
    if (status != NDIS_STATUS_SUCCESS)
        return(status);

    if (NE2000_ISA == Info.CardType)
    {
        // Check that the IoBaseAddress seems to be correct.
        DebugDump(DBG_LEVEL4,("Checking Parameters\n"));
        if (!CardCheckParameters())
        {
            // The card does not seem to be there, fail silently.
            DebugDump(DBG_LEVEL4,("  -- Failed\n"));
            NdisWriteErrorLogEntry(
                GetMiniportAdapterHandle(),
                NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
                0);
            status = NDIS_STATUS_ADAPTER_NOT_FOUND;
            goto fail2;
        }

        DebugDump(DBG_LEVEL4,("  -- Success\n"));
    }

    // Initialize the card.
    DebugDump(DBG_LEVEL4,("CardInitialize\n"));
    if (!CardInitialize())
    {

        // Card seems to have failed.
        DebugDump(DBG_LEVEL4,("  -- Failed\n"));
        NdisWriteErrorLogEntry(
            GetMiniportAdapterHandle(),
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
        );

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;
        goto fail2;
    }

    DebugDump(DBG_LEVEL4,("  -- Success\n"));

    // For programmed I/O, we will refer to transmit/receive memory in
    // terms of offsets in the card's 64K address space.
    Info.XmitStart = Info.RamBase;

    // For the NicXXX fields, always use the addressing system
    // containing the MSB only).
    Info.NicXmitStart = (UCHAR)(((ULONG)Info.XmitStart) >> 8);
    // The start of the receive space.
    Info.PageStart = Info.XmitStart +
            (Info.NumBuffers * TX_BUF_SIZE);
    Info.NicPageStart = Info.NicXmitStart +
            (UCHAR)(Info.NumBuffers * BUFS_PER_TX);

    ASSERT(Info.PageStart < (Info.RamBase + Info.RamSize));

    // The end of the receive space.
    Info.PageStop = Info.XmitStart + Info.RamSize;
    Info.NicPageStop = Info.NicXmitStart + (UCHAR)(Info.RamSize >> 8);

    ASSERT(Info.PageStop <= (Info.RamBase + Info.RamSize));

    DebugDump(DBG_LEVEL3,("Xmit Start (0x%x, 0x%x) : Rcv Start (0x%x, 0x%x) : Rcv End (0x%x, 0x%x)\n",
              Info.XmitStart,
              Info.NicXmitStart,
              Info.PageStart,
              Info.NicPageStart,
              (ULONG)Info.PageStop,
              Info.NicPageStop
             ));

    // Initialize the receive variables.
    Info.NicReceiveConfig = RCR_REJECT_ERR;
    // Initialize the transmit buffer control.
    Info.CurBufXmitting = (XMIT_BUF)-1;
    // Initialize the transmit buffer states.
    for (i = 0; i < Info.NumBuffers; i++)
        Info.BufferStatus[i] = EMPTY;
    // Read the Ethernet address off of the PROM.
    if (!CardReadEthernetAddress())
    {
        DebugDump(DBG_LEVEL3,("Could not read the ethernet address\n"));
        NdisWriteErrorLogEntry(
            GetMiniportAdapterHandle(),
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
            );

        status = NDIS_STATUS_ADAPTER_NOT_FOUND;
        goto fail2;
    }

    // Now initialize the NIC and Gate Array registers.
    Info.NicInterruptMask = IMR_RCV | IMR_XMIT | IMR_XMIT_ERR | IMR_OVERFLOW;
    // Link us on to the chain of adapters for this driver.
    GetMiniportOwner()->AddAdapter(this); 
    // Setup the card based on the initialization information
    DebugDump(DBG_LEVEL4,("Setup\n"));
    if (!CardSetup())
    {
        // The NIC could not be written to.
        NdisWriteErrorLogEntry(
            GetMiniportAdapterHandle(),
            NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
            0
        );

        DebugDump(DBG_LEVEL4,("  -- Failed\n"));
        status = NDIS_STATUS_ADAPTER_NOT_FOUND;
        goto fail3;
    }

    DebugDump(DBG_LEVEL4,("  -- Success\n"));

    // Initialize the interrupt.
    status = RegisterInterrupt(
                 Info.InterruptNumber,
                 Info.InterruptNumber,
                 FALSE,
                 FALSE,
                 NdisInterruptLatched);
    if (status != NDIS_STATUS_SUCCESS)
    {
        NdisWriteErrorLogEntry(
            GetMiniportAdapterHandle(),
            NDIS_ERROR_CODE_INTERRUPT_CONNECT,
            0  );

        goto fail3;
    }

    DebugDump(DBG_LEVEL3,("Interrupt Connected\n"));

    // Start up the adapter.
    CardStart(this);

    // Initialization completed successfully.
    DebugDump(DBG_LEVEL3,(" [ Ne2000 ] : OK\n"));
    return(NDIS_STATUS_SUCCESS);

    // Code to unwind what has already been set up when a part of
    // initialization fails, which is jumped into at various
    // points based on where the failure occurred. Jumping to
    // a higher-numbered failure point will execute the code
    // for that block and all lower-numbered ones.
fail3:
    // Take us out of the AdapterQueue.
    GetMiniportOwner()->RemoveAdapter(this);
    // 
    // We already enabled the interrupt on the card, so
    // turn it off.
    NdisRawWritePortUchar(Info.IoPAddr+NIC_COMMAND, CR_STOP);
fail2:
    DeregisterIoPortRange((ULONG)Info.IoBaseAddr,0x20,(PVOID)Info.IoPAddr);
    return(status);
}





/*++
Routine Description:
    This routine examines if the packet at the head of the packet
    list can be copied to the adapter, and does so.Called by the SendHandler
    each time there is a new packet to send and also each time after we receive a 
    TransmitComplete Interrupt
--*/
VOID KdNe2000Adapter::DoNextSend()

{
    // The packet to process.
    PNDIS_PACKET Packet;
    // The current destination transmit buffer.
    XMIT_BUF TmpBuf1;
    // Length of the packet
    ULONG Len;
    // Temporary looping variable
    ULONG i;

    IF_LOG( Ne2000Log('s'); )
    // Check if we have enough resources and a packet to process
    while((Info.FirstPacket != NULL) &&
          (Info.BufferStatus[Info.NextBufToFill] == EMPTY)) 
    {
        // Get the length of the packet.
        NdisQueryPacket(Info.FirstPacket, NULL, NULL, NULL, (UINT *)&Len);
        // Convert length to the number of transmit buffers needed.
        Len = (Len + 255) >> 8;
        // If not transmitting
        if (Info.CurBufXmitting == -1) 
        {
            // Then check from the next free buffer if the packet will
            // fit.
            if (Info.BufferStatus[Info.NextBufToXmit] == EMPTY) 
            {
                // It won't fit at the end, so put it at the first buffer
                if (Info.NextBufToFill + Len > MAX_XMIT_BUFS) 
                {
                    Info.NextBufToFill = 0;
                }

            } 
            else 
            {
                // Check if this packet will fit before the packet on the
                // adapter.
                if (Info.NextBufToXmit > Info.NextBufToFill) 
                {
                    if (Info.NextBufToFill + Len > Info.NextBufToXmit) 
                    {
                        IF_LOG( Ne2000Log('^'); )
                        IF_LOG( Ne2000Log('S'); )
                        break;
                    }

                } 
                else 
                {
                    // Check if it will fit after the packet already on the
                    // adapter.
                    if (Info.NextBufToFill + Len > MAX_XMIT_BUFS) 
                    {

                        Info.NextBufToFill = 0;
                        if (Info.NextBufToFill + Len > Info.NextBufToXmit)
                        {
                            IF_LOG( Ne2000Log('%'); )
                            IF_LOG( Ne2000Log('S'); )
                            break;
                        }
                    }
                }
            }

        } 
        else 
        {
            // Check if the packet will fit before the packet currently
            // transmitting
            if (Info.CurBufXmitting > Info.NextBufToFill) 
            {
                if (Info.NextBufToFill + Len > Info.CurBufXmitting) 
                {
                    IF_LOG( Ne2000Log('$'); )
                    IF_LOG( Ne2000Log('S'); )
                    break;
                }
            }
            else 
            {
                // Check if it will fit after the packet currently transmitting
                if (Info.NextBufToFill + Len > MAX_XMIT_BUFS) 
                {
                    Info.NextBufToFill = 0;
                    if (Info.NextBufToFill + Len > Info.CurBufXmitting)
                    {
                        IF_LOG( Ne2000Log('!'); )
                        IF_LOG( Ne2000Log('S'); )
                        break;
                    }
                }
            }
        }

        // Set starting location
        TmpBuf1 = Info.NextBufToFill;
        // Remove the packet from the queue.
        Packet = Info.FirstPacket;
        Info.FirstPacket = RESERVED(Packet)->Next;

        if (Packet == Info.LastPacket) 
        {
            Info.LastPacket = NULL;
        }
        // Store the packet in the list
        Info.Packets[TmpBuf1] = Packet;
        // Copy down the packet.
        if (CardCopyDownPacket(Packet,&Info.PacketLens[TmpBuf1]) == FALSE) 
        {
            for (i = TmpBuf1; i < TmpBuf1 + Len; i++) 
            {
                Info.BufferStatus[i] = EMPTY;
            }
            Info.Packets[TmpBuf1] = NULL;
            IF_LOG( Ne2000Log('F'); )
            IF_LOG( Ne2000Log('S'); )

            SendComplete(Packet, NDIS_STATUS_FAILURE);
            continue;
        }

        // Pad short packets with blanks.
        if (Info.PacketLens[TmpBuf1] < 60) 
        {
            (VOID)CardCopyDown(
                    ((PUCHAR)Info.XmitStart +
                    TmpBuf1*TX_BUF_SIZE +
                    Info.PacketLens[TmpBuf1]),
                    BlankBuffer,
                    60-Info.PacketLens[TmpBuf1]
                    );
        }

        // Set the buffer status
        for (i = TmpBuf1; i < (TmpBuf1 + Len); i++) 
        {
                Info.BufferStatus[i] = FULL;
        }

        // Update next free buffer
        Info.NextBufToFill += Len;
        if (Info.NextBufToFill == MAX_XMIT_BUFS) 
        {
            Info.NextBufToFill = 0;
        }

        // See whether to start the transmission.
        if (Info.CurBufXmitting == -1) 
        {
            // OK to start transmission.
            if (Info.BufferStatus[Info.NextBufToXmit] == EMPTY &&
                Info.NextBufToFill != Info.NextBufToXmit) 
            {
                Info.NextBufToXmit = 0;
            }

            Info.CurBufXmitting = Info.NextBufToXmit;
            IF_LOG( Ne2000Log('4');)

            // If we are currently handling an overflow, then we need to let
            // the overflow handler send this packet...
            if (Info.BufferOverflow) 
            {
                Info.OverflowRestartXmitDpc = TRUE;
                IF_LOG( Ne2000Log('O');)
                DebugDump(DBG_LEVEL3, ("Info.OverflowRestartXmitDpc set:copy and send"));

            } 
            else 
            {

                // This is used to check if stopping the chip prevented
                // a transmit complete interrupt from coming through (it
                // is cleared in the ISR if a transmit DPC is queued).
                Info.TransmitInterruptPending = TRUE;
                IF_LOG( Ne2000Log('9'); )
                CardStartXmit();
            }

        }

        // Ack the send immediately.  If for some reason it
        // should fail, the protocol should be able to handle
        // the retransmit.
        IF_LOG( Ne2000Log('S'); )
        SendComplete(Packet,NDIS_STATUS_SUCCESS);
    }

}

⌨️ 快捷键说明

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