2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/pci/config.c
5 * PURPOSE: PCI Configuration Space Routines
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 BOOLEAN PciAssignBusNumbers
;
19 /* FUNCTIONS ******************************************************************/
23 PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension
)
25 PDEVICE_OBJECT AttachedDevice
;
26 IO_STATUS_BLOCK IoStatusBlock
;
30 PIO_STACK_LOCATION IoStackLocation
;
31 PPCI_BUS_INTERFACE_STANDARD PciInterface
;
33 ASSERT(PCI_IS_ROOT_FDO(FdoExtension
));
35 /* Allocate space for the inteface */
36 PciInterface
= ExAllocatePoolWithTag(NonPagedPool
,
37 sizeof(PCI_BUS_INTERFACE_STANDARD
),
39 if (!PciInterface
) return STATUS_INSUFFICIENT_RESOURCES
;
41 /* Get the device the PDO is attached to, should be the Root (ACPI) */
42 AttachedDevice
= IoGetAttachedDeviceReference(FdoExtension
->PhysicalDeviceObject
);
44 /* Build an IRP for this request */
45 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
46 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_PNP
,
55 /* Initialize the default PnP response */
56 Irp
->IoStatus
.Status
= STATUS_NOT_SUPPORTED
;
57 Irp
->IoStatus
.Information
= 0;
59 /* Make it a Query Interface IRP */
60 IoStackLocation
= IoGetNextIrpStackLocation(Irp
);
61 ASSERT(IoStackLocation
->MajorFunction
== IRP_MJ_PNP
);
62 IoStackLocation
->MinorFunction
= IRP_MN_QUERY_INTERFACE
;
63 IoStackLocation
->Parameters
.QueryInterface
.InterfaceType
= &GUID_PCI_BUS_INTERFACE_STANDARD
;
64 IoStackLocation
->Parameters
.QueryInterface
.Size
= sizeof(GUID_PCI_BUS_INTERFACE_STANDARD
);
65 IoStackLocation
->Parameters
.QueryInterface
.Version
= PCI_BUS_INTERFACE_STANDARD_VERSION
;
66 IoStackLocation
->Parameters
.QueryInterface
.Interface
= (PINTERFACE
)PciInterface
;
67 IoStackLocation
->Parameters
.QueryInterface
.InterfaceSpecificData
= NULL
;
69 /* Send it to the root PDO */
70 Status
= IoCallDriver(AttachedDevice
, Irp
);
71 if (Status
== STATUS_PENDING
)
73 /* Wait for completion */
74 KeWaitForSingleObject(&Event
,
79 Status
= Irp
->IoStatus
.Status
;
82 /* Check if an interface was returned */
83 if (!NT_SUCCESS(Status
))
85 /* No interface was returned by the root PDO */
86 FdoExtension
->PciBusInterface
= NULL
;
87 ExFreePoolWithTag(PciInterface
, 0);
91 /* An interface was returned, save it */
92 FdoExtension
->PciBusInterface
= PciInterface
;
95 /* Dereference the device object because we took a reference earlier */
96 ObfDereferenceObject(AttachedDevice
);
100 /* Failure path, dereference the device object and set failure code */
101 if (AttachedDevice
) ObfDereferenceObject(AttachedDevice
);
102 ExFreePoolWithTag(PciInterface
, 0);
103 Status
= STATUS_INSUFFICIENT_RESOURCES
;
106 /* Return status code to caller */
112 PciGetConfigHandlers(IN PPCI_FDO_EXTENSION FdoExtension
)
114 PBUS_HANDLER BusHandler
;
116 ASSERT(FdoExtension
->BusHandler
== NULL
);
118 /* Check if this is the FDO for the root bus */
119 if (PCI_IS_ROOT_FDO(FdoExtension
))
121 /* Query the PCI Bus Interface that ACPI exposes */
122 ASSERT(FdoExtension
->PciBusInterface
== NULL
);
123 Status
= PciQueryForPciBusInterface(FdoExtension
);
124 if (!NT_SUCCESS(Status
))
126 /* No ACPI, so Bus Numbers should be maintained by BIOS */
127 ASSERT(!PciAssignBusNumbers
);
131 /* ACPI detected, PCI Bus Driver will reconfigure bus numbers*/
132 PciAssignBusNumbers
= TRUE
;
137 /* Check if the root bus already has the interface set up */
138 if (FdoExtension
->BusRootFdoExtension
->PciBusInterface
)
140 /* Nothing for this FDO to do */
141 return STATUS_SUCCESS
;
144 /* Fail into case below so we can query the HAL interface */
145 Status
= STATUS_NOT_SUPPORTED
;
148 /* If the ACPI PCI Bus Interface couldn't be obtained, try the HAL */
149 if (!NT_SUCCESS(Status
))
151 /* Bus number assignment should be static */
152 ASSERT(Status
== STATUS_NOT_SUPPORTED
);
153 ASSERT(!PciAssignBusNumbers
);
155 /* Call the HAL to obtain the bus handler for PCI */
156 BusHandler
= HalReferenceHandlerForBus(PCIBus
, FdoExtension
->BaseBus
);
157 FdoExtension
->BusHandler
= BusHandler
;
159 /* Fail if the HAL does not have a PCI Bus Handler for this bus */
160 if (!BusHandler
) return STATUS_INVALID_DEVICE_REQUEST
;
163 /* Appropriate interface was obtained */
164 return STATUS_SUCCESS
;