// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 /******************************************************************************* * * Module Name: hwpci - Obtain PCI bus, device, and function numbers * ******************************************************************************/ #include <acpi/acpi.h> #include "accommon.h" #define _COMPONENT … ACPI_MODULE_NAME("hwpci") /* PCI configuration space values */ #define PCI_CFG_HEADER_TYPE_REG … #define PCI_CFG_PRIMARY_BUS_NUMBER_REG … #define PCI_CFG_SECONDARY_BUS_NUMBER_REG … /* PCI header values */ #define PCI_HEADER_TYPE_MASK … #define PCI_TYPE_BRIDGE … #define PCI_TYPE_CARDBUS_BRIDGE … acpi_pci_device; /* Local prototypes */ static acpi_status acpi_hw_build_pci_list(acpi_handle root_pci_device, acpi_handle pci_region, struct acpi_pci_device **return_list_head); static acpi_status acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, struct acpi_pci_device *list_head); static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head); static acpi_status acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, acpi_handle pci_device, u16 *bus_number, u8 *is_bridge); /******************************************************************************* * * FUNCTION: acpi_hw_derive_pci_id * * PARAMETERS: pci_id - Initial values for the PCI ID. May be * modified by this function. * root_pci_device - A handle to a PCI device object. This * object must be a PCI Root Bridge having a * _HID value of either PNP0A03 or PNP0A08 * pci_region - 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 pci_id with the actual * values as determined by the hardware and operating system * configuration. * * The pci_id 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 acpi_os_derive_pci_id * interface since this feature is OS-independent. This module * specifically avoids any use of recursion by building a local * temporary device list. * ******************************************************************************/ acpi_status acpi_hw_derive_pci_id(struct acpi_pci_id *pci_id, acpi_handle root_pci_device, acpi_handle pci_region) { … } /******************************************************************************* * * FUNCTION: acpi_hw_build_pci_list * * PARAMETERS: root_pci_device - 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 * pci_region - A handle to the PCI configuration space * Operation Region * return_list_head - 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 acpi_hw_build_pci_list(acpi_handle root_pci_device, acpi_handle pci_region, struct acpi_pci_device **return_list_head) { … } /******************************************************************************* * * FUNCTION: acpi_hw_process_pci_list * * PARAMETERS: pci_id - Initial values for the PCI ID. May be * modified by this function. * list_head - Device list created by * acpi_hw_build_pci_list * * 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 acpi_hw_process_pci_list(struct acpi_pci_id *pci_id, struct acpi_pci_device *list_head) { … } /******************************************************************************* * * FUNCTION: acpi_hw_delete_pci_list * * PARAMETERS: list_head - Device list created by * acpi_hw_build_pci_list * * RETURN: None * * DESCRIPTION: Free the entire PCI list. * ******************************************************************************/ static void acpi_hw_delete_pci_list(struct acpi_pci_device *list_head) { … } /******************************************************************************* * * FUNCTION: acpi_hw_get_pci_device_info * * PARAMETERS: pci_id - Initial values for the PCI ID. May be * modified by this function. * pci_device - Handle for the PCI device object * bus_number - Where a PCI bridge bus number is returned * is_bridge - 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 acpi_hw_get_pci_device_info(struct acpi_pci_id *pci_id, acpi_handle pci_device, u16 *bus_number, u8 *is_bridge) { … }