diff options
Diffstat (limited to 'drivers/acpi/acpica')
-rw-r--r-- | drivers/acpi/acpica/hwsleep.c | 43 | ||||
-rw-r--r-- | drivers/acpi/acpica/hwvalid.c | 86 | ||||
-rw-r--r-- | drivers/acpi/acpica/rscalc.c | 7 | ||||
-rw-r--r-- | drivers/acpi/acpica/rscreate.c | 27 |
4 files changed, 107 insertions, 56 deletions
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index baa5fc05e124..db307a356f08 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -211,6 +211,12 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) | |||
211 | 211 | ||
212 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | 212 | ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) |
213 | 213 | ||
214 | static unsigned int gts, bfs; | ||
215 | module_param(gts, uint, 0644); | ||
216 | module_param(bfs, uint, 0644); | ||
217 | MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); | ||
218 | MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); | ||
219 | |||
214 | /******************************************************************************* | 220 | /******************************************************************************* |
215 | * | 221 | * |
216 | * FUNCTION: acpi_enter_sleep_state | 222 | * FUNCTION: acpi_enter_sleep_state |
@@ -278,16 +284,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) | |||
278 | return_ACPI_STATUS(status); | 284 | return_ACPI_STATUS(status); |
279 | } | 285 | } |
280 | 286 | ||
281 | /* Execute the _GTS method */ | 287 | if (gts) { |
288 | /* Execute the _GTS method */ | ||
282 | 289 | ||
283 | arg_list.count = 1; | 290 | arg_list.count = 1; |
284 | arg_list.pointer = &arg; | 291 | arg_list.pointer = &arg; |
285 | arg.type = ACPI_TYPE_INTEGER; | 292 | arg.type = ACPI_TYPE_INTEGER; |
286 | arg.integer.value = sleep_state; | 293 | arg.integer.value = sleep_state; |
287 | 294 | ||
288 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); | 295 | status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL); |
289 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 296 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
290 | return_ACPI_STATUS(status); | 297 | return_ACPI_STATUS(status); |
298 | } | ||
291 | } | 299 | } |
292 | 300 | ||
293 | /* Get current value of PM1A control */ | 301 | /* Get current value of PM1A control */ |
@@ -513,18 +521,19 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) | |||
513 | } | 521 | } |
514 | } | 522 | } |
515 | 523 | ||
516 | /* Execute the _BFS method */ | 524 | if (bfs) { |
525 | /* Execute the _BFS method */ | ||
517 | 526 | ||
518 | arg_list.count = 1; | 527 | arg_list.count = 1; |
519 | arg_list.pointer = &arg; | 528 | arg_list.pointer = &arg; |
520 | arg.type = ACPI_TYPE_INTEGER; | 529 | arg.type = ACPI_TYPE_INTEGER; |
521 | arg.integer.value = sleep_state; | 530 | arg.integer.value = sleep_state; |
522 | 531 | ||
523 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); | 532 | status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL); |
524 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 533 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
525 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); | 534 | ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); |
535 | } | ||
526 | } | 536 | } |
527 | |||
528 | return_ACPI_STATUS(status); | 537 | return_ACPI_STATUS(status); |
529 | } | 538 | } |
530 | 539 | ||
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index 7737afb157c3..ec33f270c5b7 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c | |||
@@ -90,6 +90,7 @@ static const struct acpi_port_info acpi_protected_ports[] = { | |||
90 | {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, | 90 | {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP}, |
91 | {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, | 91 | {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP}, |
92 | {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, | 92 | {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP}, |
93 | {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP}, | ||
93 | {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, | 94 | {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP}, |
94 | {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, | 95 | {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP}, |
95 | {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, | 96 | {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP}, |
@@ -151,7 +152,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) | |||
151 | ACPI_ERROR((AE_INFO, | 152 | ACPI_ERROR((AE_INFO, |
152 | "Illegal I/O port address/length above 64K: 0x%p/%X", | 153 | "Illegal I/O port address/length above 64K: 0x%p/%X", |
153 | ACPI_CAST_PTR(void, address), byte_width)); | 154 | ACPI_CAST_PTR(void, address), byte_width)); |
154 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | 155 | return_ACPI_STATUS(AE_LIMIT); |
155 | } | 156 | } |
156 | 157 | ||
157 | /* Exit if requested address is not within the protected port table */ | 158 | /* Exit if requested address is not within the protected port table */ |
@@ -178,11 +179,12 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) | |||
178 | /* Port illegality may depend on the _OSI calls made by the BIOS */ | 179 | /* Port illegality may depend on the _OSI calls made by the BIOS */ |
179 | 180 | ||
180 | if (acpi_gbl_osi_data >= port_info->osi_dependency) { | 181 | if (acpi_gbl_osi_data >= port_info->osi_dependency) { |
181 | ACPI_ERROR((AE_INFO, | 182 | ACPI_DEBUG_PRINT((ACPI_DB_IO, |
182 | "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", | 183 | "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)", |
183 | ACPI_CAST_PTR(void, address), | 184 | ACPI_CAST_PTR(void, address), |
184 | byte_width, port_info->name, | 185 | byte_width, port_info->name, |
185 | port_info->start, port_info->end)); | 186 | port_info->start, |
187 | port_info->end)); | ||
186 | 188 | ||
187 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); | 189 | return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS); |
188 | } | 190 | } |
@@ -206,7 +208,7 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) | |||
206 | * Value Where value is placed | 208 | * Value Where value is placed |
207 | * Width Number of bits | 209 | * Width Number of bits |
208 | * | 210 | * |
209 | * RETURN: Value read from port | 211 | * RETURN: Status and value read from port |
210 | * | 212 | * |
211 | * DESCRIPTION: Read data from an I/O port or register. This is a front-end | 213 | * DESCRIPTION: Read data from an I/O port or register. This is a front-end |
212 | * to acpi_os_read_port that performs validation on both the port | 214 | * to acpi_os_read_port that performs validation on both the port |
@@ -217,14 +219,43 @@ acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width) | |||
217 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) | 219 | acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) |
218 | { | 220 | { |
219 | acpi_status status; | 221 | acpi_status status; |
222 | u32 one_byte; | ||
223 | u32 i; | ||
224 | |||
225 | /* Validate the entire request and perform the I/O */ | ||
220 | 226 | ||
221 | status = acpi_hw_validate_io_request(address, width); | 227 | status = acpi_hw_validate_io_request(address, width); |
222 | if (ACPI_FAILURE(status)) { | 228 | if (ACPI_SUCCESS(status)) { |
229 | status = acpi_os_read_port(address, value, width); | ||
223 | return status; | 230 | return status; |
224 | } | 231 | } |
225 | 232 | ||
226 | status = acpi_os_read_port(address, value, width); | 233 | if (status != AE_AML_ILLEGAL_ADDRESS) { |
227 | return status; | 234 | return status; |
235 | } | ||
236 | |||
237 | /* | ||
238 | * There has been a protection violation within the request. Fall | ||
239 | * back to byte granularity port I/O and ignore the failing bytes. | ||
240 | * This provides Windows compatibility. | ||
241 | */ | ||
242 | for (i = 0, *value = 0; i < width; i += 8) { | ||
243 | |||
244 | /* Validate and read one byte */ | ||
245 | |||
246 | if (acpi_hw_validate_io_request(address, 8) == AE_OK) { | ||
247 | status = acpi_os_read_port(address, &one_byte, 8); | ||
248 | if (ACPI_FAILURE(status)) { | ||
249 | return status; | ||
250 | } | ||
251 | |||
252 | *value |= (one_byte << i); | ||
253 | } | ||
254 | |||
255 | address++; | ||
256 | } | ||
257 | |||
258 | return AE_OK; | ||
228 | } | 259 | } |
229 | 260 | ||
230 | /****************************************************************************** | 261 | /****************************************************************************** |
@@ -235,7 +266,7 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) | |||
235 | * Value Value to write | 266 | * Value Value to write |
236 | * Width Number of bits | 267 | * Width Number of bits |
237 | * | 268 | * |
238 | * RETURN: None | 269 | * RETURN: Status |
239 | * | 270 | * |
240 | * DESCRIPTION: Write data to an I/O port or register. This is a front-end | 271 | * DESCRIPTION: Write data to an I/O port or register. This is a front-end |
241 | * to acpi_os_write_port that performs validation on both the port | 272 | * to acpi_os_write_port that performs validation on both the port |
@@ -246,12 +277,39 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) | |||
246 | acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) | 277 | acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) |
247 | { | 278 | { |
248 | acpi_status status; | 279 | acpi_status status; |
280 | u32 i; | ||
281 | |||
282 | /* Validate the entire request and perform the I/O */ | ||
249 | 283 | ||
250 | status = acpi_hw_validate_io_request(address, width); | 284 | status = acpi_hw_validate_io_request(address, width); |
251 | if (ACPI_FAILURE(status)) { | 285 | if (ACPI_SUCCESS(status)) { |
286 | status = acpi_os_write_port(address, value, width); | ||
252 | return status; | 287 | return status; |
253 | } | 288 | } |
254 | 289 | ||
255 | status = acpi_os_write_port(address, value, width); | 290 | if (status != AE_AML_ILLEGAL_ADDRESS) { |
256 | return status; | 291 | return status; |
292 | } | ||
293 | |||
294 | /* | ||
295 | * There has been a protection violation within the request. Fall | ||
296 | * back to byte granularity port I/O and ignore the failing bytes. | ||
297 | * This provides Windows compatibility. | ||
298 | */ | ||
299 | for (i = 0; i < width; i += 8) { | ||
300 | |||
301 | /* Validate and write one byte */ | ||
302 | |||
303 | if (acpi_hw_validate_io_request(address, 8) == AE_OK) { | ||
304 | status = | ||
305 | acpi_os_write_port(address, (value >> i) & 0xFF, 8); | ||
306 | if (ACPI_FAILURE(status)) { | ||
307 | return status; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | address++; | ||
312 | } | ||
313 | |||
314 | return AE_OK; | ||
257 | } | 315 | } |
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c index b6667ff059e5..88b5a2c4814d 100644 --- a/drivers/acpi/acpica/rscalc.c +++ b/drivers/acpi/acpica/rscalc.c | |||
@@ -543,6 +543,13 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object, | |||
543 | 543 | ||
544 | package_element = *top_object_list; | 544 | package_element = *top_object_list; |
545 | 545 | ||
546 | /* We must have a valid Package object */ | ||
547 | |||
548 | if (!package_element || | ||
549 | (package_element->common.type != ACPI_TYPE_PACKAGE)) { | ||
550 | return_ACPI_STATUS (AE_AML_OPERAND_TYPE); | ||
551 | } | ||
552 | |||
546 | /* | 553 | /* |
547 | * The sub_object_list will now point to an array of the | 554 | * The sub_object_list will now point to an array of the |
548 | * four IRQ elements: Address, Pin, Source and source_index | 555 | * four IRQ elements: Address, Pin, Source and source_index |
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c index 663f692fffcf..a3c23d686d5f 100644 --- a/drivers/acpi/acpica/rscreate.c +++ b/drivers/acpi/acpica/rscreate.c | |||
@@ -191,8 +191,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
191 | user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); | 191 | user_prt = ACPI_CAST_PTR(struct acpi_pci_routing_table, buffer); |
192 | 192 | ||
193 | for (index = 0; index < number_of_elements; index++) { | 193 | for (index = 0; index < number_of_elements; index++) { |
194 | int source_name_index = 2; | ||
195 | int source_index_index = 3; | ||
196 | 194 | ||
197 | /* | 195 | /* |
198 | * Point user_prt past this current structure | 196 | * Point user_prt past this current structure |
@@ -261,27 +259,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
261 | return_ACPI_STATUS(AE_BAD_DATA); | 259 | return_ACPI_STATUS(AE_BAD_DATA); |
262 | } | 260 | } |
263 | 261 | ||
264 | /* | ||
265 | * If BIOS erroneously reversed the _PRT source_name and source_index, | ||
266 | * then reverse them back. | ||
267 | */ | ||
268 | if ((sub_object_list[3])->common.type != | ||
269 | ACPI_TYPE_INTEGER) { | ||
270 | if (acpi_gbl_enable_interpreter_slack) { | ||
271 | source_name_index = 3; | ||
272 | source_index_index = 2; | ||
273 | printk(KERN_WARNING | ||
274 | "ACPI: Handling Garbled _PRT entry\n"); | ||
275 | } else { | ||
276 | ACPI_ERROR((AE_INFO, | ||
277 | "(PRT[%X].source_index) Need Integer, found %s", | ||
278 | index, | ||
279 | acpi_ut_get_object_type_name | ||
280 | (sub_object_list[3]))); | ||
281 | return_ACPI_STATUS(AE_BAD_DATA); | ||
282 | } | ||
283 | } | ||
284 | |||
285 | user_prt->pin = (u32) obj_desc->integer.value; | 262 | user_prt->pin = (u32) obj_desc->integer.value; |
286 | 263 | ||
287 | /* | 264 | /* |
@@ -304,7 +281,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
304 | * 3) Third subobject: Dereference the PRT.source_name | 281 | * 3) Third subobject: Dereference the PRT.source_name |
305 | * The name may be unresolved (slack mode), so allow a null object | 282 | * The name may be unresolved (slack mode), so allow a null object |
306 | */ | 283 | */ |
307 | obj_desc = sub_object_list[source_name_index]; | 284 | obj_desc = sub_object_list[2]; |
308 | if (obj_desc) { | 285 | if (obj_desc) { |
309 | switch (obj_desc->common.type) { | 286 | switch (obj_desc->common.type) { |
310 | case ACPI_TYPE_LOCAL_REFERENCE: | 287 | case ACPI_TYPE_LOCAL_REFERENCE: |
@@ -378,7 +355,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object, | |||
378 | 355 | ||
379 | /* 4) Fourth subobject: Dereference the PRT.source_index */ | 356 | /* 4) Fourth subobject: Dereference the PRT.source_index */ |
380 | 357 | ||
381 | obj_desc = sub_object_list[source_index_index]; | 358 | obj_desc = sub_object_list[3]; |
382 | if (obj_desc->common.type != ACPI_TYPE_INTEGER) { | 359 | if (obj_desc->common.type != ACPI_TYPE_INTEGER) { |
383 | ACPI_ERROR((AE_INFO, | 360 | ACPI_ERROR((AE_INFO, |
384 | "(PRT[%X].SourceIndex) Need Integer, found %s", | 361 | "(PRT[%X].SourceIndex) Need Integer, found %s", |