📄 pdo.c
字号:
Descriptor->u.Port.Length = Length;
Descriptor->u.Port.Alignment = Length;
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
}
else
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
Descriptor->u.Memory.Length = Length;
Descriptor->u.Memory.Alignment = Length;
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
}
Descriptor++;
}
/* FIXME: Check ROM address */
if (PciConfig.u.type0.InterruptPin != 0)
{
Descriptor->Option = 0; /* Required */
Descriptor->Type = CmResourceTypeInterrupt;
Descriptor->ShareDisposition = CmResourceShareShared;
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
Descriptor->u.Interrupt.MinimumVector = 0;
Descriptor->u.Interrupt.MaximumVector = 0xFF;
}
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
if (!PdoGetRangeLength(DeviceExtension,
0x10 + i * 4,
&Base,
&Length,
&Flags))
{
DPRINT1("PdoGetRangeLength() failed\n");
break;
}
if (Length == 0)
{
DPRINT("Unused address register\n");
continue;
}
/* Set preferred descriptor */
Descriptor->Option = IO_RESOURCE_PREFERRED;
if (Flags & PCI_ADDRESS_IO_SPACE)
{
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_PORT_IO |
CM_RESOURCE_PORT_16_BIT_DECODE |
CM_RESOURCE_PORT_POSITIVE_DECODE;
Descriptor->u.Port.Length = Length;
Descriptor->u.Port.Alignment = 1;
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)Base;
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
}
else
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
Descriptor->u.Memory.Length = Length;
Descriptor->u.Memory.Alignment = 1;
Descriptor->u.Memory.MinimumAddress.QuadPart = (ULONGLONG)Base;
Descriptor->u.Memory.MaximumAddress.QuadPart = (ULONGLONG)(Base + Length - 1);
}
Descriptor++;
/* Set alternative descriptor */
Descriptor->Option = IO_RESOURCE_ALTERNATIVE;
if (Flags & PCI_ADDRESS_IO_SPACE)
{
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_PORT_IO |
CM_RESOURCE_PORT_16_BIT_DECODE |
CM_RESOURCE_PORT_POSITIVE_DECODE;
Descriptor->u.Port.Length = Length;
Descriptor->u.Port.Alignment = Length;
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
}
else
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
Descriptor->u.Memory.Length = Length;
Descriptor->u.Memory.Alignment = Length;
Descriptor->u.Port.MinimumAddress.QuadPart = (ULONGLONG)0;
Descriptor->u.Port.MaximumAddress.QuadPart = (ULONGLONG)0x00000000FFFFFFFF;
}
Descriptor++;
}
if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
{
Descriptor->Option = 0; /* Required */
Descriptor->Type = CmResourceTypeBusNumber;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->u.BusNumber.MinBusNumber =
Descriptor->u.BusNumber.MaxBusNumber = DeviceExtension->PciDevice->PciConfig.u.type1.SecondaryBus;
Descriptor->u.BusNumber.Length = 1;
Descriptor->u.BusNumber.Reserved = 0;
}
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
/* FIXME: Add Cardbus bridge resources */
}
Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
return STATUS_SUCCESS;
}
static NTSTATUS
PdoQueryResources(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
PCI_COMMON_CONFIG PciConfig;
PCM_RESOURCE_LIST ResourceList;
PCM_PARTIAL_RESOURCE_LIST PartialList;
PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
ULONG Size;
ULONG ResCount = 0;
ULONG ListSize;
ULONG i;
ULONG Base;
ULONG Length;
ULONG Flags;
DPRINT("PdoQueryResources() called\n");
DeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* Get PCI configuration space */
Size= HalGetBusData(PCIConfiguration,
DeviceExtension->PciDevice->BusNumber,
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
&PciConfig,
PCI_COMMON_HDR_LENGTH);
DPRINT("Size %lu\n", Size);
if (Size < PCI_COMMON_HDR_LENGTH)
{
Irp->IoStatus.Information = 0;
return STATUS_UNSUCCESSFUL;
}
DPRINT("Command register: 0x%04hx\n", PciConfig.Command);
/* Count required resource descriptors */
ResCount = 0;
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
{
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
{
if (!PdoGetRangeLength(DeviceExtension,
0x10 + i * 4,
&Base,
&Length,
&Flags))
break;
if (Length)
ResCount++;
}
if ((PciConfig.u.type0.InterruptPin != 0) &&
(PciConfig.u.type0.InterruptLine != 0xFF))
ResCount++;
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
if (!PdoGetRangeLength(DeviceExtension,
0x10 + i * 4,
&Base,
&Length,
&Flags))
break;
if (Length != 0)
ResCount++;
}
if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
ResCount++;
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
/* FIXME: Count Cardbus bridge resources */
}
else
{
DPRINT1("Unsupported header type %u\n", PCI_CONFIGURATION_TYPE(&PciConfig));
}
if (ResCount == 0)
{
Irp->IoStatus.Information = 0;
return STATUS_SUCCESS;
}
/* Calculate the resource list size */
ListSize = FIELD_OFFSET(CM_RESOURCE_LIST, List->PartialResourceList.PartialDescriptors)
+ ResCount * sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR);
/* Allocate the resource list */
ResourceList = ExAllocatePoolWithTag(PagedPool,
ListSize, TAG_PCI);
if (ResourceList == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
RtlZeroMemory(ResourceList, ListSize);
ResourceList->Count = 1;
ResourceList->List[0].InterfaceType = PCIBus;
ResourceList->List[0].BusNumber = DeviceExtension->PciDevice->BusNumber;
PartialList = &ResourceList->List[0].PartialResourceList;
PartialList->Version = 1;
PartialList->Revision = 1;
PartialList->Count = ResCount;
Descriptor = &PartialList->PartialDescriptors[0];
if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_DEVICE_TYPE)
{
for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
{
if (!PdoGetRangeLength(DeviceExtension,
0x10 + i * 4,
&Base,
&Length,
&Flags))
{
DPRINT1("PdoGetRangeLength() failed\n");
break;
}
if (Length == 0)
{
DPRINT("Unused address register\n");
continue;
}
if (Flags & PCI_ADDRESS_IO_SPACE)
{
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_PORT_IO;
Descriptor->u.Port.Start.QuadPart =
(ULONGLONG)Base;
Descriptor->u.Port.Length = Length;
}
else
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
Descriptor->u.Memory.Start.QuadPart =
(ULONGLONG)Base;
Descriptor->u.Memory.Length = Length;
}
Descriptor++;
}
/* Add interrupt resource */
if ((PciConfig.u.type0.InterruptPin != 0) &&
(PciConfig.u.type0.InterruptLine != 0xFF))
{
Descriptor->Type = CmResourceTypeInterrupt;
Descriptor->ShareDisposition = CmResourceShareShared;
Descriptor->Flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE;
Descriptor->u.Interrupt.Level = PciConfig.u.type0.InterruptLine;
Descriptor->u.Interrupt.Vector = 0;
Descriptor->u.Interrupt.Affinity = 0xFFFFFFFF;
}
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_BRIDGE_TYPE)
{
for (i = 0; i < PCI_TYPE1_ADDRESSES; i++)
{
if (!PdoGetRangeLength(DeviceExtension,
0x10 + i * 4,
&Base,
&Length,
&Flags))
{
DPRINT1("PdoGetRangeLength() failed\n");
break;
}
if (Length == 0)
{
DPRINT("Unused address register\n");
continue;
}
if (Flags & PCI_ADDRESS_IO_SPACE)
{
Descriptor->Type = CmResourceTypePort;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_PORT_IO;
Descriptor->u.Port.Start.QuadPart =
(ULONGLONG)Base;
Descriptor->u.Port.Length = Length;
}
else
{
Descriptor->Type = CmResourceTypeMemory;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->Flags = CM_RESOURCE_MEMORY_READ_WRITE;
Descriptor->u.Memory.Start.QuadPart =
(ULONGLONG)Base;
Descriptor->u.Memory.Length = Length;
}
Descriptor++;
}
if (DeviceExtension->PciDevice->PciConfig.BaseClass == PCI_CLASS_BRIDGE_DEV)
{
Descriptor->Type = CmResourceTypeBusNumber;
Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
Descriptor->u.BusNumber.Start = DeviceExtension->PciDevice->PciConfig.u.type1.SecondaryBus;
Descriptor->u.BusNumber.Length = 1;
Descriptor->u.BusNumber.Reserved = 0;
}
}
else if (PCI_CONFIGURATION_TYPE(&PciConfig) == PCI_CARDBUS_BRIDGE_TYPE)
{
/* FIXME: Add Cardbus bridge resources */
}
Irp->IoStatus.Information = (ULONG_PTR)ResourceList;
return STATUS_SUCCESS;
}
static VOID NTAPI
InterfaceReference(
IN PVOID Context)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
DPRINT("InterfaceReference(%p)\n", Context);
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
InterlockedIncrement(&DeviceExtension->References);
}
static VOID NTAPI
InterfaceDereference(
IN PVOID Context)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
DPRINT("InterfaceDereference(%p)\n", Context);
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
InterlockedDecrement(&DeviceExtension->References);
}
static BOOLEAN NTAPI
InterfaceBusTranslateBusAddress(
IN PVOID Context,
IN PHYSICAL_ADDRESS BusAddress,
IN ULONG Length,
IN OUT PULONG AddressSpace,
OUT PPHYSICAL_ADDRESS TranslatedAddress)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
DPRINT("InterfaceBusTranslateBusAddress(%p %p 0x%lx %p %p)\n",
Context, BusAddress, Length, AddressSpace, TranslatedAddress);
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
return HalTranslateBusAddress(
PCIBus, DeviceExtension->PciDevice->BusNumber,
BusAddress, AddressSpace, TranslatedAddress);
}
static PDMA_ADAPTER NTAPI
InterfaceBusGetDmaAdapter(
IN PVOID Context,
IN PDEVICE_DESCRIPTION DeviceDescription,
OUT PULONG NumberOfMapRegisters)
{
DPRINT("InterfaceBusGetDmaAdapter(%p %p %p)\n",
Context, DeviceDescription, NumberOfMapRegisters);
return (PDMA_ADAPTER)HalGetAdapter(DeviceDescription, NumberOfMapRegisters);
}
static ULONG NTAPI
InterfaceBusSetBusData(
IN PVOID Context,
IN ULONG DataType,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
ULONG Size;
DPRINT("InterfaceBusSetBusData(%p 0x%lx %p 0x%lx 0x%lx)\n",
Context, DataType, Buffer, Offset, Length);
if (DataType != PCI_WHICHSPACE_CONFIG)
{
DPRINT("Unknown DataType %lu\n", DataType);
return 0;
}
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
/* Get PCI configuration space */
Size = HalSetBusDataByOffset(PCIConfiguration,
DeviceExtension->PciDevice->BusNumber,
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
Buffer,
Offset,
Length);
return Size;
}
static ULONG NTAPI
InterfaceBusGetBusData(
IN PVOID Context,
IN ULONG DataType,
IN PVOID Buffer,
IN ULONG Offset,
IN ULONG Length)
{
PPDO_DEVICE_EXTENSION DeviceExtension;
ULONG Size;
DPRINT("InterfaceBusGetBusData(%p 0x%lx %p 0x%lx 0x%lx) called\n",
Context, DataType, Buffer, Offset, Length);
if (DataType != PCI_WHICHSPACE_CONFIG)
{
DPRINT("Unknown DataType %lu\n", DataType);
return 0;
}
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
/* Get PCI configuration space */
Size = HalGetBusDataByOffset(PCIConfiguration,
DeviceExtension->PciDevice->BusNumber,
DeviceExtension->PciDevice->SlotNumber.u.AsULONG,
Buffer,
Offset,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -