1 /*
2 * PROJECT: ReactOS PCI Bus Driver
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: drivers/bus/pci/hookhal.c
5 * PURPOSE: HAL Bus Handler Dispatch Routine Support
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
18 pHalTranslateBusAddress PcipSavedTranslateBusAddress;
19 pHalAssignSlotResources PcipSavedAssignSlotResources;
20
21 /* FUNCTIONS ******************************************************************/
22
23 BOOLEAN
24 NTAPI
PciTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,IN ULONG BusNumber,IN PHYSICAL_ADDRESS BusAddress,OUT PULONG AddressSpace,OUT PPHYSICAL_ADDRESS TranslatedAddress)25 PciTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
26 IN ULONG BusNumber,
27 IN PHYSICAL_ADDRESS BusAddress,
28 OUT PULONG AddressSpace,
29 OUT PPHYSICAL_ADDRESS TranslatedAddress)
30 {
31 UNREFERENCED_PARAMETER(InterfaceType);
32 UNREFERENCED_PARAMETER(BusNumber);
33 UNREFERENCED_PARAMETER(AddressSpace);
34
35 /* FIXME: Broken translation */
36 UNIMPLEMENTED;
37 TranslatedAddress->QuadPart = BusAddress.QuadPart;
38 return TRUE;
39 }
40
41 PPCI_PDO_EXTENSION
42 NTAPI
PciFindPdoByLocation(IN ULONG BusNumber,IN ULONG SlotNumber)43 PciFindPdoByLocation(IN ULONG BusNumber,
44 IN ULONG SlotNumber)
45 {
46 PPCI_FDO_EXTENSION DeviceExtension;
47 PPCI_PDO_EXTENSION PdoExtension;
48 PCI_SLOT_NUMBER PciSlot;
49 PciSlot.u.AsULONG = SlotNumber;
50
51 /* Acquire the global lock */
52 KeEnterCriticalRegion();
53 KeWaitForSingleObject(&PciGlobalLock, Executive, KernelMode, FALSE, NULL);
54
55 /* Now search for the extension */
56 DeviceExtension = (PPCI_FDO_EXTENSION)PciFdoExtensionListHead.Next;
57 while (DeviceExtension)
58 {
59 /* If we found it, break out */
60 if (DeviceExtension->BaseBus == BusNumber) break;
61
62 /* Move to the next device */
63 DeviceExtension = (PPCI_FDO_EXTENSION)DeviceExtension->List.Next;
64 }
65
66 /* Release the global lock */
67 KeSetEvent(&PciGlobalLock, IO_NO_INCREMENT, FALSE);
68 KeLeaveCriticalRegion();
69
70 /* Check if the device extension for the bus was found */
71 if (!DeviceExtension)
72 {
73 /* It wasn't, bail out */
74 DPRINT1("Pci: Could not find PCI bus FDO. Bus Number = 0x%x\n", BusNumber);
75 return NULL;
76 }
77
78 /* Acquire this device's lock */
79 KeEnterCriticalRegion();
80 KeWaitForSingleObject(&DeviceExtension->ChildListLock,
81 Executive,
82 KernelMode,
83 FALSE,
84 NULL);
85
86 /* Loop every child PDO */
87 for (PdoExtension = DeviceExtension->ChildPdoList;
88 PdoExtension;
89 PdoExtension = PdoExtension->Next)
90 {
91 /* Check if the function number and header data matches */
92 if ((PdoExtension->Slot.u.bits.FunctionNumber == PciSlot.u.bits.FunctionNumber) &&
93 (PdoExtension->Slot.u.bits.DeviceNumber == PciSlot.u.bits.DeviceNumber))
94 {
95 /* This is considered to be the same PDO */
96 ASSERT(PdoExtension->Slot.u.AsULONG == PciSlot.u.AsULONG);
97 break;
98 }
99 }
100
101 /* Release this device's lock */
102 KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
103 KeLeaveCriticalRegion();
104
105 /* Check if we found something */
106 if (!PdoExtension)
107 {
108 /* Let the debugger know */
109 DPRINT1("Pci: Could not find PDO for device @ %x.%x.%x\n",
110 BusNumber,
111 PciSlot.u.bits.DeviceNumber,
112 PciSlot.u.bits.FunctionNumber);
113 }
114
115 /* If the search found something, this is non-NULL, otherwise it's NULL */
116 return PdoExtension;
117 }
118
119 NTSTATUS
120 NTAPI
PciAssignSlotResources(IN PUNICODE_STRING RegistryPath,IN PUNICODE_STRING DriverClassName OPTIONAL,IN PDRIVER_OBJECT DriverObject,IN PDEVICE_OBJECT DeviceObject,IN INTERFACE_TYPE BusType,IN ULONG BusNumber,IN ULONG SlotNumber,IN OUT PCM_RESOURCE_LIST * AllocatedResources)121 PciAssignSlotResources(IN PUNICODE_STRING RegistryPath,
122 IN PUNICODE_STRING DriverClassName OPTIONAL,
123 IN PDRIVER_OBJECT DriverObject,
124 IN PDEVICE_OBJECT DeviceObject,
125 IN INTERFACE_TYPE BusType,
126 IN ULONG BusNumber,
127 IN ULONG SlotNumber,
128 IN OUT PCM_RESOURCE_LIST *AllocatedResources)
129 {
130 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList = NULL;
131 PCM_RESOURCE_LIST Resources = NULL;
132 PCI_COMMON_HEADER PciData;
133 PPCI_PDO_EXTENSION PdoExtension;
134 NTSTATUS Status;
135 PDEVICE_OBJECT ExistingDeviceObject;
136 PAGED_CODE();
137 ASSERT(PcipSavedAssignSlotResources);
138 ASSERT(BusType == PCIBus);
139
140 /* Assume no resources */
141 *AllocatedResources = NULL;
142
143 /* Find the PDO for this slot and make sure it exists and is started */
144 PdoExtension = PciFindPdoByLocation(BusNumber, SlotNumber);
145 if (!PdoExtension) return STATUS_DEVICE_DOES_NOT_EXIST;
146 if (PdoExtension->DeviceState == PciNotStarted) return STATUS_INVALID_OWNER;
147
148 /* Acquire the global lock while we attempt to assign resources */
149 KeEnterCriticalRegion();
150 KeWaitForSingleObject(&PciGlobalLock, Executive, KernelMode, FALSE, NULL);
151 do
152 {
153 /* Make sure we're not on the PDO for some reason */
154 ASSERT(DeviceObject != PdoExtension->PhysicalDeviceObject);
155
156 /* Read the PCI header and cache the routing information */
157 PciReadDeviceConfig(PdoExtension, &PciData, 0, PCI_COMMON_HDR_LENGTH);
158 Status = PciCacheLegacyDeviceRouting(DeviceObject,
159 BusNumber,
160 SlotNumber,
161 PciData.u.type0.InterruptLine,
162 PciData.u.type0.InterruptPin,
163 PciData.BaseClass,
164 PciData.SubClass,
165 PdoExtension->ParentFdoExtension->
166 PhysicalDeviceObject,
167 PdoExtension,
168 &ExistingDeviceObject);
169 if (NT_SUCCESS(Status))
170 {
171 /* Manually build the requirements for this device, and mark it legacy */
172 Status = PciBuildRequirementsList(PdoExtension,
173 &PciData,
174 &RequirementsList);
175 PdoExtension->LegacyDriver = TRUE;
176 if (NT_SUCCESS(Status))
177 {
178 /* Now call the legacy Pnp function to actually assign resources */
179 Status = IoAssignResources(RegistryPath,
180 DriverClassName,
181 DriverObject,
182 DeviceObject,
183 RequirementsList,
184 &Resources);
185 if (NT_SUCCESS(Status))
186 {
187 /* Resources are ready, so enable all decodes */
188 PdoExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE |
189 PCI_ENABLE_MEMORY_SPACE |
190 PCI_ENABLE_BUS_MASTER);
191
192 /* Compute new resource settings based on what PnP assigned */
193 PciComputeNewCurrentSettings(PdoExtension, Resources);
194
195 /* Set these new resources on the device */
196 Status = PciSetResources(PdoExtension, TRUE, TRUE);
197 if (NT_SUCCESS(Status))
198 {
199 /* Some work needs to happen here to handle this */
200 ASSERT(Resources->Count == 1);
201 //ASSERT(PartialList->Count > 0);
202
203 UNIMPLEMENTED;
204
205 /* Return the allocated resources, and success */
206 *AllocatedResources = Resources;
207 Resources = NULL;
208 Status = STATUS_SUCCESS;
209 }
210 }
211 else
212 {
213 /* If assignment failed, no resources should exist */
214 ASSERT(Resources == NULL);
215 }
216
217 /* If assignment succeed, then we are done */
218 if (NT_SUCCESS(Status)) break;
219 }
220
221 /* Otherwise, cache the new routing */
222 PciCacheLegacyDeviceRouting(ExistingDeviceObject,
223 BusNumber,
224 SlotNumber,
225 PciData.u.type0.InterruptLine,
226 PciData.u.type0.InterruptPin,
227 PciData.BaseClass,
228 PciData.SubClass,
229 PdoExtension->ParentFdoExtension->
230 PhysicalDeviceObject,
231 PdoExtension,
232 NULL);
233 }
234 } while (0);
235
236 /* Release the lock */
237 KeSetEvent(&PciGlobalLock, 0, 0);
238 KeLeaveCriticalRegion();
239
240 /* Free any temporary resource data and return the status */
241 if (RequirementsList) ExFreePoolWithTag(RequirementsList, 0);
242 if (Resources) ExFreePoolWithTag(Resources, 0);
243 return Status;
244 }
245
246 VOID
247 NTAPI
PciHookHal(VOID)248 PciHookHal(VOID)
249 {
250 /* Save the old HAL routines */
251 ASSERT(PcipSavedAssignSlotResources == NULL);
252 ASSERT(PcipSavedTranslateBusAddress == NULL);
253 PcipSavedAssignSlotResources = HalPciAssignSlotResources;
254 PcipSavedTranslateBusAddress = HalPciTranslateBusAddress;
255
256 /* Take over the HAL's Bus Handler functions */
257 // HalPciAssignSlotResources = PciAssignSlotResources;
258 HalPciTranslateBusAddress = PciTranslateBusAddress;
259 }
260
261 /* EOF */
262