⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdo.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -