/* GLOBALS ********************************************************************/
+pHalTranslateBusAddress PcipSavedTranslateBusAddress;
+pHalAssignSlotResources PcipSavedAssignSlotResources;
+
/* FUNCTIONS ******************************************************************/
+BOOLEAN
+NTAPI
+PciTranslateBusAddress(IN INTERFACE_TYPE InterfaceType,
+ IN ULONG BusNumber,
+ IN PHYSICAL_ADDRESS BusAddress,
+ OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress)
+{
+ UNREFERENCED_PARAMETER(InterfaceType);
+ UNREFERENCED_PARAMETER(BusNumber);
+ UNREFERENCED_PARAMETER(AddressSpace);
+
+ /* FIXME: Broken translation */
+ UNIMPLEMENTED;
+ TranslatedAddress->QuadPart = BusAddress.QuadPart;
+ return TRUE;
+}
+
+PPCI_PDO_EXTENSION
+NTAPI
+PciFindPdoByLocation(IN ULONG BusNumber,
+ IN ULONG SlotNumber)
+{
+ PPCI_FDO_EXTENSION DeviceExtension;
+ PPCI_PDO_EXTENSION PdoExtension;
+ PCI_SLOT_NUMBER PciSlot;
+ PciSlot.u.AsULONG = SlotNumber;
+
+ /* Acquire the global lock */
+ KeEnterCriticalRegion();
+ KeWaitForSingleObject(&PciGlobalLock, Executive, KernelMode, FALSE, NULL);
+
+ /* Now search for the extension */
+ DeviceExtension = (PPCI_FDO_EXTENSION)PciFdoExtensionListHead.Next;
+ while (DeviceExtension)
+ {
+ /* If we found it, break out */
+ if (DeviceExtension->BaseBus == BusNumber) break;
+
+ /* Move to the next device */
+ DeviceExtension = (PPCI_FDO_EXTENSION)DeviceExtension->List.Next;
+ }
+
+ /* Release the global lock */
+ KeSetEvent(&PciGlobalLock, IO_NO_INCREMENT, FALSE);
+ KeLeaveCriticalRegion();
+
+ /* Check if the device extension for the bus was found */
+ if (!DeviceExtension)
+ {
+ /* It wasn't, bail out */
+ DPRINT1("Pci: Could not find PCI bus FDO. Bus Number = 0x%x\n", BusNumber);
+ return NULL;
+ }
+
+ /* Acquire this device's lock */
+ KeEnterCriticalRegion();
+ KeWaitForSingleObject(&DeviceExtension->ChildListLock,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ /* Loop every child PDO */
+ for (PdoExtension = DeviceExtension->ChildPdoList;
+ PdoExtension;
+ PdoExtension = PdoExtension->Next)
+ {
+ /* Check if the function number and header data matches */
+ if ((PdoExtension->Slot.u.bits.FunctionNumber == PciSlot.u.bits.FunctionNumber) &&
+ (PdoExtension->Slot.u.bits.DeviceNumber == PciSlot.u.bits.DeviceNumber))
+ {
+ /* This is considered to be the same PDO */
+ ASSERT(PdoExtension->Slot.u.AsULONG == PciSlot.u.AsULONG);
+ break;
+ }
+ }
+
+ /* Release this device's lock */
+ KeSetEvent(&DeviceExtension->ChildListLock, IO_NO_INCREMENT, FALSE);
+ KeLeaveCriticalRegion();
+
+ /* Check if we found something */
+ if (!PdoExtension)
+ {
+ /* Let the debugger know */
+ DPRINT1("Pci: Could not find PDO for device @ %x.%x.%x\n",
+ BusNumber,
+ PciSlot.u.bits.DeviceNumber,
+ PciSlot.u.bits.FunctionNumber);
+ }
+
+ /* If the search found something, this is non-NULL, otherwise it's NULL */
+ return PdoExtension;
+}
+
+NTSTATUS
+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)
+{
+ PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList = NULL;
+ PCM_RESOURCE_LIST Resources = NULL;
+ PCI_COMMON_HEADER PciData;
+ PPCI_PDO_EXTENSION PdoExtension;
+ NTSTATUS Status;
+ PDEVICE_OBJECT ExistingDeviceObject;
+ PAGED_CODE();
+ ASSERT(PcipSavedAssignSlotResources);
+ ASSERT(BusType == PCIBus);
+
+ /* Assume no resources */
+ *AllocatedResources = NULL;
+
+ /* Find the PDO for this slot and make sure it exists and is started */
+ PdoExtension = PciFindPdoByLocation(BusNumber, SlotNumber);
+ if (!PdoExtension) return STATUS_DEVICE_DOES_NOT_EXIST;
+ if (PdoExtension->DeviceState == PciNotStarted) return STATUS_INVALID_OWNER;
+
+ /* Acquire the global lock while we attempt to assign resources */
+ KeEnterCriticalRegion();
+ KeWaitForSingleObject(&PciGlobalLock, Executive, KernelMode, FALSE, NULL);
+ do
+ {
+ /* Make sure we're not on the PDO for some reason */
+ ASSERT(DeviceObject != PdoExtension->PhysicalDeviceObject);
+
+ /* Read the PCI header and cache the routing information */
+ PciReadDeviceConfig(PdoExtension, &PciData, 0, PCI_COMMON_HDR_LENGTH);
+ Status = PciCacheLegacyDeviceRouting(DeviceObject,
+ BusNumber,
+ SlotNumber,
+ PciData.u.type0.InterruptLine,
+ PciData.u.type0.InterruptPin,
+ PciData.BaseClass,
+ PciData.SubClass,
+ PdoExtension->ParentFdoExtension->
+ PhysicalDeviceObject,
+ PdoExtension,
+ &ExistingDeviceObject);
+ if (NT_SUCCESS(Status))
+ {
+ /* Manually build the requirements for this device, and mark it legacy */
+ Status = PciBuildRequirementsList(PdoExtension,
+ &PciData,
+ &RequirementsList);
+ PdoExtension->LegacyDriver = TRUE;
+ if (NT_SUCCESS(Status))
+ {
+ /* Now call the legacy Pnp function to actually assign resources */
+ Status = IoAssignResources(RegistryPath,
+ DriverClassName,
+ DriverObject,
+ DeviceObject,
+ RequirementsList,
+ &Resources);
+ if (NT_SUCCESS(Status))
+ {
+ /* Resources are ready, so enable all decodes */
+ PdoExtension->CommandEnables |= (PCI_ENABLE_IO_SPACE |
+ PCI_ENABLE_MEMORY_SPACE |
+ PCI_ENABLE_BUS_MASTER);
+
+ /* Compute new resource settings based on what PnP assigned */
+ PciComputeNewCurrentSettings(PdoExtension, Resources);
+
+ /* Set these new resources on the device */
+ Status = PciSetResources(PdoExtension, TRUE, TRUE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Some work needs to happen here to handle this */
+ ASSERT(Resources->Count == 1);
+ //ASSERT(PartialList->Count > 0);
+
+ UNIMPLEMENTED;
+
+ /* Return the allocated resources, and success */
+ *AllocatedResources = Resources;
+ Resources = NULL;
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* If assignment failed, no resources should exist */
+ ASSERT(Resources == NULL);
+ }
+
+ /* If assignment succeeed, then we are done */
+ if (NT_SUCCESS(Status)) break;
+ }
+
+ /* Otherwise, cache the new routing */
+ PciCacheLegacyDeviceRouting(ExistingDeviceObject,
+ BusNumber,
+ SlotNumber,
+ PciData.u.type0.InterruptLine,
+ PciData.u.type0.InterruptPin,
+ PciData.BaseClass,
+ PciData.SubClass,
+ PdoExtension->ParentFdoExtension->
+ PhysicalDeviceObject,
+ PdoExtension,
+ NULL);
+ }
+ } while (0);
+
+ /* Release the lock */
+ KeSetEvent(&PciGlobalLock, 0, 0);
+ KeLeaveCriticalRegion();
+
+ /* Free any temporary resource data and return the status */
+ if (RequirementsList) ExFreePoolWithTag(RequirementsList, 0);
+ if (Resources) ExFreePoolWithTag(Resources, 0);
+ return Status;
+}
+
+VOID
+NTAPI
+PciHookHal(VOID)
+{
+ /* Save the old HAL routines */
+ ASSERT(PcipSavedAssignSlotResources == NULL);
+ ASSERT(PcipSavedTranslateBusAddress == NULL);
+ PcipSavedAssignSlotResources = HalPciAssignSlotResources;
+ PcipSavedTranslateBusAddress = HalPciTranslateBusAddress;
+
+ /* Take over the HAL's Bus Handler functions */
+// HalPciAssignSlotResources = PciAssignSlotResources;
+ HalPciTranslateBusAddress = PciTranslateBusAddress;
+}
+
/* EOF */