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 *******************************************************************/
16 /* GLOBALS ********************************************************************/
18 pHalTranslateBusAddress PcipSavedTranslateBusAddress
;
19 pHalAssignSlotResources PcipSavedAssignSlotResources
;
21 /* FUNCTIONS ******************************************************************/
25 PciTranslateBusAddress(IN INTERFACE_TYPE InterfaceType
,
27 IN PHYSICAL_ADDRESS BusAddress
,
28 OUT PULONG AddressSpace
,
29 OUT PPHYSICAL_ADDRESS TranslatedAddress
)
31 UNREFERENCED_PARAMETER(InterfaceType
);
32 UNREFERENCED_PARAMETER(BusNumber
);
33 UNREFERENCED_PARAMETER(AddressSpace
);
35 /* FIXME: Broken translation */
37 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
43 PciFindPdoByLocation(IN ULONG BusNumber
,
46 PPCI_FDO_EXTENSION DeviceExtension
;
47 PPCI_PDO_EXTENSION PdoExtension
;
48 PCI_SLOT_NUMBER PciSlot
;
49 PciSlot
.u
.AsULONG
= SlotNumber
;
51 /* Acquire the global lock */
52 KeEnterCriticalRegion();
53 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
55 /* Now search for the extension */
56 DeviceExtension
= (PPCI_FDO_EXTENSION
)PciFdoExtensionListHead
.Next
;
57 while (DeviceExtension
)
59 /* If we found it, break out */
60 if (DeviceExtension
->BaseBus
== BusNumber
) break;
62 /* Move to the next device */
63 DeviceExtension
= (PPCI_FDO_EXTENSION
)DeviceExtension
->List
.Next
;
66 /* Release the global lock */
67 KeSetEvent(&PciGlobalLock
, IO_NO_INCREMENT
, FALSE
);
68 KeLeaveCriticalRegion();
70 /* Check if the device extension for the bus was found */
73 /* It wasn't, bail out */
74 DPRINT1("Pci: Could not find PCI bus FDO. Bus Number = 0x%x\n", BusNumber
);
78 /* Acquire this device's lock */
79 KeEnterCriticalRegion();
80 KeWaitForSingleObject(&DeviceExtension
->ChildListLock
,
86 /* Loop every child PDO */
87 for (PdoExtension
= DeviceExtension
->ChildPdoList
;
89 PdoExtension
= PdoExtension
->Next
)
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
))
95 /* This is considered to be the same PDO */
96 ASSERT(PdoExtension
->Slot
.u
.AsULONG
== PciSlot
.u
.AsULONG
);
101 /* Release this device's lock */
102 KeSetEvent(&DeviceExtension
->ChildListLock
, IO_NO_INCREMENT
, FALSE
);
103 KeLeaveCriticalRegion();
105 /* Check if we found something */
108 /* Let the debugger know */
109 DPRINT1("Pci: Could not find PDO for device @ %x.%x.%x\n",
111 PciSlot
.u
.bits
.DeviceNumber
,
112 PciSlot
.u
.bits
.FunctionNumber
);
115 /* If the search found something, this is non-NULL, otherwise it's NULL */
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
,
128 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
130 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
= NULL
;
131 PCM_RESOURCE_LIST Resources
= NULL
;
132 PCI_COMMON_HEADER PciData
;
133 PPCI_PDO_EXTENSION PdoExtension
;
135 PDEVICE_OBJECT ExistingDeviceObject
;
137 ASSERT(PcipSavedAssignSlotResources
);
138 ASSERT(BusType
== PCIBus
);
140 /* Assume no resources */
141 *AllocatedResources
= NULL
;
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
;
148 /* Acquire the global lock while we attempt to assign resources */
149 KeEnterCriticalRegion();
150 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
153 /* Make sure we're not on the PDO for some reason */
154 ASSERT(DeviceObject
!= PdoExtension
->PhysicalDeviceObject
);
156 /* Read the PCI header and cache the routing information */
157 PciReadDeviceConfig(PdoExtension
, &PciData
, 0, PCI_COMMON_HDR_LENGTH
);
158 Status
= PciCacheLegacyDeviceRouting(DeviceObject
,
161 PciData
.u
.type0
.InterruptLine
,
162 PciData
.u
.type0
.InterruptPin
,
165 PdoExtension
->ParentFdoExtension
->
166 PhysicalDeviceObject
,
168 &ExistingDeviceObject
);
169 if (NT_SUCCESS(Status
))
171 /* Manually build the requirements for this device, and mark it legacy */
172 Status
= PciBuildRequirementsList(PdoExtension
,
175 PdoExtension
->LegacyDriver
= TRUE
;
176 if (NT_SUCCESS(Status
))
178 /* Now call the legacy Pnp function to actually assign resources */
179 Status
= IoAssignResources(RegistryPath
,
185 if (NT_SUCCESS(Status
))
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
);
192 /* Compute new resource settings based on what PnP assigned */
193 PciComputeNewCurrentSettings(PdoExtension
, Resources
);
195 /* Set these new resources on the device */
196 Status
= PciSetResources(PdoExtension
, TRUE
, TRUE
);
197 if (NT_SUCCESS(Status
))
199 /* Some work needs to happen here to handle this */
200 ASSERT(Resources
->Count
== 1);
201 //ASSERT(PartialList->Count > 0);
205 /* Return the allocated resources, and success */
206 *AllocatedResources
= Resources
;
208 Status
= STATUS_SUCCESS
;
213 /* If assignment failed, no resources should exist */
214 ASSERT(Resources
== NULL
);
217 /* If assignment succeed, then we are done */
218 if (NT_SUCCESS(Status
)) break;
221 /* Otherwise, cache the new routing */
222 PciCacheLegacyDeviceRouting(ExistingDeviceObject
,
225 PciData
.u
.type0
.InterruptLine
,
226 PciData
.u
.type0
.InterruptPin
,
229 PdoExtension
->ParentFdoExtension
->
230 PhysicalDeviceObject
,
236 /* Release the lock */
237 KeSetEvent(&PciGlobalLock
, 0, 0);
238 KeLeaveCriticalRegion();
240 /* Free any temporary resource data and return the status */
241 if (RequirementsList
) ExFreePoolWithTag(RequirementsList
, 0);
242 if (Resources
) ExFreePoolWithTag(Resources
, 0);
250 /* Save the old HAL routines */
251 ASSERT(PcipSavedAssignSlotResources
== NULL
);
252 ASSERT(PcipSavedTranslateBusAddress
== NULL
);
253 PcipSavedAssignSlotResources
= HalPciAssignSlotResources
;
254 PcipSavedTranslateBusAddress
= HalPciTranslateBusAddress
;
256 /* Take over the HAL's Bus Handler functions */
257 // HalPciAssignSlotResources = PciAssignSlotResources;
258 HalPciTranslateBusAddress
= PciTranslateBusAddress
;