📄 isapnp.c
字号:
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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -