ReactOS  0.4.14-dev-608-gd495a4f
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 
22 UCHAR
23 NTAPI
25 {
26  UCHAR InterruptLine = 0, PciInterruptLine;
27  ULONG Length;
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 
47 VOID
48 NTAPI
50  IN PCI_SLOT_NUMBER Slot,
51  IN PVOID Buffer,
52  IN ULONG Offset,
53  IN ULONG Length,
54  IN BOOLEAN Read)
55 {
56  PPCI_BUS_INTERFACE_STANDARD PciInterface;
57  PBUS_HANDLER BusHandler;
58  PPCIBUSDATA BusData;
59  PciReadWriteConfig HalFunction;
60 
61  /* Only the root FDO can access configuration space */
62  ASSERT(PCI_IS_ROOT_FDO(DeviceExtension->BusRootFdoExtension));
63 
64  /* Get the ACPI-compliant PCI interface */
65  PciInterface = DeviceExtension->BusRootFdoExtension->PciBusInterface;
66  if (PciInterface)
67  {
68  /* Currently this driver only supports the legacy HAL interface */
70  }
71  else
72  {
73  /* Make sure there's a registered HAL bus handler */
74  ASSERT(DeviceExtension->BusHandler);
75 
76  /* PCI Bus Number assignment is only valid on ACPI systems */
78 
79  /* Grab the HAL PCI Bus Handler data */
80  BusHandler = (PBUS_HANDLER)DeviceExtension->BusHandler;
81  BusData = (PPCIBUSDATA)BusHandler->BusData;
82 
83  /* Choose the appropriate read or write function, and call it */
84  HalFunction = Read ? BusData->ReadConfig : BusData->WriteConfig;
85  HalFunction(BusHandler, Slot, Buffer, Offset, Length);
86  }
87 }
88 
89 VOID
90 NTAPI
92  IN PVOID Buffer,
93  IN ULONG Offset,
94  IN ULONG Length)
95 {
96  /* Call the generic worker function */
97  PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
98  DeviceExtension->Slot,
99  Buffer,
100  Offset,
101  Length,
102  FALSE);
103 }
104 
105 VOID
106 NTAPI
108  IN PVOID Buffer,
109  IN ULONG Offset,
110  IN ULONG Length)
111 {
112  /* Call the generic worker function */
113  PciReadWriteConfigSpace(DeviceExtension->ParentFdoExtension,
114  DeviceExtension->Slot,
115  Buffer,
116  Offset,
117  Length,
118  TRUE);
119 }
120 
121 VOID
122 NTAPI
124  IN PCI_SLOT_NUMBER Slot,
125  IN PVOID Buffer,
126  IN ULONG Offset,
127  IN ULONG Length)
128 {
129  /* Call the generic worker function */
130  PciReadWriteConfigSpace(DeviceExtension, Slot, Buffer, Offset, Length, TRUE);
131 }
132 
133 NTSTATUS
134 NTAPI
136 {
137  PDEVICE_OBJECT AttachedDevice;
139  KEVENT Event;
141  PIRP Irp;
142  PIO_STACK_LOCATION IoStackLocation;
143  PPCI_BUS_INTERFACE_STANDARD PciInterface;
144  PAGED_CODE();
146 
147  /* Allocate space for the interface */
148  PciInterface = ExAllocatePoolWithTag(NonPagedPool,
150  PCI_POOL_TAG);
151  if (!PciInterface) return STATUS_INSUFFICIENT_RESOURCES;
152 
153  /* Get the device the PDO is attached to, should be the Root (ACPI) */
154  AttachedDevice = IoGetAttachedDeviceReference(FdoExtension->PhysicalDeviceObject);
155 
156  /* Build an IRP for this request */
159  AttachedDevice,
160  NULL,
161  0,
162  NULL,
163  &Event,
164  &IoStatusBlock);
165  if (Irp)
166  {
167  /* Initialize the default PnP response */
168  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
169  Irp->IoStatus.Information = 0;
170 
171  /* Make it a Query Interface IRP */
172  IoStackLocation = IoGetNextIrpStackLocation(Irp);
173  ASSERT(IoStackLocation->MajorFunction == IRP_MJ_PNP);
174  IoStackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
175  IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_PCI_BUS_INTERFACE_STANDARD;
176  IoStackLocation->Parameters.QueryInterface.Size = sizeof(PCI_BUS_INTERFACE_STANDARD);
178  IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)PciInterface;
179  IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL;
180 
181  /* Send it to the root PDO */
182  Status = IoCallDriver(AttachedDevice, Irp);
183  if (Status == STATUS_PENDING)
184  {
185  /* Wait for completion */
187  Executive,
188  KernelMode,
189  FALSE,
190  NULL);
191  Status = Irp->IoStatus.Status;
192  }
193 
194  /* Check if an interface was returned */
195  if (!NT_SUCCESS(Status))
196  {
197  /* No interface was returned by the root PDO */
198  FdoExtension->PciBusInterface = NULL;
199  ExFreePoolWithTag(PciInterface, 0);
200  }
201  else
202  {
203  /* An interface was returned, save it */
204  FdoExtension->PciBusInterface = PciInterface;
205  }
206 
207  /* Dereference the device object because we took a reference earlier */
208  ObDereferenceObject(AttachedDevice);
209  }
210  else
211  {
212  /* Failure path, dereference the device object and set failure code */
213  if (AttachedDevice) ObDereferenceObject(AttachedDevice);
214  ExFreePoolWithTag(PciInterface, 0);
216  }
217 
218  /* Return status code to caller */
219  return Status;
220 }
221 
222 NTSTATUS
223 NTAPI
225 {
226  PBUS_HANDLER BusHandler;
228  ASSERT(FdoExtension->BusHandler == NULL);
229 
230  /* Check if this is the FDO for the root bus */
232  {
233  /* Query the PCI Bus Interface that ACPI exposes */
234  ASSERT(FdoExtension->PciBusInterface == NULL);
236  if (!NT_SUCCESS(Status))
237  {
238  /* No ACPI, so Bus Numbers should be maintained by BIOS */
240  }
241  else
242  {
243  /* ACPI detected, PCI Bus Driver will reconfigure bus numbers*/
245  }
246  }
247  else
248  {
249  /* Check if the root bus already has the interface set up */
250  if (FdoExtension->BusRootFdoExtension->PciBusInterface)
251  {
252  /* Nothing for this FDO to do */
253  return STATUS_SUCCESS;
254  }
255 
256  /* Fail into case below so we can query the HAL interface */
258  }
259 
260  /* If the ACPI PCI Bus Interface couldn't be obtained, try the HAL */
261  if (!NT_SUCCESS(Status))
262  {
263  /* Bus number assignment should be static */
266 
267  /* Call the HAL to obtain the bus handler for PCI */
268  BusHandler = HalReferenceHandlerForBus(PCIBus, FdoExtension->BaseBus);
269  FdoExtension->BusHandler = BusHandler;
270 
271  /* Fail if the HAL does not have a PCI Bus Handler for this bus */
272  if (!BusHandler) return STATUS_INVALID_DEVICE_REQUEST;
273  }
274 
275  /* Appropriate interface was obtained */
276  return STATUS_SUCCESS;
277 }
278 
279 /* EOF */
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
#define HalReferenceHandlerForBus
Definition: haltypes.h:286
#define IN
Definition: typedefs.h:38
_In_ BOOLEAN Read
Definition: strmini.h:479
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define PCI_POOL_TAG
Definition: pci.h:25
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:1069
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS NTAPI PciGetConfigHandlers(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: config.c:224
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
PciReadWriteConfig WriteConfig
Definition: iotypes.h:4926
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
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
#define PAGED_CODE()
Definition: video.h:57
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:91
struct _PCI_BUS_INTERFACE_STANDARD PCI_BUS_INTERFACE_STANDARD
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
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:123
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
struct _INTERFACE * PINTERFACE
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
BOOLEAN PciAssignBusNumbers
Definition: config.c:18
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
PciReadWriteConfig ReadConfig
Definition: iotypes.h:4925
#define IRP_MN_QUERY_INTERFACE
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
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
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define PCI_BUS_INTERFACE_STANDARD_VERSION
Definition: iotypes.h:4980
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:4912
Status
Definition: gdiplustypes.h:24
#define PCI_IS_ROOT_FDO(x)
Definition: pci.h:30
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
VOID NTAPI PciReadDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:107
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
struct _BUS_HANDLER * PBUS_HANDLER
Definition: nt_native.h:37
NTSTATUS NTAPI PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension)
Definition: config.c:135
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
UCHAR NTAPI PciGetAdjustedInterruptLine(IN PPCI_PDO_EXTENSION PdoExtension)
Definition: config.c:24
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
PVOID BusData
Definition: haltypes.h:229