2010-04-01 19:07:40 +00:00
|
|
|
/*
|
|
|
|
* 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 <pci.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* GLOBALS ********************************************************************/
|
|
|
|
|
2010-07-17 15:59:09 +00:00
|
|
|
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
|
|
|
|
};
|
|
|
|
|
2010-04-01 19:07:40 +00:00
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
2010-07-17 15:59:09 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-04-01 19:07:40 +00:00
|
|
|
/* EOF */
|