ReactOS 0.4.17-dev-1190-g4c812f4
routintf.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/intrface/routinf.c
5 * PURPOSE: Routing Interface
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
21{
22 &GUID_INT_ROUTE_INTERFACE_STANDARD,
27 0,
31};
32
33/* FUNCTIONS ******************************************************************/
34
38{
40 /* PnP Interfaces don't get Initialized */
41 ASSERTMSG("PCI routeintrf_Initializer, unexpected call.\n", FALSE);
43}
44
45/*
46 * These are called back from interrupt arbitration, which can run while
47 * PciAssignSlotResources holds PciGlobalLock, so they must not take it.
48 */
49
54static
60{
63
64 *LegacyDevice = NULL;
65 if (!DeviceObject)
66 return NULL;
67
68 if (DeviceObject->DriverObject == PciDriverObject)
69 {
70 /* Our FDOs share the driver object */
71 PdoExtension = DeviceObject->DeviceExtension;
72 if (PdoExtension->ExtensionType != PciPdoExtensionType)
73 return NULL;
74
75 return PdoExtension;
76 }
77
78 for (Entry = PciLegacyDeviceHead; Entry; Entry = Entry->Next)
79 {
80 if (Entry->DeviceObject != DeviceObject || !Entry->PdoExtension)
81 continue;
82
83 *LegacyDevice = Entry;
84 return Entry->PdoExtension;
85 }
86
87 return NULL;
88}
89
90static
91VOID
95{
96 /* Nothing is reached through the context, so there is nothing to count */
98}
99
100static
101VOID
102NTAPI
105{
107}
108
113static
115NTAPI
118 _Out_ ULONG *Bus,
120 _Out_ UCHAR *InterruptLine,
121 _Out_ UCHAR *InterruptPin,
122 _Out_ UCHAR *ClassCode,
123 _Out_ UCHAR *SubClassCode,
124 _Out_ PDEVICE_OBJECT *ParentPdo,
125 _Out_ ROUTING_TOKEN *RoutingToken,
127{
129 PPCI_LEGACY_DEVICE LegacyDevice;
130 PAGED_CODE();
131
132 *Flags = 0;
133
134 PdoExtension = routeintrf_FindDevice(Pdo, &LegacyDevice);
135 if (!PdoExtension)
136 return STATUS_NOT_FOUND;
137
138 if (LegacyDevice)
139 {
140 /* Answer with what was captured when the legacy driver claimed the slot */
141 *Bus = LegacyDevice->BusNumber;
142 *PciSlot = LegacyDevice->SlotNumber;
143 *InterruptLine = LegacyDevice->InterruptLine;
144 *InterruptPin = LegacyDevice->InterruptPin;
145 *ClassCode = LegacyDevice->BaseClass;
146 *SubClassCode = LegacyDevice->SubClass;
147 *ParentPdo = LegacyDevice->PhysicalDeviceObject;
148 *RoutingToken = LegacyDevice->RoutingToken;
149 return STATUS_SUCCESS;
150 }
151
152 *Bus = PdoExtension->ParentFdoExtension->BaseBus;
153 *PciSlot = PdoExtension->Slot.u.AsULONG;
154 *InterruptLine = PdoExtension->RawInterruptLine;
155 *InterruptPin = PdoExtension->InterruptPin;
156 *ClassCode = PdoExtension->BaseClass;
157 *SubClassCode = PdoExtension->SubClass;
158 *ParentPdo = PdoExtension->ParentFdoExtension->PhysicalDeviceObject;
159 *RoutingToken = PdoExtension->RoutingToken;
160 return STATUS_SUCCESS;
161}
162
163static
165NTAPI
168 _In_ PROUTING_TOKEN RoutingToken)
169{
171 PPCI_LEGACY_DEVICE LegacyDevice;
172 PAGED_CODE();
173
174 if (!RoutingToken)
176
177 PdoExtension = routeintrf_FindDevice(Pdo, &LegacyDevice);
178 if (!PdoExtension)
179 return STATUS_NOT_FOUND;
180
181 if (LegacyDevice)
182 {
183 LegacyDevice->RoutingToken = *RoutingToken;
184 }
185 else
186 {
187 PdoExtension->RoutingToken = *RoutingToken;
188 }
189
190 return STATUS_SUCCESS;
191}
192
197static
198VOID
199NTAPI
202 _In_ UCHAR LineRegister)
203{
205 PPCI_LEGACY_DEVICE LegacyDevice;
207 PAGED_CODE();
208
209 PdoExtension = routeintrf_FindDevice(Pdo, &LegacyDevice);
210 if (!PdoExtension)
211 return;
212
213 /* PciSetResources writes RawInterruptLine back whenever it programs the device */
214 PdoExtension->RawInterruptLine = LineRegister;
215 PdoExtension->AdjustedInterruptLine = LineRegister;
216 if (LegacyDevice)
217 LegacyDevice->InterruptLine = LineRegister;
218
220 &LineRegister,
221 FIELD_OFFSET(PCI_COMMON_HEADER, u.type0.InterruptLine),
222 sizeof(LineRegister));
223
225 return;
226
227 if (BiosData.u.type0.InterruptLine == LineRegister)
228 return;
229
230 BiosData.u.type0.InterruptLine = LineRegister;
232}
233
235NTAPI
238 IN PVOID InterfaceData,
240 IN USHORT Size,
242{
244 PAGED_CODE();
245
247 UNREFERENCED_PARAMETER(InterfaceData);
249
250 /* Only version 1 is supported */
252
253 RouteInterface->Size = sizeof(*RouteInterface);
255 RouteInterface->Context = DeviceExtension;
261 return STATUS_SUCCESS;
262}
263
265NTAPI
269 IN UCHAR InterruptLine,
270 IN UCHAR InterruptPin,
271 IN UCHAR BaseClass,
272 IN UCHAR SubClass,
275 OUT PDEVICE_OBJECT *pFoundDeviceObject)
276{
278 PPCI_LEGACY_DEVICE LegacyDevice;
279 PDEVICE_OBJECT FoundDeviceObject;
280 PAGED_CODE();
281
282 /* Scan current registered devices */
283 LegacyDevice = PciLegacyDeviceHead;
285 while (LegacyDevice)
286 {
287 /* Find a match */
288 if ((BusNumber == LegacyDevice->BusNumber) &&
289 (SlotNumber == LegacyDevice->SlotNumber))
290 {
291 /* We already know about this routing */
292 break;
293 }
294
295 /* We know about device already, but for a different location */
296 if (LegacyDevice->DeviceObject == DeviceObject)
297 {
298 /* Free the existing structure, move to the next one */
299 *Link = LegacyDevice->Next;
300 ExFreePoolWithTag(LegacyDevice, 0);
301 LegacyDevice = *Link;
302 }
303 else
304 {
305 /* Keep going */
306 Link = &LegacyDevice->Next;
307 LegacyDevice = LegacyDevice->Next;
308 }
309 }
310
311 /* Did we find a match? */
312 if (!LegacyDevice)
313 {
314 /* Allocate a new cache structure */
315 LegacyDevice = ExAllocatePoolWithTag(PagedPool,
316 sizeof(PCI_LEGACY_DEVICE),
318 if (!LegacyDevice) return STATUS_INSUFFICIENT_RESOURCES;
319
320 /* Save all the data in it */
321 RtlZeroMemory(LegacyDevice, sizeof(PCI_LEGACY_DEVICE));
322 LegacyDevice->BusNumber = BusNumber;
323 LegacyDevice->SlotNumber = SlotNumber;
324 LegacyDevice->InterruptLine = InterruptLine;
325 LegacyDevice->InterruptPin = InterruptPin;
326 LegacyDevice->BaseClass = BaseClass;
327 LegacyDevice->SubClass = SubClass;
329 LegacyDevice->DeviceObject = DeviceObject;
330 LegacyDevice->PdoExtension = PdoExtension;
331
332 /* Link it in the list */
333 LegacyDevice->Next = PciLegacyDeviceHead;
334 PciLegacyDeviceHead = LegacyDevice;
335 }
336
337 /* Check if we found, or created, a matching caching structure */
338 FoundDeviceObject = LegacyDevice->DeviceObject;
339 if (FoundDeviceObject == DeviceObject)
340 {
341 /* Return the device object and success */
342 if (pFoundDeviceObject) *pFoundDeviceObject = DeviceObject;
343 return STATUS_SUCCESS;
344 }
345
346 /* Otherwise, this is a new device object for this location */
347 LegacyDevice->DeviceObject = DeviceObject;
348 if (pFoundDeviceObject) *pFoundDeviceObject = FoundDeviceObject;
349 return STATUS_SUCCESS;
350}
351
355VOID
356NTAPI
358{
359 PPCI_LEGACY_DEVICE LegacyDevice;
360 PAGED_CODE();
361
362 while (PciLegacyDeviceHead)
363 {
364 LegacyDevice = PciLegacyDeviceHead;
365 PciLegacyDeviceHead = LegacyDevice->Next;
366 ExFreePoolWithTag(LegacyDevice, TAG_PCI_ROUTING);
367 }
368}
369
370/* EOF */
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
PDRIVER_OBJECT PciDriverObject
Definition: init.c:19
VOID NTAPI PciWriteDeviceConfig(IN PPCI_PDO_EXTENSION DeviceExtension, IN PVOID Buffer, IN ULONG Offset, IN ULONG Length)
Definition: config.c:133
#define PCI_INTERFACE_FDO
Definition: pci.h:68
NTSTATUS NTAPI PciGetBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
Definition: utils.c:840
NTSTATUS NTAPI PciSaveBiosConfig(IN PPCI_PDO_EXTENSION DeviceExtension, OUT PPCI_COMMON_HEADER PciData)
#define TAG_PCI_ROUTING
Definition: pci.h:32
@ PciPdoExtensionType
Definition: pci.h:133
@ PciInterface_IntRouteHandler
Definition: pci.h:141
@ PdoExtension
Definition: precomp.h:61
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
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
_In_ UCXUSBDEVICE _In_ PDEVICE_OBJECT Pdo
Definition: hubucx.h:280
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define _Outptr_result_maybenull_
Definition: no_sal2.h:266
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
#define STATUS_NOINTERFACE
Definition: ntstatus.h:937
_In_ ULONG _In_ PCI_SLOT_NUMBER PciSlot
Definition: pciidex.h:66
_In_ ULONG BusNumber
Definition: pciidex.h:65
unsigned short USHORT
Definition: pedump.c:61
NTSTATUS NTAPI routeintrf_Constructor(IN PVOID DeviceExtension, IN PVOID Instance, IN PVOID InterfaceData, IN USHORT Version, IN USHORT Size, IN PINTERFACE Interface)
Definition: routintf.c:236
VOID NTAPI PciFreeLegacyDeviceCache(VOID)
Frees the routing cached for slots claimed by legacy drivers.
Definition: routintf.c:357
NTSTATUS NTAPI routeintrf_Initializer(IN PVOID Instance)
Definition: routintf.c:37
NTSTATUS NTAPI PciCacheLegacyDeviceRouting(IN PDEVICE_OBJECT DeviceObject, IN ULONG BusNumber, IN ULONG SlotNumber, IN UCHAR InterruptLine, IN UCHAR InterruptPin, IN UCHAR BaseClass, IN UCHAR SubClass, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PPCI_PDO_EXTENSION PdoExtension, OUT PDEVICE_OBJECT *pFoundDeviceObject)
Definition: routintf.c:266
PCI_INTERFACE PciRoutingInterface
Definition: routintf.c:20
static PPCI_PDO_EXTENSION NTAPI routeintrf_FindDevice(_In_opt_ PDEVICE_OBJECT DeviceObject, _Outptr_result_maybenull_ PPCI_LEGACY_DEVICE *LegacyDevice)
Finds the PDO extension behind one of our PDOs or a cached legacy device object. LegacyDevice receive...
Definition: routintf.c:57
static VOID NTAPI routeintrf_UpdateInterruptLine(_In_ PDEVICE_OBJECT Pdo, _In_ UCHAR LineRegister)
Programs the IRQ chosen for a device into its interrupt line register. The saved BIOS copy is updated...
Definition: routintf.c:200
static NTSTATUS NTAPI routeintrf_GetInterruptRouting(_In_ PDEVICE_OBJECT Pdo, _Out_ ULONG *Bus, _Out_ ULONG *PciSlot, _Out_ UCHAR *InterruptLine, _Out_ UCHAR *InterruptPin, _Out_ UCHAR *ClassCode, _Out_ UCHAR *SubClassCode, _Out_ PDEVICE_OBJECT *ParentPdo, _Out_ ROUTING_TOKEN *RoutingToken, _Out_ UCHAR *Flags)
Describes where a device's interrupt pin is wired. ParentPdo is the PDO of the bridge above the devic...
Definition: routintf.c:116
PPCI_LEGACY_DEVICE PciLegacyDeviceHead
Definition: routintf.c:18
static NTSTATUS NTAPI routeintrf_SetInterruptRoutingToken(_In_ PDEVICE_OBJECT Pdo, _In_ PROUTING_TOKEN RoutingToken)
Definition: routintf.c:166
static VOID NTAPI routeintrf_Dereference(_In_ PVOID Context)
Definition: routintf.c:103
static VOID NTAPI routeintrf_Reference(_In_ PVOID Context)
Definition: routintf.c:93
Entry
Definition: section.c:5216
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
PINTERFACE_DEREFERENCE InterfaceDereference
Definition: iotypes.h:5517
PGET_INTERRUPT_ROUTING GetInterruptRouting
Definition: iotypes.h:5518
PUPDATE_INTERRUPT_LINE UpdateInterruptLine
Definition: iotypes.h:5520
PINTERFACE_REFERENCE InterfaceReference
Definition: iotypes.h:5516
PSET_INTERRUPT_ROUTING_TOKEN SetInterruptRoutingToken
Definition: iotypes.h:5519
UCHAR InterruptPin
Definition: pci.h:593
UCHAR SubClass
Definition: pci.h:595
UCHAR BaseClass
Definition: pci.h:594
PPCI_PDO_EXTENSION PdoExtension
Definition: pci.h:598
UCHAR InterruptLine
Definition: pci.h:592
PDEVICE_OBJECT PhysicalDeviceObject
Definition: pci.h:596
PDEVICE_OBJECT DeviceObject
Definition: pci.h:589
ROUTING_TOKEN RoutingToken
Definition: pci.h:597
struct _PCI_LEGACY_DEVICE * Next
Definition: pci.h:588
ULONG BusNumber
Definition: pci.h:590
ULONG SlotNumber
Definition: pci.h:591
PBIOS_DATA BiosData
Definition: bios.c:42
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ UCXUSBDEVICE _In_ ULONG Interface
Definition: ucxusbdevice.h:428
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static int Link(const char **args)
Definition: vfdcmd.c:2414
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_WMI_INSTANCE_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_opt_ WDFWMIINSTANCE * Instance
Definition: wdfwmi.h:481
struct _INT_ROUTE_INTERFACE_STANDARD * PINT_ROUTE_INTERFACE_STANDARD
struct _INT_ROUTE_INTERFACE_STANDARD INT_ROUTE_INTERFACE_STANDARD
#define PCI_INT_ROUTE_INTRF_STANDARD_VER
Definition: iotypes.h:5473