?? card.c
字號:
/*++
Copyright (c) 1990-1998 Microsoft Corporation, All Rights Reserved.
Module Name:
card.c
Abstract:
Card-specific functions for the NDIS 3.0 Novell 2000 driver.
Author:
Sean Selitrennikoff
Environment:
Kernel mode, FSD
Revision History:
--*/
#include "precomp.h"
BOOLEAN
CardSlotTest(
IN PNE2000_ADAPTER Adapter
);
BOOLEAN
CardRamTest(
IN PNE2000_ADAPTER Adapter
);
#pragma NDIS_PAGEABLE_FUNCTION(CardCheckParameters)
BOOLEAN CardCheckParameters(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Checks that the I/O base address is correct.
Arguments:
Adapter - pointer to the adapter block.
Return Value:
TRUE, if IoBaseAddress appears correct.
--*/
{
UCHAR Tmp;
//
// If adapter responds to a stop command correctly -- assume it is there.
//
//
// Turn off interrupts first.
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_INTR_MASK, 0);
//
// Stop the card.
//
SyncCardStop(Adapter);
//
// Pause
//
NdisStallExecution(2000);
//
// Read response
//
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_COMMAND, &Tmp);
if ((Tmp == (CR_NO_DMA | CR_STOP)) ||
(Tmp == (CR_NO_DMA | CR_STOP | CR_START))
)
{
return(TRUE);
}
else
{
return(FALSE);
}
}
#ifdef NE2000
#pragma NDIS_PAGEABLE_FUNCTION(CardSlotTest)
BOOLEAN CardSlotTest(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Checks if the card is in an 8 or 16 bit slot and sets a flag in the
adapter structure.
Arguments:
Adapter - pointer to the adapter block.
Return Value:
TRUE, if all goes well, else FALSE.
--*/
{
UCHAR Tmp;
UCHAR RomCopy[32];
UCHAR i;
BOOLEAN found;
//
// Reset the chip
//
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_RESET, &Tmp);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RESET, 0xFF);
//
// Go to page 0 and stop
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_COMMAND, CR_STOP | CR_NO_DMA);
//
// Pause
//
NdisStallExecution(2000);
//
// Check that it is stopped
//
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_COMMAND, &Tmp);
if (Tmp != (CR_NO_DMA | CR_STOP))
{
IF_LOUD(DbgPrint("Could not stop the card\n");)
return(FALSE);
}
//
// Setup to read from ROM
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_DATA_CONFIG,
DCR_BYTE_WIDE | DCR_FIFO_8_BYTE | DCR_NORMAL
);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_INTR_MASK, 0x0);
//
// Ack any interrupts that may be hanging around
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_INTR_STATUS, 0xFF);
//
// Setup to read in the ROM, the address and byte count.
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RMT_ADDR_LSB, 0x0);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RMT_ADDR_MSB, 0x0);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RMT_COUNT_LSB, 32);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RMT_COUNT_MSB, 0x0);
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_COMMAND,
CR_DMA_READ | CR_START
);
//
// Read first 32 bytes in 16 bit mode
//
for (i = 0; i < 32; i++)
{
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_RACK_NIC, RomCopy + i);
}
IF_VERY_LOUD( DbgPrint("Resetting the chip\n"); )
//
// Reset the chip
//
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_RESET, &Tmp);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RESET, 0xFF);
//
// Check ROM for 'B' (byte) or 'W' (word)
// NOTE: If the buffer has bot BB and WW then use WW instead of BB
IF_VERY_LOUD( DbgPrint("Checking slot type\n"); )
found = FALSE;
for (i = 16; i < 31; i++)
{
if (((RomCopy[i] == 'B') && (RomCopy[i+1] == 'B')) ||
((RomCopy[i] == 'W') && (RomCopy[i+1] == 'W'))
)
{
if (RomCopy[i] == 'B')
{
Adapter->EightBitSlot = TRUE;
found = TRUE;
}
else
{
Adapter->EightBitSlot = FALSE;
found = TRUE;
break; // Go no farther
}
}
}
if (found)
{
IF_VERY_LOUD( (Adapter->EightBitSlot?DbgPrint("8 bit slot\n"):
DbgPrint("16 bit slot\n")); )
}
else
{
//
// If neither found -- then not an NE2000
//
IF_VERY_LOUD( DbgPrint("Failed slot type\n"); )
}
return(found);
}
#endif // NE2000
#pragma NDIS_PAGEABLE_FUNCTION(CardRamTest)
BOOLEAN
CardRamTest(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Finds out how much RAM the adapter has. It starts at 1K and checks thru
60K. It will set Adapter->RamSize to the appropriate value iff this
function returns TRUE.
Arguments:
Adapter - pointer to the adapter block.
Return Value:
TRUE, if all goes well, else FALSE.
--*/
{
PUCHAR RamBase, RamPointer;
PUCHAR RamEnd;
UCHAR TestPattern[]={ 0xAA, 0x55, 0xFF, 0x00 };
PULONG pTestPattern = (PULONG)TestPattern;
UCHAR ReadPattern[4];
PULONG pReadPattern = (PULONG)ReadPattern;
for (RamBase = (PUCHAR)0x400; RamBase < (PUCHAR)0x10000; RamBase += 0x400) {
//
// Write Test pattern
//
if (!CardCopyDown(Adapter, RamBase, TestPattern, 4)) {
continue;
}
//
// Read pattern
//
if (!CardCopyUp(Adapter, ReadPattern, RamBase, 4)) {
continue;
}
IF_VERY_LOUD( DbgPrint("Addr 0x%x: 0x%x, 0x%x, 0x%x, 0x%x\n",
RamBase,
ReadPattern[0],
ReadPattern[1],
ReadPattern[2],
);
)
//
// If they are the same, find the end
//
if (*pReadPattern == *pTestPattern) {
for (RamEnd = RamBase; !(PtrToUlong(RamEnd) & 0xFFFF0000); RamEnd += 0x400) {
//
// Write test pattern
//
if (!CardCopyDown(Adapter, RamEnd, TestPattern, 4)) {
break;
}
//
//
if (!CardCopyUp(Adapter, ReadPattern, RamEnd, 4)) {
break;
}
if (*pReadPattern != *pTestPattern) {
break;
}
}
break;
}
}
IF_LOUD( DbgPrint("RamBase 0x%x, RamEnd 0x%x\n", RamBase, RamEnd); )
//
// If not found, error out
//
if ((RamBase >= (PUCHAR)0x10000) || (RamBase == RamEnd)) {
return(FALSE);
}
//
// Watch for boundary case when RamEnd is maximum value
//
if ((ULONG_PTR)RamEnd & 0xFFFF0000) {
RamEnd -= 0x100;
}
//
// Check all of ram
//
for (RamPointer = RamBase; RamPointer < RamEnd; RamPointer += 4) {
//
// Write test pattern
//
if (!CardCopyDown(Adapter, RamPointer, TestPattern, 4)) {
return(FALSE);
}
//
// Read pattern
//
if (!CardCopyUp(Adapter, ReadPattern, RamBase, 4)) {
return(FALSE);
}
if (*pReadPattern != *pTestPattern) {
return(FALSE);
}
}
//
// Store Results
//
Adapter->RamBase = RamBase;
Adapter->RamSize = (ULONG)(RamEnd - RamBase);
return(TRUE);
}
#pragma NDIS_PAGEABLE_FUNCTION(CardInitialize)
BOOLEAN
CardInitialize(
IN PNE2000_ADAPTER Adapter
)
/*++
Routine Description:
Initializes the card into a running state.
Arguments:
Adapter - pointer to the adapter block.
Return Value:
TRUE, if all goes well, else FALSE.
--*/
{
UCHAR Tmp;
USHORT i;
//
// Stop the card.
//
SyncCardStop(Adapter);
//
// Initialize the Data Configuration register.
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_DATA_CONFIG,
DCR_AUTO_INIT | DCR_FIFO_8_BYTE
);
//
// Set Xmit start location
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_XMIT_START, 0xA0);
//
// Set Xmit configuration
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_XMIT_CONFIG, 0x0);
//
// Set Receive configuration
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RCV_CONFIG, RCR_MONITOR);
//
// Set Receive start
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_PAGE_START, 0x4);
//
// Set Receive end
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_PAGE_STOP, 0xFF);
//
// Set Receive boundary
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_BOUNDARY, 0x4);
//
// Set Xmit bytes
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_XMIT_COUNT_LSB, 0x3C);
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_XMIT_COUNT_MSB, 0x0);
//
// Pause
//
NdisStallExecution(2000);
//
// Ack all interrupts that we might have produced
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_INTR_STATUS, 0xFF);
//
// Change to page 1
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_COMMAND, CR_PAGE1 | CR_STOP);
//
// Set current
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_CURRENT, 0x4);
//
// Back to page 0
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_COMMAND, CR_PAGE0 | CR_STOP);
//
// Pause
//
NdisStallExecution(2000);
//
// Check that Command register reflects this last command
//
NdisRawReadPortUchar(Adapter->IoPAddr + NIC_COMMAND, &Tmp);
if (!(Tmp & CR_STOP))
{
IF_LOUD(DbgPrint("Invalid command register\n");)
return(FALSE);
}
//
// Do initialization errata
//
NdisRawWritePortUchar(Adapter->IoPAddr + NIC_RMT_COUNT_LSB, 55);
//
// Setup for a read
//
NdisRawWritePortUchar(
Adapter->IoPAddr + NIC_COMMAND,
CR_DMA_READ | CR_START
);
#ifdef NE2000
//
// Check if the slot is 8 or 16 bit (affects data transfer rate).
//
if ((Adapter->BusType == NdisInterfaceMca) ||
(NE2000_PCMCIA == Adapter->CardType))
{
Adapter->EightBitSlot = FALSE;
}
else
{
IF_VERY_LOUD(DbgPrint("CardSlotTest\n");)
if (CardSlotTest(Adapter) == FALSE)
{
//
// Stop chip
//
SyncCardStop(Adapter);
IF_LOUD(DbgPrint(" -- Failed\n");)
return(FALSE);
}
}
#else // NE2000
Adapter->EightBitSlot = TRUE;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -