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
9 /* INCLUDES *******************************************************************/
15 /* GLOBALS ********************************************************************/
17 pHalTranslateBusAddress PcipSavedTranslateBusAddress
;
18 pHalAssignSlotResources PcipSavedAssignSlotResources
;
20 /* FUNCTIONS ******************************************************************/
24 PciTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
26 IN PHYSICAL_ADDRESS BusAddress
,
27 OUT PULONG AddressSpace
,
28 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
30 UNREFERENCED_PARAMETER(InterfaceType
);
31 UNREFERENCED_PARAMETER(BusNumber
);
32 UNREFERENCED_PARAMETER(AddressSpace
);
34 /* FIXME: Broken translation */
36 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
42 PciFindPdoByLocation(IN ULONG BusNumber
,
45 PPCI_FDO_EXTENSION DeviceExtension
;
46 PPCI_PDO_EXTENSION PdoExtension
;
47 PCI_SLOT_NUMBER PciSlot
;
48 PciSlot
.u
.AsULONG
= SlotNumber
;
50 /* Acquire the global lock */
51 KeEnterCriticalRegion();
52 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
54 /* Now search for the extension */
55 DeviceExtension
= (PPCI_FDO_EXTENSION
)PciFdoExtensionListHead
.Next
;
56 while (DeviceExtension
)
58 /* If we found it, break out */
59 if (DeviceExtension
->BaseBus
== BusNumber
) break;
61 /* Move to the next device */
62 DeviceExtension
= (PPCI_FDO_EXTENSION
)DeviceExtension
->List
.Next
;
65 /* Release the global lock */
66 KeSetEvent(&PciGlobalLock
, IO_NO_INCREMENT
, FALSE
);
67 KeLeaveCriticalRegion();
69 /* Check if the device extension for the bus was found */
72 /* It wasn't, bail out */
73 DPRINT1("Pci: Could not find PCI bus FDO. Bus Number = 0x%x\n", BusNumber
);
77 /* Acquire this device's lock */
78 KeEnterCriticalRegion();
79 KeWaitForSingleObject(&DeviceExtension
->ChildListLock
,
85 /* Loop every child PDO */
86 for (PdoExtension
= DeviceExtension
->ChildPdoList
;
88 PdoExtension
= PdoExtension
->Next
)
90 /* Check if the function number and header data matches */
91 if ((PdoExtension
->Slot
.u
.bits
.FunctionNumber
== PciSlot
.u
.bits
.FunctionNumber
) &&
92 (PdoExtension
->Slot
.u
.bits
.DeviceNumber
== PciSlot
.u
.bits
.DeviceNumber
))
94 /* This is considered to be the same PDO */
95 ASSERT(PdoExtension
->Slot
.u
.AsULONG
== PciSlot
.u
.AsULONG
);
100 /* Release this device's lock */
101 KeSetEvent(&DeviceExtension
->ChildListLock
, IO_NO_INCREMENT
, FALSE
);
102 KeLeaveCriticalRegion();
104 /* Check if we found something */
107 /* Let the debugger know */
108 DPRINT1("Pci: Could not find PDO for device @ %x.%x.%x\n",
110 PciSlot
.u
.bits
.DeviceNumber
,
111 PciSlot
.u
.bits
.FunctionNumber
);
114 /* If the search found something, this is non-NULL, otherwise it's NULL */
120 PciAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
121 IN PUNICODE_STRING DriverClassName OPTIONAL
,
122 IN PDRIVER_OBJECT DriverObject
,
123 IN PDEVICE_OBJECT DeviceObject
,
124 IN INTERFACE_TYPE BusType
,
127 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
129 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
= NULL
;
130 PCM_RESOURCE_LIST Resources
= NULL
;
131 PCI_COMMON_HEADER PciData
;
132 PPCI_PDO_EXTENSION PdoExtension
;
134 PDEVICE_OBJECT ExistingDeviceObject
;
136 ASSERT(PcipSavedAssignSlotResources
);
137 ASSERT(BusType
== PCIBus
);
139 /* Assume no resources */
140 *AllocatedResources
= NULL
;
142 /* Find the PDO for this slot and make sure it exists and is started */
143 PdoExtension
= PciFindPdoByLocation(BusNumber
, SlotNumber
);
144 if (!PdoExtension
) return STATUS_DEVICE_DOES_NOT_EXIST
;
145 if (PdoExtension
->DeviceState
== PciNotStarted
) return STATUS_INVALID_OWNER
;
147 /* Acquire the global lock while we attempt to assign resources */
148 KeEnterCriticalRegion();
149 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
152 /* Make sure we're not on the PDO for some reason */
153 ASSERT(DeviceObject
!= PdoExtension
->PhysicalDeviceObject
);
155 /* Read the PCI header and cache the routing information */
156 PciReadDeviceConfig(PdoExtension
, &PciData
, 0, PCI_COMMON_HDR_LENGTH
);
157 Status
= PciCacheLegacyDeviceRouting(DeviceObject
,
160 PciData
.u
.type0
.InterruptLine
,
161 PciData
.u
.type0
.InterruptPin
,
164 PdoExtension
->ParentFdoExtension
->
165 PhysicalDeviceObject
,
167 &ExistingDeviceObject
);
168 if (NT_SUCCESS(Status
))
170 /* Manually build the requirements for this device, and mark it legacy */
171 Status
= PciBuildRequirementsList(PdoExtension
,
174 PdoExtension
->LegacyDriver
= TRUE
;
175 if (NT_SUCCESS(Status
))
177 /* Now call the legacy Pnp function to actually assign resources */
178 Status
= IoAssignResources(RegistryPath
,
184 if (NT_SUCCESS(Status
))
186 /* Resources are ready, so enable all decodes */
187 PdoExtension
->CommandEnables
|= (PCI_ENABLE_IO_SPACE
|
188 PCI_ENABLE_MEMORY_SPACE
|
189 PCI_ENABLE_BUS_MASTER
);
191 /* Compute new resource settings based on what PnP assigned */
192 PciComputeNewCurrentSettings(PdoExtension
, Resources
);
194 /* Set these new resources on the device */
195 Status
= PciSetResources(PdoExtension
, TRUE
, TRUE
);
196 if (NT_SUCCESS(Status
))
198 /* Some work needs to happen here to handle this */
199 ASSERT(Resources
->Count
== 1);
200 //ASSERT(PartialList->Count > 0);
204 /* Return the allocated resources, and success */
205 *AllocatedResources
= Resources
;
207 Status
= STATUS_SUCCESS
;
212 /* If assignment failed, no resources should exist */
213 ASSERT(Resources
== NULL
);
216 /* If assignment succeeed, then we are done */
217 if (NT_SUCCESS(Status
)) break;
220 /* Otherwise, cache the new routing */
221 PciCacheLegacyDeviceRouting(ExistingDeviceObject
,
224 PciData
.u
.type0
.InterruptLine
,
225 PciData
.u
.type0
.InterruptPin
,
228 PdoExtension
->ParentFdoExtension
->
229 PhysicalDeviceObject
,
235 /* Release the lock */
236 KeSetEvent(&PciGlobalLock
, 0, 0);
237 KeLeaveCriticalRegion();
239 /* Free any temporary resource data and return the status */
240 if (RequirementsList
) ExFreePoolWithTag(RequirementsList
, 0);
241 if (Resources
) ExFreePoolWithTag(Resources
, 0);
249 /* Save the old HAL routines */
250 ASSERT(PcipSavedAssignSlotResources
== NULL
);
251 ASSERT(PcipSavedTranslateBusAddress
== NULL
);
252 PcipSavedAssignSlotResources
= HalPciAssignSlotResources
;
253 PcipSavedTranslateBusAddress
= HalPciTranslateBusAddress
;
255 /* Take over the HAL's Bus Handler functions */
256 // HalPciAssignSlotResources = PciAssignSlotResources;
257 HalPciTranslateBusAddress
= PciTranslateBusAddress
;