mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-27 22:51:31 +00:00
c100beb9cc
Per the PCI Firmware spec, r3.2, sec 4.5.1, the OS can request control of AER via bit 3 of the _OSC Control Field. In the returned value of the Control Field: The firmware sets [bit 3] to 1 to grant control over PCI Express Advanced Error Reporting. ... after control is transferred to the operating system, firmware must not modify the Advanced Error Reporting Capability. If control of this feature was requested and denied or was not requested, firmware returns this bit set to 0. Previously the pci_root driver looked at the HEST FIRMWARE_FIRST bit to determine whether to request ownership of the AER Capability. This was based on ACPI spec v6.3, sec 18.3.2.4, and similar sections, which say things like: Bit [0] - FIRMWARE_FIRST: If set, indicates that system firmware will handle errors from this source first. Bit [1] - GLOBAL: If set, indicates that the settings contained in this structure apply globally to all PCI Express Devices. These ACPI references don't say anything about ownership of the AER Capability. Remove use of the FIRMWARE_FIRST bit and rely only on the _OSC bit to determine whether we have control of the AER Capability. Link: https://lore.kernel.org/r/20181115231605.24352-1-mr.nuke.me@gmail.com/ v1 Link: https://lore.kernel.org/r/20190326172343.28946-1-mr.nuke.me@gmail.com/ v2 Link: https://lore.kernel.org/r/67af2931705bed9a588b5a39d369cb70b9942190.1587925636.git.sathyanarayanan.kuppuswamy@linux.intel.com [bhelgaas: commit log, note: Alex posted this identical patch 18 months ago, and I failed to apply it then, so I made him the author, added links to his postings, and added his Signed-off-by] Signed-off-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Jon Derrick <jonathan.derrick@intel.com>
128 lines
3.6 KiB
C
128 lines
3.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* File pci-acpi.h
|
|
*
|
|
* Copyright (C) 2004 Intel
|
|
* Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
|
|
*/
|
|
|
|
#ifndef _PCI_ACPI_H_
|
|
#define _PCI_ACPI_H_
|
|
|
|
#include <linux/acpi.h>
|
|
|
|
#ifdef CONFIG_ACPI
|
|
extern acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev);
|
|
static inline acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
|
|
{
|
|
return acpi_remove_pm_notifier(dev);
|
|
}
|
|
extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
|
|
struct pci_dev *pci_dev);
|
|
static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
|
|
{
|
|
return acpi_remove_pm_notifier(dev);
|
|
}
|
|
extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
|
|
|
|
struct pci_ecam_ops;
|
|
extern int pci_mcfg_lookup(struct acpi_pci_root *root, struct resource *cfgres,
|
|
struct pci_ecam_ops **ecam_ops);
|
|
|
|
static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
|
|
{
|
|
struct pci_bus *pbus = pdev->bus;
|
|
|
|
/* Find a PCI root bus */
|
|
while (!pci_is_root_bus(pbus))
|
|
pbus = pbus->parent;
|
|
|
|
return ACPI_HANDLE(pbus->bridge);
|
|
}
|
|
|
|
static inline acpi_handle acpi_pci_get_bridge_handle(struct pci_bus *pbus)
|
|
{
|
|
struct device *dev;
|
|
|
|
if (pci_is_root_bus(pbus))
|
|
dev = pbus->bridge;
|
|
else {
|
|
/* If pbus is a virtual bus, there is no bridge to it */
|
|
if (!pbus->self)
|
|
return NULL;
|
|
|
|
dev = &pbus->self->dev;
|
|
}
|
|
|
|
return ACPI_HANDLE(dev);
|
|
}
|
|
|
|
struct acpi_pci_root;
|
|
struct acpi_pci_root_ops;
|
|
|
|
struct acpi_pci_root_info {
|
|
struct acpi_pci_root *root;
|
|
struct acpi_device *bridge;
|
|
struct acpi_pci_root_ops *ops;
|
|
struct list_head resources;
|
|
char name[16];
|
|
};
|
|
|
|
struct acpi_pci_root_ops {
|
|
struct pci_ops *pci_ops;
|
|
int (*init_info)(struct acpi_pci_root_info *info);
|
|
void (*release_info)(struct acpi_pci_root_info *info);
|
|
int (*prepare_resources)(struct acpi_pci_root_info *info);
|
|
};
|
|
|
|
extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info);
|
|
extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root,
|
|
struct acpi_pci_root_ops *ops,
|
|
struct acpi_pci_root_info *info,
|
|
void *sd);
|
|
|
|
void acpi_pci_add_bus(struct pci_bus *bus);
|
|
void acpi_pci_remove_bus(struct pci_bus *bus);
|
|
|
|
#ifdef CONFIG_ACPI_PCI_SLOT
|
|
void acpi_pci_slot_init(void);
|
|
void acpi_pci_slot_enumerate(struct pci_bus *bus);
|
|
void acpi_pci_slot_remove(struct pci_bus *bus);
|
|
#else
|
|
static inline void acpi_pci_slot_init(void) { }
|
|
static inline void acpi_pci_slot_enumerate(struct pci_bus *bus) { }
|
|
static inline void acpi_pci_slot_remove(struct pci_bus *bus) { }
|
|
#endif
|
|
|
|
#ifdef CONFIG_HOTPLUG_PCI_ACPI
|
|
void acpiphp_init(void);
|
|
void acpiphp_enumerate_slots(struct pci_bus *bus);
|
|
void acpiphp_remove_slots(struct pci_bus *bus);
|
|
void acpiphp_check_host_bridge(struct acpi_device *adev);
|
|
#else
|
|
static inline void acpiphp_init(void) { }
|
|
static inline void acpiphp_enumerate_slots(struct pci_bus *bus) { }
|
|
static inline void acpiphp_remove_slots(struct pci_bus *bus) { }
|
|
static inline void acpiphp_check_host_bridge(struct acpi_device *adev) { }
|
|
#endif
|
|
|
|
extern const guid_t pci_acpi_dsm_guid;
|
|
#define IGNORE_PCI_BOOT_CONFIG_DSM 0x05
|
|
#define DEVICE_LABEL_DSM 0x07
|
|
#define RESET_DELAY_DSM 0x08
|
|
#define FUNCTION_DELAY_DSM 0x09
|
|
|
|
#ifdef CONFIG_PCIE_EDR
|
|
void pci_acpi_add_edr_notifier(struct pci_dev *pdev);
|
|
void pci_acpi_remove_edr_notifier(struct pci_dev *pdev);
|
|
#else
|
|
static inline void pci_acpi_add_edr_notifier(struct pci_dev *pdev) { }
|
|
static inline void pci_acpi_remove_edr_notifier(struct pci_dev *pdev) { }
|
|
#endif /* CONFIG_PCIE_EDR */
|
|
|
|
#else /* CONFIG_ACPI */
|
|
static inline void acpi_pci_add_bus(struct pci_bus *bus) { }
|
|
static inline void acpi_pci_remove_bus(struct pci_bus *bus) { }
|
|
#endif /* CONFIG_ACPI */
|
|
|
|
#endif /* _PCI_ACPI_H_ */
|