827 lines
23 KiB
C
827 lines
23 KiB
C
#if 1 // The following includes are used when building with the microsoft internal build tree.
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#else // These headers are used when building with the microsoft DDK.
|
|
#include <ntddk.h>
|
|
#include <windef.h>
|
|
#include <winerror.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ntddnetd.h>
|
|
#include <ncnet.h>
|
|
#include <netdet.h>
|
|
|
|
BOOLEAN
|
|
Nia35DetInit(
|
|
IN HANDLE hModule,
|
|
IN DWORD dwReason,
|
|
IN DWORD dwReserved
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
This routine is the entry point into the detection dll.
|
|
This routine only return "TRUE".
|
|
|
|
++*/
|
|
{
|
|
return (TRUE);
|
|
}
|
|
|
|
|
|
|
|
ULONG
|
|
Nia35NextIoAddress(
|
|
IN ULONG IoBaseAddress
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
This routine provide next I/O address for detect PC-9801-107/108.
|
|
|
|
++*/
|
|
{
|
|
switch(IoBaseAddress){
|
|
case 0x0770:
|
|
return (0x2770);
|
|
case 0x2770:
|
|
return (0x4770);
|
|
case 0x4770:
|
|
return (0x6770);
|
|
default:
|
|
return (0xffff);
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
Nia35CardSetup(
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN ULONG IoBaseAddress,
|
|
OUT PULONG MemoryBaseAddress,
|
|
IN BOOLEAN EightBitSlot
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Sets up the card, using the sequence given in the Etherlink II
|
|
technical reference.
|
|
|
|
Arguments:
|
|
|
|
InterfaceType - The type of bus, ISA or EISA.
|
|
BusNumber - The bus number in the system.
|
|
IoBaseAddress - The IO port address of the card.
|
|
MemoryBaseAddress - Pointer to store the base address of card memory.
|
|
EightBitSlot - TRUE if the adapter is in an 8-bit slot.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
UINT i;
|
|
UCHAR Tmp;
|
|
NTSTATUS NtStatus;
|
|
LARGE_INTEGER Delay;
|
|
|
|
*MemoryBaseAddress = 0;
|
|
|
|
// Stop the card.
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x21); // STOP | ABORT_DMA
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Initialize the Data Configuration register.
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100c, // NIC_DATA_CONFIG
|
|
0x50); // DCR_AUTO_INIT | DCR_FIFO_8_BYTE
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Xmit start location
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x0008, // NIC_XMIT_START
|
|
0xA0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Xmit configuration
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100a, // NIC_XMIT_CONFIG
|
|
0x0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Receive configuration
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1008, // NIC_RCV_CONFIG
|
|
0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Receive start
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x0002, // NIC_PAGE_START
|
|
0x4);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Receive end
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x0004, // NIC_PAGE_STOP
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Receive boundary
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x0006, // NIC_BOUNDARY
|
|
0x4);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set Xmit bytes
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000a, // NIC_XMIT_COUNT_LSB
|
|
0x3C);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000c, // NIC_XMIT_COUNT_MSB
|
|
0x0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Pause
|
|
|
|
// Wait for reset to complete. (100 ms)
|
|
Delay.LowPart = 100000;
|
|
Delay.HighPart = 0;
|
|
|
|
NtDelayExecution(FALSE, &Delay);
|
|
|
|
// Ack all interrupts that we might have produced
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000e, // NIC_INTR_STATUS
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Change to page 1
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x61); // CR_PAGE1 | CR_STOP
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Set current
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000e, // NIC_CURRENT
|
|
0x4);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Back to page 0
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x21); // CR_PAGE0 | CR_STOP
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Pause
|
|
Delay.LowPart = 2000;
|
|
Delay.HighPart = 0;
|
|
|
|
NtDelayExecution(FALSE, &Delay);
|
|
|
|
// Do initialization errata
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1004, // NIC_RMT_COUNT_LSB
|
|
55);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Reset the chip
|
|
NtStatus = NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
&Tmp);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Start the chip
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x22);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Mask Interrupts
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100e, // NIC_INTR_MASK
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
if(EightBitSlot){
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100c, // NIC_DATA_CONFIG
|
|
0x48); // DCR_FIFO_8_BYTE | DCR_NORMAL | DCR_BYTE_WIDE
|
|
}else{
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100c, // NIC_DATA_CONFIG
|
|
0x49); // DCR_FIFO_8_BYTE | DCR_NORMAL | DCR_WORD_WIDE
|
|
}
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100a, // NIC_XMIT_CONFIG
|
|
0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1008, // NIC_RCV_CONFIG
|
|
0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000e, // NIC_INTR_STATUS
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x21); // CR_NO_DMA | CR_STOP
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1004, // NIC_RMT_COUNT_LSB
|
|
0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1006, // NIC_RMT_COUNT_MSB
|
|
0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// Wait for STOP to complete
|
|
i = 0xFF;
|
|
while (--i){
|
|
NtStatus = NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000e, // NIC_INTR_STATUS
|
|
&Tmp);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return;
|
|
}
|
|
|
|
// ISR_RESET
|
|
if(Tmp & 0x80){
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Put card in loopback mode
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100a, // NIC_XMIT_CONFIG
|
|
0x2); // TCR_LOOPBACK
|
|
|
|
if(NtStatus != STATUS_SUCCESS){
|
|
return;
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x22); // CR_NO_DMA | CR_START
|
|
|
|
if(NtStatus != STATUS_SUCCESS){
|
|
return;
|
|
}
|
|
|
|
// ... but it is still in loopback mode.
|
|
return;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
Nia35CardSlotTest(
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN ULONG IoBaseAddress,
|
|
OUT PBOOLEAN EightBitSlot
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Checks if the card is in an 8 or 16 bit slot and sets a flag in the
|
|
adapter structure.
|
|
|
|
Arguments:
|
|
|
|
|
|
InterfaceType - The type of bus, ISA or EISA.
|
|
BusNumber - The bus number in the system.
|
|
IoBaseAddress - The IO port address of the card.
|
|
EightBitSlot - Result of test.
|
|
|
|
Return Value:
|
|
|
|
TRUE, if all goes well, else FALSE.
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR Tmp;
|
|
UCHAR RomCopy[32];
|
|
UCHAR i;
|
|
NTSTATUS NtStatus;
|
|
LARGE_INTEGER Delay;
|
|
|
|
// Reset the chip
|
|
NtStatus = NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
&Tmp);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
0xFF);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
// Go to page 0 and stop
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x21); // CR_STOP | CR_NO_DMA
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
// Pause
|
|
Delay.LowPart = 2000;
|
|
Delay.HighPart = 0;
|
|
|
|
NtDelayExecution(FALSE, &Delay);
|
|
|
|
// Setup to read from ROM
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100c, // NIC_DATA_CONFIG
|
|
0x48); // DCR_BYTE_WIDE | DCR_FIFO_8_BYTE | DCR_NORMAL
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x100e, // NIC_INTR_MASK
|
|
0x0);
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
// Ack any interrupts that may be hanging around
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x000e, // NIC_INTR_STATUS
|
|
0xFF);
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1000, // NIC_RMT_ADDR_LSB
|
|
0x0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1002, // NIC_RMT_ADDR_MSB,
|
|
0x0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1004, // NIC_RMT_COUNT_LSB
|
|
32);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1006, // NIC_RMT_COUNT_MSB
|
|
0x0);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0xA); // CR_DMA_READ | CR_START
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
return(NtStatus);
|
|
}
|
|
|
|
// Read first 32 bytes in 16 bit mode
|
|
for (i = 0; i < 32; i++){
|
|
NtStatus = NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x0888, //NIC_RACK_NIC
|
|
RomCopy + i);
|
|
|
|
if(NtStatus != STATUS_SUCCESS){
|
|
return(NtStatus);
|
|
}
|
|
}
|
|
|
|
// Reset the chip
|
|
NtStatus = NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
&Tmp);
|
|
|
|
if(NtStatus != STATUS_SUCCESS){
|
|
return(NtStatus);
|
|
}
|
|
|
|
NtStatus = NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
0xFF);
|
|
if(NtStatus != STATUS_SUCCESS){
|
|
return(NtStatus);
|
|
}
|
|
|
|
// Check ROM for 'B' (byte) or 'W' (word)
|
|
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'){
|
|
*EightBitSlot = TRUE;
|
|
}else{
|
|
*EightBitSlot = FALSE;
|
|
}
|
|
|
|
// Now check that the address is singular. On an Ne1000 the
|
|
// ethernet address is store in offsets 0 thru 5. On the Ne2000 and Nia35
|
|
// the address is stored in offsets 0 thru 11, where each byte
|
|
// is duplicated.
|
|
//
|
|
if ((RomCopy[0] == RomCopy[1]) &&
|
|
(RomCopy[2] == RomCopy[3]) &&
|
|
(RomCopy[4] == RomCopy[5]) &&
|
|
(RomCopy[6] == RomCopy[7]) &&
|
|
(RomCopy[8] == RomCopy[9]) &&
|
|
(RomCopy[10] == RomCopy[11])){
|
|
return(STATUS_SUCCESS);
|
|
}
|
|
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
}
|
|
|
|
// If neither found -- then not an NIA35
|
|
return(STATUS_UNSUCCESSFUL);
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
FindNia35Adapter(
|
|
OUT PMND_ADAPTER_INFO *pDetectedAdapter,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN ULONG IoBaseAddress,
|
|
IN PWSTR pPnpId
|
|
)
|
|
{
|
|
NTSTATUS NtStatus;
|
|
UCHAR Data;
|
|
USHORT CheckSum = 0;
|
|
USHORT StoredCheckSum;
|
|
UINT Place;
|
|
UCHAR Interrupt = 0;
|
|
HANDLE TrapHandle;
|
|
UCHAR InterruptList[4];
|
|
UCHAR ResultList[4] = {0};
|
|
UINT cResources;
|
|
UINT c;
|
|
UCHAR Value;
|
|
ULONG RamAddr = 0;
|
|
|
|
do{
|
|
|
|
// check I/O port range.
|
|
NtStatus = NDetCheckPortUsage(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
0x10);
|
|
NtStatus |= NDetCheckPortUsage(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress + 0x1000, // upper range
|
|
0x10);
|
|
NtStatus |= NDetCheckPortUsage(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x0888, // NIC_RACK_NIC
|
|
0x2);
|
|
NtStatus |= NDetCheckPortUsage(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, // NIC_RESET
|
|
0x2);
|
|
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
#if DBG
|
|
DbgPrint("FindNia35Adapter : Port range in use. IoBaseAddress = %x\n", IoBaseAddress);
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
&Value);
|
|
NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
0xFF);
|
|
NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress, // COMMAND
|
|
0x21);
|
|
|
|
// check interrupt.
|
|
InterruptList[0] = 3;
|
|
InterruptList[1] = 5;
|
|
InterruptList[2] = 6;
|
|
InterruptList[3] = 12;
|
|
|
|
NtStatus = NDetSetInterruptTrap(InterfaceType,
|
|
BusNumber,
|
|
&TrapHandle,
|
|
InterruptList,
|
|
4);
|
|
if(NT_SUCCESS(NtStatus)){
|
|
|
|
NtStatus = Nia35CardSlotTest(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
&Value);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
NDetRemoveInterruptTrap(TrapHandle);
|
|
break;
|
|
}
|
|
|
|
// CardSetup
|
|
Nia35CardSetup(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
&RamAddr,
|
|
Value);
|
|
|
|
// Check for interrupt.
|
|
NtStatus = NDetQueryInterruptTrap(TrapHandle, ResultList, 4);
|
|
|
|
// Stop the chip.
|
|
NDetReadPortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
&Value);
|
|
|
|
NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, //NIC_RESET
|
|
0xFF);
|
|
|
|
NDetWritePortUchar(InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress, // COMMAND
|
|
0x21);
|
|
|
|
NtStatus = NDetRemoveInterruptTrap(TrapHandle);
|
|
if(!NT_SUCCESS(NtStatus)){
|
|
break;
|
|
}
|
|
|
|
for(c=0 ; c<4 ; c++){
|
|
if((ResultList[c] == 1) || (ResultList[c] == 2)){
|
|
Interrupt = InterruptList[c];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Allocate the adapter information.
|
|
NtStatus = NetDetectAllocAdapterInfo(pDetectedAdapter,
|
|
InterfaceType,
|
|
BusNumber,
|
|
pPnpId,
|
|
0,
|
|
0,
|
|
0,
|
|
2);
|
|
if (!NT_SUCCESS(NtStatus)){
|
|
#if DBG
|
|
DbgPrint("FindNia35Adapter: Unable to allocate adapter info\n");
|
|
#endif
|
|
break;
|
|
}
|
|
|
|
// Initialize the resources.
|
|
NetDetectInitializeResource(*pDetectedAdapter,
|
|
0,
|
|
MndResourcePort,
|
|
IoBaseAddress,
|
|
0x10);
|
|
NetDetectInitializeResource(*pDetectedAdapter,
|
|
0,
|
|
MndResourcePort,
|
|
IoBaseAddress + 0x1000,
|
|
0x10);
|
|
NetDetectInitializeResource(*pDetectedAdapter,
|
|
0,
|
|
MndResourcePort,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x0888, // NIC_RACK_NIC
|
|
0x2);
|
|
NetDetectInitializeResource(*pDetectedAdapter,
|
|
0,
|
|
MndResourcePort,
|
|
((IoBaseAddress >> 1) & 0xf000) + 0x088a, // NIC_RESET
|
|
0x2);
|
|
|
|
|
|
if(Interrupt != 0){
|
|
NetDetectInitializeResource(*pDetectedAdapter,
|
|
1,
|
|
MndResourceInterrupt,
|
|
Interrupt,
|
|
MND_RESOURCE_INTERRUPT_LATCHED);
|
|
}
|
|
|
|
NtStatus = STATUS_SUCCESS;
|
|
|
|
}while(FALSE);
|
|
|
|
return (NtStatus);
|
|
|
|
}
|
|
|
|
NTSTATUS
|
|
WINAPI
|
|
FindAdapterHandler(
|
|
IN OUT PMND_ADAPTER_INFO *pDetectedAdapter,
|
|
IN INTERFACE_TYPE InterfaceType,
|
|
IN ULONG BusNumber,
|
|
IN PDET_ADAPTER_INFO pAdapterInfo,
|
|
IN PDET_CONTEXT pDetContext
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS NtStatus;
|
|
ULONG IoBaseAddress;
|
|
|
|
if(InterfaceType != Isa){
|
|
return(STATUS_INVALID_PARAMETER);
|
|
}
|
|
|
|
// Are we looking for the first adapter?
|
|
if (fDET_CONTEXT_FIND_FIRST == (pDetContext->Flags & fDET_CONTEXT_FIND_FIRST)){
|
|
// Initialize the context information so that we start detecting
|
|
// at the initialize port range.
|
|
pDetContext->ISA.IoBaseAddress = 0x0770;
|
|
}
|
|
|
|
for (IoBaseAddress = pDetContext->ISA.IoBaseAddress;
|
|
IoBaseAddress <= 0x6770;
|
|
IoBaseAddress = Nia35NextIoAddress(IoBaseAddress)){
|
|
|
|
// Look for the ee16 adapter at the current port.
|
|
NtStatus = FindNia35Adapter(pDetectedAdapter,
|
|
InterfaceType,
|
|
BusNumber,
|
|
IoBaseAddress,
|
|
pAdapterInfo->PnPId);
|
|
|
|
if (NT_SUCCESS(NtStatus)){
|
|
// We found an adapter. Save the next IO address to check.
|
|
pDetContext->ISA.IoBaseAddress = Nia35NextIoAddress(IoBaseAddress);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (0xffff == IoBaseAddress){
|
|
NtStatus = STATUS_NO_MORE_ENTRIES;
|
|
}
|
|
|
|
return(NtStatus);
|
|
|
|
}
|