fdo.c
来自「一个类似windows」· C语言 代码 · 共 591 行 · 第 1/2 页
C
591 行
/*
* PROJECT: ReactOS PCI bus driver
* FILE: fdo.c
* PURPOSE: PCI device object dispatch routines
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
* 10-09-2001 CSH Created
*/
#include "pci.h"
#define NDEBUG
#include <debug.h>
/*** PRIVATE *****************************************************************/
static NTSTATUS
FdoLocateChildDevice(
PPCI_DEVICE *Device,
PFDO_DEVICE_EXTENSION DeviceExtension,
PCI_SLOT_NUMBER SlotNumber,
PPCI_COMMON_CONFIG PciConfig)
{
PLIST_ENTRY CurrentEntry;
PPCI_DEVICE CurrentDevice;
DPRINT("Called\n");
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
CurrentDevice = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
/* If both vendor ID and device ID match, it is the same device */
if ((PciConfig->VendorID == CurrentDevice->PciConfig.VendorID) &&
(PciConfig->DeviceID == CurrentDevice->PciConfig.DeviceID) &&
(SlotNumber.u.AsULONG == CurrentDevice->SlotNumber.u.AsULONG)) {
*Device = CurrentDevice;
DPRINT("Done\n");
return STATUS_SUCCESS;
}
CurrentEntry = CurrentEntry->Flink;
}
*Device = NULL;
DPRINT("Done\n");
return STATUS_UNSUCCESSFUL;
}
static NTSTATUS
FdoEnumerateDevices(
PDEVICE_OBJECT DeviceObject)
{
PFDO_DEVICE_EXTENSION DeviceExtension;
PCI_COMMON_CONFIG PciConfig;
PLIST_ENTRY CurrentEntry;
PPCI_DEVICE Device;
PCI_SLOT_NUMBER SlotNumber;
ULONG DeviceNumber;
ULONG FunctionNumber;
ULONG Size;
NTSTATUS Status;
DPRINT("Called\n");
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* Mark all devices to be removed. If we don't discover them again during
enumeration, assume that they have been surprise removed */
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
Device->RemovePending = TRUE;
CurrentEntry = CurrentEntry->Flink;
}
DeviceExtension->DeviceListCount = 0;
/* Enumerate devices on the PCI bus */
SlotNumber.u.AsULONG = 0;
for (DeviceNumber = 0; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
{
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
for (FunctionNumber = 0; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
{
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
DPRINT("Bus %1lu Device %2lu Func %1lu\n",
DeviceExtension->BusNumber,
DeviceNumber,
FunctionNumber);
RtlZeroMemory(&PciConfig,
sizeof(PCI_COMMON_CONFIG));
Size = HalGetBusData(PCIConfiguration,
DeviceExtension->BusNumber,
SlotNumber.u.AsULONG,
&PciConfig,
PCI_COMMON_HDR_LENGTH);
DPRINT("Size %lu\n", Size);
if (Size < PCI_COMMON_HDR_LENGTH)
{
if (FunctionNumber == 0)
{
break;
}
else
{
continue;
}
}
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
DeviceExtension->BusNumber,
DeviceNumber,
FunctionNumber,
PciConfig.VendorID,
PciConfig.DeviceID);
Status = FdoLocateChildDevice(&Device, DeviceExtension, SlotNumber, &PciConfig);
if (!NT_SUCCESS(Status))
{
Device = (PPCI_DEVICE)ExAllocatePool(NonPagedPool, sizeof(PCI_DEVICE));
if (!Device)
{
/* FIXME: Cleanup resources for already discovered devices */
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Device,
sizeof(PCI_DEVICE));
Device->BusNumber = DeviceExtension->BusNumber;
RtlCopyMemory(&Device->SlotNumber,
&SlotNumber,
sizeof(PCI_SLOT_NUMBER));
RtlCopyMemory(&Device->PciConfig,
&PciConfig,
sizeof(PCI_COMMON_CONFIG));
ExInterlockedInsertTailList(
&DeviceExtension->DeviceListHead,
&Device->ListEntry,
&DeviceExtension->DeviceListLock);
}
/* Don't remove this device */
Device->RemovePending = FALSE;
DeviceExtension->DeviceListCount++;
/* Skip to next device if the current one is not a multifunction device */
if ((FunctionNumber == 0) &&
((PciConfig.HeaderType & 0x80) == 0))
{
break;
}
}
}
DPRINT("Done\n");
return STATUS_SUCCESS;
}
static NTSTATUS
FdoQueryBusRelations(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
PIO_STACK_LOCATION IrpSp)
{
PPDO_DEVICE_EXTENSION PdoDeviceExtension;
PFDO_DEVICE_EXTENSION DeviceExtension;
PDEVICE_RELATIONS Relations;
PLIST_ENTRY CurrentEntry;
PPCI_DEVICE Device;
NTSTATUS Status;
BOOLEAN ErrorOccurred;
NTSTATUS ErrorStatus;
ULONG Size;
ULONG i;
DPRINT("Called\n");
ErrorStatus = STATUS_INSUFFICIENT_RESOURCES;
Status = STATUS_SUCCESS;
ErrorOccurred = FALSE;
FdoEnumerateDevices(DeviceObject);
DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (Irp->IoStatus.Information) {
/* FIXME: Another bus driver has already created a DEVICE_RELATIONS
structure so we must merge this structure with our own */
}
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
(DeviceExtension->DeviceListCount - 1);
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
if (!Relations)
return STATUS_INSUFFICIENT_RESOURCES;
Relations->Count = DeviceExtension->DeviceListCount;
i = 0;
CurrentEntry = DeviceExtension->DeviceListHead.Flink;
while (CurrentEntry != &DeviceExtension->DeviceListHead) {
Device = CONTAINING_RECORD(CurrentEntry, PCI_DEVICE, ListEntry);
PdoDeviceExtension = NULL;
if (!Device->Pdo) {
/* Create a physical device object for the
device as it does not already have one */
Status = IoCreateDevice(
DeviceObject->DriverObject,
sizeof(PDO_DEVICE_EXTENSION),
NULL,
FILE_DEVICE_CONTROLLER,
FILE_AUTOGENERATED_DEVICE_NAME,
FALSE,
&Device->Pdo);
if (!NT_SUCCESS(Status)) {
DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
ErrorStatus = Status;
ErrorOccurred = TRUE;
break;
}
Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;
//Device->Pdo->Flags |= DO_POWER_PAGABLE;
PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;
RtlZeroMemory(PdoDeviceExtension, sizeof(PDO_DEVICE_EXTENSION));
PdoDeviceExtension->Common.IsFDO = FALSE;
PdoDeviceExtension->Common.DeviceObject = Device->Pdo;
PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;
PdoDeviceExtension->Fdo = DeviceObject;
PdoDeviceExtension->PciDevice = Device;
/* Add Device ID string */
Status = PciCreateDeviceIDString(&PdoDeviceExtension->DeviceID, Device);
if (!NT_SUCCESS(Status))
{
ErrorStatus = Status;
ErrorOccurred = TRUE;
break;
}
DPRINT("DeviceID: %S\n", PdoDeviceExtension->DeviceID.Buffer);
/* Add Instance ID string */
Status = PciCreateInstanceIDString(&PdoDeviceExtension->InstanceID, Device);
if (!NT_SUCCESS(Status))
{
ErrorStatus = Status;
ErrorOccurred = TRUE;
break;
}
/* Add Hardware IDs string */
Status = PciCreateHardwareIDsString(&PdoDeviceExtension->HardwareIDs, Device);
if (!NT_SUCCESS(Status))
{
ErrorStatus = Status;
ErrorOccurred = TRUE;
break;
}
/* Add Compatible IDs string */
Status = PciCreateCompatibleIDsString(&PdoDeviceExtension->CompatibleIDs, Device);
if (!NT_SUCCESS(Status))
{
ErrorStatus = Status;
ErrorOccurred = TRUE;
break;
}
/* Add device description string */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?