static ACPI_STATUS AcpiHwBuildPciList ( ACPI_HANDLE RootPciDevice, ACPI_HANDLE PciRegion, ACPI_PCI_DEVICE **ReturnListHead) { ACPI_HANDLE CurrentDevice; ACPI_HANDLE ParentDevice; ACPI_STATUS Status; ACPI_PCI_DEVICE *ListElement; ACPI_PCI_DEVICE *ListHead = NULL; /* * Ascend namespace branch until the RootPciDevice is reached, building * a list of device nodes. Loop will exit when either the PCI device is * found, or the root of the namespace is reached. */ CurrentDevice = PciRegion; while (1) { Status = AcpiGetParent (CurrentDevice, &ParentDevice); if (ACPI_FAILURE (Status)) { /* Must delete the list before exit */ AcpiHwDeletePciList (*ReturnListHead); return (Status); } /* Finished when we reach the PCI root device (PNP0A03 or PNP0A08) */ if (ParentDevice == RootPciDevice) { *ReturnListHead = ListHead; return (AE_OK); } ListElement = ACPI_ALLOCATE (sizeof (ACPI_PCI_DEVICE)); if (!ListElement) { /* Must delete the list before exit */ AcpiHwDeletePciList (*ReturnListHead); return (AE_NO_MEMORY); } /* Put new element at the head of the list */ ListElement->Next = ListHead; ListElement->Device = ParentDevice; ListHead = ListElement; CurrentDevice = ParentDevice; } }
ACPI_STATUS AcpiHwDerivePciId ( ACPI_PCI_ID *PciId, ACPI_HANDLE RootPciDevice, ACPI_HANDLE PciRegion) { ACPI_STATUS Status; ACPI_PCI_DEVICE *ListHead; ACPI_FUNCTION_TRACE (HwDerivePciId); if (!PciId) { return_ACPI_STATUS (AE_BAD_PARAMETER); } /* Build a list of PCI devices, from PciRegion up to RootPciDevice */ Status = AcpiHwBuildPciList (RootPciDevice, PciRegion, &ListHead); if (ACPI_SUCCESS (Status)) { /* Walk the list, updating the PCI device/function/bus numbers */ Status = AcpiHwProcessPciList (PciId, ListHead); /* Delete the list */ AcpiHwDeletePciList (ListHead); } return_ACPI_STATUS (Status); }