mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 14:53:40 +00:00
[ISAPNP]
- Rewrite the ISAPnP driver based off EtherBoot source - TODO: Resource stuff svn path=/trunk/; revision=46768
This commit is contained in:
parent
da1fa61cf0
commit
d9face83c6
7 changed files with 1115 additions and 1991 deletions
141
reactos/drivers/bus/isapnp/fdo.c
Normal file
141
reactos/drivers/bus/isapnp/fdo.c
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS ISA PnP Bus driver
|
||||||
|
* FILE: fdo.c
|
||||||
|
* PURPOSE: FDO-specific code
|
||||||
|
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
||||||
|
*/
|
||||||
|
#include <isapnp.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaFdoStartDevice(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
||||||
|
|
||||||
|
Status = IsaHwDetectReadDataPort(FdoExt);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdoExt->Common.State = dsStarted;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaFdoQueryDeviceRelations(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PLIST_ENTRY CurrentEntry;
|
||||||
|
PISAPNP_LOGICAL_DEVICE IsaDevice;
|
||||||
|
PDEVICE_RELATIONS DeviceRelations;
|
||||||
|
KIRQL OldIrql;
|
||||||
|
ULONG i = 0;
|
||||||
|
|
||||||
|
if (IrpSp->Parameters.QueryDeviceRelations.Type != BusRelations)
|
||||||
|
return Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&FdoExt->Lock, &OldIrql);
|
||||||
|
|
||||||
|
Status = IsaHwFillDeviceList(FdoExt);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceRelations = ExAllocatePool(NonPagedPool,
|
||||||
|
sizeof(DEVICE_RELATIONS) + sizeof(DEVICE_OBJECT) * (FdoExt->DeviceCount - 1));
|
||||||
|
if (!DeviceRelations)
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentEntry = FdoExt->DeviceListHead.Flink;
|
||||||
|
while (CurrentEntry != &FdoExt->DeviceListHead)
|
||||||
|
{
|
||||||
|
IsaDevice = CONTAINING_RECORD(CurrentEntry, ISAPNP_LOGICAL_DEVICE, ListEntry);
|
||||||
|
|
||||||
|
DeviceRelations->Objects[i++] = IsaDevice->Common.Self;
|
||||||
|
|
||||||
|
ObReferenceObject(IsaDevice->Common.Self);
|
||||||
|
|
||||||
|
CurrentEntry = CurrentEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceRelations->Count = FdoExt->DeviceCount;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&FdoExt->Lock, OldIrql);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaFdoPnp(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
switch (IrpSp->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
Status = IsaForwardIrpSynchronous(FdoExt, Irp);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
Status = IsaFdoStartDevice(FdoExt, Irp, IrpSp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
case IRP_MN_STOP_DEVICE:
|
||||||
|
FdoExt->Common.State = dsStopped;
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
Status = IsaFdoQueryDeviceRelations(FdoExt, Irp, IrpSp);
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
|
||||||
|
DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IoSkipCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
return IoCallDriver(FdoExt->Ldo, Irp);
|
||||||
|
}
|
579
reactos/drivers/bus/isapnp/hardware.c
Normal file
579
reactos/drivers/bus/isapnp/hardware.c
Normal file
|
@ -0,0 +1,579 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS ISA PnP Bus driver
|
||||||
|
* FILE: hardware.c
|
||||||
|
* PURPOSE: Hardware support code
|
||||||
|
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
||||||
|
*/
|
||||||
|
#include <isapnp.h>
|
||||||
|
#include <isapnphw.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WriteAddress(USHORT Address)
|
||||||
|
{
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS, Address);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WriteData(USHORT Data)
|
||||||
|
{
|
||||||
|
WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_DATA, Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
UCHAR
|
||||||
|
ReadData(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
return READ_PORT_UCHAR(ReadDataPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WriteByte(USHORT Address, USHORT Value)
|
||||||
|
{
|
||||||
|
WriteAddress(Address);
|
||||||
|
WriteData(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
UCHAR
|
||||||
|
ReadByte(PUCHAR ReadDataPort, USHORT Address)
|
||||||
|
{
|
||||||
|
WriteAddress(Address);
|
||||||
|
return ReadData(ReadDataPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadWord(PUCHAR ReadDataPort, USHORT Address)
|
||||||
|
{
|
||||||
|
return ((ReadByte(ReadDataPort, Address) << 8) |
|
||||||
|
(ReadByte(ReadDataPort, Address + 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
SetReadDataPort(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_READPORT, ((ULONG_PTR)ReadDataPort >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
EnterIsolationState(VOID)
|
||||||
|
{
|
||||||
|
WriteAddress(ISAPNP_SERIALISOLATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WaitForKey(VOID)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_WAIT_FOR_KEY);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
ResetCsn(VOID)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_CONFIGCONTROL, ISAPNP_CONFIG_RESET_CSN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
Wake(USHORT Csn)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_WAKE, Csn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadResourceData(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
return ReadByte(ReadDataPort, ISAPNP_RESOURCEDATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadStatus(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
return ReadByte(ReadDataPort, ISAPNP_STATUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WriteCsn(USHORT Csn)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_CARDSELECTNUMBER, Csn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
WriteLogicalDeviceNumber(USHORT LogDev)
|
||||||
|
{
|
||||||
|
WriteByte(ISAPNP_LOGICALDEVICENUMBER, LogDev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
ActivateDevice(USHORT LogDev)
|
||||||
|
{
|
||||||
|
WriteLogicalDeviceNumber(LogDev);
|
||||||
|
WriteByte(ISAPNP_ACTIVATE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
DeactivateDevice(USHORT LogDev)
|
||||||
|
{
|
||||||
|
WriteLogicalDeviceNumber(LogDev);
|
||||||
|
WriteByte(ISAPNP_ACTIVATE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadIoBase(PUCHAR ReadDataPort, USHORT Index)
|
||||||
|
{
|
||||||
|
return ReadWord(ReadDataPort, ISAPNP_IOBASE(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
ReadIrqNo(PUCHAR ReadDataPort, USHORT Index)
|
||||||
|
{
|
||||||
|
return ReadByte(ReadDataPort, ISAPNP_IRQNO(Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
VOID
|
||||||
|
HwDelay(VOID)
|
||||||
|
{
|
||||||
|
KeStallExecutionProcessor(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
inline
|
||||||
|
USHORT
|
||||||
|
NextLFSR(USHORT Lfsr, USHORT InputBit)
|
||||||
|
{
|
||||||
|
ULONG NextLfsr = Lfsr >> 1;
|
||||||
|
|
||||||
|
NextLfsr |= (((Lfsr ^ NextLfsr) ^ InputBit)) << 7;
|
||||||
|
|
||||||
|
return NextLfsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
SendKey(VOID)
|
||||||
|
{
|
||||||
|
USHORT i, Lfsr;
|
||||||
|
|
||||||
|
HwDelay();
|
||||||
|
WriteAddress(0x00);
|
||||||
|
WriteAddress(0x00);
|
||||||
|
|
||||||
|
Lfsr = ISAPNP_LFSR_SEED;
|
||||||
|
for (i = 0; i < 32; i++)
|
||||||
|
{
|
||||||
|
WriteAddress(Lfsr);
|
||||||
|
Lfsr = NextLFSR(Lfsr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
USHORT
|
||||||
|
PeekByte(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
|
||||||
|
for (i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
if (ReadStatus(ReadDataPort) & 0x01)
|
||||||
|
return ReadResourceData(ReadDataPort);
|
||||||
|
|
||||||
|
HwDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
VOID
|
||||||
|
Peek(PUCHAR ReadDataPort, PVOID Buffer, ULONG Length)
|
||||||
|
{
|
||||||
|
USHORT i, byte;
|
||||||
|
|
||||||
|
for (i = 0; i < Length; i++)
|
||||||
|
{
|
||||||
|
byte = PeekByte(ReadDataPort);
|
||||||
|
if (Buffer)
|
||||||
|
*((PUCHAR)Buffer + i) = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
USHORT
|
||||||
|
IsaPnpChecksum(PISAPNP_IDENTIFIER Identifier)
|
||||||
|
{
|
||||||
|
USHORT i,j, Lfsr, Byte;
|
||||||
|
|
||||||
|
Lfsr = ISAPNP_LFSR_SEED;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
Byte = *(((PUCHAR)Identifier) + i);
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
Lfsr = NextLFSR(Lfsr, Byte);
|
||||||
|
Byte >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Lfsr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
FindTag(PUCHAR ReadDataPort, USHORT WantedTag, PVOID Buffer, ULONG Length)
|
||||||
|
{
|
||||||
|
USHORT Tag, TagLen;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Tag == WantedTag)
|
||||||
|
{
|
||||||
|
if (Length > TagLen)
|
||||||
|
Length = TagLen;
|
||||||
|
|
||||||
|
Peek(ReadDataPort, Buffer, Length);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Peek(ReadDataPort, NULL, Length);
|
||||||
|
}
|
||||||
|
} while (Tag != ISAPNP_TAG_END);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
BOOLEAN
|
||||||
|
FindLogDevId(PUCHAR ReadDataPort, USHORT LogDev, PISAPNP_LOGDEVID LogDeviceId)
|
||||||
|
{
|
||||||
|
USHORT i;
|
||||||
|
|
||||||
|
for (i = 0; i <= LogDev; i++)
|
||||||
|
{
|
||||||
|
if (!FindTag(ReadDataPort, ISAPNP_TAG_LOGDEVID, LogDeviceId, sizeof(*LogDeviceId)))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
INT
|
||||||
|
TryIsolate(PUCHAR ReadDataPort)
|
||||||
|
{
|
||||||
|
ISAPNP_IDENTIFIER Identifier;
|
||||||
|
USHORT i, j;
|
||||||
|
BOOLEAN Seen55aa, SeenLife;
|
||||||
|
INT Csn = 0;
|
||||||
|
USHORT Byte, Data;
|
||||||
|
|
||||||
|
DPRINT("Setting read data port: 0x%x\n", ReadDataPort);
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
SendKey();
|
||||||
|
|
||||||
|
ResetCsn();
|
||||||
|
HwDelay();
|
||||||
|
HwDelay();
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
SendKey();
|
||||||
|
Wake(0x00);
|
||||||
|
|
||||||
|
SetReadDataPort(ReadDataPort);
|
||||||
|
HwDelay();
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
EnterIsolationState();
|
||||||
|
HwDelay();
|
||||||
|
|
||||||
|
RtlZeroMemory(&Identifier, sizeof(Identifier));
|
||||||
|
|
||||||
|
Seen55aa = SeenLife = FALSE;
|
||||||
|
for (i = 0; i < 9; i++)
|
||||||
|
{
|
||||||
|
Byte = 0;
|
||||||
|
for (j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
Data = ReadData(ReadDataPort);
|
||||||
|
HwDelay();
|
||||||
|
Data = ((Data << 8) | ReadData(ReadDataPort));
|
||||||
|
HwDelay();
|
||||||
|
Data >>= 1;
|
||||||
|
|
||||||
|
if (Data != 0xFFFF)
|
||||||
|
{
|
||||||
|
SeenLife = TRUE;
|
||||||
|
if (Data == 0x55AA)
|
||||||
|
{
|
||||||
|
Byte |= 0x80;
|
||||||
|
Seen55aa = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*(((PUCHAR)&Identifier) + i) = Byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Identifier.Checksum != IsaPnpChecksum(&Identifier))
|
||||||
|
{
|
||||||
|
DPRINT("Bad checksum, trying next read data port\n");
|
||||||
|
Csn = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Csn++;
|
||||||
|
|
||||||
|
WriteCsn(Csn);
|
||||||
|
HwDelay();
|
||||||
|
|
||||||
|
Wake(0x00);
|
||||||
|
HwDelay();
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
|
||||||
|
if (Csn > 0)
|
||||||
|
{
|
||||||
|
DPRINT("Found %d cards at read port 0x%x\n", Csn, ReadDataPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Csn;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
PUCHAR
|
||||||
|
Isolate(VOID)
|
||||||
|
{
|
||||||
|
PUCHAR ReadPort;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (TryIsolate(ReadPort) > 0)
|
||||||
|
return ReadPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
DeviceActivation(PISAPNP_LOGICAL_DEVICE IsaDevice,
|
||||||
|
BOOLEAN Activate)
|
||||||
|
{
|
||||||
|
WaitForKey();
|
||||||
|
SendKey();
|
||||||
|
Wake(IsaDevice->CSN);
|
||||||
|
|
||||||
|
if (Activate)
|
||||||
|
ActivateDevice(IsaDevice->LDN);
|
||||||
|
else
|
||||||
|
DeactivateDevice(IsaDevice->LDN);
|
||||||
|
|
||||||
|
HwDelay();
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
ProbeIsaPnpBus(PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
|
{
|
||||||
|
PISAPNP_LOGICAL_DEVICE LogDevice;
|
||||||
|
ISAPNP_IDENTIFIER Identifier;
|
||||||
|
ISAPNP_LOGDEVID LogDevId;
|
||||||
|
USHORT Csn;
|
||||||
|
USHORT LogDev;
|
||||||
|
PDEVICE_OBJECT Pdo;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
ASSERT(FdoExt->ReadDataPort);
|
||||||
|
|
||||||
|
for (Csn = 1; Csn <= 0xFF; Csn++)
|
||||||
|
{
|
||||||
|
for (LogDev = 0; LogDev <= 0xFF; LogDev++)
|
||||||
|
{
|
||||||
|
Status = IoCreateDevice(FdoExt->Common.Self->DriverObject,
|
||||||
|
sizeof(ISAPNP_LOGICAL_DEVICE),
|
||||||
|
NULL,
|
||||||
|
FILE_DEVICE_CONTROLLER,
|
||||||
|
FILE_DEVICE_SECURE_OPEN,
|
||||||
|
FALSE,
|
||||||
|
&Pdo);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
|
||||||
|
|
||||||
|
LogDevice = Pdo->DeviceExtension;
|
||||||
|
|
||||||
|
RtlZeroMemory(LogDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
|
||||||
|
|
||||||
|
LogDevice->Common.Self = Pdo;
|
||||||
|
LogDevice->Common.IsFdo = FALSE;
|
||||||
|
LogDevice->Common.State = dsStopped;
|
||||||
|
|
||||||
|
LogDevice->CSN = Csn;
|
||||||
|
LogDevice->LDN = LogDev;
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
SendKey();
|
||||||
|
Wake(Csn);
|
||||||
|
|
||||||
|
Peek(FdoExt->ReadDataPort, &Identifier, sizeof(Identifier));
|
||||||
|
|
||||||
|
if (Identifier.VendorId & 0x80)
|
||||||
|
{
|
||||||
|
IoDeleteDevice(LogDevice->Common.Self);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FindLogDevId(FdoExt->ReadDataPort, LogDev, &LogDevId))
|
||||||
|
break;
|
||||||
|
|
||||||
|
WriteLogicalDeviceNumber(LogDev);
|
||||||
|
|
||||||
|
LogDevice->VendorId = LogDevId.VendorId;
|
||||||
|
LogDevice->ProdId = LogDevId.ProdId;
|
||||||
|
LogDevice->IoAddr = ReadIoBase(FdoExt->ReadDataPort, 0);
|
||||||
|
LogDevice->IrqNo = ReadIrqNo(FdoExt->ReadDataPort, 0);
|
||||||
|
|
||||||
|
DPRINT1("Detected ISA PnP device - VID: 0x%x PID: 0x%x IoBase: 0x%x IRQ:0x%x\n",
|
||||||
|
LogDevice->VendorId, LogDevice->ProdId, LogDevice->IoAddr, LogDevice->IrqNo);
|
||||||
|
|
||||||
|
WaitForKey();
|
||||||
|
|
||||||
|
Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
|
InsertTailList(&FdoExt->DeviceListHead, &LogDevice->ListEntry);
|
||||||
|
FdoExt->DeviceCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwDetectReadDataPort(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
|
{
|
||||||
|
FdoExt->ReadDataPort = Isolate();
|
||||||
|
if (!FdoExt->ReadDataPort)
|
||||||
|
{
|
||||||
|
DPRINT1("No read data port found\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DPRINT1("Detected read data port at 0x%x\n", FdoExt->ReadDataPort);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwActivateDevice(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
|
||||||
|
{
|
||||||
|
DeviceActivation(LogicalDevice,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwDeactivateDevice(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice)
|
||||||
|
{
|
||||||
|
DeviceActivation(LogicalDevice,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwFillDeviceList(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt)
|
||||||
|
{
|
||||||
|
return ProbeIsaPnpBus(FdoExt);
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ntddk.h>
|
#include <wdm.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -8,331 +8,88 @@ extern "C" {
|
||||||
|
|
||||||
#define TAG_ISAPNP 'PNPI'
|
#define TAG_ISAPNP 'PNPI'
|
||||||
|
|
||||||
#define IO_RESOURCE_REQUIRED 0x00 //ROS Extension
|
|
||||||
|
|
||||||
#define ISAPNP_ADDRESS_PORT 0x0279 // ADDRESS (W)
|
|
||||||
#define ISAPNP_WRITE_PORT 0x0A79 // WRITE_DATA (W)
|
|
||||||
#define ISAPNP_MIN_READ_PORT 0x0203 // READ_DATA (R)
|
|
||||||
#define ISAPNP_MAX_READ_PORT 0x03FF // READ_DATA (R)
|
|
||||||
|
|
||||||
// Card control registers
|
|
||||||
#define ISAPNP_CARD_READ_DATA_PORT 0x00 // Set READ_DATA port
|
|
||||||
#define ISAPNP_CARD_ISOLATION 0x01 // Isolation
|
|
||||||
#define ISAPNP_CARD_CONFIG_COTROL 0x02 // Configuration control
|
|
||||||
#define ISAPNP_CARD_WAKECSN 0x03 // Wake[CSN]
|
|
||||||
#define ISAPNP_CARD_RESOUCE_DATA 0x04 // Resource data port
|
|
||||||
#define ISAPNP_CARD_STATUS 0x05 // Status port
|
|
||||||
#define ISAPNP_CARD_CSN 0x06 // Card Select Number port
|
|
||||||
#define ISAPNP_CARD_LOG_DEVICE_NUM 0x07 // Logical Device Number
|
|
||||||
#define ISAPNP_CARD_RESERVED 0x08 // Card level reserved
|
|
||||||
#define ISAPNP_CARD_VENDOR_DEFINED 0x20 // Vendor defined
|
|
||||||
|
|
||||||
// Logical device control registers
|
|
||||||
#define ISAPNP_CONTROL_ACTIVATE 0x30 // Activate logical device
|
|
||||||
#define ISAPNP_CONTROL_IO_RANGE_CHECK 0x31 // I/O range conflict check
|
|
||||||
#define ISAPNP_CONTROL_LDC_RESERVED 0x32 // Logical Device Control reserved
|
|
||||||
#define ISAPNP_CONTROL_LDCV_RESERVED 0x38 // Logical Device Control Vendor reserved
|
|
||||||
|
|
||||||
// Logical device configuration registers
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_BASE2 0x00 // Memory base address bits 23-16
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_BASE1 0x01 // Memory base address bits 15-8
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_CONTROL 0x02 // Memory control
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_LIMIT2 0x03 // Memory limit bits 23-16
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_LIMIT1 0x04 // Memory limit bits 15-8
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_DESC0 0x40 // Memory descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_DESC1 0x48 // Memory descriptor 1
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_DESC2 0x50 // Memory descriptor 2
|
|
||||||
#define ISAPNP_CONFIG_MEMORY_DESC3 0x58 // Memory descriptor 3
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_BASE3 0x00 // 32-bit memory base address bits 31-24
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_BASE2 0x01 // 32-bit memory base address bits 23-16
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_BASE1 0x01 // 32-bit memory base address bits 15-8
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_CONTROL 0x02 // 32-bit memory control
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_LIMIT3 0x03 // 32-bit memory limit bits 31-24
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_LIMIT2 0x04 // 32-bit memory limit bits 23-16
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_LIMIT1 0x05 // 32-bit memory limit bits 15-8
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_DESC0 0x76 // 32-bit memory descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_DESC1 0x80 // 32-bit memory descriptor 1
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_DESC2 0x90 // 32-bit memory descriptor 2
|
|
||||||
#define ISAPNP_CONFIG_MEMORY32_DESC3 0xA0 // 32-bit memory descriptor 3
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_IO_BASE1 0x00 // I/O port base address bits 15-8
|
|
||||||
#define ISAPNP_CONFIG_IO_BASE0 0x01 // I/O port base address bits 7-0
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC0 0x60 // I/O port descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC1 0x62 // I/O port descriptor 1
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC2 0x64 // I/O port descriptor 2
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC3 0x66 // I/O port descriptor 3
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC4 0x68 // I/O port descriptor 4
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC5 0x6A // I/O port descriptor 5
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC6 0x6C // I/O port descriptor 6
|
|
||||||
#define ISAPNP_CONFIG_IO_DESC7 0x6E // I/O port descriptor 7
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_IRQ_LEVEL0 0x70 // Interupt level for descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_IRQ_TYPE0 0x71 // Type level for descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_IRQ_LEVEL1 0x72 // Interupt level for descriptor 1
|
|
||||||
#define ISAPNP_CONFIG_IRQ_TYPE1 0x73 // Type level for descriptor 1
|
|
||||||
|
|
||||||
#define ISAPNP_CONFIG_DMA_CHANNEL0 0x74 // DMA channel for descriptor 0
|
|
||||||
#define ISAPNP_CONFIG_DMA_CHANNEL1 0x75 // DMA channel for descriptor 1
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _PNPISA_SERIAL_ID
|
|
||||||
{
|
|
||||||
UCHAR VendorId[4]; // Vendor Identifier
|
|
||||||
UCHAR SerialId[4]; // Serial number
|
|
||||||
UCHAR Checksum; // Checksum
|
|
||||||
} PNPISA_SERIAL_ID, *PPNPISA_SERIAL_ID;
|
|
||||||
|
|
||||||
|
|
||||||
#define ISAPNP_RES_PRIORITY_PREFERRED 0
|
|
||||||
#define ISAPNP_RES_PRIORITY_ACCEPTABLE 1
|
|
||||||
#define ISAPNP_RES_PRIORITY_FUNCTIONAL 2
|
|
||||||
#define ISAPNP_RES_PRIORITY_INVALID 65535
|
|
||||||
|
|
||||||
|
|
||||||
#define ISAPNP_RESOURCE_ITEM_TYPE 0x80 // 0 = small, 1 = large
|
|
||||||
|
|
||||||
// Small Resource Item Names (SRINs)
|
|
||||||
#define ISAPNP_SRIN_VERSION 0x1 // PnP version number
|
|
||||||
#define ISAPNP_SRIN_LDEVICE_ID 0x2 // Logical device id
|
|
||||||
#define ISAPNP_SRIN_CDEVICE_ID 0x3 // Compatible device id
|
|
||||||
#define ISAPNP_SRIN_IRQ_FORMAT 0x4 // IRQ format
|
|
||||||
#define ISAPNP_SRIN_DMA_FORMAT 0x5 // DMA format
|
|
||||||
#define ISAPNP_SRIN_START_DFUNCTION 0x6 // Start dependant function
|
|
||||||
#define ISAPNP_SRIN_END_DFUNCTION 0x7 // End dependant function
|
|
||||||
#define ISAPNP_SRIN_IO_DESCRIPTOR 0x8 // I/O port descriptor
|
|
||||||
#define ISAPNP_SRIN_FL_IO_DESCRIPOTOR 0x9 // Fixed location I/O port descriptor
|
|
||||||
#define ISAPNP_SRIN_VENDOR_DEFINED 0xE // Vendor defined
|
|
||||||
#define ISAPNP_SRIN_END_TAG 0xF // End tag
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_VERSION
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
UCHAR Version; // Packed BCD format version number
|
|
||||||
UCHAR VendorVersion; // Vendor specific version number
|
|
||||||
} ISAPNP_SRI_VERSION, *PISAPNP_SRI_VERSION;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_LDEVICE_ID
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT DeviceId; // Logical device id
|
|
||||||
USHORT VendorId; // Manufacturer id
|
|
||||||
UCHAR Flags; // Flags
|
|
||||||
} ISAPNP_SRI_LDEVICE_ID, *PISAPNP_SRI_LDEVICE_ID;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_CDEVICE_ID
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT DeviceId; // Logical device id
|
|
||||||
USHORT VendorId; // Manufacturer id
|
|
||||||
} ISAPNP_SRI_CDEVICE_ID, *PISAPNP_SRI_CDEVICE_ID;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_IRQ_FORMAT
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Mask; // IRQ mask (bit 0 = irq 0, etc.)
|
|
||||||
UCHAR Information; // IRQ information
|
|
||||||
} ISAPNP_SRI_IRQ_FORMAT, *PISAPNP_SRI_IRQ_FORMAT;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_DMA_FORMAT
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Mask; // DMA channel mask (bit 0 = channel 0, etc.)
|
|
||||||
UCHAR Information; // DMA information
|
|
||||||
} ISAPNP_SRI_DMA_FORMAT, *PISAPNP_SRI_DMA_FORMAT;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_START_DFUNCTION
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
} ISAPNP_SRI_START_DFUNCTION, *PISAPNP_SRI_START_DFUNCTION;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_END_DFUNCTION
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
} ISAPNP_SRI_END_DFUNCTION, *PISAPNP_SRI_END_DFUNCTION;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_IO_DESCRIPTOR
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
UCHAR Information; // Information
|
|
||||||
USHORT RangeMinBase; // Minimum base address
|
|
||||||
USHORT RangeMaxBase; // Maximum base address
|
|
||||||
UCHAR Alignment; // Base alignment
|
|
||||||
UCHAR RangeLength; // Length of range
|
|
||||||
} ISAPNP_SRI_IO_DESCRIPTOR, *PISAPNP_SRI_IO_DESCRIPTOR;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_FL_IO_DESCRIPTOR
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT RangeBase; // Range base address
|
|
||||||
UCHAR RangeLength; // Length of range
|
|
||||||
} ISAPNP_SRI_FL_IO_DESCRIPTOR, *PISAPNP_SRI_FL_IO_DESCRIPTOR;
|
|
||||||
|
|
||||||
typedef struct _PISAPNP_SRI_VENDOR_DEFINED
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
UCHAR Reserved[0]; // Vendor defined
|
|
||||||
} ISAPNP_SRI_VENDOR_DEFINED, *PISAPNP_SRI_VENDOR_DEFINED;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_SRI_END_TAG
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
UCHAR Checksum; // Checksum
|
|
||||||
} ISAPNP_SRI_END_TAG, *PISAPNP_SRI_END_TAG;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
} ISAPNP_LRI, *PISAPNP_LRI;
|
|
||||||
|
|
||||||
// Large Resource Item Names (LRINs)
|
|
||||||
#define ISAPNP_LRIN_MEMORY_RANGE 0x1 // Memory range descriptor
|
|
||||||
#define ISAPNP_LRIN_ID_STRING_ANSI 0x2 // Identifier string (ANSI)
|
|
||||||
#define ISAPNP_LRIN_ID_STRING_UNICODE 0x3 // Identifier string (UNICODE)
|
|
||||||
#define ISAPNP_LRIN_VENDOR_DEFINED 0x4 // Vendor defined
|
|
||||||
#define ISAPNP_LRIN_MEMORY_RANGE32 0x5 // 32-bit memory range descriptor
|
|
||||||
#define ISAPNP_LRIN_FL_MEMORY_RANGE32 0x6 // 32-bit fixed location memory range descriptor
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI_MEMORY_RANGE
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
UCHAR Information; // Information
|
|
||||||
USHORT RangeMinBase; // Minimum base address
|
|
||||||
USHORT RangeMaxBase; // Maximum base address
|
|
||||||
USHORT Alignment; // Base alignment
|
|
||||||
USHORT RangeLength; // Length of range
|
|
||||||
} ISAPNP_LRI_MEMORY_RANGE, *PISAPNP_LRI_MEMORY_RANGE;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI_ID_STRING_ANSI
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
UCHAR String[0]; // Identifier string
|
|
||||||
} ISAPNP_LRI_ID_STRING_ANSI, *PISAPNP_LRI_ID_STRING_ANSI;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI_ID_STRING_UNICODE
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
USHORT CountryId; // Country identifier
|
|
||||||
USHORT String[0]; // Identifier string
|
|
||||||
} ISAPNP_LRI_ID_STRING_UNICODE, *PISAPNP_LRI_ID_STRING_UNICODE;
|
|
||||||
|
|
||||||
typedef struct _PISAPNP_LRI_VENDOR_DEFINED
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
UCHAR Reserved[0]; // Vendor defined
|
|
||||||
} ISAPNP_LRI_VENDOR_DEFINED, *PISAPNP_LRI_VENDOR_DEFINED;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI_MEMORY_RANGE32
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
UCHAR Information; // Information
|
|
||||||
ULONG RangeMinBase; // Minimum base address
|
|
||||||
ULONG RangeMaxBase; // Maximum base address
|
|
||||||
ULONG Alignment; // Base alignment
|
|
||||||
ULONG RangeLength; // Length of range
|
|
||||||
} ISAPNP_LRI_MEMORY_RANGE32, *PISAPNP_LRI_MEMORY_RANGE32;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LRI_FL_MEMORY_RANGE32
|
|
||||||
{
|
|
||||||
UCHAR Header;
|
|
||||||
USHORT Length; // Length of data items
|
|
||||||
UCHAR Information; // Information
|
|
||||||
ULONG RangeMinBase; // Minimum base address
|
|
||||||
ULONG RangeMaxBase; // Maximum base address
|
|
||||||
ULONG RangeLength; // Length of range
|
|
||||||
} ISAPNP_LRI_FL_MEMORY_RANGE32, *PISAPNP_LRI_FL_MEMORY_RANGE32;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_CARD
|
|
||||||
{
|
|
||||||
LIST_ENTRY ListEntry;
|
|
||||||
USHORT CardId;
|
|
||||||
USHORT VendorId;
|
|
||||||
USHORT DeviceId;
|
|
||||||
ULONG Serial;
|
|
||||||
UCHAR PNPVersion;
|
|
||||||
UCHAR ProductVersion;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
LIST_ENTRY LogicalDevices;
|
|
||||||
KSPIN_LOCK LogicalDevicesLock;
|
|
||||||
} ISAPNP_CARD, *PISAPNP_CARD;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_DESCRIPTOR
|
|
||||||
{
|
|
||||||
LIST_ENTRY ListEntry;
|
|
||||||
IO_RESOURCE_DESCRIPTOR Descriptor;
|
|
||||||
} ISAPNP_DESCRIPTOR, *PISAPNP_DESCRIPTOR;
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_CONFIGURATION_LIST
|
|
||||||
{
|
|
||||||
LIST_ENTRY ListEntry;
|
|
||||||
ULONG Priority;
|
|
||||||
LIST_ENTRY ListHead;
|
|
||||||
} ISAPNP_CONFIGURATION_LIST, *PISAPNP_CONFIGURATION_LIST;
|
|
||||||
|
|
||||||
|
|
||||||
#define MAX_COMPATIBLE_ID 32
|
|
||||||
|
|
||||||
typedef struct _ISAPNP_LOGICAL_DEVICE
|
|
||||||
{
|
|
||||||
LIST_ENTRY CardListEntry;
|
|
||||||
LIST_ENTRY DeviceListEntry;
|
|
||||||
USHORT Number;
|
|
||||||
USHORT VendorId;
|
|
||||||
USHORT DeviceId;
|
|
||||||
USHORT CVendorId[MAX_COMPATIBLE_ID];
|
|
||||||
USHORT CDeviceId[MAX_COMPATIBLE_ID];
|
|
||||||
USHORT Regs;
|
|
||||||
PISAPNP_CARD Card;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
PDEVICE_OBJECT Pdo;
|
|
||||||
PIO_RESOURCE_REQUIREMENTS_LIST ResourceLists;
|
|
||||||
LIST_ENTRY Configuration;
|
|
||||||
ULONG ConfigurationSize;
|
|
||||||
ULONG DescriptorCount;
|
|
||||||
ULONG CurrentDescriptorCount;
|
|
||||||
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
dsStopped,
|
dsStopped,
|
||||||
dsStarted
|
dsStarted
|
||||||
} ISAPNP_DEVICE_STATE;
|
} ISAPNP_DEVICE_STATE;
|
||||||
|
|
||||||
typedef struct _ISAPNP_DEVICE_EXTENSION
|
typedef struct _ISAPNP_COMMON_EXTENSION {
|
||||||
{
|
PDEVICE_OBJECT Self;
|
||||||
// Physical Device Object
|
BOOLEAN IsFdo;
|
||||||
PDEVICE_OBJECT Pdo;
|
|
||||||
// Lower device object
|
|
||||||
PDEVICE_OBJECT Ldo;
|
|
||||||
// List of ISA PnP cards managed by this driver
|
|
||||||
LIST_ENTRY CardListHead;
|
|
||||||
// List of devices managed by this driver
|
|
||||||
LIST_ENTRY DeviceListHead;
|
|
||||||
// Number of devices managed by this driver
|
|
||||||
ULONG DeviceListCount;
|
|
||||||
// Spinlock for the linked lists
|
|
||||||
KSPIN_LOCK GlobalListLock;
|
|
||||||
// Current state of the driver
|
|
||||||
ISAPNP_DEVICE_STATE State;
|
ISAPNP_DEVICE_STATE State;
|
||||||
} ISAPNP_DEVICE_EXTENSION, *PISAPNP_DEVICE_EXTENSION;
|
} ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct _ISAPNP_FDO_EXTENSION {
|
||||||
|
ISAPNP_COMMON_EXTENSION Common;
|
||||||
|
PDEVICE_OBJECT Ldo;
|
||||||
|
PDEVICE_OBJECT Pdo;
|
||||||
|
LIST_ENTRY DeviceListHead;
|
||||||
|
ULONG DeviceCount;
|
||||||
|
PUCHAR ReadDataPort;
|
||||||
|
KSPIN_LOCK Lock;
|
||||||
|
} ISAPNP_FDO_EXTENSION, *PISAPNP_FDO_EXTENSION;
|
||||||
|
|
||||||
|
typedef struct _ISAPNP_LOGICAL_DEVICE {
|
||||||
|
ISAPNP_COMMON_EXTENSION Common;
|
||||||
|
USHORT VendorId;
|
||||||
|
USHORT ProdId;
|
||||||
|
USHORT IoAddr;
|
||||||
|
UCHAR IrqNo;
|
||||||
|
UCHAR CSN;
|
||||||
|
UCHAR LDN;
|
||||||
|
LIST_ENTRY ListEntry;
|
||||||
|
} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
|
||||||
|
|
||||||
|
/* isapnp.c */
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DriverEntry(
|
DriverEntry(
|
||||||
IN PDRIVER_OBJECT DriverObject,
|
IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PUNICODE_STRING RegistryPath);
|
IN PUNICODE_STRING RegistryPath);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaForwardIrpSynchronous(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
/* fdo.c */
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaFdoPnp(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
|
/* pdo.c */
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaPdoPnp(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp);
|
||||||
|
|
||||||
|
/* hardware.c */
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwDetectReadDataPort(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwFillDeviceList(
|
||||||
|
IN PISAPNP_FDO_EXTENSION FdoExt);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwDeactivateDevice(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaHwActivateDevice(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||||
<module name="isapnp" type="kernelmodedriver" installbase="system32/drivers" installname="isapnp.sys">
|
<module name="isapnp" type="kernelmodedriver" installbase="system32/drivers" installname="isapnp.sys">
|
||||||
|
<bootstrap installbase="$(CDOUTPUT)"/>
|
||||||
<include base="isapnp">.</include>
|
<include base="isapnp">.</include>
|
||||||
<library>ntoskrnl</library>
|
<library>ntoskrnl</library>
|
||||||
<library>hal</library>
|
<library>hal</library>
|
||||||
<file>isapnp.c</file>
|
<file>isapnp.c</file>
|
||||||
|
<file>pdo.c</file>
|
||||||
|
<file>fdo.c</file>
|
||||||
|
<file>hardware.c</file>
|
||||||
<file>isapnp.rc</file>
|
<file>isapnp.rc</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
106
reactos/drivers/bus/isapnp/isapnphw.h
Normal file
106
reactos/drivers/bus/isapnp/isapnphw.h
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ISAPNP_ADDRESS 0x279
|
||||||
|
#define ISAPNP_WRITE_DATA 0xA79
|
||||||
|
|
||||||
|
#define ISAPNP_READ_PORT_MIN 0x203
|
||||||
|
#define ISAPNP_READ_PORT_START 0x213
|
||||||
|
#define ISAPNP_READ_PORT_MAX 0x3FF
|
||||||
|
#define ISAPNP_READ_PORT_STEP 0x10
|
||||||
|
|
||||||
|
#define ISAPNP_CSN_MIN 0x01
|
||||||
|
#define ISAPNP_CSN_MAX 0x0F
|
||||||
|
|
||||||
|
#define ISAPNP_READPORT 0x00
|
||||||
|
#define ISAPNP_SERIALISOLATION 0x01
|
||||||
|
#define ISAPNP_CONFIGCONTROL 0x02
|
||||||
|
#define ISAPNP_WAKE 0x03
|
||||||
|
#define ISAPNP_RESOURCEDATA 0x04
|
||||||
|
#define ISAPNP_STATUS 0x05
|
||||||
|
#define ISAPNP_CARDSELECTNUMBER 0x06
|
||||||
|
#define ISAPNP_LOGICALDEVICENUMBER 0x07
|
||||||
|
|
||||||
|
#define ISAPNP_ACTIVATE 0x30
|
||||||
|
#define ISAPNP_IORANGECHECK 0x31
|
||||||
|
|
||||||
|
#define ISAPNP_IOBASE(n) (0x60 + ((n)*2))
|
||||||
|
#define ISAPNP_IRQNO(n) (0x70 + ((n)*2))
|
||||||
|
#define ISAPNP_IRQTYPE(n) (0x71 + ((n) * 2))
|
||||||
|
|
||||||
|
#define ISAPNP_CONFIG_RESET (1 << 0)
|
||||||
|
#define ISAPNP_CONFIG_WAIT_FOR_KEY (1 << 1)
|
||||||
|
#define ISAPNP_CONFIG_RESET_CSN (1 << 2)
|
||||||
|
|
||||||
|
#define ISAPNP_LFSR_SEED 0x6A
|
||||||
|
|
||||||
|
#define ISAPNP_IS_SMALL_TAG(t) (!((t) & 0x80))
|
||||||
|
#define ISAPNP_SMALL_TAG_NAME(t) (((t) >> 3) & 0xF)
|
||||||
|
#define ISAPNP_SMALL_TAG_LEN(t) (((t) & 0x7))
|
||||||
|
#define ISAPNP_TAG_PNPVERNO 0x01
|
||||||
|
#define ISAPNP_TAG_LOGDEVID 0x02
|
||||||
|
#define ISAPNP_TAG_COMPATDEVID 0x03
|
||||||
|
#define ISAPNP_TAG_IRQ 0x04
|
||||||
|
#define ISAPNP_TAG_DMA 0x05
|
||||||
|
#define ISAPNP_TAG_STARTDEP 0x06
|
||||||
|
#define ISAPNP_TAG_ENDDEP 0x07
|
||||||
|
#define ISAPNP_TAG_IOPORT 0x08
|
||||||
|
#define ISAPNP_TAG_FIXEDIO 0x09
|
||||||
|
#define ISAPNP_TAG_RSVDSHORTA 0x0A
|
||||||
|
#define ISAPNP_TAG_RSVDSHORTB 0x0B
|
||||||
|
#define ISAPNP_TAG_RSVDSHORTC 0x0C
|
||||||
|
#define ISAPNP_TAG_RSVDSHORTD 0x0D
|
||||||
|
#define ISAPNP_TAG_VENDORSHORT 0x0E
|
||||||
|
#define ISAPNP_TAG_END 0x0F
|
||||||
|
|
||||||
|
#define ISAPNP_IS_LARGE_TAG(t) (((t) & 0x80))
|
||||||
|
#define ISAPNP_LARGE_TAG_NAME(t) (t)
|
||||||
|
#define ISAPNP_TAG_MEMRANGE 0x81
|
||||||
|
#define ISAPNP_TAG_ANSISTR 0x82
|
||||||
|
#define ISAPNP_TAG_UNICODESTR 0x83
|
||||||
|
#define ISAPNP_TAG_VENDORLONG 0x84
|
||||||
|
#define ISAPNP_TAG_MEM32RANGE 0x85
|
||||||
|
#define ISAPNP_TAG_FIXEDMEM32RANGE 0x86
|
||||||
|
#define ISAPNP_TAG_RSVDLONG0 0xF0
|
||||||
|
#define ISAPNP_TAG_RSVDLONG1 0xF1
|
||||||
|
#define ISAPNP_TAG_RSVDLONG2 0xF2
|
||||||
|
#define ISAPNP_TAG_RSVDLONG3 0xF3
|
||||||
|
#define ISAPNP_TAG_RSVDLONG4 0xF4
|
||||||
|
#define ISAPNP_TAG_RSVDLONG5 0xF5
|
||||||
|
#define ISAPNP_TAG_RSVDLONG6 0xF6
|
||||||
|
#define ISAPNP_TAG_RSVDLONG7 0xF7
|
||||||
|
#define ISAPNP_TAG_RSVDLONG8 0xF8
|
||||||
|
#define ISAPNP_TAG_RSVDLONG9 0xF9
|
||||||
|
#define ISAPNP_TAG_RSVDLONGA 0xFA
|
||||||
|
#define ISAPNP_TAG_RSVDLONGB 0xFB
|
||||||
|
#define ISAPNP_TAG_RSVDLONGC 0xFC
|
||||||
|
#define ISAPNP_TAG_RSVDLONGD 0xFD
|
||||||
|
#define ISAPNP_TAG_RSVDLONGE 0xFE
|
||||||
|
#define ISAPNP_TAG_RSVDLONGF 0xFF
|
||||||
|
#define ISAPNP_TAG_PSEUDO_NEWBOARD 0x100
|
||||||
|
|
||||||
|
typedef struct _ISAPNP_IDENTIFIER {
|
||||||
|
USHORT VendorId;
|
||||||
|
USHORT ProdId;
|
||||||
|
ULONG Serial;
|
||||||
|
UCHAR Checksum;
|
||||||
|
} ISAPNP_IDENTIFIER, *PISAPNP_IDENTIFIER;
|
||||||
|
|
||||||
|
typedef struct _ISAPNP_LOGDEVID {
|
||||||
|
USHORT VendorId;
|
||||||
|
USHORT ProdId;
|
||||||
|
USHORT Flags;
|
||||||
|
} ISAPNP_LOGDEVID, *PISAPNP_LOGDEVID;
|
||||||
|
|
||||||
|
typedef struct _ISAPNP_DEVICEID {
|
||||||
|
CHAR* Name;
|
||||||
|
USHORT VendorId;
|
||||||
|
USHORT ProdId;
|
||||||
|
} ISAPNP_DEVICEID, *PISAPNP_DEVICEID;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
83
reactos/drivers/bus/isapnp/pdo.c
Normal file
83
reactos/drivers/bus/isapnp/pdo.c
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS ISA PnP Bus driver
|
||||||
|
* FILE: pdo.c
|
||||||
|
* PURPOSE: PDO-specific code
|
||||||
|
* PROGRAMMERS: Cameron Gutman (cameron.gutman@reactos.org)
|
||||||
|
*/
|
||||||
|
#include <isapnp.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaPdoQueryDeviceRelations(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
PDEVICE_RELATIONS DeviceRelations;
|
||||||
|
|
||||||
|
if (IrpSp->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation)
|
||||||
|
return Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
DeviceRelations = ExAllocatePool(PagedPool, sizeof(*DeviceRelations));
|
||||||
|
if (!DeviceRelations)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
DeviceRelations->Count = 1;
|
||||||
|
DeviceRelations->Objects[0] = LogDev->Common.Self;
|
||||||
|
ObReferenceObject(LogDev->Common.Self);
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IsaPdoPnp(
|
||||||
|
IN PISAPNP_LOGICAL_DEVICE LogDev,
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
NTSTATUS Status = Irp->IoStatus.Status;
|
||||||
|
|
||||||
|
switch (IrpSp->MinorFunction)
|
||||||
|
{
|
||||||
|
case IRP_MN_START_DEVICE:
|
||||||
|
Status = IsaHwActivateDevice(LogDev);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
LogDev->Common.State = dsStarted;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MN_STOP_DEVICE:
|
||||||
|
Status = IsaHwDeactivateDevice(LogDev);
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
LogDev->Common.State = dsStopped;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MN_QUERY_DEVICE_RELATIONS:
|
||||||
|
Status = IsaPdoQueryDeviceRelations(LogDev, Irp, IrpSp);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MN_QUERY_RESOURCES:
|
||||||
|
DPRINT1("IRP_MN_QUERY_RESOURCES is UNIMPLEMENTED!\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
|
||||||
|
DPRINT1("IRP_MN_QUERY_RESOURCE_REQUIREMENTS is UNIMPLEMENTED!\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DPRINT1("Unknown PnP code: %x\n", IrpSp->MinorFunction);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Status = Status;
|
||||||
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue