Implement InterfacePciDevicePresent(Ex) of PCI_DEVICE_PRESENT_INTERFACE

svn path=/trunk/; revision=19340
This commit is contained in:
Hervé Poussineau 2005-11-19 09:08:08 +00:00
parent e6bbd8f247
commit b4c206def5
4 changed files with 174 additions and 31 deletions

View file

@ -125,7 +125,7 @@ FdoEnumerateDevices(
Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig); Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
Device = (PPCI_DEVICE)ExAllocatePool(PagedPool, sizeof(PCI_DEVICE)); Device = (PPCI_DEVICE)ExAllocatePool(NonPagedPool, sizeof(PCI_DEVICE));
if (!Device) if (!Device)
{ {
/* FIXME: Cleanup resources for already discovered devices */ /* FIXME: Cleanup resources for already discovered devices */
@ -413,6 +413,11 @@ FdoStartDevice(
DeviceExtension->DeviceListCount = 0; DeviceExtension->DeviceListCount = 0;
DeviceExtension->State = dsStarted; DeviceExtension->State = dsStarted;
ExInterlockedInsertTailList(
&DriverExtension->BusListHead,
&DeviceExtension->ListEntry,
&DriverExtension->BusListLock);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;

View file

@ -29,6 +29,7 @@
/*** PUBLIC ******************************************************************/ /*** PUBLIC ******************************************************************/
PPCI_DRIVER_EXTENSION DriverExtension = NULL;
/*** PRIVATE *****************************************************************/ /*** PRIVATE *****************************************************************/
@ -173,6 +174,8 @@ DriverEntry(
IN PDRIVER_OBJECT DriverObject, IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath) IN PUNICODE_STRING RegistryPath)
{ {
NTSTATUS Status;
DPRINT("Peripheral Component Interconnect Bus Driver\n"); DPRINT("Peripheral Component Interconnect Bus Driver\n");
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PciDispatchDeviceControl;
@ -180,6 +183,18 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl; DriverObject->MajorFunction[IRP_MJ_POWER] = PciPowerControl;
DriverObject->DriverExtension->AddDevice = PciAddDevice; DriverObject->DriverExtension->AddDevice = PciAddDevice;
Status = IoAllocateDriverObjectExtension(
DriverObject,
DriverObject,
sizeof(PCI_DRIVER_EXTENSION),
(PVOID*)&DriverExtension);
if (!NT_SUCCESS(Status))
return Status;
RtlZeroMemory(DriverExtension, sizeof(PCI_DRIVER_EXTENSION));
InitializeListHead(&DriverExtension->BusListHead);
KeInitializeSpinLock(&DriverExtension->BusListLock);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -2,13 +2,6 @@
#define __PCI_H #define __PCI_H
typedef enum {
pbtUnknown = 0,
pbtType1,
pbtType2,
} PCI_BUS_TYPE;
typedef struct _PCI_DEVICE typedef struct _PCI_DEVICE
{ {
// Entry on device list // Entry on device list
@ -77,6 +70,8 @@ typedef struct _FDO_DEVICE_EXTENSION
{ {
// Common device data // Common device data
COMMON_DEVICE_EXTENSION Common; COMMON_DEVICE_EXTENSION Common;
// Entry on device list
LIST_ENTRY ListEntry;
// PCI bus number serviced by this FDO // PCI bus number serviced by this FDO
ULONG BusNumber; ULONG BusNumber;
// Current state of the driver // Current state of the driver
@ -92,6 +87,21 @@ typedef struct _FDO_DEVICE_EXTENSION
} FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION; } FDO_DEVICE_EXTENSION, *PFDO_DEVICE_EXTENSION;
/* Driver extension associated with PCI driver */
typedef struct _PCI_DRIVER_EXTENSION
{
//
LIST_ENTRY BusListHead;
// Lock for namespace bus list
KSPIN_LOCK BusListLock;
} PCI_DRIVER_EXTENSION, *PPCI_DRIVER_EXTENSION;
/* We need a global variable to get the driver extension,
* because at least InterfacePciDevicePresent has no
* other way to get it... */
extern PPCI_DRIVER_EXTENSION DriverExtension;
/* fdo.c */ /* fdo.c */
NTSTATUS NTSTATUS

View file

@ -954,6 +954,7 @@ InterfaceBusGetBusData(
return Size; return Size;
} }
static BOOLEAN NTAPI static BOOLEAN NTAPI
InterfacePciDevicePresent( InterfacePciDevicePresent(
IN USHORT VendorID, IN USHORT VendorID,
@ -961,14 +962,89 @@ InterfacePciDevicePresent(
IN UCHAR RevisionID, IN UCHAR RevisionID,
IN USHORT SubVendorID, IN USHORT SubVendorID,
IN USHORT SubSystemID, IN USHORT SubSystemID,
IN ULONG Flags IN ULONG Flags)
)
{ {
DPRINT1("Checking for PCI %04X:%04X not implemented\n", PFDO_DEVICE_EXTENSION FdoDeviceExtension;
VendorID, DeviceID); PPCI_DEVICE PciDevice;
PLIST_ENTRY CurrentBus, CurrentEntry;
KIRQL OldIrql;
BOOLEAN Found = FALSE;
KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
CurrentBus = DriverExtension->BusListHead.Flink;
while (!Found && CurrentBus != &DriverExtension->BusListHead)
{
FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
{
PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
if (PciDevice->PciConfig.VendorID == VendorID &&
PciDevice->PciConfig.DeviceID == DeviceID)
{
if (!(Flags & PCI_USE_SUBSYSTEM_IDS) || (
PciDevice->PciConfig.u.type0.SubVendorID == SubVendorID &&
PciDevice->PciConfig.u.type0.SubSystemID == SubSystemID))
{
if (!(Flags & PCI_USE_REVISION) ||
PciDevice->PciConfig.RevisionID == RevisionID)
{
DPRINT("Found the PCI device\n");
Found = TRUE;
}
}
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentBus = CurrentBus->Flink;
}
KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
return Found;
}
static BOOLEAN
CheckPciDevice(
IN PPCI_COMMON_CONFIG PciConfig,
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
{
if ((Parameters->Flags & PCI_USE_VENDEV_IDS) && (
PciConfig->VendorID != Parameters->VendorID ||
PciConfig->DeviceID != Parameters->DeviceID))
{
return FALSE; return FALSE;
} }
if ((Parameters->Flags && PCI_USE_CLASS_SUBCLASS) && (
PciConfig->u.type0.SubVendorID != Parameters->SubVendorID ||
PciConfig->u.type0.SubSystemID != Parameters->SubSystemID))
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_PROGIF) &&
PciConfig->ProgIf != Parameters->ProgIf)
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_SUBSYSTEM_IDS) && (
PciConfig->Command != Parameters->SubVendorID ||
PciConfig->Status != Parameters->SubSystemID))
{
return FALSE;
}
if ((Parameters->Flags & PCI_USE_REVISION) &&
PciConfig->RevisionID != Parameters->RevisionID)
{
return FALSE;
}
return TRUE;
}
static BOOLEAN NTAPI static BOOLEAN NTAPI
InterfacePciDevicePresentEx( InterfacePciDevicePresentEx(
@ -976,19 +1052,56 @@ InterfacePciDevicePresentEx(
IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters) IN PPCI_DEVICE_PRESENCE_PARAMETERS Parameters)
{ {
PPDO_DEVICE_EXTENSION DeviceExtension; PPDO_DEVICE_EXTENSION DeviceExtension;
PFDO_DEVICE_EXTENSION MyFdoDeviceExtension;
PFDO_DEVICE_EXTENSION FdoDeviceExtension;
PPCI_DEVICE PciDevice;
PLIST_ENTRY CurrentBus, CurrentEntry;
KIRQL OldIrql;
BOOLEAN Found = FALSE;
DPRINT1("InterfacePciDevicePresentEx(%p %p) called\n", DPRINT("InterfacePciDevicePresentEx(%p %p) called\n",
Context, Parameters); Context, Parameters);
if (!Parameters || Parameters->Size != sizeof(PCI_DEVICE_PRESENCE_PARAMETERS)) if (!Parameters || Parameters->Size != sizeof(PCI_DEVICE_PRESENCE_PARAMETERS))
return FALSE; return FALSE;
DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension; DeviceExtension = (PPDO_DEVICE_EXTENSION)((PDEVICE_OBJECT)Context)->DeviceExtension;
MyFdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceExtension->Fdo->DeviceExtension;
DPRINT1("Checking for PCI %04X:%04X not implemented\n", if (Parameters->Flags & PCI_USE_LOCAL_DEVICE)
Parameters->VendorID, Parameters->DeviceID); {
return CheckPciDevice(&DeviceExtension->PciDevice->PciConfig, Parameters);
}
return FALSE; KeAcquireSpinLock(&DriverExtension->BusListLock, &OldIrql);
CurrentBus = DriverExtension->BusListHead.Flink;
while (!Found && CurrentBus != &DriverExtension->BusListHead)
{
FdoDeviceExtension = CONTAINING_RECORD(CurrentBus, FDO_DEVICE_EXTENSION, ListEntry);
if (!(Parameters->Flags & PCI_USE_LOCAL_BUS) || FdoDeviceExtension == MyFdoDeviceExtension)
{
KeAcquireSpinLockAtDpcLevel(&FdoDeviceExtension->DeviceListLock);
CurrentEntry = FdoDeviceExtension->DeviceListHead.Flink;
while (!Found && CurrentEntry != &FdoDeviceExtension->DeviceListHead)
{
PciDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
if (CheckPciDevice(&PciDevice->PciConfig, Parameters))
{
DPRINT("Found the PCI device\n");
Found = TRUE;
}
CurrentEntry = CurrentEntry->Flink;
}
KeReleaseSpinLockFromDpcLevel(&FdoDeviceExtension->DeviceListLock);
}
CurrentBus = CurrentBus->Flink;
}
KeReleaseSpinLock(&DriverExtension->BusListLock, OldIrql);
return Found;
} }
@ -1034,15 +1147,15 @@ PdoQueryInterface(
Status = STATUS_BUFFER_TOO_SMALL; Status = STATUS_BUFFER_TOO_SMALL;
else else
{ {
PPCI_DEVICE_PRESENT_INTERFACE BusInterface; PPCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface;
BusInterface = (PPCI_DEVICE_PRESENT_INTERFACE)IrpSp->Parameters.QueryInterface.Interface; PciDevicePresentInterface = (PPCI_DEVICE_PRESENT_INTERFACE)IrpSp->Parameters.QueryInterface.Interface;
BusInterface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE); PciDevicePresentInterface->Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
BusInterface->Version = 1; PciDevicePresentInterface->Version = 1;
BusInterface->Context = DeviceObject; PciDevicePresentInterface->Context = DeviceObject;
BusInterface->InterfaceReference = InterfaceReference; PciDevicePresentInterface->InterfaceReference = InterfaceReference;
BusInterface->InterfaceDereference = InterfaceDereference; PciDevicePresentInterface->InterfaceDereference = InterfaceDereference;
BusInterface->IsDevicePresent = InterfacePciDevicePresent; PciDevicePresentInterface->IsDevicePresent = InterfacePciDevicePresent;
BusInterface->IsDevicePresentEx = InterfacePciDevicePresentEx; PciDevicePresentInterface->IsDevicePresentEx = InterfacePciDevicePresentEx;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
} }