/* GLOBALS ********************************************************************/
+LONG PciPdoSequenceNumber;
+
+C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, DeviceState) == FIELD_OFFSET(PCI_PDO_EXTENSION, DeviceState));
+C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, TentativeNextState) == FIELD_OFFSET(PCI_PDO_EXTENSION, TentativeNextState));
+C_ASSERT(FIELD_OFFSET(PCI_FDO_EXTENSION, List) == FIELD_OFFSET(PCI_PDO_EXTENSION, Next));
+
+PCI_MN_DISPATCH_TABLE PciPdoDispatchPowerTable[] =
+{
+ {IRP_DISPATCH, (PCI_DISPATCH_FUNCTION)PciPdoWaitWake},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoSetPowerState},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryPower},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
+};
+
+PCI_MN_DISPATCH_TABLE PciPdoDispatchPnpTable[] =
+{
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStartDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryRemoveDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpRemoveDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelRemoveDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpStopDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryStopDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpCancelStopDevice},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceRelations},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryInterface},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryCapabilities},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResources},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryResourceRequirements},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceText},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpReadConfig},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpWriteConfig},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryId},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryDeviceState},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryBusInformation},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpDeviceUsageNotification},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpSurpriseRemoval},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciPdoIrpQueryLegacyBusInformation},
+ {IRP_COMPLETE, (PCI_DISPATCH_FUNCTION)PciIrpNotSupported}
+};
+
+PCI_MJ_DISPATCH_TABLE PciPdoDispatchTable =
+{
+ IRP_MN_QUERY_LEGACY_BUS_INFORMATION,
+ PciPdoDispatchPnpTable,
+ IRP_MN_QUERY_POWER,
+ PciPdoDispatchPowerTable,
+ IRP_COMPLETE,
+ (PCI_DISPATCH_FUNCTION)PciIrpNotSupported,
+ IRP_COMPLETE,
+ (PCI_DISPATCH_FUNCTION)PciIrpInvalidDeviceRequest
+};
+
/* FUNCTIONS ******************************************************************/
+NTSTATUS
+NTAPI
+PciPdoWaitWake(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoSetPowerState(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryPower(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpStartDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryRemoveDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpRemoveDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpCancelRemoveDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpStopDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryStopDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpCancelStopDevice(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryInterface(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryDeviceRelations(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryCapabilities(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryResources(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryResourceRequirements(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryDeviceText(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryId(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryBusInformation(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpReadConfig(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpWriteConfig(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryDeviceState(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpDeviceUsageNotification(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpSurpriseRemoval(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoIrpQueryLegacyBusInformation(IN PIRP Irp,
+ IN PIO_STACK_LOCATION IoStackLocation,
+ IN PPCI_PDO_EXTENSION DeviceExtension)
+{
+ UNIMPLEMENTED;
+ while (TRUE);
+ return STATUS_NOT_SUPPORTED;
+}
+
+NTSTATUS
+NTAPI
+PciPdoCreate(IN PPCI_FDO_EXTENSION DeviceExtension,
+ IN PCI_SLOT_NUMBER Slot,
+ OUT PDEVICE_OBJECT *PdoDeviceObject)
+{
+ WCHAR DeviceName[32];
+ UNICODE_STRING DeviceString;
+ NTSTATUS Status;
+ PDEVICE_OBJECT DeviceObject;
+ PPCI_PDO_EXTENSION PdoExtension;
+ ULONG SequenceNumber;
+ PAGED_CODE();
+
+ /* Pick an atomically unique sequence number for this device */
+ SequenceNumber = InterlockedIncrement(&PciPdoSequenceNumber);
+
+ /* Create the standard PCI device name for a PDO */
+ swprintf(DeviceName, L"\\Device\\NTPNP_PCI%04d", SequenceNumber);
+ RtlInitUnicodeString(&DeviceString, DeviceName);
+
+ /* Create the actual device now */
+ Status = IoCreateDevice(DeviceExtension->FunctionalDeviceObject->DriverObject,
+ sizeof(PCI_PDO_EXTENSION),
+ &DeviceString,
+ FILE_DEVICE_BUS_EXTENDER,
+ 0,
+ 0,
+ &DeviceObject);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Get the extension for it */
+ PdoExtension = (PPCI_PDO_EXTENSION)DeviceObject->DeviceExtension;
+ DPRINT1("PCI: New PDO (b=0x%x, d=0x%x, f=0x%x) @ %p, ext @ %p\n",
+ DeviceExtension->BaseBus,
+ Slot.u.bits.DeviceNumber,
+ Slot.u.bits.FunctionNumber,
+ DeviceObject,
+ DeviceObject->DeviceExtension);
+
+ /* Configure the extension */
+ PdoExtension->ExtensionType = PciPdoExtensionType;
+ PdoExtension->IrpDispatchTable = &PciPdoDispatchTable;
+ PdoExtension->PhysicalDeviceObject = DeviceObject;
+ PdoExtension->Slot = Slot;
+ PdoExtension->PowerState.CurrentSystemState = PowerDeviceD0;
+ PdoExtension->PowerState.CurrentDeviceState = PowerDeviceD0;
+ PdoExtension->ParentFdoExtension = DeviceExtension;
+
+ /* Initialize the lock for arbiters and other interfaces */
+ KeInitializeEvent(&PdoExtension->SecondaryExtLock, SynchronizationEvent, TRUE);
+
+ /* Initialize the state machine */
+ PciInitializeState((PPCI_FDO_EXTENSION)PdoExtension);
+
+ /* Add the PDO to the parent's list */
+ PdoExtension->Next = NULL;
+ PciInsertEntryAtTail((PSINGLE_LIST_ENTRY)&DeviceExtension->ChildPdoList,
+ (PPCI_FDO_EXTENSION)PdoExtension,
+ &DeviceExtension->ChildListLock);
+
+ /* And finally return it to the caller */
+ *PdoDeviceObject = DeviceObject;
+ return STATUS_SUCCESS;
+}
+
/* EOF */