/* pci_get_hp_params
 *
 * @dev - the pci_dev for which we want parameters
 * @hpp - allocated by the caller
 */
int pci_get_hp_params(struct pci_dev *dev, struct hotplug_params *hpp)
{
	acpi_status status;
	acpi_handle handle, phandle;
	struct pci_bus *pbus;

	handle = NULL;
	for (pbus = dev->bus; pbus; pbus = pbus->parent) {
		handle = acpi_pci_get_bridge_handle(pbus);
		if (handle)
			break;
	}

	/*
	 * _HPP settings apply to all child buses, until another _HPP is
	 * encountered. If we don't find an _HPP for the input pci dev,
	 * look for it in the parent device scope since that would apply to
	 * this pci dev.
	 */
	while (handle) {
		status = acpi_run_hpx(handle, hpp);
		if (ACPI_SUCCESS(status))
			return 0;
		status = acpi_run_hpp(handle, hpp);
		if (ACPI_SUCCESS(status))
			return 0;
		if (acpi_is_root_bridge(handle))
			break;
		status = acpi_get_parent(handle, &phandle);
		if (ACPI_FAILURE(status))
			break;
		handle = phandle;
	}
	return -ENODEV;
}
Esempio n. 2
0
/* acpi_get_hp_params_from_firmware
 *
 * @bus - the pci_bus of the bus on which the device is newly added
 * @hpp - allocated by the caller
 */
acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
        struct hotplug_params *hpp)
{
    acpi_status status = AE_NOT_FOUND;
    acpi_handle handle, phandle;
    struct pci_bus *pbus = bus;
    struct pci_dev *pdev;

    do {
        pdev = pbus->self;
        if (!pdev) {
            handle = acpi_get_pci_rootbridge_handle(
                pci_domain_nr(pbus), pbus->number);
            break;
        }
        handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
        pbus = pbus->parent;
    } while (!handle);

    /*
     * _HPP settings apply to all child buses, until another _HPP is
     * encountered. If we don't find an _HPP for the input pci dev,
     * look for it in the parent device scope since that would apply to
     * this pci dev. If we don't find any _HPP, use hardcoded defaults
     */
    while (handle) {
        status = acpi_run_hpx(handle, hpp);
        if (ACPI_SUCCESS(status))
            break;
        status = acpi_run_hpp(handle, hpp);
        if (ACPI_SUCCESS(status))
            break;
        if (acpi_root_bridge(handle))
            break;
        status = acpi_get_parent(handle, &phandle);
        if (ACPI_FAILURE(status))
            break;
        handle = phandle;
    }
    return status;
}
void pciehp_get_hp_params_from_firmware(struct pci_dev *dev,
		struct hotplug_params *hpp)
{
	acpi_status status = AE_NOT_FOUND;
	struct pci_dev *pdev = dev;

	/*
	 * _HPP settings apply to all child buses, until another _HPP is
	 * encountered. If we don't find an _HPP for the input pci dev,
	 * look for it in the parent device scope since that would apply to
	 * this pci dev. If we don't find any _HPP, use hardcoded defaults
	 */
	while (pdev && (ACPI_FAILURE(status))) {
		acpi_handle handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
		if (!handle)
			break;
		status = acpi_run_hpp(handle, hpp);
		if (!(pdev->bus->parent))
			break;
		/* Check if a parent object supports _HPP */
		pdev = pdev->bus->parent->self;
	}
}