Merge branch 'pci/enumeration'
- Unexport acpi_pci_osc_control_set() (Bjorn Helgaas) - Remove unnecessary osc_lock mutex (Bjorn Helgaas) - Clarify _OSC failure message (Bjorn Helgaas) - Fix pci-bridge-emul array overruns and improve safety (Russell King) - Fix pci_register_io_range() memory leak (Geert Uytterhoeven) * pci/enumeration: PCI: Fix pci_register_io_range() memory leak PCI: pci-bridge-emul: Fix array overruns, improve safety PCI/ACPI: Clarify message about _OSC failure PCI/ACPI: Remove unnecessary osc_lock PCI/ACPI: Make acpi_pci_osc_control_set() static
This commit is contained in:
Коммит
ce3e292eb7
|
@ -56,8 +56,6 @@ static struct acpi_scan_handler pci_root_handler = {
|
|||
},
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(osc_lock);
|
||||
|
||||
/**
|
||||
* acpi_is_root_bridge - determine whether an ACPI CA node is a PCI root bridge
|
||||
* @handle: the ACPI CA node in question.
|
||||
|
@ -223,12 +221,7 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
|
|||
|
||||
static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
mutex_lock(&osc_lock);
|
||||
status = acpi_pci_query_osc(root, flags, NULL);
|
||||
mutex_unlock(&osc_lock);
|
||||
return status;
|
||||
return acpi_pci_query_osc(root, flags, NULL);
|
||||
}
|
||||
|
||||
struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
|
||||
|
@ -353,10 +346,10 @@ EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
|
|||
* _OSC bits the BIOS has granted control of, but its contents are meaningless
|
||||
* on failure.
|
||||
**/
|
||||
acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
|
||||
static acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
|
||||
{
|
||||
struct acpi_pci_root *root;
|
||||
acpi_status status = AE_OK;
|
||||
acpi_status status;
|
||||
u32 ctrl, capbuf[3];
|
||||
|
||||
if (!mask)
|
||||
|
@ -370,18 +363,16 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
|
|||
if (!root)
|
||||
return AE_NOT_EXIST;
|
||||
|
||||
mutex_lock(&osc_lock);
|
||||
|
||||
*mask = ctrl | root->osc_control_set;
|
||||
/* No need to evaluate _OSC if the control was already granted. */
|
||||
if ((root->osc_control_set & ctrl) == ctrl)
|
||||
goto out;
|
||||
return AE_OK;
|
||||
|
||||
/* Need to check the available controls bits before requesting them. */
|
||||
while (*mask) {
|
||||
status = acpi_pci_query_osc(root, root->osc_support_set, mask);
|
||||
if (ACPI_FAILURE(status))
|
||||
goto out;
|
||||
return status;
|
||||
if (ctrl == *mask)
|
||||
break;
|
||||
decode_osc_control(root, "platform does not support",
|
||||
|
@ -392,21 +383,19 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
|
|||
if ((ctrl & req) != req) {
|
||||
decode_osc_control(root, "not requesting control; platform does not support",
|
||||
req & ~(ctrl));
|
||||
status = AE_SUPPORT;
|
||||
goto out;
|
||||
return AE_SUPPORT;
|
||||
}
|
||||
|
||||
capbuf[OSC_QUERY_DWORD] = 0;
|
||||
capbuf[OSC_SUPPORT_DWORD] = root->osc_support_set;
|
||||
capbuf[OSC_CONTROL_DWORD] = ctrl;
|
||||
status = acpi_pci_run_osc(handle, capbuf, mask);
|
||||
if (ACPI_SUCCESS(status))
|
||||
root->osc_control_set = *mask;
|
||||
out:
|
||||
mutex_unlock(&osc_lock);
|
||||
return status;
|
||||
if (ACPI_FAILURE(status))
|
||||
return status;
|
||||
|
||||
root->osc_control_set = *mask;
|
||||
return AE_OK;
|
||||
}
|
||||
EXPORT_SYMBOL(acpi_pci_osc_control_set);
|
||||
|
||||
static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
|
||||
bool is_pcie)
|
||||
|
@ -452,9 +441,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
|
|||
if ((status == AE_NOT_FOUND) && !is_pcie)
|
||||
return;
|
||||
|
||||
dev_info(&device->dev, "_OSC failed (%s)%s\n",
|
||||
acpi_format_exception(status),
|
||||
pcie_aspm_support_enabled() ? "; disabling ASPM" : "");
|
||||
dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n",
|
||||
acpi_format_exception(status));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -510,7 +498,7 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
|
|||
} else {
|
||||
decode_osc_control(root, "OS requested", requested);
|
||||
decode_osc_control(root, "platform willing to grant", control);
|
||||
dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n",
|
||||
dev_info(&device->dev, "_OSC: platform retains control of PCIe features (%s)\n",
|
||||
acpi_format_exception(status));
|
||||
|
||||
/*
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
#include "pci-bridge-emul.h"
|
||||
|
||||
#define PCI_BRIDGE_CONF_END PCI_STD_HEADER_SIZEOF
|
||||
#define PCI_CAP_PCIE_SIZEOF (PCI_EXP_SLTSTA2 + 2)
|
||||
#define PCI_CAP_PCIE_START PCI_BRIDGE_CONF_END
|
||||
#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_EXP_SLTSTA2 + 2)
|
||||
#define PCI_CAP_PCIE_END (PCI_CAP_PCIE_START + PCI_CAP_PCIE_SIZEOF)
|
||||
|
||||
/**
|
||||
* struct pci_bridge_reg_behavior - register bits behaviors
|
||||
|
@ -46,7 +47,8 @@ struct pci_bridge_reg_behavior {
|
|||
u32 w1c;
|
||||
};
|
||||
|
||||
static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
|
||||
static const
|
||||
struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = {
|
||||
[PCI_VENDOR_ID / 4] = { .ro = ~0 },
|
||||
[PCI_COMMAND / 4] = {
|
||||
.rw = (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
|
||||
|
@ -164,7 +166,8 @@ static const struct pci_bridge_reg_behavior pci_regs_behavior[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
|
||||
static const
|
||||
struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] = {
|
||||
[PCI_CAP_LIST_ID / 4] = {
|
||||
/*
|
||||
* Capability ID, Next Capability Pointer and
|
||||
|
@ -260,6 +263,8 @@ static const struct pci_bridge_reg_behavior pcie_cap_regs_behavior[] = {
|
|||
int pci_bridge_emul_init(struct pci_bridge_emul *bridge,
|
||||
unsigned int flags)
|
||||
{
|
||||
BUILD_BUG_ON(sizeof(bridge->conf) != PCI_BRIDGE_CONF_END);
|
||||
|
||||
bridge->conf.class_revision |= cpu_to_le32(PCI_CLASS_BRIDGE_PCI << 16);
|
||||
bridge->conf.header_type = PCI_HEADER_TYPE_BRIDGE;
|
||||
bridge->conf.cache_line_size = 0x10;
|
||||
|
|
|
@ -4029,6 +4029,10 @@ int pci_register_io_range(struct fwnode_handle *fwnode, phys_addr_t addr,
|
|||
ret = logic_pio_register_range(range);
|
||||
if (ret)
|
||||
kfree(range);
|
||||
|
||||
/* Ignore duplicates due to deferred probing */
|
||||
if (ret == -EEXIST)
|
||||
ret = 0;
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -581,9 +581,6 @@ extern bool osc_pc_lpi_support_confirmed;
|
|||
#define ACPI_GSB_ACCESS_ATTRIB_RAW_BYTES 0x0000000E
|
||||
#define ACPI_GSB_ACCESS_ATTRIB_RAW_PROCESS 0x0000000F
|
||||
|
||||
extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
|
||||
u32 *mask, u32 req);
|
||||
|
||||
/* Enable _OST when all relevant hotplug operations are enabled */
|
||||
#if defined(CONFIG_ACPI_HOTPLUG_CPU) && \
|
||||
defined(CONFIG_ACPI_HOTPLUG_MEMORY) && \
|
||||
|
|
|
@ -28,6 +28,8 @@ static DEFINE_MUTEX(io_range_mutex);
|
|||
* @new_range: pointer to the IO range to be registered.
|
||||
*
|
||||
* Returns 0 on success, the error code in case of failure.
|
||||
* If the range already exists, -EEXIST will be returned, which should be
|
||||
* considered a success.
|
||||
*
|
||||
* Register a new IO range node in the IO range list.
|
||||
*/
|
||||
|
@ -51,6 +53,7 @@ int logic_pio_register_range(struct logic_pio_hwaddr *new_range)
|
|||
list_for_each_entry(range, &io_range_list, list) {
|
||||
if (range->fwnode == new_range->fwnode) {
|
||||
/* range already there */
|
||||
ret = -EEXIST;
|
||||
goto end_register;
|
||||
}
|
||||
if (range->flags == LOGIC_PIO_CPU_MMIO &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче