From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kenji Kaneshige Subject: [PATCH 2/6] ACPI/PCI: do not preserve query result Date: Fri, 30 Jul 2010 15:21:15 +0900 Message-ID: <4C526F5B.2050202@jp.fujitsu.com> References: <201007282323.56351.rjw@sisk.pl> <20100728144358.5e2c12ce@virtuousgeek.org> <4C510B90.9070302@jp.fujitsu.com> <201007291745.39285.rjw@sisk.pl> <4C526A85.3070902@jp.fujitsu.com> <4C526E3E.3000600@jp.fujitsu.com> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <4C526E3E.3000600@jp.fujitsu.com> Sender: linux-pci-owner@vger.kernel.org To: "Rafael J. Wysocki" Cc: Jesse Barnes , Len Brown , ACPI Devel Maling List , linux-pm@lists.linux-foundation.org, linux-pci@vger.kernel.org, Matthew Garrett , Hidetoshi Seto List-Id: linux-acpi@vger.kernel.org Currently, all the _OSC controls are queried at the same time in acpi_pci_osc_support() and the result is preserved for later acpi_pci_osc_control_set() call. But query result can vary depending on the combination of requested controls. Therefore, query result must not be preserved. Signed-off-by: Kenji Kaneshige --- drivers/acpi/pci_root.c | 49 ++++++++++++++++++++++++++---------------------- include/acpi/acpi_bus.h | 3 -- 2 files changed, 27 insertions(+), 25 deletions(-) Index: linux-2.6.35-rc6/drivers/acpi/pci_root.c =================================================================== --- linux-2.6.35-rc6.orig/drivers/acpi/pci_root.c +++ linux-2.6.35-rc6/drivers/acpi/pci_root.c @@ -230,35 +230,42 @@ static acpi_status acpi_pci_run_osc(acpi return status; } -static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) +static acpi_status acpi_pci_osc_control_query(struct acpi_pci_root *root, + u32 flags, u32 *result) { - acpi_status status; - u32 result; - - /* do _OSC query for all possible controls */ - flags &= OSC_PCI_SUPPORT_MASKS; - status = acpi_pci_run_osc(root->device->handle, - root->osc_support_set | flags, - OSC_PCI_CONTROL_MASKS, - true, &result); - if (ACPI_SUCCESS(status)) { - root->osc_support_set |= flags; - root->osc_control_qry = result; - root->osc_queried = 1; + /* No need to run _OSC if requested control bits are already granted */ + flags &= OSC_PCI_CONTROL_MASKS; + if ((root->osc_control_set & flags) == flags) { + *result = root->osc_control_set; + return AE_OK; } - return status; + return acpi_pci_run_osc(root->device->handle, + root->osc_support_set, + root->osc_control_set | flags, + true, result); } static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags) { acpi_status status; acpi_handle tmp; + u32 result; status = acpi_get_handle(root->device->handle, "_OSC", &tmp); if (ACPI_FAILURE(status)) return status; mutex_lock(&osc_lock); - status = acpi_pci_query_osc(root, flags); + /* No need to run _OSC if requested support bits are already set */ + flags &= OSC_PCI_SUPPORT_MASKS; + if ((root->osc_support_set & flags) == flags) + goto out; + status = acpi_pci_run_osc(root->device->handle, + root->osc_support_set | flags, + root->osc_control_set, + true, &result); + if (ACPI_SUCCESS(status)) + root->osc_support_set |= flags; +out: mutex_unlock(&osc_lock); return status; } @@ -399,12 +406,10 @@ acpi_status acpi_pci_osc_control_set(acp goto out; /* Need to query controls first before requesting them */ - if (!root->osc_queried) { - status = acpi_pci_query_osc(root, root->osc_support_set); - if (ACPI_FAILURE(status)) - goto out; - } - if ((root->osc_control_qry & control_req) != control_req) { + status = acpi_pci_osc_control_query(root, control_req, &result); + if (ACPI_FAILURE(status)) + goto out; + if ((result & control_req) != control_req) { printk(KERN_DEBUG "Firmware did not grant requested _OSC control\n"); status = AE_SUPPORT; Index: linux-2.6.35-rc6/include/acpi/acpi_bus.h =================================================================== --- linux-2.6.35-rc6.orig/include/acpi/acpi_bus.h +++ linux-2.6.35-rc6/include/acpi/acpi_bus.h @@ -377,9 +377,6 @@ struct acpi_pci_root { u32 osc_support_set; /* _OSC state of support bits */ u32 osc_control_set; /* _OSC state of control bits */ - u32 osc_control_qry; /* the latest _OSC query result */ - - u32 osc_queried:1; /* has _OSC control been queried? */ }; /* helper */