diff options
author | Bob Moore <robert.moore@intel.com> | 2008-04-10 11:06:43 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2008-04-22 14:29:31 -0400 |
commit | 1d5b285da1893b90507b081664ac27f1a8a3dc5b (patch) | |
tree | debc9adbd1471bc86bc12d1bc0ff9875c86e30a0 /drivers/acpi | |
parent | 3fa347770a8a9cb3568600380ce4b5c041b3ac0b (diff) |
ACPICA: Fix for resource descriptor optimization issues for _CRS/_SRC
Fixed a problem where resource descriptor size optimization
could cause a problem when a _CRS resource template is passed
to a _SRS method. The _SRS resource template must use the same
descriptors (with the same size) as returned from _CRS. This
change affects the following resource descriptors: IRQ/IRQNoFlags
and StartDependendentFn/StartDependentFnNoPri.
http://bugzilla.kernel.org/show_bug.cgi?id=9487
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Alexey Starikovskiy <astarikovskiy@suse.de>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/resources/rscalc.c | 7 | ||||
-rw-r--r-- | drivers/acpi/resources/rsdump.c | 8 | ||||
-rw-r--r-- | drivers/acpi/resources/rsio.c | 39 | ||||
-rw-r--r-- | drivers/acpi/resources/rsirq.c | 43 | ||||
-rw-r--r-- | drivers/acpi/resources/rsmisc.c | 11 |
5 files changed, 100 insertions, 8 deletions
diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index dcc51e92ac92..db0a835e3317 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c | |||
@@ -211,6 +211,13 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed) | |||
211 | * variable-length fields | 211 | * variable-length fields |
212 | */ | 212 | */ |
213 | switch (resource->type) { | 213 | switch (resource->type) { |
214 | case ACPI_RESOURCE_TYPE_IRQ: | ||
215 | |||
216 | if (resource->data.irq.descriptor_length == 2) { | ||
217 | total_size--; | ||
218 | } | ||
219 | break; | ||
220 | |||
214 | case ACPI_RESOURCE_TYPE_VENDOR: | 221 | case ACPI_RESOURCE_TYPE_VENDOR: |
215 | /* | 222 | /* |
216 | * Vendor Defined Resource: | 223 | * Vendor Defined Resource: |
diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 46da116a4030..ed6447dcea78 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c | |||
@@ -87,8 +87,10 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table); | |||
87 | * | 87 | * |
88 | ******************************************************************************/ | 88 | ******************************************************************************/ |
89 | 89 | ||
90 | struct acpi_rsdump_info acpi_rs_dump_irq[6] = { | 90 | struct acpi_rsdump_info acpi_rs_dump_irq[7] = { |
91 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, | 91 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_irq), "IRQ", NULL}, |
92 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(irq.descriptor_length), | ||
93 | "Descriptor Length", NULL}, | ||
92 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", | 94 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.triggering), "Triggering", |
93 | acpi_gbl_he_decode}, | 95 | acpi_gbl_he_decode}, |
94 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", | 96 | {ACPI_RSD_1BITFLAG, ACPI_RSD_OFFSET(irq.polarity), "Polarity", |
@@ -115,9 +117,11 @@ struct acpi_rsdump_info acpi_rs_dump_dma[6] = { | |||
115 | NULL} | 117 | NULL} |
116 | }; | 118 | }; |
117 | 119 | ||
118 | struct acpi_rsdump_info acpi_rs_dump_start_dpf[3] = { | 120 | struct acpi_rsdump_info acpi_rs_dump_start_dpf[4] = { |
119 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), | 121 | {ACPI_RSD_TITLE, ACPI_RSD_TABLE_SIZE(acpi_rs_dump_start_dpf), |
120 | "Start-Dependent-Functions", NULL}, | 122 | "Start-Dependent-Functions", NULL}, |
123 | {ACPI_RSD_UINT8, ACPI_RSD_OFFSET(start_dpf.descriptor_length), | ||
124 | "Descriptor Length", NULL}, | ||
121 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), | 125 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.compatibility_priority), |
122 | "Compatibility Priority", acpi_gbl_config_decode}, | 126 | "Compatibility Priority", acpi_gbl_config_decode}, |
123 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), | 127 | {ACPI_RSD_2BITFLAG, ACPI_RSD_OFFSET(start_dpf.performance_robustness), |
diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index b297bc3e4419..50f3acdd9c8e 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c | |||
@@ -185,7 +185,7 @@ struct acpi_rsconvert_info acpi_rs_convert_end_tag[2] = { | |||
185 | * | 185 | * |
186 | ******************************************************************************/ | 186 | ******************************************************************************/ |
187 | 187 | ||
188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | 188 | struct acpi_rsconvert_info acpi_rs_get_start_dpf[6] = { |
189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, | 189 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_START_DEPENDENT, |
190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), | 190 | ACPI_RS_SIZE(struct acpi_resource_start_dependent), |
191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, | 191 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_start_dpf)}, |
@@ -196,6 +196,12 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | |||
196 | ACPI_ACCEPTABLE_CONFIGURATION, | 196 | ACPI_ACCEPTABLE_CONFIGURATION, |
197 | 2}, | 197 | 2}, |
198 | 198 | ||
199 | /* Get the descriptor length (0 or 1 for Start Dpf descriptor) */ | ||
200 | |||
201 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
202 | AML_OFFSET(start_dpf.descriptor_type), | ||
203 | 0}, | ||
204 | |||
199 | /* All done if there is no flag byte present in the descriptor */ | 205 | /* All done if there is no flag byte present in the descriptor */ |
200 | 206 | ||
201 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, | 207 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 1}, |
@@ -219,7 +225,9 @@ struct acpi_rsconvert_info acpi_rs_get_start_dpf[5] = { | |||
219 | * | 225 | * |
220 | ******************************************************************************/ | 226 | ******************************************************************************/ |
221 | 227 | ||
222 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { | 228 | struct acpi_rsconvert_info acpi_rs_set_start_dpf[10] = { |
229 | /* Start with a default descriptor of length 1 */ | ||
230 | |||
223 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, | 231 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_START_DEPENDENT, |
224 | sizeof(struct aml_resource_start_dependent), | 232 | sizeof(struct aml_resource_start_dependent), |
225 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, | 233 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_start_dpf)}, |
@@ -236,6 +244,33 @@ struct acpi_rsconvert_info acpi_rs_set_start_dpf[6] = { | |||
236 | AML_OFFSET(start_dpf.flags), | 244 | AML_OFFSET(start_dpf.flags), |
237 | 2}, | 245 | 2}, |
238 | /* | 246 | /* |
247 | * All done if the output descriptor length is required to be 1 | ||
248 | * (i.e., optimization to 0 bytes cannot be attempted) | ||
249 | */ | ||
250 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
251 | ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
252 | 1}, | ||
253 | |||
254 | /* Set length to 0 bytes (no flags byte) */ | ||
255 | |||
256 | {ACPI_RSC_LENGTH, 0, 0, | ||
257 | sizeof(struct aml_resource_start_dependent_noprio)}, | ||
258 | |||
259 | /* | ||
260 | * All done if the output descriptor length is required to be 0. | ||
261 | * | ||
262 | * TBD: Perhaps we should check for error if input flags are not | ||
263 | * compatible with a 0-byte descriptor. | ||
264 | */ | ||
265 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
266 | ACPI_RS_OFFSET(data.start_dpf.descriptor_length), | ||
267 | 0}, | ||
268 | |||
269 | /* Reset length to 1 byte (descriptor with flags byte) */ | ||
270 | |||
271 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)}, | ||
272 | |||
273 | /* | ||
239 | * All done if flags byte is necessary -- if either priority value | 274 | * All done if flags byte is necessary -- if either priority value |
240 | * is not ACPI_ACCEPTABLE_CONFIGURATION | 275 | * is not ACPI_ACCEPTABLE_CONFIGURATION |
241 | */ | 276 | */ |
diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 5657f7b95039..382a77b8400d 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c | |||
@@ -52,7 +52,7 @@ ACPI_MODULE_NAME("rsirq") | |||
52 | * acpi_rs_get_irq | 52 | * acpi_rs_get_irq |
53 | * | 53 | * |
54 | ******************************************************************************/ | 54 | ******************************************************************************/ |
55 | struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | 55 | struct acpi_rsconvert_info acpi_rs_get_irq[8] = { |
56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, | 56 | {ACPI_RSC_INITGET, ACPI_RESOURCE_TYPE_IRQ, |
57 | ACPI_RS_SIZE(struct acpi_resource_irq), | 57 | ACPI_RS_SIZE(struct acpi_resource_irq), |
58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, | 58 | ACPI_RSC_TABLE_SIZE(acpi_rs_get_irq)}, |
@@ -69,6 +69,12 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | |||
69 | ACPI_EDGE_SENSITIVE, | 69 | ACPI_EDGE_SENSITIVE, |
70 | 1}, | 70 | 1}, |
71 | 71 | ||
72 | /* Get the descriptor length (2 or 3 for IRQ descriptor) */ | ||
73 | |||
74 | {ACPI_RSC_2BITFLAG, ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
75 | AML_OFFSET(irq.descriptor_type), | ||
76 | 0}, | ||
77 | |||
72 | /* All done if no flag byte present in descriptor */ | 78 | /* All done if no flag byte present in descriptor */ |
73 | 79 | ||
74 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, | 80 | {ACPI_RSC_EXIT_NE, ACPI_RSC_COMPARE_AML_LENGTH, 0, 3}, |
@@ -94,7 +100,9 @@ struct acpi_rsconvert_info acpi_rs_get_irq[7] = { | |||
94 | * | 100 | * |
95 | ******************************************************************************/ | 101 | ******************************************************************************/ |
96 | 102 | ||
97 | struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | 103 | struct acpi_rsconvert_info acpi_rs_set_irq[13] = { |
104 | /* Start with a default descriptor of length 3 */ | ||
105 | |||
98 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, | 106 | {ACPI_RSC_INITSET, ACPI_RESOURCE_NAME_IRQ, |
99 | sizeof(struct aml_resource_irq), | 107 | sizeof(struct aml_resource_irq), |
100 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, | 108 | ACPI_RSC_TABLE_SIZE(acpi_rs_set_irq)}, |
@@ -105,7 +113,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
105 | AML_OFFSET(irq.irq_mask), | 113 | AML_OFFSET(irq.irq_mask), |
106 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, | 114 | ACPI_RS_OFFSET(data.irq.interrupt_count)}, |
107 | 115 | ||
108 | /* Set the flags byte by default */ | 116 | /* Set the flags byte */ |
109 | 117 | ||
110 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), | 118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.triggering), |
111 | AML_OFFSET(irq.flags), | 119 | AML_OFFSET(irq.flags), |
@@ -118,6 +126,33 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
118 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), | 126 | {ACPI_RSC_1BITFLAG, ACPI_RS_OFFSET(data.irq.sharable), |
119 | AML_OFFSET(irq.flags), | 127 | AML_OFFSET(irq.flags), |
120 | 4}, | 128 | 4}, |
129 | |||
130 | /* | ||
131 | * All done if the output descriptor length is required to be 3 | ||
132 | * (i.e., optimization to 2 bytes cannot be attempted) | ||
133 | */ | ||
134 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
135 | ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
136 | 3}, | ||
137 | |||
138 | /* Set length to 2 bytes (no flags byte) */ | ||
139 | |||
140 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)}, | ||
141 | |||
142 | /* | ||
143 | * All done if the output descriptor length is required to be 2. | ||
144 | * | ||
145 | * TBD: Perhaps we should check for error if input flags are not | ||
146 | * compatible with a 2-byte descriptor. | ||
147 | */ | ||
148 | {ACPI_RSC_EXIT_EQ, ACPI_RSC_COMPARE_VALUE, | ||
149 | ACPI_RS_OFFSET(data.irq.descriptor_length), | ||
150 | 2}, | ||
151 | |||
152 | /* Reset length to 3 bytes (descriptor with flags byte) */ | ||
153 | |||
154 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq)}, | ||
155 | |||
121 | /* | 156 | /* |
122 | * Check if the flags byte is necessary. Not needed if the flags are: | 157 | * Check if the flags byte is necessary. Not needed if the flags are: |
123 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE | 158 | * ACPI_EDGE_SENSITIVE, ACPI_ACTIVE_HIGH, ACPI_EXCLUSIVE |
@@ -134,7 +169,7 @@ struct acpi_rsconvert_info acpi_rs_set_irq[9] = { | |||
134 | ACPI_RS_OFFSET(data.irq.sharable), | 169 | ACPI_RS_OFFSET(data.irq.sharable), |
135 | ACPI_EXCLUSIVE}, | 170 | ACPI_EXCLUSIVE}, |
136 | 171 | ||
137 | /* irq_no_flags() descriptor can be used */ | 172 | /* We can optimize to a 2-byte irq_no_flags() descriptor */ |
138 | 173 | ||
139 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} | 174 | {ACPI_RSC_LENGTH, 0, 0, sizeof(struct aml_resource_irq_noflags)} |
140 | }; | 175 | }; |
diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index c7081afa893a..3e69eff303fb 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c | |||
@@ -497,6 +497,17 @@ acpi_rs_convert_resource_to_aml(struct acpi_resource *resource, | |||
497 | } | 497 | } |
498 | break; | 498 | break; |
499 | 499 | ||
500 | case ACPI_RSC_EXIT_EQ: | ||
501 | /* | ||
502 | * Control - Exit conversion if equal | ||
503 | */ | ||
504 | if (*ACPI_ADD_PTR(u8, resource, | ||
505 | COMPARE_TARGET(info)) == | ||
506 | COMPARE_VALUE(info)) { | ||
507 | goto exit; | ||
508 | } | ||
509 | break; | ||
510 | |||
500 | default: | 511 | default: |
501 | 512 | ||
502 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); | 513 | ACPI_ERROR((AE_INFO, "Invalid conversion opcode")); |