1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * PROJECT: ReactOS PCI Bus Driver
3*c2c66affSColin Finck * LICENSE: BSD - See COPYING.ARM in the top level directory
4*c2c66affSColin Finck * FILE: drivers/bus/pci/intrface/intrface.c
5*c2c66affSColin Finck * PURPOSE: Common Interface Support Routines
6*c2c66affSColin Finck * PROGRAMMERS: ReactOS Portable Systems Group
7*c2c66affSColin Finck */
8*c2c66affSColin Finck
9*c2c66affSColin Finck /* INCLUDES *******************************************************************/
10*c2c66affSColin Finck
11*c2c66affSColin Finck #include <pci.h>
12*c2c66affSColin Finck
13*c2c66affSColin Finck #define NDEBUG
14*c2c66affSColin Finck #include <debug.h>
15*c2c66affSColin Finck
16*c2c66affSColin Finck /* GLOBALS ********************************************************************/
17*c2c66affSColin Finck
18*c2c66affSColin Finck PPCI_INTERFACE PciInterfaces[] =
19*c2c66affSColin Finck {
20*c2c66affSColin Finck &ArbiterInterfaceBusNumber,
21*c2c66affSColin Finck &ArbiterInterfaceMemory,
22*c2c66affSColin Finck &ArbiterInterfaceIo,
23*c2c66affSColin Finck &BusHandlerInterface,
24*c2c66affSColin Finck &PciRoutingInterface,
25*c2c66affSColin Finck &PciCardbusPrivateInterface,
26*c2c66affSColin Finck &PciLegacyDeviceDetectionInterface,
27*c2c66affSColin Finck &PciPmeInterface,
28*c2c66affSColin Finck &PciDevicePresentInterface,
29*c2c66affSColin Finck // &PciNativeIdeInterface,
30*c2c66affSColin Finck &PciLocationInterface,
31*c2c66affSColin Finck &AgpTargetInterface,
32*c2c66affSColin Finck NULL
33*c2c66affSColin Finck };
34*c2c66affSColin Finck
35*c2c66affSColin Finck PPCI_INTERFACE PciInterfacesLastResort[] =
36*c2c66affSColin Finck {
37*c2c66affSColin Finck &TranslatorInterfaceInterrupt,
38*c2c66affSColin Finck NULL
39*c2c66affSColin Finck };
40*c2c66affSColin Finck
41*c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
42*c2c66affSColin Finck
43*c2c66affSColin Finck NTSTATUS
44*c2c66affSColin Finck NTAPI
PciQueryInterface(IN PPCI_FDO_EXTENSION DeviceExtension,IN CONST GUID * InterfaceType,IN ULONG Size,IN ULONG Version,IN PVOID InterfaceData,IN PINTERFACE Interface,IN BOOLEAN LastChance)45*c2c66affSColin Finck PciQueryInterface(IN PPCI_FDO_EXTENSION DeviceExtension,
46*c2c66affSColin Finck IN CONST GUID* InterfaceType,
47*c2c66affSColin Finck IN ULONG Size,
48*c2c66affSColin Finck IN ULONG Version,
49*c2c66affSColin Finck IN PVOID InterfaceData,
50*c2c66affSColin Finck IN PINTERFACE Interface,
51*c2c66affSColin Finck IN BOOLEAN LastChance)
52*c2c66affSColin Finck {
53*c2c66affSColin Finck UNICODE_STRING GuidString;
54*c2c66affSColin Finck NTSTATUS Status;
55*c2c66affSColin Finck PPCI_INTERFACE *InterfaceList;
56*c2c66affSColin Finck PPCI_INTERFACE PciInterface;
57*c2c66affSColin Finck RtlStringFromGUID(InterfaceType, &GuidString);
58*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface TYPE = %wZ\n", &GuidString);
59*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
60*c2c66affSColin Finck DPRINT1(" Size = %u, Version = %u, InterfaceData = %p, LastChance = %s\n",
61*c2c66affSColin Finck Size,
62*c2c66affSColin Finck Version,
63*c2c66affSColin Finck InterfaceData,
64*c2c66affSColin Finck LastChance ? "TRUE" : "FALSE");
65*c2c66affSColin Finck
66*c2c66affSColin Finck /* Loop all the available interfaces */
67*c2c66affSColin Finck for (InterfaceList = LastChance ? PciInterfacesLastResort : PciInterfaces;
68*c2c66affSColin Finck *InterfaceList;
69*c2c66affSColin Finck InterfaceList++)
70*c2c66affSColin Finck {
71*c2c66affSColin Finck /* Get the current interface */
72*c2c66affSColin Finck PciInterface = *InterfaceList;
73*c2c66affSColin Finck
74*c2c66affSColin Finck /* For debugging, construct the GUID string */
75*c2c66affSColin Finck RtlStringFromGUID(PciInterface->InterfaceType, &GuidString);
76*c2c66affSColin Finck
77*c2c66affSColin Finck /* Check if this is an FDO or PDO */
78*c2c66affSColin Finck if (DeviceExtension->ExtensionType == PciFdoExtensionType)
79*c2c66affSColin Finck {
80*c2c66affSColin Finck /* Check if the interface is for FDOs */
81*c2c66affSColin Finck if (!(PciInterface->Flags & PCI_INTERFACE_FDO))
82*c2c66affSColin Finck {
83*c2c66affSColin Finck /* This interface is not for FDOs, skip it */
84*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface: guid = %wZ only for FDOs\n",
85*c2c66affSColin Finck &GuidString);
86*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
87*c2c66affSColin Finck continue;
88*c2c66affSColin Finck }
89*c2c66affSColin Finck
90*c2c66affSColin Finck /* Check if the interface is for root FDO only */
91*c2c66affSColin Finck if ((PciInterface->Flags & PCI_INTERFACE_ROOT) &&
92*c2c66affSColin Finck (!PCI_IS_ROOT_FDO(DeviceExtension)))
93*c2c66affSColin Finck {
94*c2c66affSColin Finck /* This FDO isn't the root, skip the interface */
95*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface: guid = %wZ only for ROOT\n",
96*c2c66affSColin Finck &GuidString);
97*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
98*c2c66affSColin Finck continue;
99*c2c66affSColin Finck }
100*c2c66affSColin Finck }
101*c2c66affSColin Finck else
102*c2c66affSColin Finck {
103*c2c66affSColin Finck /* This is a PDO, check if the interface is for PDOs too */
104*c2c66affSColin Finck if (!(PciInterface->Flags & PCI_INTERFACE_PDO))
105*c2c66affSColin Finck {
106*c2c66affSColin Finck /* It isn't, skip it */
107*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface: guid = %wZ only for PDOs\n",
108*c2c66affSColin Finck &GuidString);
109*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
110*c2c66affSColin Finck continue;
111*c2c66affSColin Finck }
112*c2c66affSColin Finck }
113*c2c66affSColin Finck
114*c2c66affSColin Finck /* Print the GUID for debugging, and then free the string */
115*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface looking at guid = %wZ\n", &GuidString);
116*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
117*c2c66affSColin Finck
118*c2c66affSColin Finck /* Check if the GUID, version, and size all match */
119*c2c66affSColin Finck if ((IsEqualGUIDAligned(PciInterface->InterfaceType, InterfaceType)) &&
120*c2c66affSColin Finck (Version >= PciInterface->MinVersion) &&
121*c2c66affSColin Finck (Version <= PciInterface->MaxVersion) &&
122*c2c66affSColin Finck (Size >= PciInterface->MinSize))
123*c2c66affSColin Finck {
124*c2c66affSColin Finck /* Call the interface's constructor */
125*c2c66affSColin Finck Status = PciInterface->Constructor(DeviceExtension,
126*c2c66affSColin Finck PciInterface,
127*c2c66affSColin Finck InterfaceData,
128*c2c66affSColin Finck Version,
129*c2c66affSColin Finck Size,
130*c2c66affSColin Finck Interface);
131*c2c66affSColin Finck if (!NT_SUCCESS(Status))
132*c2c66affSColin Finck {
133*c2c66affSColin Finck /* This interface was not initialized correctly, skip it */
134*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface - Constructor %p = %08lx\n",
135*c2c66affSColin Finck PciInterface->Constructor, Status);
136*c2c66affSColin Finck continue;
137*c2c66affSColin Finck }
138*c2c66affSColin Finck
139*c2c66affSColin Finck /* Reference the interface and return success, all is good */
140*c2c66affSColin Finck Interface->InterfaceReference(Interface->Context);
141*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface returning SUCCESS\n");
142*c2c66affSColin Finck return Status;
143*c2c66affSColin Finck }
144*c2c66affSColin Finck }
145*c2c66affSColin Finck
146*c2c66affSColin Finck /* An interface of this type, and for this device, could not be found */
147*c2c66affSColin Finck DPRINT1("PCI - PciQueryInterface FAILED TO FIND INTERFACE\n");
148*c2c66affSColin Finck return STATUS_NOT_SUPPORTED;
149*c2c66affSColin Finck }
150*c2c66affSColin Finck
151*c2c66affSColin Finck /* EOF */
152