Skip to content
Snippets Groups Projects
Commit 955f14b4 authored by Bjorn Helgaas's avatar Bjorn Helgaas
Browse files

PCI/ACPI: Decode _OSC bitmasks symbolically


This updates _OSC-related messages to be more human-readable.  We now always
show the features we declare support for (this was previously invisible) as
well as the features we are granted control of.

Typical changes:

  -acpi PNP0A08:00: Requesting ACPI _OSC control (0x1d)
  -acpi PNP0A08:00: ACPI _OSC control (0x1d) granted
  +acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]
  +acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME AER PCIeCapability]

Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Acked-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent de189662
No related branches found
No related tags found
No related merge requests found
...@@ -127,6 +127,55 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle, ...@@ -127,6 +127,55 @@ static acpi_status try_get_root_bridge_busnr(acpi_handle handle,
return AE_OK; return AE_OK;
} }
struct pci_osc_bit_struct {
u32 bit;
char *desc;
};
static struct pci_osc_bit_struct pci_osc_support_bit[] = {
{ OSC_PCI_EXT_CONFIG_SUPPORT, "ExtendedConfig" },
{ OSC_PCI_ASPM_SUPPORT, "ASPM" },
{ OSC_PCI_CLOCK_PM_SUPPORT, "ClockPM" },
{ OSC_PCI_SEGMENT_GROUPS_SUPPORT, "Segments" },
{ OSC_PCI_MSI_SUPPORT, "MSI" },
};
static struct pci_osc_bit_struct pci_osc_control_bit[] = {
{ OSC_PCI_EXPRESS_NATIVE_HP_CONTROL, "PCIeHotplug" },
{ OSC_PCI_SHPC_NATIVE_HP_CONTROL, "SHPCHotplug" },
{ OSC_PCI_EXPRESS_PME_CONTROL, "PME" },
{ OSC_PCI_EXPRESS_AER_CONTROL, "AER" },
{ OSC_PCI_EXPRESS_CAPABILITY_CONTROL, "PCIeCapability" },
};
static void decode_osc_bits(struct acpi_pci_root *root, char *msg, u32 word,
struct pci_osc_bit_struct *table, int size)
{
char buf[80];
int i, len = 0;
struct pci_osc_bit_struct *entry;
buf[0] = '\0';
for (i = 0, entry = table; i < size; i++, entry++)
if (word & entry->bit)
len += snprintf(buf + len, sizeof(buf) - len, "%s%s",
len ? " " : "", entry->desc);
dev_info(&root->device->dev, "_OSC: %s [%s]\n", msg, buf);
}
static void decode_osc_support(struct acpi_pci_root *root, char *msg, u32 word)
{
decode_osc_bits(root, msg, word, pci_osc_support_bit,
ARRAY_SIZE(pci_osc_support_bit));
}
static void decode_osc_control(struct acpi_pci_root *root, char *msg, u32 word)
{
decode_osc_bits(root, msg, word, pci_osc_control_bit,
ARRAY_SIZE(pci_osc_control_bit));
}
static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766"; static u8 pci_osc_uuid_str[] = "33DB4D5B-1FF7-401C-9657-7441C03DD766";
static acpi_status acpi_pci_run_osc(acpi_handle handle, static acpi_status acpi_pci_run_osc(acpi_handle handle,
...@@ -340,10 +389,14 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req) ...@@ -340,10 +389,14 @@ acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
goto out; goto out;
if (ctrl == *mask) if (ctrl == *mask)
break; break;
decode_osc_control(root, "platform does not support",
ctrl & ~(*mask));
ctrl = *mask; ctrl = *mask;
} }
if ((ctrl & req) != req) { if ((ctrl & req) != req) {
decode_osc_control(root, "not requesting control; platform does not support",
req & ~(ctrl));
status = AE_SUPPORT; status = AE_SUPPORT;
goto out; goto out;
} }
...@@ -363,7 +416,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set); ...@@ -363,7 +416,7 @@ EXPORT_SYMBOL(acpi_pci_osc_control_set);
static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
int *clear_aspm) int *clear_aspm)
{ {
u32 support, control; u32 support, control, requested;
acpi_status status; acpi_status status;
struct acpi_device *device = root->device; struct acpi_device *device = root->device;
acpi_handle handle = device->handle; acpi_handle handle = device->handle;
...@@ -379,6 +432,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, ...@@ -379,6 +432,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT; support |= OSC_PCI_ASPM_SUPPORT | OSC_PCI_CLOCK_PM_SUPPORT;
if (pci_msi_enabled()) if (pci_msi_enabled())
support |= OSC_PCI_MSI_SUPPORT; support |= OSC_PCI_MSI_SUPPORT;
decode_osc_support(root, "OS supports", support);
status = acpi_pci_osc_support(root, support); status = acpi_pci_osc_support(root, support);
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n", dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n",
...@@ -393,8 +448,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, ...@@ -393,8 +448,8 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
} }
if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) { if ((support & ACPI_PCIE_REQ_SUPPORT) != ACPI_PCIE_REQ_SUPPORT) {
dev_info(&device->dev, "Not requesting _OSC control (we support %#02x but %#02x are required)\n", decode_osc_support(root, "not requesting OS control; OS requires",
support, ACPI_PCIE_REQ_SUPPORT); ACPI_PCIE_REQ_SUPPORT);
return; return;
} }
...@@ -404,21 +459,17 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, ...@@ -404,21 +459,17 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
if (pci_aer_available()) { if (pci_aer_available()) {
if (aer_acpi_firmware_first()) if (aer_acpi_firmware_first())
dev_dbg(&device->dev, dev_info(&device->dev,
"PCIe errors handled by BIOS.\n"); "PCIe AER handled by firmware\n");
else else
control |= OSC_PCI_EXPRESS_AER_CONTROL; control |= OSC_PCI_EXPRESS_AER_CONTROL;
} }
dev_info(&device->dev, requested = control;
"Requesting ACPI _OSC control (0x%02x)\n", control);
status = acpi_pci_osc_control_set(handle, &control, status = acpi_pci_osc_control_set(handle, &control,
OSC_PCI_EXPRESS_CAPABILITY_CONTROL); OSC_PCI_EXPRESS_CAPABILITY_CONTROL);
if (ACPI_SUCCESS(status)) { if (ACPI_SUCCESS(status)) {
dev_info(&device->dev, decode_osc_control(root, "OS now controls", control);
"ACPI _OSC control (0x%02x) granted\n",
control);
if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
/* /*
* We have ASPM control, but the FADT indicates * We have ASPM control, but the FADT indicates
...@@ -427,12 +478,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm, ...@@ -427,12 +478,11 @@ static void negotiate_os_control(struct acpi_pci_root *root, int *no_aspm,
*clear_aspm = 1; *clear_aspm = 1;
} }
} else { } else {
dev_info(&device->dev, decode_osc_control(root, "OS requested", requested);
"ACPI _OSC request failed (%s), " decode_osc_control(root, "platform willing to grant", control);
"returned control mask: 0x%02x\n", dev_info(&device->dev, "_OSC failed (%s); disabling ASPM\n",
acpi_format_exception(status), control); acpi_format_exception(status));
dev_info(&device->dev,
"ACPI _OSC control for PCIe not granted, disabling ASPM\n");
/* /*
* We want to disable ASPM here, but aspm_disabled * We want to disable ASPM here, but aspm_disabled
* needs to remain in its state from boot so that we * needs to remain in its state from boot so that we
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment