--- old/usr/src/uts/intel/io/acpica/hardware/hwpci.c	jeu. déc. 26 13:49:13 2013
+++ /dev/null	jeu. déc. 26 13:49:12 2013
@@ -1,459 +0,0 @@
-/*******************************************************************************
- *
- * Module Name: hwpci - Obtain PCI bus, device, and function numbers
- *
- ******************************************************************************/
-
-/*
- * Copyright (C) 2000 - 2011, Intel Corp.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    substantially similar to the "NO WARRANTY" disclaimer below
- *    ("Disclaimer") and any redistribution must be conditioned upon
- *    including a substantially similar Disclaimer requirement for further
- *    binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGES.
- */
-
-#define __HWPCI_C__
-
-#include "acpi.h"
-#include "accommon.h"
-
-
-#define _COMPONENT          ACPI_NAMESPACE
-        ACPI_MODULE_NAME    ("hwpci")
-
-
-/* PCI configuration space values */
-
-#define PCI_CFG_HEADER_TYPE_REG             0x0E
-#define PCI_CFG_PRIMARY_BUS_NUMBER_REG      0x18
-#define PCI_CFG_SECONDARY_BUS_NUMBER_REG    0x19
-
-/* PCI header values */
-
-#define PCI_HEADER_TYPE_MASK                0x7F
-#define PCI_TYPE_BRIDGE                     0x01
-#define PCI_TYPE_CARDBUS_BRIDGE             0x02
-
-typedef struct acpi_pci_device
-{
-    ACPI_HANDLE             Device;
-    struct acpi_pci_device  *Next;
-
-} ACPI_PCI_DEVICE;
-
-
-/* Local prototypes */
-
-static ACPI_STATUS
-AcpiHwBuildPciList (
-    ACPI_HANDLE             RootPciDevice,
-    ACPI_HANDLE             PciRegion,
-    ACPI_PCI_DEVICE         **ReturnListHead);
-
-static ACPI_STATUS
-AcpiHwProcessPciList (
-    ACPI_PCI_ID             *PciId,
-    ACPI_PCI_DEVICE         *ListHead);
-
-static void
-AcpiHwDeletePciList (
-    ACPI_PCI_DEVICE         *ListHead);
-
-static ACPI_STATUS
-AcpiHwGetPciDeviceInfo (
-    ACPI_PCI_ID             *PciId,
-    ACPI_HANDLE             PciDevice,
-    UINT16                  *BusNumber,
-    BOOLEAN                 *IsBridge);
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiHwDerivePciId
- *
- * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
- *                                    modified by this function.
- *              RootPciDevice       - A handle to a PCI device object. This
- *                                    object must be a PCI Root Bridge having a
- *                                    _HID value of either PNP0A03 or PNP0A08
- *              PciRegion           - A handle to a PCI configuration space
- *                                    Operation Region being initialized
- *
- * RETURN:      Status
- *
- * DESCRIPTION: This function derives a full PCI ID for a PCI device,
- *              consisting of a Segment number, Bus number, Device number,
- *              and function code.
- *
- *              The PCI hardware dynamically configures PCI bus numbers
- *              depending on the bus topology discovered during system
- *              initialization. This function is invoked during configuration
- *              of a PCI_Config Operation Region in order to (possibly) update
- *              the Bus/Device/Function numbers in the PciId with the actual
- *              values as determined by the hardware and operating system
- *              configuration.
- *
- *              The PciId parameter is initially populated during the Operation
- *              Region initialization. This function is then called, and is
- *              will make any necessary modifications to the Bus, Device, or
- *              Function number PCI ID subfields as appropriate for the
- *              current hardware and OS configuration.
- *
- * NOTE:        Created 08/2010. Replaces the previous OSL AcpiOsDerivePciId
- *              interface since this feature is OS-independent. This module
- *              specifically avoids any use of recursion by building a local
- *              temporary device list.
- *
- ******************************************************************************/
-
-ACPI_STATUS
-AcpiHwDerivePciId (
-    ACPI_PCI_ID             *PciId,
-    ACPI_HANDLE             RootPciDevice,
-    ACPI_HANDLE             PciRegion)
-{
-    ACPI_STATUS             Status;
-    ACPI_PCI_DEVICE         *ListHead = NULL;
-
-
-    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);
-    }
-
-    /* Always delete the list */
-
-    AcpiHwDeletePciList (ListHead);
-    return_ACPI_STATUS (Status);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiHwBuildPciList
- *
- * PARAMETERS:  RootPciDevice       - A handle to a PCI device object. This
- *                                    object is guaranteed to be a PCI Root
- *                                    Bridge having a _HID value of either
- *                                    PNP0A03 or PNP0A08
- *              PciRegion           - A handle to the PCI configuration space
- *                                    Operation Region
- *              ReturnListHead      - Where the PCI device list is returned
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Builds a list of devices from the input PCI region up to the
- *              Root PCI device for this namespace subtree.
- *
- ******************************************************************************/
-
-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))
-        {
-            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)
-        {
-            return (AE_NO_MEMORY);
-        }
-
-        /* Put new element at the head of the list */
-
-        ListElement->Next = ListHead;
-        ListElement->Device = ParentDevice;
-        ListHead = ListElement;
-
-        CurrentDevice = ParentDevice;
-    }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiHwProcessPciList
- *
- * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
- *                                    modified by this function.
- *              ListHead            - Device list created by
- *                                    AcpiHwBuildPciList
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Walk downward through the PCI device list, getting the device
- *              info for each, via the PCI configuration space and updating
- *              the PCI ID as necessary. Deletes the list during traversal.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiHwProcessPciList (
-    ACPI_PCI_ID             *PciId,
-    ACPI_PCI_DEVICE         *ListHead)
-{
-    ACPI_STATUS             Status = AE_OK;
-    ACPI_PCI_DEVICE         *Info;
-    UINT16                  BusNumber;
-    BOOLEAN                 IsBridge = TRUE;
-
-
-    ACPI_FUNCTION_NAME (HwProcessPciList);
-
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-        "Input PciId:  Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n",
-        PciId->Segment, PciId->Bus, PciId->Device, PciId->Function));
-
-    BusNumber = PciId->Bus;
-
-    /*
-     * Descend down the namespace tree, collecting PCI device, function,
-     * and bus numbers. BusNumber is only important for PCI bridges.
-     * Algorithm: As we descend the tree, use the last valid PCI device,
-     * function, and bus numbers that are discovered, and assign them
-     * to the PCI ID for the target device.
-     */
-    Info = ListHead;
-    while (Info)
-    {
-        Status = AcpiHwGetPciDeviceInfo (PciId, Info->Device,
-            &BusNumber, &IsBridge);
-        if (ACPI_FAILURE (Status))
-        {
-            return_ACPI_STATUS (Status);
-        }
-
-        Info = Info->Next;
-    }
-
-    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
-        "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X "
-        "Status %X BusNumber %X IsBridge %X\n",
-        PciId->Segment, PciId->Bus, PciId->Device, PciId->Function,
-        Status, BusNumber, IsBridge));
-
-    return_ACPI_STATUS (AE_OK);
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiHwDeletePciList
- *
- * PARAMETERS:  ListHead            - Device list created by
- *                                    AcpiHwBuildPciList
- *
- * RETURN:      None
- *
- * DESCRIPTION: Free the entire PCI list.
- *
- ******************************************************************************/
-
-static void
-AcpiHwDeletePciList (
-    ACPI_PCI_DEVICE         *ListHead)
-{
-    ACPI_PCI_DEVICE         *Next;
-    ACPI_PCI_DEVICE         *Previous;
-
-
-    Next = ListHead;
-    while (Next)
-    {
-        Previous = Next;
-        Next = Previous->Next;
-        ACPI_FREE (Previous);
-    }
-}
-
-
-/*******************************************************************************
- *
- * FUNCTION:    AcpiHwGetPciDeviceInfo
- *
- * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
- *                                    modified by this function.
- *              PciDevice           - Handle for the PCI device object
- *              BusNumber           - Where a PCI bridge bus number is returned
- *              IsBridge            - Return value, indicates if this PCI
- *                                    device is a PCI bridge
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Get the device info for a single PCI device object. Get the
- *              _ADR (contains PCI device and function numbers), and for PCI
- *              bridge devices, get the bus number from PCI configuration
- *              space.
- *
- ******************************************************************************/
-
-static ACPI_STATUS
-AcpiHwGetPciDeviceInfo (
-    ACPI_PCI_ID             *PciId,
-    ACPI_HANDLE             PciDevice,
-    UINT16                  *BusNumber,
-    BOOLEAN                 *IsBridge)
-{
-    ACPI_STATUS             Status;
-    ACPI_OBJECT_TYPE        ObjectType;
-    UINT64                  ReturnValue;
-    UINT64                  PciValue;
-
-
-    /* We only care about objects of type Device */
-
-    Status = AcpiGetType (PciDevice, &ObjectType);
-    if (ACPI_FAILURE (Status))
-    {
-        return (Status);
-    }
-
-    if (ObjectType != ACPI_TYPE_DEVICE)
-    {
-        return (AE_OK);
-    }
-
-    /* We need an _ADR. Ignore device if not present */
-
-    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
-        PciDevice, &ReturnValue);
-    if (ACPI_FAILURE (Status))
-    {
-        return (AE_OK);
-    }
-
-    /*
-     * From _ADR, get the PCI Device and Function and
-     * update the PCI ID.
-     */
-    PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue));
-    PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue));
-
-    /*
-     * If the previous device was a bridge, use the previous
-     * device bus number
-     */
-    if (*IsBridge)
-    {
-        PciId->Bus = *BusNumber;
-    }
-
-    /*
-     * Get the bus numbers from PCI Config space:
-     *
-     * First, get the PCI HeaderType
-     */
-    *IsBridge = FALSE;
-    Status = AcpiOsReadPciConfiguration (PciId,
-        PCI_CFG_HEADER_TYPE_REG, &PciValue, 8);
-    if (ACPI_FAILURE (Status))
-    {
-        return (Status);
-    }
-
-    /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */
-
-    PciValue &= PCI_HEADER_TYPE_MASK;
-
-    if ((PciValue != PCI_TYPE_BRIDGE) &&
-        (PciValue != PCI_TYPE_CARDBUS_BRIDGE))
-    {
-        return (AE_OK);
-    }
-
-    /* Bridge: Get the Primary BusNumber */
-
-    Status = AcpiOsReadPciConfiguration (PciId,
-        PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8);
-    if (ACPI_FAILURE (Status))
-    {
-        return (Status);
-    }
-
-    *IsBridge = TRUE;
-    PciId->Bus = (UINT16) PciValue;
-
-    /* Bridge: Get the Secondary BusNumber */
-
-    Status = AcpiOsReadPciConfiguration (PciId,
-        PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8);
-    if (ACPI_FAILURE (Status))
-    {
-        return (Status);
-    }
-
-    *BusNumber = (UINT16) PciValue;
-    return (AE_OK);
-}
--- /dev/null	jeu. déc. 26 13:49:12 2013
+++ new/usr/src/common/acpica/components/hardware/hwpci.c	jeu. déc. 26 13:49:13 2013
@@ -0,0 +1,459 @@
+/*******************************************************************************
+ *
+ * Module Name: hwpci - Obtain PCI bus, device, and function numbers
+ *
+ ******************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2013, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#define __HWPCI_C__
+
+#include "acpi.h"
+#include "accommon.h"
+
+
+#define _COMPONENT          ACPI_NAMESPACE
+        ACPI_MODULE_NAME    ("hwpci")
+
+
+/* PCI configuration space values */
+
+#define PCI_CFG_HEADER_TYPE_REG             0x0E
+#define PCI_CFG_PRIMARY_BUS_NUMBER_REG      0x18
+#define PCI_CFG_SECONDARY_BUS_NUMBER_REG    0x19
+
+/* PCI header values */
+
+#define PCI_HEADER_TYPE_MASK                0x7F
+#define PCI_TYPE_BRIDGE                     0x01
+#define PCI_TYPE_CARDBUS_BRIDGE             0x02
+
+typedef struct acpi_pci_device
+{
+    ACPI_HANDLE             Device;
+    struct acpi_pci_device  *Next;
+
+} ACPI_PCI_DEVICE;
+
+
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiHwBuildPciList (
+    ACPI_HANDLE             RootPciDevice,
+    ACPI_HANDLE             PciRegion,
+    ACPI_PCI_DEVICE         **ReturnListHead);
+
+static ACPI_STATUS
+AcpiHwProcessPciList (
+    ACPI_PCI_ID             *PciId,
+    ACPI_PCI_DEVICE         *ListHead);
+
+static void
+AcpiHwDeletePciList (
+    ACPI_PCI_DEVICE         *ListHead);
+
+static ACPI_STATUS
+AcpiHwGetPciDeviceInfo (
+    ACPI_PCI_ID             *PciId,
+    ACPI_HANDLE             PciDevice,
+    UINT16                  *BusNumber,
+    BOOLEAN                 *IsBridge);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiHwDerivePciId
+ *
+ * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
+ *                                    modified by this function.
+ *              RootPciDevice       - A handle to a PCI device object. This
+ *                                    object must be a PCI Root Bridge having a
+ *                                    _HID value of either PNP0A03 or PNP0A08
+ *              PciRegion           - A handle to a PCI configuration space
+ *                                    Operation Region being initialized
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: This function derives a full PCI ID for a PCI device,
+ *              consisting of a Segment number, Bus number, Device number,
+ *              and function code.
+ *
+ *              The PCI hardware dynamically configures PCI bus numbers
+ *              depending on the bus topology discovered during system
+ *              initialization. This function is invoked during configuration
+ *              of a PCI_Config Operation Region in order to (possibly) update
+ *              the Bus/Device/Function numbers in the PciId with the actual
+ *              values as determined by the hardware and operating system
+ *              configuration.
+ *
+ *              The PciId parameter is initially populated during the Operation
+ *              Region initialization. This function is then called, and is
+ *              will make any necessary modifications to the Bus, Device, or
+ *              Function number PCI ID subfields as appropriate for the
+ *              current hardware and OS configuration.
+ *
+ * NOTE:        Created 08/2010. Replaces the previous OSL AcpiOsDerivePciId
+ *              interface since this feature is OS-independent. This module
+ *              specifically avoids any use of recursion by building a local
+ *              temporary device list.
+ *
+ ******************************************************************************/
+
+ACPI_STATUS
+AcpiHwDerivePciId (
+    ACPI_PCI_ID             *PciId,
+    ACPI_HANDLE             RootPciDevice,
+    ACPI_HANDLE             PciRegion)
+{
+    ACPI_STATUS             Status;
+    ACPI_PCI_DEVICE         *ListHead = NULL;
+
+
+    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);
+    }
+
+    /* Always delete the list */
+
+    AcpiHwDeletePciList (ListHead);
+    return_ACPI_STATUS (Status);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiHwBuildPciList
+ *
+ * PARAMETERS:  RootPciDevice       - A handle to a PCI device object. This
+ *                                    object is guaranteed to be a PCI Root
+ *                                    Bridge having a _HID value of either
+ *                                    PNP0A03 or PNP0A08
+ *              PciRegion           - A handle to the PCI configuration space
+ *                                    Operation Region
+ *              ReturnListHead      - Where the PCI device list is returned
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Builds a list of devices from the input PCI region up to the
+ *              Root PCI device for this namespace subtree.
+ *
+ ******************************************************************************/
+
+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))
+        {
+            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)
+        {
+            return (AE_NO_MEMORY);
+        }
+
+        /* Put new element at the head of the list */
+
+        ListElement->Next = ListHead;
+        ListElement->Device = ParentDevice;
+        ListHead = ListElement;
+
+        CurrentDevice = ParentDevice;
+    }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiHwProcessPciList
+ *
+ * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
+ *                                    modified by this function.
+ *              ListHead            - Device list created by
+ *                                    AcpiHwBuildPciList
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Walk downward through the PCI device list, getting the device
+ *              info for each, via the PCI configuration space and updating
+ *              the PCI ID as necessary. Deletes the list during traversal.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwProcessPciList (
+    ACPI_PCI_ID             *PciId,
+    ACPI_PCI_DEVICE         *ListHead)
+{
+    ACPI_STATUS             Status = AE_OK;
+    ACPI_PCI_DEVICE         *Info;
+    UINT16                  BusNumber;
+    BOOLEAN                 IsBridge = TRUE;
+
+
+    ACPI_FUNCTION_NAME (HwProcessPciList);
+
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+        "Input PciId:  Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X\n",
+        PciId->Segment, PciId->Bus, PciId->Device, PciId->Function));
+
+    BusNumber = PciId->Bus;
+
+    /*
+     * Descend down the namespace tree, collecting PCI device, function,
+     * and bus numbers. BusNumber is only important for PCI bridges.
+     * Algorithm: As we descend the tree, use the last valid PCI device,
+     * function, and bus numbers that are discovered, and assign them
+     * to the PCI ID for the target device.
+     */
+    Info = ListHead;
+    while (Info)
+    {
+        Status = AcpiHwGetPciDeviceInfo (PciId, Info->Device,
+            &BusNumber, &IsBridge);
+        if (ACPI_FAILURE (Status))
+        {
+            return (Status);
+        }
+
+        Info = Info->Next;
+    }
+
+    ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+        "Output PciId: Seg %4.4X Bus %4.4X Dev %4.4X Func %4.4X "
+        "Status %X BusNumber %X IsBridge %X\n",
+        PciId->Segment, PciId->Bus, PciId->Device, PciId->Function,
+        Status, BusNumber, IsBridge));
+
+    return (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiHwDeletePciList
+ *
+ * PARAMETERS:  ListHead            - Device list created by
+ *                                    AcpiHwBuildPciList
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Free the entire PCI list.
+ *
+ ******************************************************************************/
+
+static void
+AcpiHwDeletePciList (
+    ACPI_PCI_DEVICE         *ListHead)
+{
+    ACPI_PCI_DEVICE         *Next;
+    ACPI_PCI_DEVICE         *Previous;
+
+
+    Next = ListHead;
+    while (Next)
+    {
+        Previous = Next;
+        Next = Previous->Next;
+        ACPI_FREE (Previous);
+    }
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION:    AcpiHwGetPciDeviceInfo
+ *
+ * PARAMETERS:  PciId               - Initial values for the PCI ID. May be
+ *                                    modified by this function.
+ *              PciDevice           - Handle for the PCI device object
+ *              BusNumber           - Where a PCI bridge bus number is returned
+ *              IsBridge            - Return value, indicates if this PCI
+ *                                    device is a PCI bridge
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Get the device info for a single PCI device object. Get the
+ *              _ADR (contains PCI device and function numbers), and for PCI
+ *              bridge devices, get the bus number from PCI configuration
+ *              space.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiHwGetPciDeviceInfo (
+    ACPI_PCI_ID             *PciId,
+    ACPI_HANDLE             PciDevice,
+    UINT16                  *BusNumber,
+    BOOLEAN                 *IsBridge)
+{
+    ACPI_STATUS             Status;
+    ACPI_OBJECT_TYPE        ObjectType;
+    UINT64                  ReturnValue;
+    UINT64                  PciValue;
+
+
+    /* We only care about objects of type Device */
+
+    Status = AcpiGetType (PciDevice, &ObjectType);
+    if (ACPI_FAILURE (Status))
+    {
+        return (Status);
+    }
+
+    if (ObjectType != ACPI_TYPE_DEVICE)
+    {
+        return (AE_OK);
+    }
+
+    /* We need an _ADR. Ignore device if not present */
+
+    Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR,
+        PciDevice, &ReturnValue);
+    if (ACPI_FAILURE (Status))
+    {
+        return (AE_OK);
+    }
+
+    /*
+     * From _ADR, get the PCI Device and Function and
+     * update the PCI ID.
+     */
+    PciId->Device = ACPI_HIWORD (ACPI_LODWORD (ReturnValue));
+    PciId->Function = ACPI_LOWORD (ACPI_LODWORD (ReturnValue));
+
+    /*
+     * If the previous device was a bridge, use the previous
+     * device bus number
+     */
+    if (*IsBridge)
+    {
+        PciId->Bus = *BusNumber;
+    }
+
+    /*
+     * Get the bus numbers from PCI Config space:
+     *
+     * First, get the PCI HeaderType
+     */
+    *IsBridge = FALSE;
+    Status = AcpiOsReadPciConfiguration (PciId,
+        PCI_CFG_HEADER_TYPE_REG, &PciValue, 8);
+    if (ACPI_FAILURE (Status))
+    {
+        return (Status);
+    }
+
+    /* We only care about bridges (1=PciBridge, 2=CardBusBridge) */
+
+    PciValue &= PCI_HEADER_TYPE_MASK;
+
+    if ((PciValue != PCI_TYPE_BRIDGE) &&
+        (PciValue != PCI_TYPE_CARDBUS_BRIDGE))
+    {
+        return (AE_OK);
+    }
+
+    /* Bridge: Get the Primary BusNumber */
+
+    Status = AcpiOsReadPciConfiguration (PciId,
+        PCI_CFG_PRIMARY_BUS_NUMBER_REG, &PciValue, 8);
+    if (ACPI_FAILURE (Status))
+    {
+        return (Status);
+    }
+
+    *IsBridge = TRUE;
+    PciId->Bus = (UINT16) PciValue;
+
+    /* Bridge: Get the Secondary BusNumber */
+
+    Status = AcpiOsReadPciConfiguration (PciId,
+        PCI_CFG_SECONDARY_BUS_NUMBER_REG, &PciValue, 8);
+    if (ACPI_FAILURE (Status))
+    {
+        return (Status);
+    }
+
+    *BusNumber = (UINT16) PciValue;
+    return (AE_OK);
+}
