/* * PROJECT: ReactOS PCI Bus Driver * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/bus/pci/pdo.c * PURPOSE: PDO Device Management * PROGRAMMERS: ReactOS Portable Systems Group */ /* INCLUDES *******************************************************************/ #include #define NDEBUG #include /* 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 */