X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=drivers%2Fbus%2Fisapnp%2Fisapnp.c;h=594b5a9054106ea0f455df1d511394193888455f;hp=656e28d9335748a29f884cc8d89ba9b0ea839cf3;hb=62ff6c86b704e3c3018a2bdaaef13c3391f79a50;hpb=79e9ba171b07100f209c1abca802d015cef7b522 diff --git a/drivers/bus/isapnp/isapnp.c b/drivers/bus/isapnp/isapnp.c index 656e28d9335..594b5a90541 100644 --- a/drivers/bus/isapnp/isapnp.c +++ b/drivers/bus/isapnp/isapnp.c @@ -1,1740 +1,199 @@ -/* $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 - -#ifndef NDEBUG -#define NDEBUG -#endif -#include - - -#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 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 FindNextReadPort(VOID) -{ - ULONG Port; - - - - Port = (ULONG)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 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; - 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)IsaPnPReadPort); - KeStallExecutionProcessor(1000); - WriteAddress(0x01); - KeStallExecutionProcessor(1000); - goto next; - } - if (iteration == 1) { - IsaPnPReadPort += READ_DATA_PORT_STEP; - 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)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 +#define NDEBUG +#include -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; - - i++; - - CurrentEntry = CurrentEntry->Flink; - } - - Irp->IoStatus.Information = (ULONG)Relations; + if (Irp->PendingReturned) + KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); - 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"); + KeInitializeEvent(&Event, NotificationEvent, FALSE); + IoCopyCurrentIrpStackLocationToNext(Irp); - DeviceExtension = (PISAPNP_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + IoSetCompletionRoutine(Irp, ForwardIrpCompletion, &Event, TRUE, TRUE, TRUE); - if (DeviceExtension->State == dsStopped) - return STATUS_UNSUCCESSFUL; - - 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 -STDCALL -ISAPNPDispatchOpenClose( +static +NTSTATUS +NTAPI +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 -STDCALL -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 -STDCALL -ISAPNPDispatchDeviceControl( +static +NTSTATUS +NTAPI +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 -STDCALL -ISAPNPControl( +static +NTSTATUS +NTAPI +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; + DPRINT("%s(%p, %p)\n", __FUNCTION__, DeviceObject, Irp); - case IRP_MN_START_DEVICE: - Status = ISAPNPStartDevice(DeviceObject, Irp, IrpSp); - break; - - case IRP_MN_STOP_DEVICE: - Status = ISAPNPStopDevice(DeviceObject, Irp, IrpSp); - 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 -STDCALL -ISAPNPAddDevice( +static +NTSTATUS +NTAPI +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; + FdoExt = Fdo->DeviceExtension; + RtlZeroMemory(FdoExt, sizeof(*FdoExt)); - DeviceExtension->Pdo = PhysicalDeviceObject; + FdoExt->Common.Self = Fdo; + FdoExt->Common.IsFdo = TRUE; + FdoExt->Common.State = dsStopped; + FdoExt->Pdo = PhysicalDeviceObject; + FdoExt->Ldo = IoAttachDeviceToDeviceStack(Fdo, + PhysicalDeviceObject); - DeviceExtension->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 -STDCALL +NTAPI 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; }