[ISAPNP]
authorCameron Gutman <aicommander@gmail.com>
Wed, 7 Apr 2010 20:19:29 +0000 (20:19 +0000)
committerCameron Gutman <aicommander@gmail.com>
Wed, 7 Apr 2010 20:19:29 +0000 (20:19 +0000)
- Rewrite the ISAPnP driver based off EtherBoot source
- TODO: Resource stuff

svn path=/trunk/; revision=46768

reactos/drivers/bus/isapnp/fdo.c [new file with mode: 0644]
reactos/drivers/bus/isapnp/hardware.c [new file with mode: 0644]
reactos/drivers/bus/isapnp/isapnp.c
reactos/drivers/bus/isapnp/isapnp.h
reactos/drivers/bus/isapnp/isapnp.rbuild
reactos/drivers/bus/isapnp/isapnphw.h [new file with mode: 0644]
reactos/drivers/bus/isapnp/pdo.c [new file with mode: 0644]

diff --git a/reactos/drivers/bus/isapnp/fdo.c b/reactos/drivers/bus/isapnp/fdo.c
new file mode 100644 (file)
index 0000000..51a0f4b
--- /dev/null
@@ -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);
+}
diff --git a/reactos/drivers/bus/isapnp/hardware.c b/reactos/drivers/bus/isapnp/hardware.c
new file mode 100644 (file)
index 0000000..67a9039
--- /dev/null
@@ -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);
+}
index 37262c3..594b5a9 100644 (file)
-/* $Id$
- *
- * PROJECT:         ReactOS ISA PnP Bus driver
- * FILE:            isapnp.c
- * PURPOSE:         Driver entry
- * PROGRAMMERS:     Casper S. Hornstrup (chorns@users.sourceforge.net)
- * NOTE:            Parts adapted from linux ISA PnP driver
- * UPDATE HISTORY:
- *      01-05-2001  CSH  Created
- */
-#include <isapnp.h>
-
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-#include <debug.h>
-
-
-#ifdef  ALLOC_PRAGMA
-
-// Make the initialization routines discardable, so that they
-// don't waste space
-
-#pragma  alloc_text(init, DriverEntry)
-
-
-#endif  /*  ALLOC_PRAGMA  */
-
-
-PUCHAR IsaPnPReadPort;
-
-
-#define UCHAR2USHORT(v0, v1) \
-  ((v1 << 8) | v0)
-
-#define UCHAR2ULONG(v0, v1, v2, v3) \
-  ((UCHAR2USHORT(v2, v3) << 16) | UCHAR2USHORT(v0, v1))
-
-
-#ifndef NDEBUG
-
-struct
-{
-  PCH Name;
-} SmallTags[] = {
-  {"Unknown Small Tag"},
-  {"ISAPNP_SRIN_VERSION"},
-  {"ISAPNP_SRIN_LDEVICE_ID"},
-  {"ISAPNP_SRIN_CDEVICE_ID"},
-  {"ISAPNP_SRIN_IRQ_FORMAT"},
-  {"ISAPNP_SRIN_DMA_FORMAT"},
-  {"ISAPNP_SRIN_START_DFUNCTION"},
-  {"ISAPNP_SRIN_END_DFUNCTION"},
-  {"ISAPNP_SRIN_IO_DESCRIPTOR"},
-  {"ISAPNP_SRIN_FL_IO_DESCRIPOTOR"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"Reserved Small Tag"},
-  {"ISAPNP_SRIN_VENDOR_DEFINED"},
-  {"ISAPNP_SRIN_END_TAG"}
-};
-
-struct
-{
-  PCH Name;
-} LargeTags[] = {
-  {"Unknown Large Tag"},
-  {"ISAPNP_LRIN_MEMORY_RANGE"},
-  {"ISAPNP_LRIN_ID_STRING_ANSI"},
-  {"ISAPNP_LRIN_ID_STRING_UNICODE"},
-  {"ISAPNP_LRIN_VENDOR_DEFINED"},
-  {"ISAPNP_LRIN_MEMORY_RANGE32"},
-  {"ISAPNP_LRIN_FL_MEMORY_RANGE32"}
-};
-
-PCSZ TagName(ULONG Tag, BOOLEAN Small)
-{
-  if (Small && (Tag <= ISAPNP_SRIN_END_TAG)) {
-    return SmallTags[Tag].Name;
-  } else if (Tag <= ISAPNP_LRIN_FL_MEMORY_RANGE32){
-    return LargeTags[Tag].Name;
-  }
-
-  return NULL;
-}
-
-#endif
-
-static __inline VOID WriteData(UCHAR Value)
-{
-  WRITE_PORT_UCHAR((PUCHAR)ISAPNP_WRITE_PORT, Value);
-}
-
-static __inline VOID WriteAddress(UCHAR Value)
-{
-       WRITE_PORT_UCHAR((PUCHAR)ISAPNP_ADDRESS_PORT, Value);
-       KeStallExecutionProcessor(20);
-}
-
-static __inline UCHAR ReadData(VOID)
-{
-       return READ_PORT_UCHAR(IsaPnPReadPort);
-}
-
-static UCHAR ReadUchar(UCHAR Index)
-{
-       WriteAddress(Index);
-       return ReadData();
-}
-
-#if 0
-static USHORT ReadUshort(UCHAR Index)
-{
-       USHORT Value;
-
-       Value = ReadUchar(Index);
-       Value = (Value << 8) + ReadUchar(Index + 1);
-       return Value;
-}
-
-static ULONG ReadUlong(UCHAR Index)
-{
-       ULONG Value;
-
-       Value = ReadUchar(Index);
-       Value = (Value << 8) + ReadUchar(Index + 1);
-       Value = (Value << 8) + ReadUchar(Index + 2);
-       Value = (Value << 8) + ReadUchar(Index + 3);
-       return Value;
-}
-#endif
-
-static VOID WriteUchar(UCHAR Index, UCHAR Value)
-{
-       WriteAddress(Index);
-       WriteData(Value);
-}
-
-#if 0
-static VOID WriteUshort(UCHAR Index, USHORT Value)
-{
-       WriteUchar(Index, Value >> 8);
-       WriteUchar(Index + 1, Value);
-}
-
-static VOID WriteUlong(UCHAR Index, ULONG Value)
-{
-       WriteUchar(Index, Value >> 24);
-       WriteUchar(Index + 1, Value >> 16);
-       WriteUchar(Index + 2, Value >> 8);
-       WriteUchar(Index + 3, Value);
-}
-#endif
-
-static __inline VOID SetReadDataPort(ULONG_PTR Port)
-{
-  IsaPnPReadPort = (PUCHAR)Port;
-       WriteUchar(0x00, (UCHAR) (Port >> 2));
-       KeStallExecutionProcessor(100);
-}
-
-static VOID SendKey(VOID)
-{
-  ULONG i;
-  UCHAR msb;
-       UCHAR code;
-
-  /* FIXME: Is there something better? */
-       KeStallExecutionProcessor(1000);
-       WriteAddress(0x00);
-       WriteAddress(0x00);
-
-  code = 0x6a;
-       WriteAddress(code);
-       for (i = 1; i < 32; i++) {
-               msb = ((code & 0x01) ^ ((code & 0x02) >> 1)) << 7;
-               code = (code >> 1) | msb;
-               WriteAddress(code);
-       }
-}
-
-/* Place all PnP cards in wait-for-key state */
-static VOID SendWait(VOID)
-{
-       WriteUchar(0x02, 0x02);
-}
-
-static VOID SendWake(UCHAR csn)
-{
-       WriteUchar(ISAPNP_CARD_WAKECSN, csn);
-}
-
-#if 0
-static VOID SelectLogicalDevice(UCHAR LogicalDevice)
-{
-       WriteUchar(ISAPNP_CARD_LOG_DEVICE_NUM, LogicalDevice);
-}
-
-static VOID ActivateLogicalDevice(UCHAR LogicalDevice)
-{
-       SelectLogicalDevice(LogicalDevice);
-       WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x1);
-       KeStallExecutionProcessor(250);
-}
-
-static VOID DeactivateLogicalDevice(UCHAR LogicalDevice)
-{
-       SelectLogicalDevice(LogicalDevice);
-       WriteUchar(ISAPNP_CONTROL_ACTIVATE, 0x0);
-       KeStallExecutionProcessor(500);
-}
-#endif
-
-#define READ_DATA_PORT_STEP 32  /* Minimum is 4 */
-
-static ULONG_PTR FindNextReadPort(VOID)
-{
-       ULONG_PTR Port;
-
-
-
-       Port = (ULONG_PTR)IsaPnPReadPort;
-
-       while (TRUE) {
-
-               Port += READ_DATA_PORT_STEP;
-
-
-
-               if (Port > ISAPNP_MAX_READ_PORT)
-
-               {
-
-                       return 0;
-
-               }
-
-
-
-               /*
-
-                * We cannot use NE2000 probe spaces for
-
-                * ISAPnP or we will lock up machines
-
-                */
-
-               if ((Port < 0x280) || (Port > 0x380))
-
-               {
-
-                       return Port;
-
-               }
-
-       }
-
-}
-
-static BOOLEAN IsolateReadDataPortSelect(VOID)
-{
-  ULONG_PTR Port;
-
-       SendWait();
-       SendKey();
-
-       /* Control: reset CSN and conditionally everything else too */
-       WriteUchar(0x02, 0x05);
-       KeStallExecutionProcessor(2000);
-
-       SendWait();
-       SendKey();
-       SendWake(0x00);
-
-       Port = FindNextReadPort();
-  if (Port == 0) {
-               SendWait();
-               return FALSE;
-       }
-
-       SetReadDataPort(Port);
-       KeStallExecutionProcessor(1000);
-  WriteAddress(0x01);
-       KeStallExecutionProcessor(1000);
-       return TRUE;
-}
-
-/*
- * Isolate (assign uniqued CSN) to all ISA PnP devices
- */
-static ULONG IsolatePnPCards(VOID)
-{
-       UCHAR checksum = 0x6a;
-       UCHAR chksum = 0x00;
-       UCHAR bit = 0x00;
-       ULONG data;
-       ULONG csn = 0;
-       ULONG i;
-       ULONG iteration = 1;
-
-  DPRINT("Called\n");
-
-       IsaPnPReadPort = (PUCHAR)(ISAPNP_MIN_READ_PORT - READ_DATA_PORT_STEP);
-  if (!IsolateReadDataPortSelect()) {
-    DPRINT("Could not set read data port\n");
-               return 0;
-  }
-
-       while (TRUE) {
-               for (i = 1; i <= 64; i++) {
-                       data = ReadData() << 8;
-                       KeStallExecutionProcessor(250);
-                       data = data | ReadData();
-                       KeStallExecutionProcessor(250);
-                       if (data == 0x55aa)
-                               bit = 0x01;
-                       checksum = ((((checksum ^ (checksum >> 1)) & 0x01) ^ bit) << 7) | (checksum >> 1);
-                       bit = 0x00;
-               }
-               for (i = 65; i <= 72; i++) {
-                       data = ReadData() << 8;
-                       KeStallExecutionProcessor(250);
-                       data = data | ReadData();
-                       KeStallExecutionProcessor(250);
-                       if (data == 0x55aa)
-                               chksum |= (1 << (i - 65));
-               }
-               if ((checksum != 0x00) && (checksum == chksum)) {
-                       csn++;
-
-                       WriteUchar(0x06, (UCHAR) csn);
-                       KeStallExecutionProcessor(250);
-                       iteration++;
-                       SendWake(0x00);
-                       SetReadDataPort((ULONG_PTR)IsaPnPReadPort);
-                       KeStallExecutionProcessor(1000);
-                       WriteAddress(0x01);
-                       KeStallExecutionProcessor(1000);
-                       goto next;
-               }
-               if (iteration == 1) {
-      if (!IsolateReadDataPortSelect()) {
-        DPRINT("Could not set read data port\n");
-                               return 0;
-      }
-               } else if (iteration > 1) {
-                       break;
-               }
-next:
-               checksum = 0x6a;
-               chksum = 0x00;
-               bit = 0x00;
-       }
-       SendWait();
-       return csn;
-}
-
-
-static VOID Peek(PUCHAR Data, ULONG Count)
-{
-       ULONG i, j;
-       UCHAR d = 0;
-
-       for (i = 1; i <= Count; i++) {
-               for (j = 0; j < 20; j++) {
-                       d = ReadUchar(0x05);
-                       if (d & 0x1)
-                               break;
-                       KeStallExecutionProcessor(100);
-               }
-               if (!(d & 0x1)) {
-                       if (Data != NULL)
-                               *Data++ = 0xff;
-                       continue;
-               }
-               d = ReadUchar(0x04); /* PRESDI */
-               if (Data != NULL)
-                       *Data++ = d;
-       }
-}
-
-
-/*
- * Skip specified number of bytes from stream
- */
-static VOID Skip(ULONG Count)
-{
-       Peek(NULL, Count);
-}
-
-
-/*
- * Read one tag from stream
- */
-static BOOLEAN ReadTag(PUCHAR Type,
-  PUSHORT Size,
-  PBOOLEAN Small)
-{
-       UCHAR tag, tmp[2];
-
-       Peek(&tag, 1);
-  if (tag == 0) {
-    /* Invalid tag */
-    DPRINT("Invalid tag with value 0\n");
-#ifndef NDEBUG
-    for (;;);
-#endif
-               return FALSE;
-  }
-
-       if (tag & ISAPNP_RESOURCE_ITEM_TYPE) {
-    /* Large resource item */
-               *Type = (tag & 0x7f);
-               Peek(tmp, 2);
-               *Size = UCHAR2USHORT(tmp[0], tmp[1]);
-    *Small = FALSE;
-#ifndef NDEBUG
-    if (*Type > ISAPNP_LRIN_FL_MEMORY_RANGE32) {
-      DPRINT("Invalid large tag with value 0x%X\n", *Type);
-      for (;;);
-    }
-#endif
-       } else {
-    /* Small resource item */
-               *Type = (tag >> 3) & 0x0f;
-               *Size = tag & 0x07;
-    *Small = TRUE;
-#ifndef NDEBUG
-    if (*Type > ISAPNP_SRIN_END_TAG) {
-      DPRINT("Invalid small tag with value 0x%X\n", *Type);
-      for (;;);
-    }
-#endif
-  }
-#if 0
-       DPRINT("Tag = 0x%X, Type = 0x%X, Size = %d (%s)\n",
-    tag, *Type, *Size, TagName(*Type, *Small));
-#endif
-  /* Probably invalid data */
-  if ((*Type == 0xff) && (*Size == 0xffff)) {
-    DPRINT("Invalid data (Type 0x%X  Size 0x%X)\n", *Type, *Size);
-    for (;;);
-               return FALSE;
-  }
-
-       return TRUE;
-}
-
-
-/*
- * Parse ANSI name for ISA PnP logical device
- */
-static NTSTATUS ParseAnsiName(PUNICODE_STRING Name, PUSHORT Size)
-{
-  ANSI_STRING AnsiString;
-  UCHAR Buffer[256];
-  USHORT size1;
-
-  size1 = (*Size >= sizeof(Buffer)) ? (sizeof(Buffer) - 1) : *Size;
-
-  Peek(Buffer, size1);
-  Buffer[size1] = '\0';
-  *Size -= size1;
-
-  /* Clean whitespace from end of string */
-  while ((size1 > 0) && (Buffer[--size1] == ' '))
-    Buffer[size1] = '\0';
-
-  DPRINT("ANSI name: %s\n", Buffer);
-
-  RtlInitAnsiString(&AnsiString, (PCSZ)&Buffer);
-  return RtlAnsiStringToUnicodeString(Name, &AnsiString, TRUE);
-}
-
-
-/*
- * Add a resource list to the
- * resource lists of a logical device
- */
-static NTSTATUS AddResourceList(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Priority,
-  PISAPNP_CONFIGURATION_LIST *NewList)
-{
-  PISAPNP_CONFIGURATION_LIST List;
-
-  DPRINT("Adding resource list for logical device %d on card %d (Priority %d)\n",
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId,
-        Priority);
-
-  List = (PISAPNP_CONFIGURATION_LIST)
-      ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_CONFIGURATION_LIST), TAG_ISAPNP);
-  if (!List)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  RtlZeroMemory(List, sizeof(ISAPNP_CONFIGURATION_LIST));
-
-  List->Priority = Priority;
-
-  InitializeListHead(&List->ListHead);
-
-  InsertTailList(&LogicalDevice->Configuration, &List->ListEntry);
-
-  *NewList = List;
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Add a resource entry to the
- * resource list of a logical device
- */
-static NTSTATUS AddResourceDescriptor(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Priority,
-  ULONG Option,
-  PISAPNP_DESCRIPTOR *Descriptor)
-{
-  PLIST_ENTRY CurrentEntry;
-  PISAPNP_CONFIGURATION_LIST List;
-  PISAPNP_DESCRIPTOR d;
-  NTSTATUS Status;
-
-  DPRINT("Adding resource descriptor for logical device %d on card %d (%d of %d)\n",
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId,
-        LogicalDevice->CurrentDescriptorCount,
-        LogicalDevice->DescriptorCount);
-
-  d = (PISAPNP_DESCRIPTOR)
-    ExAllocatePoolWithTag(PagedPool, sizeof(ISAPNP_DESCRIPTOR), TAG_ISAPNP);
-  if (!d)
-    return STATUS_NO_MEMORY;
-
-  RtlZeroMemory(d, sizeof(ISAPNP_DESCRIPTOR));
-
-  d->Descriptor.Option = (UCHAR) Option;
-
-  *Descriptor = d;
-
-  CurrentEntry = LogicalDevice->Configuration.Flink;
-  while (CurrentEntry != &LogicalDevice->Configuration) {
-    List = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry);
-
-    if (List->Priority == Priority) {
-
-      LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_DESCRIPTOR);
-      InsertTailList(&List->ListHead, &d->ListEntry);
-      LogicalDevice->CurrentDescriptorCount++;
-      if (LogicalDevice->DescriptorCount <
-        LogicalDevice->CurrentDescriptorCount) {
-        LogicalDevice->DescriptorCount =
-          LogicalDevice->CurrentDescriptorCount;
-      }
-
-      return STATUS_SUCCESS;
-    }
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  Status = AddResourceList(LogicalDevice, Priority, &List);
-  if (NT_SUCCESS(Status)) {
-    LogicalDevice->ConfigurationSize += sizeof(IO_RESOURCE_LIST);
-    LogicalDevice->CurrentDescriptorCount = 0;
-    InsertTailList(&List->ListHead, &d->ListEntry);
-  }
-
-  return Status;
-}
-
-
-/*
- * Add IRQ resource to resources list
- */
-static NTSTATUS AddIrqResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[3];
-  ULONG irq, i, last = 0;
-  BOOLEAN found;
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-       irq = UCHAR2USHORT(tmp[0], tmp[0]);
-
-  DPRINT("IRQ bitmask: 0x%X\n", irq);
-
-  found = FALSE;
-  for (i = 0; i < 16; i++) {
-    if (!found && (irq & (1 << i))) {
-      last = i;
-      found = TRUE;
-    }
-
-    if ((found && !(irq & (1 << i))) || (irq & (1 << i) && (i == 15))) {
-      Status = AddResourceDescriptor(LogicalDevice,
-        Priority, Option, &Descriptor);
-      if (!NT_SUCCESS(Status))
-        return Status;
-      Descriptor->Descriptor.Type = CmResourceTypeInterrupt;
-      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-      Descriptor->Descriptor.u.Interrupt.MinimumVector = last;
-
-      if ((irq & (1 << i)) && (i == 15))
-        Descriptor->Descriptor.u.Interrupt.MaximumVector = i;
-      else
-        Descriptor->Descriptor.u.Interrupt.MaximumVector = i - 1;
-
-      DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n",
-        Descriptor->Descriptor.u.Interrupt.MinimumVector,
-        Descriptor->Descriptor.u.Interrupt.MaximumVector,
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId);
-
-      found = FALSE;
-    }
-  }
-
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add DMA resource to resources list
- */
-static NTSTATUS AddDmaResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[2];
-  ULONG dma, flags, i, last = 0;
-  BOOLEAN found;
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-       dma = tmp[0];
-  flags = tmp[1];
-
-  DPRINT("DMA bitmask: 0x%X\n", dma);
-
-  found = FALSE;
-  for (i = 0; i < 8; i++) {
-    if (!found && (dma & (1 << i))) {
-      last = i;
-      found = TRUE;
-    }
-
-    if ((found && !(dma & (1 << i))) || (dma & (1 << i) && (i == 15))) {
-      Status = AddResourceDescriptor(LogicalDevice,
-        Priority, Option, &Descriptor);
-      if (!NT_SUCCESS(Status))
-        return Status;
-      Descriptor->Descriptor.Type = CmResourceTypeDma;
-      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-      Descriptor->Descriptor.u.Dma.MinimumChannel = last;
-
-      if ((dma & (1 << i)) && (i == 15))
-        Descriptor->Descriptor.u.Dma.MaximumChannel = i;
-      else
-        Descriptor->Descriptor.u.Dma.MaximumChannel = i - 1;
-
-      /* FIXME: Parse flags */
-
-      DPRINT("Found DMA range %d - %d for logical device %d on card %d\n",
-        Descriptor->Descriptor.u.Dma.MinimumChannel,
-        Descriptor->Descriptor.u.Dma.MaximumChannel,
-        LogicalDevice->Number,
-        LogicalDevice->Card->CardId);
-
-      found = FALSE;
-    }
-  }
-
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add port resource to resources list
- */
-static NTSTATUS AddIOPortResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("I/O port: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[7];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypePort;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Port.Length = tmp[6];
-  /* FIXME: Parse flags */
-  Descriptor->Descriptor.u.Port.Alignment = 0;
-  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]);
-  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[4], tmp[4]);
-
-  DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Port.MinimumAddress,
-    Descriptor->Descriptor.u.Port.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add fixed port resource to resources list
- */
-static NTSTATUS AddFixedIOPortResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Fixed I/O port: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[3];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypePort;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Port.Length = tmp[2];
-  Descriptor->Descriptor.u.Port.Alignment = 0;
-  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);
-  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);
-
-  DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Port.MinimumAddress,
-    Descriptor->Descriptor.u.Port.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add memory resource to resources list
- */
-static NTSTATUS AddMemoryResource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[9];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length = UCHAR2USHORT(tmp[7], tmp[8]) << 8;
-  Descriptor->Descriptor.u.Memory.Alignment = UCHAR2USHORT(tmp[5], tmp[6]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]) << 8;
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[3], tmp[4]) << 8;
-
-  DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add 32-bit memory resource to resources list
- */
-static NTSTATUS AddMemory32Resource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory32 range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[17];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length =
-    UCHAR2ULONG(tmp[13], tmp[14], tmp[15], tmp[16]);
-  Descriptor->Descriptor.u.Memory.Alignment =
-    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
-    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);
-
-  DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-/*
- * Add 32-bit fixed memory resource to resources list
- */
-static NTSTATUS AddFixedMemory32Resource(
-  PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  ULONG Size,
-  ULONG Priority,
-  ULONG Option)
-{
-#if 0
-  DPRINT("Memory32 range: size 0x%X\n", Size);
-  Skip(Size);
-#else
-  PISAPNP_DESCRIPTOR Descriptor;
-       UCHAR tmp[17];
-  NTSTATUS Status;
-
-       Peek(tmp, Size);
-
-  Status = AddResourceDescriptor(LogicalDevice,
-    Priority, Option, &Descriptor);
-  if (!NT_SUCCESS(Status))
-    return Status;
-  Descriptor->Descriptor.Type = CmResourceTypeMemory;
-  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
-  Descriptor->Descriptor.u.Memory.Length =
-    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
-  Descriptor->Descriptor.u.Memory.Alignment =
-    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);
-  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
-    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
-
-  DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
-    Descriptor->Descriptor.u.Memory.MinimumAddress,
-    Descriptor->Descriptor.u.Memory.MaximumAddress,
-    LogicalDevice->Number,
-    LogicalDevice->Card->CardId);
-#endif
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Parse logical device tag
- */
-static PISAPNP_LOGICAL_DEVICE ParseLogicalDevice(
-  PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card,
-  ULONG Size,
-  USHORT Number)
-{
-       UCHAR tmp[6];
-       PISAPNP_LOGICAL_DEVICE LogicalDevice;
-
-  DPRINT("Card %d  Number %d\n", Card->CardId, Number);
-
-  Peek(tmp, Size);
-
-  LogicalDevice = (PISAPNP_LOGICAL_DEVICE)ExAllocatePoolWithTag(
-    PagedPool, sizeof(ISAPNP_LOGICAL_DEVICE), TAG_ISAPNP);
-       if (!LogicalDevice)
-               return NULL;
-
-  RtlZeroMemory(LogicalDevice, sizeof(ISAPNP_LOGICAL_DEVICE));
-
-  LogicalDevice->Number = Number;
-       LogicalDevice->VendorId = UCHAR2USHORT(tmp[0], tmp[1]);
-       LogicalDevice->DeviceId = UCHAR2USHORT(tmp[2], tmp[3]);
-       LogicalDevice->Regs = tmp[4];
-       LogicalDevice->Card = Card;
-       if (Size > 5)
-               LogicalDevice->Regs |= tmp[5] << 8;
-
-  InitializeListHead(&LogicalDevice->Configuration);
-
-  ExInterlockedInsertTailList(&Card->LogicalDevices,
-    &LogicalDevice->CardListEntry,
-    &Card->LogicalDevicesLock);
-
-  ExInterlockedInsertTailList(&DeviceExtension->DeviceListHead,
-    &LogicalDevice->DeviceListEntry,
-    &DeviceExtension->GlobalListLock);
-
-  DeviceExtension->DeviceListCount++;
-
-       return LogicalDevice;
-}
-
-
-/*
- * Parse resource map for logical device
- */
-static BOOLEAN CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card, USHORT Size)
-{
-       ULONG number = 0, skip = 0, compat = 0;
-       UCHAR type, tmp[17];
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  BOOLEAN Small;
-  ULONG Priority = 0;
-  ULONG Option = IO_RESOURCE_REQUIRED;
-
-  DPRINT("Card %d  Size %d\n", Card->CardId, Size);
-
-  LogicalDevice = ParseLogicalDevice(DeviceExtension, Card, Size, (USHORT) number++);
-       if (!LogicalDevice)
-               return FALSE;
-
-  while (TRUE) {
-               if (!ReadTag(&type, &Size, &Small))
-                       return FALSE;
-
-                if (skip && !(Small && ((type == ISAPNP_SRIN_LDEVICE_ID)
-      || (type == ISAPNP_SRIN_END_TAG))))
-                       goto skip;
-
-    if (Small) {
-               switch (type) {
-               case ISAPNP_SRIN_LDEVICE_ID:
-        if ((Size >= 5) && (Size <= 6)) {
-          LogicalDevice = ParseLogicalDevice(
-            DeviceExtension, Card, Size, (USHORT)number++);
-               if (!LogicalDevice)
-               return FALSE;
-                               Size = 0;
-                               skip = 0;
-                       } else {
-                               skip = 1;
-                         }
-        Priority = 0;
-        Option = IO_RESOURCE_REQUIRED;
-                         compat = 0;
-                         break;
-
-                 case ISAPNP_SRIN_CDEVICE_ID:
-                         if ((Size == 4) && (compat < MAX_COMPATIBLE_ID)) {
-                                 Peek(tmp, 4);
-                                 LogicalDevice->CVendorId[compat] = UCHAR2USHORT(tmp[0], tmp[1]);
-                                 LogicalDevice->CDeviceId[compat] = UCHAR2USHORT(tmp[2], tmp[3]);
-                                 compat++;
-                                 Size = 0;
-                         }
-                         break;
-
-                 case ISAPNP_SRIN_IRQ_FORMAT:
-                       if ((Size < 2) || (Size > 3))
-                                 goto skip;
-                         AddIrqResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_DMA_FORMAT:
-                       if (Size != 2)
-                                 goto skip;
-        AddDmaResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_START_DFUNCTION:
-                       if (Size > 1)
-                                 goto skip;
-
-        if (Size > 0) {
-                               Peek(tmp, Size);
-          Priority = tmp[0];
-                                 Size = 0;
-          /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */
-          Option = IO_RESOURCE_ALTERNATIVE;
-        } else {
-          Priority = 0;
-          Option = IO_RESOURCE_ALTERNATIVE;
-        }
-
-        DPRINT("   Start priority %d   \n", Priority);
-
-        LogicalDevice->CurrentDescriptorCount = 0;
-
-                         break;
-
-               case ISAPNP_SRIN_END_DFUNCTION:
-
-        DPRINT("   End priority %d   \n", Priority);
-
-                       if (Size != 0)
-                               goto skip;
-        Priority = 0;
-        Option = IO_RESOURCE_REQUIRED;
-        LogicalDevice->CurrentDescriptorCount = 0;
-                         break;
-
-               case ISAPNP_SRIN_IO_DESCRIPTOR:
-                       if (Size != 7)
-                               goto skip;
-                         AddIOPortResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_FL_IO_DESCRIPOTOR:
-                         if (Size != 3)
-                               goto skip;
-                         AddFixedIOPortResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_SRIN_VENDOR_DEFINED:
-                       break;
-
-                 case ISAPNP_SRIN_END_TAG:
-                         if (Size > 0)
-                               Skip(Size);
-        return FALSE;
-
-                 default:
-                       DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n",
-          type, LogicalDevice->Number, Card->CardId);
-      }
-    } else {
-      switch (type) {
-                 case ISAPNP_LRIN_MEMORY_RANGE:
-                         if (Size != 9)
-                               goto skip;
-                         AddMemoryResource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_LRIN_ID_STRING_ANSI:
-        ParseAnsiName(&LogicalDevice->Name, &Size);
-                         break;
-
-                 case ISAPNP_LRIN_ID_STRING_UNICODE:
-                       break;
-
-               case ISAPNP_LRIN_VENDOR_DEFINED:
-                         break;
-
-                 case ISAPNP_LRIN_MEMORY_RANGE32:
-                       if (Size != 17)
-                                 goto skip;
-                         AddMemory32Resource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 case ISAPNP_LRIN_FL_MEMORY_RANGE32:
-                       if (Size != 17)
-                                 goto skip;
-                         AddFixedMemory32Resource(LogicalDevice, Size, Priority, Option);
-                         Size = 0;
-                         break;
-
-                 default:
-                       DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n",
-          type, LogicalDevice->Number, Card->CardId);
-                 }
-    }
-skip:
-  if (Size > 0)
-         Skip(Size);
-       }
-
-       return TRUE;
-}
-
-
-/*
- * Parse resource map for ISA PnP card
- */
-static BOOLEAN ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension,
-  PISAPNP_CARD Card)
-{
-       UCHAR type, tmp[17];
-       USHORT size;
-  BOOLEAN Small;
-
-  DPRINT("Card %d\n", Card->CardId);
-
-       while (TRUE) {
-               if (!ReadTag(&type, &size, &Small))
-                       return FALSE;
-
-    if (Small) {
-                 switch (type) {
-                 case ISAPNP_SRIN_VERSION:
-                       if (size != 2)
-                               goto skip;
-                       Peek(tmp, 2);
-                         Card->PNPVersion = tmp[0];
-                         Card->ProductVersion = tmp[1];
-                         size = 0;
-                         break;
-
-      case ISAPNP_SRIN_LDEVICE_ID:
-                       if ((size >= 5) && (size <= 6)) {
-                                 if (!CreateLogicalDevice(DeviceExtension, Card, size))
-                                       return FALSE;
-                                 size = 0;
-                         }
-                         break;
-
-      case ISAPNP_SRIN_CDEVICE_ID:
-        /* FIXME: Parse compatible IDs */
-        break;
-
-                 case ISAPNP_SRIN_END_TAG:
-                         if (size > 0)
-                               Skip(size);
-                         return TRUE;
-
-                 default:
-                       DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type, Card->CardId);
-                 }
-    } else {
-                 switch (type) {
-                 case ISAPNP_LRIN_ID_STRING_ANSI:
-                       ParseAnsiName(&Card->Name, &size);
-                         break;
-
-      default:
-                       DPRINT("Ignoring large tag Type 0x%X for Card %d\n",
-          type, Card->CardId);
-                 }
-    }
-skip:
-  if (size > 0)
-    Skip(size);
-  }
-
-  return TRUE;
-}
-
-
-/*
- * Compute ISA PnP checksum for first eight bytes
- */
-static UCHAR Checksum(PUCHAR data)
-{
-       ULONG i, j;
-       UCHAR checksum = 0x6a, bit, b;
-
-       for (i = 0; i < 8; i++) {
-               b = data[i];
-               for (j = 0; j < 8; j++) {
-                       bit = 0;
-                       if (b & (1 << j))
-                               bit = 1;
-                       checksum = ((((checksum ^ (checksum >> 1)) &
-        0x01) ^ bit) << 7) | (checksum >> 1);
-               }
-       }
-       return checksum;
-}
-
-
-/*
- * Build a resource list for a logical ISA PnP device
- */
-static NTSTATUS BuildResourceList(PISAPNP_LOGICAL_DEVICE LogicalDevice,
-  PIO_RESOURCE_LIST DestinationList,
-  ULONG Priority)
-{
-  PLIST_ENTRY CurrentEntry, Entry;
-  PISAPNP_CONFIGURATION_LIST List;
-  PISAPNP_DESCRIPTOR Descriptor;
-  ULONG i;
-
-  if (IsListEmpty(&LogicalDevice->Configuration))
-    return STATUS_NOT_FOUND;
-
-  CurrentEntry = LogicalDevice->Configuration.Flink;
-  while (CurrentEntry != &LogicalDevice->Configuration) {
-    List = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CONFIGURATION_LIST, ListEntry);
-
-    if (List->Priority == Priority) {
-
-      DPRINT("Logical device %d  DestinationList %p\n",
-        LogicalDevice->Number,
-        DestinationList);
-
-      DestinationList->Version = 1;
-      DestinationList->Revision = 1;
-      DestinationList->Count = LogicalDevice->DescriptorCount;
-
-      i = 0;
-      Entry = List->ListHead.Flink;
-      while (Entry != &List->ListHead) {
-        Descriptor = CONTAINING_RECORD(
-          Entry, ISAPNP_DESCRIPTOR, ListEntry);
-
-        DPRINT("Logical device %d  Destination %p(%d)\n",
-          LogicalDevice->Number,
-          &DestinationList->Descriptors[i],
-          i);
-
-        RtlCopyMemory(&DestinationList->Descriptors[i],
-          &Descriptor->Descriptor,
-          sizeof(IO_RESOURCE_DESCRIPTOR));
-
-        i++;
-
-        Entry = Entry->Flink;
-      }
-
-      RemoveEntryList(&List->ListEntry);
-
-      ExFreePool(List);
-
-      return STATUS_SUCCESS;
-    }
-
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_UNSUCCESSFUL;
-}
-
-
-/*
- * Build resource lists for a logical ISA PnP device
- */
-static NTSTATUS BuildResourceLists(PISAPNP_LOGICAL_DEVICE LogicalDevice)
-{
-  ULONG ListSize;
-  ULONG Priority;
-  ULONG SingleListSize;
-  PIO_RESOURCE_LIST p;
-  NTSTATUS Status;
-
-  ListSize = sizeof(IO_RESOURCE_REQUIREMENTS_LIST)
-    - sizeof(IO_RESOURCE_LIST)
-    + LogicalDevice->ConfigurationSize;
-
-  DPRINT("Logical device %d  ListSize 0x%X  ConfigurationSize 0x%X  DescriptorCount %d\n",
-    LogicalDevice->Number, ListSize,
-    LogicalDevice->ConfigurationSize,
-    LogicalDevice->DescriptorCount);
-
-  LogicalDevice->ResourceLists =
-    (PIO_RESOURCE_REQUIREMENTS_LIST)ExAllocatePoolWithTag(
-      PagedPool, ListSize, TAG_ISAPNP);
-       if (!LogicalDevice->ResourceLists)
-               return STATUS_INSUFFICIENT_RESOURCES;
-
-  RtlZeroMemory(LogicalDevice->ResourceLists, ListSize);
-
-  SingleListSize = sizeof(IO_RESOURCE_LIST) +
-    (LogicalDevice->DescriptorCount - 1) *
-    sizeof(IO_RESOURCE_DESCRIPTOR);
-
-  DPRINT("SingleListSize %d\n", SingleListSize);
-
-  Priority = 0;
-  p = &LogicalDevice->ResourceLists->List[0];
-  do {
-    Status = BuildResourceList(LogicalDevice, p, Priority);
-    if (NT_SUCCESS(Status)) {
-      p = (PIO_RESOURCE_LIST)((ULONG_PTR)p + SingleListSize);
-      Priority++;
-    }
-  } while (Status != STATUS_NOT_FOUND);
-
-  LogicalDevice->ResourceLists->ListSize = ListSize;
-  LogicalDevice->ResourceLists->AlternativeLists = Priority + 1;
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Build resource lists for a ISA PnP card
- */
-static NTSTATUS BuildResourceListsForCard(PISAPNP_CARD Card)
-{
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  PLIST_ENTRY CurrentEntry;
-  NTSTATUS Status;
-
-  CurrentEntry = Card->LogicalDevices.Flink;
-  while (CurrentEntry != &Card->LogicalDevices) {
-    LogicalDevice = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_LOGICAL_DEVICE, CardListEntry);
-    Status = BuildResourceLists(LogicalDevice);
-    if (!NT_SUCCESS(Status))
-      return Status;
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
-/*
- * Build resource lists for all present ISA PnP cards
- */
-static NTSTATUS BuildResourceListsForAll(
-  PISAPNP_DEVICE_EXTENSION DeviceExtension)
-{
-  PLIST_ENTRY CurrentEntry;
-  PISAPNP_CARD Card;
-  NTSTATUS Status;
-
-  CurrentEntry = DeviceExtension->CardListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->CardListHead) {
-    Card = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_CARD, ListEntry);
-    Status = BuildResourceListsForCard(Card);
-    if (!NT_SUCCESS(Status))
-      return Status;
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
 /*
- * Build device list for all present ISA PnP cards
+ * PROJECT:         ReactOS ISA PnP Bus driver
+ * FILE:            isapnp.c
+ * PURPOSE:         Driver entry
+ * PROGRAMMERS:     Cameron Gutman (cameron.gutman@reactos.org)
  */
-static NTSTATUS BuildDeviceList(PISAPNP_DEVICE_EXTENSION DeviceExtension)
-{
-       ULONG csn;
-       UCHAR header[9], checksum;
-  PISAPNP_CARD Card;
-
-  DPRINT("Called\n");
-
-       SendWait();
-       SendKey();
-       for (csn = 1; csn <= 10; csn++) {
-               SendWake((UCHAR)csn);
-               Peek(header, 9);
-               checksum = Checksum(header);
-
-    if (checksum == 0x00 || checksum != header[8])  /* Invalid CSN */
-                       continue;
-
-               DPRINT("VENDOR: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-                       header[0], header[1], header[2], header[3],
-                       header[4], header[5], header[6], header[7], header[8]);
-
-    Card = (PISAPNP_CARD)ExAllocatePoolWithTag(
-      PagedPool, sizeof(ISAPNP_CARD), TAG_ISAPNP);
-    if (!Card)
-      return STATUS_INSUFFICIENT_RESOURCES;
-
-    RtlZeroMemory(Card, sizeof(ISAPNP_CARD));
-
-               Card->CardId = (USHORT) csn;
-               Card->VendorId = (header[1] << 8) | header[0];
-               Card->DeviceId = (header[3] << 8) | header[2];
-               Card->Serial = (header[7] << 24) | (header[6] << 16) | (header[5] << 8) | header[4];
-
-    InitializeListHead(&Card->LogicalDevices);
-    KeInitializeSpinLock(&Card->LogicalDevicesLock);
-
-    ParseResourceMap(DeviceExtension, Card);
-
-    ExInterlockedInsertTailList(&DeviceExtension->CardListHead,
-      &Card->ListEntry,
-      &DeviceExtension->GlobalListLock);
-       }
-
-  return STATUS_SUCCESS;
-}
+#include <isapnp.h>
 
+#define NDEBUG
+#include <debug.h>
 
-static NTSTATUS
-ISAPNPQueryBusRelations(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
+static
+NTSTATUS
+NTAPI
+ForwardIrpCompletion(
+       IN PDEVICE_OBJECT DeviceObject,
+       IN PIRP Irp,
+       IN PVOID Context)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-  PISAPNP_LOGICAL_DEVICE LogicalDevice;
-  PDEVICE_RELATIONS Relations;
-  PLIST_ENTRY CurrentEntry;
-  NTSTATUS Status = STATUS_SUCCESS;
-  ULONG Size;
-  ULONG i;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (Irp->IoStatus.Information) {
-    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
-              structure so we must merge this structure with our own */
-  }
-
-  Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
-    (DeviceExtension->DeviceListCount - 1);
-  Relations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(PagedPool, Size, TAG_ISAPNP);
-  if (!Relations)
-    return STATUS_INSUFFICIENT_RESOURCES;
-
-  Relations->Count = DeviceExtension->DeviceListCount;
-
-  i = 0;
-  CurrentEntry = DeviceExtension->DeviceListHead.Flink;
-  while (CurrentEntry != &DeviceExtension->DeviceListHead) {
-    LogicalDevice = CONTAINING_RECORD(
-      CurrentEntry, ISAPNP_LOGICAL_DEVICE, DeviceListEntry);
-
-    if (!LogicalDevice->Pdo) {
-      /* Create a physical device object for the
-         device as it does not already have one */
-      Status = IoCreateDevice(DeviceObject->DriverObject, 0,
-        NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &LogicalDevice->Pdo);
-      if (!NT_SUCCESS(Status)) {
-        DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
-        ExFreePool(Relations);
-        return Status;
-      }
-
-      LogicalDevice->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
-    }
-
-    /* Reference the physical device object. The PnP manager
-       will dereference it again when it is no longer needed */
-    ObReferenceObject(LogicalDevice->Pdo);
-
-    Relations->Objects[i] = LogicalDevice->Pdo;
+  if (Irp->PendingReturned)
+    KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE);
 
-    i++;
-
-    CurrentEntry = CurrentEntry->Flink;
-  }
-
-  Irp->IoStatus.Information = (ULONG_PTR)Relations;
-
-  return Status;
+  return STATUS_MORE_PROCESSING_REQUIRED;
 }
 
-
-static NTSTATUS
-ISAPNPQueryDeviceRelations(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
+NTSTATUS
+NTAPI
+IsaForwardIrpSynchronous(
+       IN PISAPNP_FDO_EXTENSION FdoExt,
+       IN PIRP Irp)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
+  KEVENT Event;
   NTSTATUS Status;
 
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
+  KeInitializeEvent(&Event, NotificationEvent, FALSE);
+  IoCopyCurrentIrpStackLocationToNext(Irp);
 
-  if (DeviceExtension->State == dsStopped)
-    return STATUS_UNSUCCESSFUL;
+  IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE);
 
-  switch (IrpSp->Parameters.QueryDeviceRelations.Type) {
-    case BusRelations:
-      Status = ISAPNPQueryBusRelations(DeviceObject, Irp, IrpSp);
-      break;
-
-    default:
-      Status = STATUS_NOT_IMPLEMENTED;
+  Status = IoCallDriver(FdoExt->Ldo, Irp);
+  if (Status == STATUS_PENDING)
+  {
+      Status = KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
+      if (NT_SUCCESS(Status))
+         Status = Irp->IoStatus.Status;
   }
 
   return Status;
 }
 
 
-static NTSTATUS
-ISAPNPStartDevice(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
-{
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-  NTSTATUS Status;
-  ULONG NumCards;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (DeviceExtension->State == dsStarted)
-    return STATUS_SUCCESS;
-
-  NumCards = IsolatePnPCards();
-
-  DPRINT("Number of ISA PnP cards found: %d\n", NumCards);
-
-  Status = BuildDeviceList(DeviceExtension);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("BuildDeviceList() failed with status 0x%X\n", Status);
-    return Status;
-  }
-
-  Status = BuildResourceListsForAll(DeviceExtension);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("BuildResourceListsForAll() failed with status 0x%X\n", Status);
-    return Status;
-  }
-
-  DeviceExtension->State = dsStarted;
-
-  return STATUS_SUCCESS;
-}
-
-
-static NTSTATUS
-ISAPNPStopDevice(
-  IN PDEVICE_OBJECT DeviceObject,
-  IN PIRP Irp,
-  PIO_STACK_LOCATION IrpSp)
-{
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
-
-  DPRINT("Called\n");
-
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-  if (DeviceExtension->State != dsStopped) {
-    /* FIXME: Stop device */
-    DeviceExtension->State = dsStopped;
-  }
-
-  return STATUS_SUCCESS;
-}
-
-
-static DRIVER_DISPATCH ISAPNPDispatchOpenClose;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPDispatchOpenClose(
+IsaCreateClose(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  DPRINT("Called\n");
-
   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = FILE_OPENED;
-  IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-  return STATUS_SUCCESS;
-}
 
-static DRIVER_DISPATCH ISAPNPDispatchReadWrite;
-static NTSTATUS
-NTAPI
-ISAPNPDispatchReadWrite(
-  IN PDEVICE_OBJECT PhysicalDeviceObject,
-  IN PIRP Irp)
-{
-  DPRINT("Called\n");
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-  Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return STATUS_UNSUCCESSFUL;
+  return STATUS_SUCCESS;
 }
 
-static DRIVER_DISPATCH ISAPNPDispatchDeviceControl;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPDispatchDeviceControl(
+IsaIoctl(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  PIO_STACK_LOCATION IrpSp;
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
   NTSTATUS Status;
 
-  DPRINT("Called\n");
-
-  Irp->IoStatus.Information = 0;
-
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
-  default:
-    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
-    Status = STATUS_NOT_IMPLEMENTED;
-    break;
-  }
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+  switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
+  {
+     default:
+        DPRINT1("Unknown ioctl code: %x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode);
+        Status = STATUS_NOT_SUPPORTED;
+        break;
   }
 
-  DPRINT("Leaving. Status 0x%X\n", Status);
+  Irp->IoStatus.Status = Status;
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
   return Status;
 }
 
-static DRIVER_DISPATCH ISAPNPControl;
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPControl(
+IsaReadWrite(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
 {
-  PIO_STACK_LOCATION IrpSp;
-  NTSTATUS Status;
-
-  DPRINT("Called\n");
-
-  IrpSp = IoGetCurrentIrpStackLocation(Irp);
-  switch (IrpSp->MinorFunction) {
-  case IRP_MN_QUERY_DEVICE_RELATIONS:
-    Status = ISAPNPQueryDeviceRelations(DeviceObject, Irp, IrpSp);
-    break;
-
-  case IRP_MN_START_DEVICE:
-    Status = ISAPNPStartDevice(DeviceObject, Irp, IrpSp);
-    break;
-
-  case IRP_MN_STOP_DEVICE:
-    Status = ISAPNPStopDevice(DeviceObject, Irp, IrpSp);
-    break;
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
 
-  case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
-    /* Nothing to do here */
-    DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
-    Status = Irp->IoStatus.Status;
-    break;
-
-  default:
-    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
-    Status = STATUS_NOT_IMPLEMENTED;
-    break;
-  }
-
-  if (Status != STATUS_PENDING) {
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-  }
+  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+  Irp->IoStatus.Information = 0;
 
-  DPRINT("Leaving. Status 0x%X\n", Status);
+  IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-  return Status;
+  return STATUS_NOT_SUPPORTED;
 }
 
-
-static NTSTATUS
+static
+NTSTATUS
 NTAPI
-ISAPNPAddDevice(
+IsaAddDevice(
   IN PDRIVER_OBJECT DriverObject,
   IN PDEVICE_OBJECT PhysicalDeviceObject)
 {
-  PISAPNP_DEVICE_EXTENSION DeviceExtension;
   PDEVICE_OBJECT Fdo;
+  PISAPNP_FDO_EXTENSION FdoExt;
   NTSTATUS Status;
 
-  DPRINT("Called\n");
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DriverObject, PhysicalDeviceObject);
 
-  Status = IoCreateDevice(DriverObject, sizeof(ISAPNP_DEVICE_EXTENSION),
-    NULL, FILE_DEVICE_BUS_EXTENDER, FILE_DEVICE_SECURE_OPEN, TRUE, &Fdo);
-  if (!NT_SUCCESS(Status)) {
-    DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
-    return Status;
+  Status = IoCreateDevice(DriverObject,
+                          sizeof(*FdoExt),
+                          NULL,
+                          FILE_DEVICE_BUS_EXTENDER,
+                          FILE_DEVICE_SECURE_OPEN,
+                          TRUE,
+                          &Fdo);
+  if (!NT_SUCCESS(Status))
+  {
+      DPRINT1("Failed to create FDO (0x%x)\n", Status);
+      return Status;
   }
 
-  DeviceExtension = (PISAPNP_DEVICE_EXTENSION)Fdo->DeviceExtension;
-
-  DeviceExtension->Pdo = PhysicalDeviceObject;
+  FdoExt = Fdo->DeviceExtension;
+  RtlZeroMemory(FdoExt, sizeof(*FdoExt));
 
-  DeviceExtension->Ldo =
-    IoAttachDeviceToDeviceStack(Fdo, PhysicalDeviceObject);
+  FdoExt->Common.Self = Fdo;
+  FdoExt->Common.IsFdo = TRUE;
+  FdoExt->Common.State = dsStopped;
+  FdoExt->Pdo = PhysicalDeviceObject;
+  FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo,
+                                            PhysicalDeviceObject);
 
-  InitializeListHead(&DeviceExtension->CardListHead);
-  InitializeListHead(&DeviceExtension->DeviceListHead);
-  DeviceExtension->DeviceListCount = 0;
-  KeInitializeSpinLock(&DeviceExtension->GlobalListLock);
-
-  DeviceExtension->State = dsStopped;
+  InitializeListHead(&FdoExt->DeviceListHead);
+  KeInitializeSpinLock(&FdoExt->Lock);
 
   Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
-  DPRINT("Done AddDevice\n");
-
   return STATUS_SUCCESS;
 }
 
+static
+NTSTATUS
+NTAPI
+IsaPnp(
+  IN PDEVICE_OBJECT DeviceObject,
+  IN PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  PISAPNP_COMMON_EXTENSION DevExt = DeviceObject->DeviceExtension;
+
+  DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp);
+
+  if (DevExt->IsFdo)
+  {
+     return IsaFdoPnp((PISAPNP_FDO_EXTENSION)DevExt,
+                      Irp,
+                      IrpSp);
+  }
+  else
+  {
+     return IsaPdoPnp((PISAPNP_LOGICAL_DEVICE)DevExt,
+                      Irp,
+                      IrpSp);
+  }
+}
 
 NTSTATUS
 NTAPI
@@ -1731,15 +185,15 @@ DriverEntry(
   IN PDRIVER_OBJECT DriverObject,
   IN PUNICODE_STRING RegistryPath)
 {
-  DbgPrint("ISA Plug and Play Bus Driver\n");
+  DPRINT("%s(%p, %wZ)\n", __FUNCTION__, DriverObject, RegistryPath);
 
-  DriverObject->MajorFunction[IRP_MJ_CREATE] = ISAPNPDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_CLOSE] = ISAPNPDispatchOpenClose;
-  DriverObject->MajorFunction[IRP_MJ_READ] = ISAPNPDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_WRITE] = ISAPNPDispatchReadWrite;
-  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ISAPNPDispatchDeviceControl;
-  DriverObject->MajorFunction[IRP_MJ_PNP] = ISAPNPControl;
-  DriverObject->DriverExtension->AddDevice = ISAPNPAddDevice;
+  DriverObject->MajorFunction[IRP_MJ_CREATE] = IsaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_CLOSE] = IsaCreateClose;
+  DriverObject->MajorFunction[IRP_MJ_READ] = IsaReadWrite;
+  DriverObject->MajorFunction[IRP_MJ_WRITE] = IsaReadWrite;
+  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IsaIoctl;
+  DriverObject->MajorFunction[IRP_MJ_PNP] = IsaPnp;
+  DriverObject->DriverExtension->AddDevice = IsaAddDevice;
 
   return STATUS_SUCCESS;
 }
index 59697b9..85fcb78 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <ntddk.h>
+#include <wdm.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -8,330 +8,87 @@ extern "C" {
 
 #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 enum {
+  dsStopped,
+  dsStarted
+} ISAPNP_DEVICE_STATE;
 
-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_COMMON_EXTENSION {
+  PDEVICE_OBJECT Self;
+  BOOLEAN IsFdo;
+  ISAPNP_DEVICE_STATE State;
+} ISAPNP_COMMON_EXTENSION, *PISAPNP_COMMON_EXTENSION;
 
-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_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_CARD
-{
-  LIST_ENTRY ListEntry;
-  USHORT CardId;
+typedef struct _ISAPNP_LOGICAL_DEVICE {
+  ISAPNP_COMMON_EXTENSION Common;
   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
-{
+  USHORT ProdId;
+  USHORT IoAddr;
+  UCHAR IrqNo;
+  UCHAR CSN;
+  UCHAR LDN;
   LIST_ENTRY ListEntry;
-  IO_RESOURCE_DESCRIPTOR Descriptor;
-} ISAPNP_DESCRIPTOR, *PISAPNP_DESCRIPTOR;
+} ISAPNP_LOGICAL_DEVICE, *PISAPNP_LOGICAL_DEVICE;
 
-typedef struct _ISAPNP_CONFIGURATION_LIST
-{
-  LIST_ENTRY ListEntry;
-  ULONG Priority;
-  LIST_ENTRY ListHead;
-} ISAPNP_CONFIGURATION_LIST, *PISAPNP_CONFIGURATION_LIST;
+/* isapnp.c */
+NTSTATUS
+NTAPI
+DriverEntry(
+  IN PDRIVER_OBJECT DriverObject,
+  IN PUNICODE_STRING RegistryPath);
 
+NTSTATUS
+NTAPI
+IsaForwardIrpSynchronous(
+       IN PISAPNP_FDO_EXTENSION FdoExt,
+       IN PIRP Irp);
 
-#define MAX_COMPATIBLE_ID   32
+/* fdo.c */
+NTSTATUS
+NTAPI
+IsaFdoPnp(
+  IN PISAPNP_FDO_EXTENSION FdoExt,
+  IN PIRP Irp,
+  IN PIO_STACK_LOCATION IrpSp);
 
-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;
+/* 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);
 
-typedef enum {
-  dsStopped,
-  dsStarted
-} ISAPNP_DEVICE_STATE;
+NTSTATUS
+NTAPI
+IsaHwFillDeviceList(
+  IN PISAPNP_FDO_EXTENSION FdoExt);
 
-typedef struct _ISAPNP_DEVICE_EXTENSION
-{
-  // Physical Device Object
-  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_EXTENSION, *PISAPNP_DEVICE_EXTENSION;
+NTSTATUS
+NTAPI
+IsaHwDeactivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
 
 NTSTATUS
 NTAPI
-DriverEntry(
-  IN PDRIVER_OBJECT DriverObject,
-  IN PUNICODE_STRING RegistryPath);
+IsaHwActivateDevice(
+  IN PISAPNP_LOGICAL_DEVICE LogicalDevice);
 
 #ifdef __cplusplus
 }
index b0b7919..bc8a96a 100644 (file)
@@ -1,9 +1,13 @@
 <?xml version="1.0"?>
 <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
 <module name="isapnp" type="kernelmodedriver" installbase="system32/drivers" installname="isapnp.sys">
+       <bootstrap installbase="$(CDOUTPUT)"/>
        <include base="isapnp">.</include>
        <library>ntoskrnl</library>
        <library>hal</library>
        <file>isapnp.c</file>
+       <file>pdo.c</file>
+       <file>fdo.c</file>
+       <file>hardware.c</file>
        <file>isapnp.rc</file>
 </module>
diff --git a/reactos/drivers/bus/isapnp/isapnphw.h b/reactos/drivers/bus/isapnp/isapnphw.h
new file mode 100644 (file)
index 0000000..aec8719
--- /dev/null
@@ -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
diff --git a/reactos/drivers/bus/isapnp/pdo.c b/reactos/drivers/bus/isapnp/pdo.c
new file mode 100644 (file)
index 0000000..0292f20
--- /dev/null
@@ -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;
+}