reactos操作系统实现(114)
PciIdeXAddDevice函数是用来添加PCIIDEX的设备,设置一个功能设备,并读取PCI总线的配置参数。具体实现代码如下:
#001 NTSTATUS NTAPI
#002 PciIdeXAddDevice(
#003 IN PDRIVER_OBJECT DriverObject,
#004 IN PDEVICE_OBJECT Pdo)
#005 {
#006 PPCIIDEX_DRIVER_EXTENSION DriverExtension;
#007 PFDO_DEVICE_EXTENSION DeviceExtension;
#008 PDEVICE_OBJECT Fdo;
#009 ULONG BytesRead;
#010 PCI_COMMON_CONFIG PciConfig;
#011 NTSTATUS Status;
#012
#013 DPRINT("PciIdeXAddDevice(%p %p)/n", DriverObject, Pdo);
#014
获取扩展设备对象。
#015 DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
#016 ASSERT(DriverExtension);
#017
创建一个总线功能设备对象。
#018 Status = IoCreateDevice(
#019 DriverObject,
#020 sizeof(FDO_DEVICE_EXTENSION) + DriverExtension->MiniControllerExtensionSize,
#021 NULL,
#022 FILE_DEVICE_BUS_EXTENDER,
#023 FILE_DEVICE_SECURE_OPEN,
#024 TRUE,
#025 &Fdo);
#026 if (!NT_SUCCESS(Status))
#027 {
#028 DPRINT("IoCreateDevice() failed with status 0x%08lx/n", Status);
#029 return Status;
#030 }
#031
清空功能设备对象扩展结构。
#032 DeviceExtension = (PFDO_DEVICE_EXTENSION)Fdo->DeviceExtension;
#033 RtlZeroMemory(DeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
#034
设置这是一个功能设备对象。
#035 DeviceExtension->Common.IsFDO = TRUE;
#036
设置功能设备到物理设备栈里,这里绑定了功能和物理设备,同时把这个设备保存到低级设备里DeviceExtension->LowerDevice,以后就可以通过这个来访问物理设备。
#037 Status = IoAttachDeviceToDeviceStackSafe(Fdo, Pdo, &DeviceExtension->LowerDevice);
#038 if (!NT_SUCCESS(Status))
#039 {
#040 DPRINT("IoAttachDeviceToDeviceStackSafe() failed with status 0x%08lx/n", Status);
#041 return Status;
#042 }
#043
设置驱动程序可以通过接口来访问PCI总线的函数。
#044 Status = GetBusInterface(DeviceExtension);
#045 if (!NT_SUCCESS(Status))
#046 {
#047 DPRINT("GetBusInterface() failed with status 0x%08lx/n", Status);
#048 IoDetachDevice(DeviceExtension->LowerDevice);
#049 return Status;
#050 }
#051
通过PCI总线函数读取PCI的配置。
#052 BytesRead = (*DeviceExtension->BusInterface->GetBusData)(
#053 DeviceExtension->BusInterface->Context,
#054 PCI_WHICHSPACE_CONFIG,
#055 &PciConfig,
#056 0,
#057 PCI_COMMON_HDR_LENGTH);
#058 if (BytesRead != PCI_COMMON_HDR_LENGTH)
#059 {
#060 DPRINT("BusInterface->GetBusData() failed()/n");
#061 ReleaseBusInterface(DeviceExtension);
#062 IoDetachDevice(DeviceExtension->LowerDevice);
#063 return STATUS_IO_DEVICE_ERROR;
#064 }
#065
保存PCI配置厂家号和设备号。
#066 DeviceExtension->VendorId = PciConfig.VendorID;
#067 DeviceExtension->DeviceId = PciConfig.DeviceID;
#068
#069 Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
#070
#071 return STATUS_SUCCESS;
#072 }