ReactOS 0.4.17-dev-683-g0dafdc5
config.c
Go to the documentation of this file.
1/*
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
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <pci.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* GLOBALS ********************************************************************/
17
19
20/* FUNCTIONS ******************************************************************/
21
25{
26 UCHAR InterruptLine = 0, PciInterruptLine;
28
29 /* Does the device have an interrupt pin? */
30 if (PdoExtension->InterruptPin)
31 {
32 /* Find the associated line on the parent bus */
34 PdoExtension->ParentFdoExtension->BaseBus,
35 PdoExtension->Slot.u.AsULONG,
36 &PciInterruptLine,
38 u.type0.InterruptLine),
39 sizeof(UCHAR));
40 if (Length) InterruptLine = PciInterruptLine;
41 }
42
43 /* Either keep the original interrupt line, or the one on the master bus */
44 return InterruptLine ? PdoExtension->RawInterruptLine : InterruptLine;
45}
46
47VOID
55{
56 PPCI_BUS_INTERFACE_STANDARD PciInterface;
57 PBUS_HANDLER BusHandler;
58 PPCIBUSDATA BusData;
59 PciReadWriteConfig HalFunction;
60 ULONG LengthProcessed;
61
62 /* Only the root FDO can access configuration space */
63 ASSERT(PCI_IS_ROOT_FDO(DeviceExtension->BusRootFdoExtension));
64
65 /* Get the ACPI-compliant PCI interface from the root */
66 PciInterface = DeviceExtension->BusRootFdoExtension->PciBusInterface;
67 if (PciInterface)
68 {
69 /* Use the PCI interface to access configuration space */
70 if (Read)
71 {
72 LengthProcessed = PciInterface->ReadConfig(PciInterface->Context,
73 DeviceExtension->BaseBus,
74 Slot.u.AsULONG,
75 Buffer,
76 Offset,
77 Length);
78 }
79 else
80 {
81 LengthProcessed = PciInterface->WriteConfig(PciInterface->Context,
82 DeviceExtension->BaseBus,
83 Slot.u.AsULONG,
84 Buffer,
85 Offset,
86 Length);
87 }
88
89 /* Verify the operation succeeded */
90 if (LengthProcessed != Length)
91 {
92 DPRINT1("PCI: Config space %s failed - Bus %x, Slot %x, Offset %x, Expected %x bytes, got %x\n",
93 Read ? "read" : "write",
94 DeviceExtension->BaseBus,
95 Slot.u.AsULONG,
96 Offset,
97 Length,
98 LengthProcessed);
99 }
100 }
101 else
102 {
103 /* Make sure there's a registered HAL bus handler */
104 ASSERT(DeviceExtension->BusHandler);
105
106 /* PCI Bus Number assignment is only valid on ACPI systems */
108
109 /* Grab the HAL PCI Bus Handler data */
110 BusHandler = (PBUS_HANDLER)DeviceExtension->BusHandler;
111 BusData = (PPCIBUSDATA)BusHandler->BusData;
112
113 /* Choose the appropriate read or write function, and call it */
114 HalFunction = Read ? BusData->ReadConfig : BusData->WriteConfig;
115 HalFunction(BusHandler, Slot, Buffer, Offset, Length);
116 }
117}
118
119VOID
120NTAPI
125{
126 /* Call the generic worker function */
127 PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
128 DeviceExtension->Slot,
129 Buffer,
130 Offset,
131 Length,
132 FALSE);
133}
134
135VOID
136NTAPI
141{
142 /* Call the generic worker function */
143 PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
144 DeviceExtension->Slot,
145 Buffer,
146 Offset,
147 Length,
148 TRUE);
149}
150
151VOID
152NTAPI
154 IN PCI_SLOT_NUMBER Slot,
158{
159 /* Call the generic worker function */
160 PciReadWriteConfigSpace(DeviceExtension, Slot, Buffer, Offset, Length, TRUE);
161}
162
164NTAPI
166{
167 PDEVICE_OBJECT AttachedDevice;
171 PIRP Irp;
173 PPCI_BUS_INTERFACE_STANDARD PciInterface;
174 PAGED_CODE();
176
177 /* Allocate space for the interface */
178 PciInterface = ExAllocatePoolWithTag(NonPagedPool,
181 if (!PciInterface) return STATUS_INSUFFICIENT_RESOURCES;
182
183 /* Get the device the PDO is attached to, should be the Root (ACPI) */
184 AttachedDevice = IoGetAttachedDeviceReference(FdoExtension->PhysicalDeviceObject);
185
186 /* Build an IRP for this request */
189 AttachedDevice,
190 NULL,
191 0,
192 NULL,
193 &Event,
195 if (Irp)
196 {
197 /* Initialize the default PnP response */
198 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
199 Irp->IoStatus.Information = 0;
200
201 /* Make it a Query Interface IRP */
205 IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_PCI_BUS_INTERFACE_STANDARD;
208 IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)PciInterface;
209 IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL;
210
211 /* Send it to the root PDO */
212 Status = IoCallDriver(AttachedDevice, Irp);
213 if (Status == STATUS_PENDING)
214 {
215 /* Wait for completion */
217 Executive,
219 FALSE,
220 NULL);
221 Status = Irp->IoStatus.Status;
222 }
223
224 /* Check if an interface was returned */
225 if (!NT_SUCCESS(Status))
226 {
227 /* No interface was returned by the root PDO */
228 FdoExtension->PciBusInterface = NULL;
229 ExFreePoolWithTag(PciInterface, 0);
230 }
231 else
232 {
233 /* An interface was returned, save it */
234 FdoExtension->PciBusInterface = PciInterface;
235 }
236
237 /* Dereference the device object because we took a reference earlier */
238 ObDereferenceObject(AttachedDevice);
239 }
240 else
241 {
242 /* Failure path, dereference the device object and set failure code */
243 if (AttachedDevice) ObDereferenceObject(AttachedDevice);
244 ExFreePoolWithTag(PciInterface, 0);
246 }
247
248 /* Return status code to caller */
249 return Status;
250}
251
253NTAPI
255{
256 PBUS_HANDLER BusHandler;
258 ASSERT(FdoExtension->BusHandler == NULL);
259
260 /* Check if this is the FDO for the root bus */
262 {
263 /* Query the PCI Bus Interface that ACPI exposes */
264 ASSERT(FdoExtension->PciBusInterface == NULL);
266 if (!NT_SUCCESS(Status))
267 {
268 /* No ACPI, so Bus Numbers should be maintained by BIOS */
270 }
271 else
272 {
273 /* ACPI detected, PCI Bus Driver will reconfigure bus numbers*/
275 }
276 }
277 else
278 {
279 /* Check if the root bus already has the interface set up */
280 if (FdoExtension->BusRootFdoExtension->PciBusInterface)
281 {
282 /* Nothing for this FDO to do */
283 return STATUS_SUCCESS;
284 }
285
286 /* Fail into case below so we can query the HAL interface */
288 }
289
290 /* If the ACPI PCI Bus Interface couldn't be obtained, try the HAL */
291 if (!NT_SUCCESS(Status))
292 {
293 /* Bus number assignment should be static */
296
297 /* Call the HAL to obtain the bus handler for PCI */
298 BusHandler = HalReferenceHandlerForBus(PCIBus, FdoExtension->BaseBus);
299 FdoExtension->BusHandler = BusHandler;
300
301 /* Fail if the HAL does not have a PCI Bus Handler for this bus */
302 if (!BusHandler) return STATUS_INVALID_DEVICE_REQUEST;
303 }
304
305 /* Appropriate interface was obtained */
306 return STATUS_SUCCESS;
307}
308
309/* EOF */
#define PAGED_CODE()
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
Definition: bufpool.h:45
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI PciReadSlotConfig(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:153
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:121
NTSTATUS NTAPI PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: config.c:165
BOOLEAN PciAssignBusNumbers
Definition: config.c:18
VOID NTAPI PciReadWriteConfigSpace(IN PPCI_FDO_EXTENSION DeviceExtension, IN PCI_SLOT_NUMBER Slot, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length, IN BOOLEAN Read)
Definition: config.c:49
UCHAR NTAPI PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: config.c:24
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:137
NTSTATUS NTAPI PciGetConfigHandlers(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: config.c:254
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:32
#define PCI_POOL_TAG
Definition: pci.h:27
@ PdoExtension
Definition: precomp.h:49
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
ULONG NTAPI HalGetBusDataByOffset(IN BUS_DATA_TYPE BusDataType, IN ULONG BusNumber, IN ULONG SlotNumber, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: bus.c:73
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define KernelMode
Definition: asm.h:38
struct _BUS_HANDLER * PBUS_HANDLER
Definition: nt_native.h:37
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ SynchronizationEvent
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:100
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1407
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1101
#define IoCallDriver
Definition: irp.c:1257
@ PCIBus
Definition: restypes.h:126
@ PCIConfiguration
Definition: miniport.h:93
struct _INTERFACE * PINTERFACE
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ BOOLEAN Read
Definition: strmini.h:479
PVOID BusData
Definition: haltypes.h:1997
struct _IO_STACK_LOCATION::@4478::@4504 QueryInterface
union _IO_STACK_LOCATION::@1708 Parameters
PciReadWriteConfig WriteConfig
Definition: iotypes.h:5285
PciReadWriteConfig ReadConfig
Definition: iotypes.h:5284
PCI_READ_WRITE_CONFIG ReadConfig
Definition: iotypes.h:5331
PCI_READ_WRITE_CONFIG WriteConfig
Definition: iotypes.h:5332
#define STATUS_PENDING
Definition: telnetd.h:14
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIO_STACK_LOCATION IoStackLocation
Definition: usbdlib.h:265
#define HalReferenceHandlerForBus
Definition: haltypes.h:307
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define PCI_BUS_INTERFACE_STANDARD_VERSION
Definition: iotypes.h:5339
struct _PCI_BUS_INTERFACE_STANDARD PCI_BUS_INTERFACE_STANDARD
#define IRP_MN_QUERY_INTERFACE
VOID(NTAPI * PciReadWriteConfig)(_In_ struct _BUS_HANDLER *BusHandler, _In_ PCI_SLOT_NUMBER Slot, _In_reads_bytes_(Length) PVOID Buffer, _In_ ULONG Offset, _In_ ULONG Length)
Definition: iotypes.h:5271
@ Executive
Definition: ketypes.h:467
#define ObDereferenceObject
Definition: obfuncs.h:203