-/* $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
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;
}
#pragma once
-#include <ntddk.h>
+#include <wdm.h>
#ifdef __cplusplus
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
}