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,41 +954,154 @@ InterfaceBusGetBusData(
return Size; return Size;
} }
static BOOLEAN NTAPI static BOOLEAN NTAPI
InterfacePciDevicePresent( InterfacePciDevicePresent(
IN USHORT VendorID, IN USHORT VendorID,
IN USHORT DeviceID, IN USHORT DeviceID,
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;
return 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;
}
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(
IN PVOID Context, IN PVOID Context,
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;
} }
} }