2010-04-07 20:19:29 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS ISA PnP Bus driver
|
|
|
|
* FILE: hardware.c
|
|
|
|
* PURPOSE: Hardware support code
|
|
|
|
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
|
|
|
*/
|
2014-02-06 11:18:34 +00:00
|
|
|
|
2010-04-07 20:19:29 +00:00
|
|
|
#include <isapnp.h>
|
|
|
|
#include <isapnphw.h>
|
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteAddress(
|
|
|
|
IN USHORT Address)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS, Address);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteData(
|
|
|
|
IN USHORT Data)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_DATA, Data);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
UCHAR
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadData(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return READ_PORT_UCHAR(ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(
|
|
|
|
IN USHORT Address,
|
|
|
|
IN USHORT Value)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteAddress(Address);
|
|
|
|
WriteData(Value);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
UCHAR
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadByte(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT Address)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteAddress(Address);
|
|
|
|
return ReadData(ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadWord(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT Address)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ((ReadByte(ReadDataPort, Address) << 8) |
|
|
|
|
(ReadByte(ReadDataPort, Address + 1)));
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
SetReadDataPort(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_READPORT, ((ULONG_PTR)ReadDataPort >> 2));
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
|
|
|
EnterIsolationState(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteAddress(ISAPNP_SERIALISOLATION);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
|
|
|
WaitForKey(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
|
|
|
ResetCsn(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
Wake(
|
|
|
|
IN USHORT Csn)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_WAKE, Csn);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadResourceData(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ReadByte(ReadDataPort, ISAPNP_RESOURCEDATA);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadStatus(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ReadByte(ReadDataPort, ISAPNP_STATUS);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteCsn(
|
|
|
|
IN USHORT Csn)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_CARDSELECTNUMBER, Csn);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteLogicalDeviceNumber(
|
|
|
|
IN USHORT LogDev)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteByte(ISAPNP_LOGICALDEVICENUMBER, LogDev);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
ActivateDevice(
|
|
|
|
IN USHORT LogDev)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteLogicalDeviceNumber(LogDev);
|
|
|
|
WriteByte(ISAPNP_ACTIVATE, 1);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
DeactivateDevice(
|
|
|
|
IN USHORT LogDev)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteLogicalDeviceNumber(LogDev);
|
|
|
|
WriteByte(ISAPNP_ACTIVATE, 0);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadIoBase(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT Index)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ReadWord(ReadDataPort, ISAPNP_IOBASE(Index));
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
ReadIrqNo(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT Index)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
|
|
|
VOID
|
|
|
|
HwDelay(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
KeStallExecutionProcessor(1000);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
inline
|
2020-02-07 22:48:22 +00:00
|
|
|
UCHAR
|
2020-03-20 18:19:30 +00:00
|
|
|
NextLFSR(
|
|
|
|
IN UCHAR Lfsr,
|
|
|
|
IN UCHAR InputBit)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
UCHAR NextLfsr = Lfsr >> 1;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return NextLfsr;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
VOID
|
|
|
|
SendKey(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
UCHAR i, Lfsr;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
HwDelay();
|
|
|
|
WriteAddress(0x00);
|
|
|
|
WriteAddress(0x00);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Lfsr = ISAPNP_LFSR_SEED;
|
|
|
|
for (i = 0; i < 32; i++)
|
|
|
|
{
|
|
|
|
WriteAddress(Lfsr);
|
|
|
|
Lfsr = NextLFSR(Lfsr, 0);
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
PeekByte(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
USHORT i;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
for (i = 0; i < 20; i++)
|
|
|
|
{
|
|
|
|
if (ReadStatus(ReadDataPort) & 0x01)
|
|
|
|
return ReadResourceData(ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
HwDelay();
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return 0xFF;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
Peek(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN OUT PVOID Buffer,
|
|
|
|
IN ULONG Length)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
USHORT i, Byte;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
for (i = 0; i < Length; i++)
|
|
|
|
{
|
|
|
|
Byte = PeekByte(ReadDataPort);
|
|
|
|
if (Buffer)
|
|
|
|
*((PUCHAR)Buffer + i) = Byte;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
USHORT
|
2020-03-20 18:19:30 +00:00
|
|
|
IsaPnpChecksum(
|
|
|
|
IN PISAPNP_IDENTIFIER Identifier)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
UCHAR i, j, Lfsr, Byte;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Lfsr = ISAPNP_LFSR_SEED;
|
|
|
|
for (i = 0; i < 8; i++)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
Byte = *(((PUCHAR)Identifier) + i);
|
|
|
|
for (j = 0; j < 8; j++)
|
|
|
|
{
|
|
|
|
Lfsr = NextLFSR(Lfsr, Byte);
|
|
|
|
Byte >>= 1;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return Lfsr;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOLEAN
|
2020-03-20 18:19:30 +00:00
|
|
|
FindTag(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT WantedTag,
|
|
|
|
IN OUT PVOID Buffer,
|
|
|
|
IN ULONG Length)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
USHORT Tag, TagLen;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
do
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
Tag = PeekByte(ReadDataPort);
|
|
|
|
if (ISAPNP_IS_SMALL_TAG(Tag))
|
|
|
|
{
|
|
|
|
TagLen = ISAPNP_SMALL_TAG_LEN(Tag);
|
|
|
|
Tag = ISAPNP_SMALL_TAG_NAME(Tag);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TagLen = PeekByte(ReadDataPort) + (PeekByte(ReadDataPort) << 8);
|
|
|
|
Tag = ISAPNP_LARGE_TAG_NAME(Tag);
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (Tag == WantedTag)
|
|
|
|
{
|
|
|
|
if (Length > TagLen)
|
|
|
|
Length = TagLen;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Peek(ReadDataPort, Buffer, Length);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Peek(ReadDataPort, NULL, TagLen);
|
|
|
|
}
|
|
|
|
} while (Tag != ISAPNP_TAG_END);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return FALSE;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
BOOLEAN
|
2020-03-20 18:19:30 +00:00
|
|
|
FindLogDevId(
|
|
|
|
IN PUCHAR ReadDataPort,
|
|
|
|
IN USHORT LogDev,
|
|
|
|
IN OUT PISAPNP_LOGDEVID LogDeviceId)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
USHORT i;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
for (i = 0; i <= LogDev; i++)
|
|
|
|
{
|
|
|
|
if (!FindTag(ReadDataPort, ISAPNP_TAG_LOGDEVID, LogDeviceId, sizeof(*LogDeviceId)))
|
|
|
|
return FALSE;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return TRUE;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
INT
|
2020-03-20 18:19:30 +00:00
|
|
|
TryIsolate(
|
|
|
|
IN PUCHAR ReadDataPort)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
ISAPNP_IDENTIFIER Identifier;
|
|
|
|
USHORT i, j;
|
|
|
|
BOOLEAN Seen55aa, SeenLife;
|
|
|
|
INT Csn = 0;
|
|
|
|
USHORT Byte, Data;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
DPRINT("Setting read data port: 0x%p\n", ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
|
|
|
SendKey();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
ResetCsn();
|
|
|
|
HwDelay();
|
|
|
|
HwDelay();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
|
|
|
SendKey();
|
|
|
|
Wake(0x00);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
SetReadDataPort(ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
HwDelay();
|
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
while (TRUE)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
EnterIsolationState();
|
2010-04-07 20:19:29 +00:00
|
|
|
HwDelay();
|
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
RtlZeroMemory(&Identifier, sizeof(Identifier));
|
|
|
|
|
|
|
|
Seen55aa = SeenLife = FALSE;
|
|
|
|
for (i = 0; i < 9; i++)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
Byte = 0;
|
|
|
|
for (j = 0; j < 8; j++)
|
|
|
|
{
|
|
|
|
Data = ReadData(ReadDataPort);
|
|
|
|
HwDelay();
|
|
|
|
Data = ((Data << 8) | ReadData(ReadDataPort));
|
|
|
|
HwDelay();
|
|
|
|
Byte >>= 1;
|
|
|
|
|
|
|
|
if (Data != 0xFFFF)
|
|
|
|
{
|
|
|
|
SeenLife = TRUE;
|
|
|
|
if (Data == 0x55AA)
|
|
|
|
{
|
|
|
|
Byte |= 0x80;
|
|
|
|
Seen55aa = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*(((PUCHAR)&Identifier) + i) = Byte;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (!Seen55aa)
|
|
|
|
{
|
|
|
|
if (Csn)
|
|
|
|
{
|
|
|
|
DPRINT("Found no more cards\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (SeenLife)
|
|
|
|
{
|
|
|
|
DPRINT("Saw life but no cards, trying new read port\n");
|
|
|
|
Csn = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
DPRINT("Saw no sign of life, abandoning isolation\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (Identifier.Checksum != IsaPnpChecksum(&Identifier))
|
|
|
|
{
|
|
|
|
DPRINT("Bad checksum, trying next read data port\n");
|
|
|
|
Csn = -1;
|
|
|
|
break;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Csn++;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteCsn(Csn);
|
|
|
|
HwDelay();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Wake(0x00);
|
|
|
|
HwDelay();
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (Csn > 0)
|
|
|
|
{
|
|
|
|
DPRINT("Found %d cards at read port 0x%p\n", Csn, ReadDataPort);
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return Csn;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
PUCHAR
|
|
|
|
Isolate(VOID)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
PUCHAR ReadPort;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
for (ReadPort = (PUCHAR)ISAPNP_READ_PORT_START;
|
|
|
|
(ULONG_PTR)ReadPort <= ISAPNP_READ_PORT_MAX;
|
|
|
|
ReadPort += ISAPNP_READ_PORT_STEP)
|
|
|
|
{
|
|
|
|
/* Avoid the NE2000 probe space */
|
|
|
|
if ((ULONG_PTR)ReadPort >= 0x280 &&
|
|
|
|
(ULONG_PTR)ReadPort <= 0x380)
|
|
|
|
continue;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (TryIsolate(ReadPort) > 0)
|
|
|
|
return ReadPort;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return 0;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2020-03-20 18:19:30 +00:00
|
|
|
DeviceActivation(
|
|
|
|
IN PISAPNP_LOGICAL_DEVICE IsaDevice,
|
|
|
|
IN BOOLEAN Activate)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
|
|
|
SendKey();
|
|
|
|
Wake(IsaDevice->CSN);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (Activate)
|
|
|
|
ActivateDevice(IsaDevice->LDN);
|
|
|
|
else
|
|
|
|
DeactivateDevice(IsaDevice->LDN);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
HwDelay();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
2020-03-20 18:19:30 +00:00
|
|
|
ProbeIsaPnpBus(
|
|
|
|
IN PISAPNP_FDO_EXTENSION FdoExt)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
PISAPNP_LOGICAL_DEVICE LogDevice;
|
|
|
|
ISAPNP_IDENTIFIER Identifier;
|
|
|
|
ISAPNP_LOGDEVID LogDevId;
|
|
|
|
USHORT Csn;
|
|
|
|
USHORT LogDev;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
ASSERT(FdoExt->ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
for (Csn = 1; Csn <= 0xFF; Csn++)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
for (LogDev = 0; LogDev <= 0xFF; LogDev++)
|
|
|
|
{
|
|
|
|
LogDevice = ExAllocatePool(NonPagedPool, sizeof(ISAPNP_LOGICAL_DEVICE));
|
|
|
|
if (!LogDevice)
|
|
|
|
return STATUS_NO_MEMORY;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
LogDevice->CSN = Csn;
|
|
|
|
LogDevice->LDN = LogDev;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
|
|
|
SendKey();
|
|
|
|
Wake(Csn);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
Peek(FdoExt->ReadDataPort, &Identifier, sizeof(Identifier));
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (Identifier.VendorId & 0x80)
|
|
|
|
{
|
|
|
|
ExFreePool(LogDevice);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
if (!FindLogDevId(FdoExt->ReadDataPort, LogDev, &LogDevId))
|
|
|
|
break;
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WriteLogicalDeviceNumber(LogDev);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
LogDevice->VendorId[0] = ((LogDevId.VendorId >> 2) & 0x1f) + 'A' - 1,
|
|
|
|
LogDevice->VendorId[1] = (((LogDevId.VendorId & 0x3) << 3) | ((LogDevId.VendorId >> 13) & 0x7)) + 'A' - 1,
|
|
|
|
LogDevice->VendorId[2] = ((LogDevId.VendorId >> 8) & 0x1f) + 'A' - 1,
|
|
|
|
LogDevice->ProdId = RtlUshortByteSwap(LogDevId.ProdId);
|
|
|
|
LogDevice->SerialNumber = Identifier.Serial;
|
|
|
|
LogDevice->IoAddr = ReadIoBase(FdoExt->ReadDataPort, 0);
|
|
|
|
LogDevice->IrqNo = ReadIrqNo(FdoExt->ReadDataPort, 0);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
DPRINT1("Detected ISA PnP device - VID: '%3s' PID: 0x%x SN: 0x%08x IoBase: 0x%x IRQ:0x%x\n",
|
|
|
|
LogDevice->VendorId, LogDevice->ProdId, LogDevice->SerialNumber, LogDevice->IoAddr, LogDevice->IrqNo);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
WaitForKey();
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
|
|
|
|
FdoExt->DeviceCount++;
|
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
IsaHwDetectReadDataPort(
|
|
|
|
IN PISAPNP_FDO_EXTENSION FdoExt)
|
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
FdoExt->ReadDataPort = Isolate();
|
|
|
|
if (!FdoExt->ReadDataPort)
|
|
|
|
{
|
|
|
|
DPRINT1("No read data port found\n");
|
2020-03-20 18:41:55 +00:00
|
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
2020-03-20 18:19:30 +00:00
|
|
|
}
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
DPRINT1("Detected read data port at 0x%p\n", FdoExt->ReadDataPort);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
IsaHwActivateDevice(
|
|
|
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
|
|
|
|
{
|
|
|
|
DeviceActivation(LogicalDevice,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
IsaHwDeactivateDevice(
|
2020-03-20 18:19:30 +00:00
|
|
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
DeviceActivation(LogicalDevice,
|
|
|
|
FALSE);
|
2010-04-07 20:19:29 +00:00
|
|
|
|
2020-03-20 18:19:30 +00:00
|
|
|
return STATUS_SUCCESS;
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
IsaHwFillDeviceList(
|
2020-03-20 18:19:30 +00:00
|
|
|
IN PISAPNP_FDO_EXTENSION FdoExt)
|
2010-04-07 20:19:29 +00:00
|
|
|
{
|
2020-03-20 18:19:30 +00:00
|
|
|
return ProbeIsaPnpBus(FdoExt);
|
2010-04-07 20:19:29 +00:00
|
|
|
}
|