]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From 4e39432f4df544d3dfe4fc90a22d87de64d15815 Mon Sep 17 00:00:00 2001 |
2 | From: Taku Izumi <izumi.taku@jp.fujitsu.com> | |
3 | Date: Fri, 17 Oct 2008 13:49:46 +0900 | |
4 | Subject: ACPI/PCI: Change pci_osc_control_set() to query control bits first | |
5 | Patch-mainline: 2.6.28 | |
6 | References: bnc#438941 | |
7 | ||
8 | Current pci_osc_control_set() evaluates _OSC without query for control | |
9 | bits, unless __pci_osc_support_set() is called beforehand. But as | |
10 | strongly recommended in PCI firmware specification, it should query | |
11 | control bits first. | |
12 | ||
13 | This patch changes pci_osc_control_set() to query control bits first | |
14 | even if __pci_osc_support_set() is not called beforehand. | |
15 | ||
16 | Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com> | |
17 | Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> | |
18 | Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> | |
19 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
20 | ||
21 | --- | |
22 | drivers/pci/pci-acpi.c | 47 +++++++++++++++++++++++++++++++---------------- | |
23 | 1 file changed, 31 insertions(+), 16 deletions(-) | |
24 | ||
25 | --- a/drivers/pci/pci-acpi.c | |
26 | +++ b/drivers/pci/pci-acpi.c | |
27 | @@ -120,14 +120,35 @@ out_kfree: | |
28 | return status; | |
29 | } | |
30 | ||
31 | +static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data) | |
32 | +{ | |
33 | + acpi_status status; | |
34 | + u32 support_set; | |
35 | + struct acpi_osc_args osc_args; | |
36 | + | |
37 | + /* do _OSC query for all possible controls */ | |
38 | + support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS); | |
39 | + osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | |
40 | + osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set; | |
41 | + osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | |
42 | + | |
43 | + status = acpi_run_osc(osc_data->handle, &osc_args); | |
44 | + if (ACPI_SUCCESS(status)) { | |
45 | + osc_data->support_set = support_set; | |
46 | + osc_data->query_result = osc_args.query_result; | |
47 | + osc_data->is_queried = 1; | |
48 | + } | |
49 | + | |
50 | + return status; | |
51 | +} | |
52 | + | |
53 | static acpi_status acpi_query_osc(acpi_handle handle, | |
54 | u32 level, void *context, void **retval) | |
55 | { | |
56 | acpi_status status; | |
57 | struct acpi_osc_data *osc_data; | |
58 | - u32 flags = (unsigned long)context, support_set; | |
59 | + u32 flags = (unsigned long)context; | |
60 | acpi_handle tmp; | |
61 | - struct acpi_osc_args osc_args; | |
62 | ||
63 | status = acpi_get_handle(handle, "_OSC", &tmp); | |
64 | if (ACPI_FAILURE(status)) | |
65 | @@ -141,18 +162,7 @@ static acpi_status acpi_query_osc(acpi_h | |
66 | goto out; | |
67 | } | |
68 | ||
69 | - /* do _OSC query for all possible controls */ | |
70 | - support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS); | |
71 | - osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; | |
72 | - osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set; | |
73 | - osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS; | |
74 | - | |
75 | - status = acpi_run_osc(handle, &osc_args); | |
76 | - if (ACPI_SUCCESS(status)) { | |
77 | - osc_data->support_set = support_set; | |
78 | - osc_data->query_result = osc_args.query_result; | |
79 | - osc_data->is_queried = 1; | |
80 | - } | |
81 | + status = __acpi_query_osc(flags, osc_data); | |
82 | out: | |
83 | mutex_unlock(&pci_acpi_lock); | |
84 | return status; | |
85 | @@ -209,8 +219,13 @@ acpi_status pci_osc_control_set(acpi_han | |
86 | goto out; | |
87 | } | |
88 | ||
89 | - if (osc_data->is_queried && | |
90 | - ((osc_data->query_result & ctrlset) != ctrlset)) { | |
91 | + if (!osc_data->is_queried) { | |
92 | + status = __acpi_query_osc(osc_data->support_set, osc_data); | |
93 | + if (ACPI_FAILURE(status)) | |
94 | + goto out; | |
95 | + } | |
96 | + | |
97 | + if ((osc_data->query_result & ctrlset) != ctrlset) { | |
98 | status = AE_SUPPORT; | |
99 | goto out; | |
100 | } |