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 /* FIXME: Broken translation */
32 TranslatedAddress
->QuadPart
= BusAddress
.QuadPart
;
38 PciFindPdoByLocation(IN ULONG BusNumber
,
41 PPCI_FDO_EXTENSION DeviceExtension
;
42 PPCI_PDO_EXTENSION PdoExtension
;
43 PCI_SLOT_NUMBER PciSlot
;
44 PciSlot
.u
.AsULONG
= SlotNumber
;
46 /* Acquire the global lock */
47 KeEnterCriticalRegion();
48 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
50 /* Now search for the extension */
51 DeviceExtension
= (PPCI_FDO_EXTENSION
)PciFdoExtensionListHead
.Next
;
52 while (DeviceExtension
)
54 /* If we found it, break out */
55 if (DeviceExtension
->BaseBus
== BusNumber
) break;
57 /* Move to the next device */
58 DeviceExtension
= (PPCI_FDO_EXTENSION
)DeviceExtension
->List
.Next
;
61 /* Release the global lock */
62 KeSetEvent(&PciGlobalLock
, IO_NO_INCREMENT
, FALSE
);
63 KeLeaveCriticalRegion();
65 /* Check if the device extension for the bus was found */
68 /* It wasn't, bail out */
69 DPRINT1("Pci: Could not find PCI bus FDO. Bus Number = 0x%x\n", BusNumber
);
73 /* Acquire this device's lock */
74 KeEnterCriticalRegion();
75 KeWaitForSingleObject(&DeviceExtension
->ChildListLock
,
81 /* Loop every child PDO */
82 for (PdoExtension
= DeviceExtension
->ChildPdoList
;
84 PdoExtension
= PdoExtension
->Next
)
86 /* Check if the function number and header data matches */
87 if ((PdoExtension
->Slot
.u
.bits
.FunctionNumber
== PciSlot
.u
.bits
.FunctionNumber
) &&
88 (PdoExtension
->Slot
.u
.bits
.DeviceNumber
== PciSlot
.u
.bits
.DeviceNumber
))
90 /* This is considered to be the same PDO */
91 ASSERT(PdoExtension
->Slot
.u
.AsULONG
== PciSlot
.u
.AsULONG
);
96 /* Release this device's lock */
97 KeSetEvent(&DeviceExtension
->ChildListLock
, IO_NO_INCREMENT
, FALSE
);
98 KeLeaveCriticalRegion();
100 /* Check if we found something */
103 /* Let the debugger know */
104 DPRINT1("Pci: Could not find PDO for device @ %x.%x.%x\n",
106 PciSlot
.u
.bits
.DeviceNumber
,
107 PciSlot
.u
.bits
.FunctionNumber
);
110 /* If the search found something, this is non-NULL, otherwise it's NULL */
116 PciAssignSlotResources(IN PUNICODE_STRING RegistryPath
,
117 IN PUNICODE_STRING DriverClassName OPTIONAL
,
118 IN PDRIVER_OBJECT DriverObject
,
119 IN PDEVICE_OBJECT DeviceObject
,
120 IN INTERFACE_TYPE BusType
,
123 IN OUT PCM_RESOURCE_LIST
*AllocatedResources
)
125 PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList
= NULL
;
126 PCM_RESOURCE_LIST Resources
= NULL
;
127 PCI_COMMON_HEADER PciData
;
128 PPCI_PDO_EXTENSION PdoExtension
;
130 PDEVICE_OBJECT ExistingDeviceObject
;
132 ASSERT(PcipSavedAssignSlotResources
);
133 ASSERT(BusType
== PCIBus
);
135 /* Assume no resources */
136 *AllocatedResources
= NULL
;
138 /* Find the PDO for this slot and make sure it exists and is started */
139 PdoExtension
= PciFindPdoByLocation(BusNumber
, SlotNumber
);
140 if (!PdoExtension
) return STATUS_DEVICE_DOES_NOT_EXIST
;
141 if (PdoExtension
->DeviceState
== PciNotStarted
) return STATUS_INVALID_OWNER
;
143 /* Acquire the global lock while we attempt to assign resources */
144 KeEnterCriticalRegion();
145 KeWaitForSingleObject(&PciGlobalLock
, Executive
, KernelMode
, FALSE
, NULL
);
148 /* Make sure we're not on the PDO for some reason */
149 ASSERT(DeviceObject
!= PdoExtension
->PhysicalDeviceObject
);
151 /* Read the PCI header and cache the routing information */
152 PciReadDeviceConfig(PdoExtension
, &PciData
, 0, PCI_COMMON_HDR_LENGTH
);
153 Status
= PciCacheLegacyDeviceRouting(DeviceObject
,
156 PciData
.u
.type0
.InterruptLine
,
157 PciData
.u
.type0
.InterruptPin
,
160 PdoExtension
->ParentFdoExtension
->
161 PhysicalDeviceObject
,
163 &ExistingDeviceObject
);
164 if (NT_SUCCESS(Status
))
166 /* Manually build the requirements for this device, and mark it legacy */
167 Status
= PciBuildRequirementsList(PdoExtension
,
170 PdoExtension
->LegacyDriver
= TRUE
;
171 if (NT_SUCCESS(Status
))
173 /* Now call the legacy Pnp function to actually assign resources */
174 Status
= IoAssignResources(RegistryPath
,
180 if (NT_SUCCESS(Status
))
182 /* Resources are ready, so enable all decodes */
183 PdoExtension
->CommandEnables
|= (PCI_ENABLE_IO_SPACE
|
184 PCI_ENABLE_MEMORY_SPACE
|
185 PCI_ENABLE_BUS_MASTER
);
187 /* Compute new resource settings based on what PnP assigned */
188 PciComputeNewCurrentSettings(PdoExtension
, Resources
);
190 /* Set these new resources on the device */
191 Status
= PciSetResources(PdoExtension
, TRUE
, TRUE
);
192 if (NT_SUCCESS(Status
))
194 /* Some work needs to happen here to handle this */
195 ASSERT(Resources
->Count
== 1);
196 //ASSERT(PartialList->Count > 0);
200 /* Return the allocated resources, and success */
201 *AllocatedResources
= Resources
;
203 Status
= STATUS_SUCCESS
;
208 /* If assignment failed, no resources should exist */
209 ASSERT(Resources
== NULL
);
212 /* If assignment succeeed, then we are done */
213 if (NT_SUCCESS(Status
)) break;
216 /* Otherwise, cache the new routing */
217 PciCacheLegacyDeviceRouting(ExistingDeviceObject
,
220 PciData
.u
.type0
.InterruptLine
,
221 PciData
.u
.type0
.InterruptPin
,
224 PdoExtension
->ParentFdoExtension
->
225 PhysicalDeviceObject
,
231 /* Release the lock */
232 KeSetEvent(&PciGlobalLock
, 0, 0);
233 KeLeaveCriticalRegion();
235 /* Free any temporary resource data and return the status */
236 if (RequirementsList
) ExFreePoolWithTag(RequirementsList
, 0);
237 if (Resources
) ExFreePoolWithTag(Resources
, 0);
245 /* Save the old HAL routines */
246 ASSERT(PcipSavedAssignSlotResources
== NULL
);
247 ASSERT(PcipSavedTranslateBusAddress
== NULL
);
248 PcipSavedAssignSlotResources
= HalPciAssignSlotResources
;
249 PcipSavedTranslateBusAddress
= HalPciTranslateBusAddress
;
251 /* Take over the HAL's Bus Handler functions */
252 // HalPciAssignSlotResources = PciAssignSlotResources;
253 HalPciTranslateBusAddress
= PciTranslateBusAddress
;