diff options
author | Bob Moore <robert.moore@intel.com> | 2012-08-17 01:07:54 -0400 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-09-21 00:26:17 -0400 |
commit | be030a576854238250d70135644cde6a0ba34b0d (patch) | |
tree | a7521a65df5e117ef6aec3fcaa8160be7596a495 /drivers/acpi | |
parent | 4e2f9c278ad84196991fcf6f6646a3e15967fe90 (diff) |
ACPICA: Add support for complex _PLD buffers.
_PLD (Physical Location of Device) returns a bit-packed buffer that
is difficult to parse. This change adds a new interface,
AcpiDecodePldBuffer that parses the buffer into a more usable
local struct. Also adds macros to both get and set individual
fields within the packed _PLD buffer. Adds a new include file,
acbuffer.h - which will be expanded to add structs for other
ACPI names that return buffers. ACPICA BZ 954.
Emit (in comments) the decoded contents of a static _PLD buffer
in order to improve comprehension of this bit-packed buffer.
Add multi-endian support to the _PLD decode routine. Deploy the
multi-endian macros to extract data from the _PLD buffer.
Signed-off-by: Bob Moore <robert.moore@intel.com>
Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/acpica/aclocal.h | 22 | ||||
-rw-r--r-- | drivers/acpi/acpica/acmacros.h | 29 | ||||
-rw-r--r-- | drivers/acpi/acpica/utxface.c | 87 |
3 files changed, 126 insertions, 12 deletions
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 493529a3500..c816ee67509 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -707,15 +707,18 @@ union acpi_parse_value { | |||
707 | u8 disasm_opcode; /* Subtype used for disassembly */\ | 707 | u8 disasm_opcode; /* Subtype used for disassembly */\ |
708 | char aml_op_name[16]) /* Op name (debug only) */ | 708 | char aml_op_name[16]) /* Op name (debug only) */ |
709 | 709 | ||
710 | #define ACPI_DASM_BUFFER 0x00 | 710 | /* Flags for disasm_flags field above */ |
711 | #define ACPI_DASM_RESOURCE 0x01 | 711 | |
712 | #define ACPI_DASM_STRING 0x02 | 712 | #define ACPI_DASM_BUFFER 0x00 /* Buffer is a simple data buffer */ |
713 | #define ACPI_DASM_UNICODE 0x03 | 713 | #define ACPI_DASM_RESOURCE 0x01 /* Buffer is a Resource Descriptor */ |
714 | #define ACPI_DASM_EISAID 0x04 | 714 | #define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */ |
715 | #define ACPI_DASM_MATCHOP 0x05 | 715 | #define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */ |
716 | #define ACPI_DASM_LNOT_PREFIX 0x06 | 716 | #define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */ |
717 | #define ACPI_DASM_LNOT_SUFFIX 0x07 | 717 | #define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */ |
718 | #define ACPI_DASM_IGNORE 0x08 | 718 | #define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ |
719 | #define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ | ||
720 | #define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ | ||
721 | #define ACPI_DASM_IGNORE 0x09 /* Not used at this time */ | ||
719 | 722 | ||
720 | /* | 723 | /* |
721 | * Generic operation (for example: If, While, Store) | 724 | * Generic operation (for example: If, While, Store) |
@@ -1025,6 +1028,7 @@ struct acpi_port_info { | |||
1025 | ****************************************************************************/ | 1028 | ****************************************************************************/ |
1026 | 1029 | ||
1027 | struct acpi_db_method_info { | 1030 | struct acpi_db_method_info { |
1031 | acpi_handle method; | ||
1028 | acpi_handle main_thread_gate; | 1032 | acpi_handle main_thread_gate; |
1029 | acpi_handle thread_complete_gate; | 1033 | acpi_handle thread_complete_gate; |
1030 | acpi_thread_id *threads; | 1034 | acpi_thread_id *threads; |
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 832b6198652..a7f68c47f51 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h | |||
@@ -277,10 +277,33 @@ | |||
277 | 277 | ||
278 | /* Bitfields within ACPI registers */ | 278 | /* Bitfields within ACPI registers */ |
279 | 279 | ||
280 | #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) ((val << pos) & mask) | 280 | #define ACPI_REGISTER_PREPARE_BITS(val, pos, mask) \ |
281 | #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) | 281 | ((val << pos) & mask) |
282 | 282 | ||
283 | #define ACPI_INSERT_BITS(target, mask, source) target = ((target & (~(mask))) | (source & mask)) | 283 | #define ACPI_REGISTER_INSERT_VALUE(reg, pos, mask, val) \ |
284 | reg = (reg & (~(mask))) | ACPI_REGISTER_PREPARE_BITS(val, pos, mask) | ||
285 | |||
286 | #define ACPI_INSERT_BITS(target, mask, source) \ | ||
287 | target = ((target & (~(mask))) | (source & mask)) | ||
288 | |||
289 | /* Generic bitfield macros and masks */ | ||
290 | |||
291 | #define ACPI_GET_BITS(source_ptr, position, mask) \ | ||
292 | ((*source_ptr >> position) & mask) | ||
293 | |||
294 | #define ACPI_SET_BITS(target_ptr, position, mask, value) \ | ||
295 | (*target_ptr |= ((value & mask) << position)) | ||
296 | |||
297 | #define ACPI_1BIT_MASK 0x00000001 | ||
298 | #define ACPI_2BIT_MASK 0x00000003 | ||
299 | #define ACPI_3BIT_MASK 0x00000007 | ||
300 | #define ACPI_4BIT_MASK 0x0000000F | ||
301 | #define ACPI_5BIT_MASK 0x0000001F | ||
302 | #define ACPI_6BIT_MASK 0x0000003F | ||
303 | #define ACPI_7BIT_MASK 0x0000007F | ||
304 | #define ACPI_8BIT_MASK 0x000000FF | ||
305 | #define ACPI_16BIT_MASK 0x0000FFFF | ||
306 | #define ACPI_24BIT_MASK 0x00FFFFFF | ||
284 | 307 | ||
285 | /* | 308 | /* |
286 | * An object of type struct acpi_namespace_node can appear in some contexts | 309 | * An object of type struct acpi_namespace_node can appear in some contexts |
diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 667229dbcba..b09632b4f5b 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c | |||
@@ -418,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id, | |||
418 | 418 | ||
419 | ACPI_EXPORT_SYMBOL(acpi_check_address_range) | 419 | ACPI_EXPORT_SYMBOL(acpi_check_address_range) |
420 | #endif /* !ACPI_ASL_COMPILER */ | 420 | #endif /* !ACPI_ASL_COMPILER */ |
421 | /******************************************************************************* | ||
422 | * | ||
423 | * FUNCTION: acpi_decode_pld_buffer | ||
424 | * | ||
425 | * PARAMETERS: in_buffer - Buffer returned by _PLD method | ||
426 | * length - Length of the in_buffer | ||
427 | * return_buffer - Where the decode buffer is returned | ||
428 | * | ||
429 | * RETURN: Status and the decoded _PLD buffer. User must deallocate | ||
430 | * the buffer via ACPI_FREE. | ||
431 | * | ||
432 | * DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into | ||
433 | * a local struct that is much more useful to an ACPI driver. | ||
434 | * | ||
435 | ******************************************************************************/ | ||
436 | acpi_status | ||
437 | acpi_decode_pld_buffer(u8 *in_buffer, | ||
438 | acpi_size length, struct acpi_pld_info ** return_buffer) | ||
439 | { | ||
440 | struct acpi_pld_info *pld_info; | ||
441 | u32 *buffer = ACPI_CAST_PTR(u32, in_buffer); | ||
442 | u32 dword; | ||
443 | |||
444 | /* Parameter validation */ | ||
445 | |||
446 | if (!in_buffer || !return_buffer || (length < 16)) { | ||
447 | return (AE_BAD_PARAMETER); | ||
448 | } | ||
449 | |||
450 | pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info)); | ||
451 | if (!pld_info) { | ||
452 | return (AE_NO_MEMORY); | ||
453 | } | ||
454 | |||
455 | /* First 32-bit DWord */ | ||
456 | |||
457 | ACPI_MOVE_32_TO_32(&dword, &buffer[0]); | ||
458 | pld_info->revision = ACPI_PLD_GET_REVISION(&dword); | ||
459 | pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword); | ||
460 | pld_info->color = ACPI_PLD_GET_COLOR(&dword); | ||
461 | |||
462 | /* Second 32-bit DWord */ | ||
463 | |||
464 | ACPI_MOVE_32_TO_32(&dword, &buffer[1]); | ||
465 | pld_info->width = ACPI_PLD_GET_WIDTH(&dword); | ||
466 | pld_info->height = ACPI_PLD_GET_HEIGHT(&dword); | ||
467 | |||
468 | /* Third 32-bit DWord */ | ||
469 | |||
470 | ACPI_MOVE_32_TO_32(&dword, &buffer[2]); | ||
471 | pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword); | ||
472 | pld_info->dock = ACPI_PLD_GET_DOCK(&dword); | ||
473 | pld_info->lid = ACPI_PLD_GET_LID(&dword); | ||
474 | pld_info->panel = ACPI_PLD_GET_PANEL(&dword); | ||
475 | pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword); | ||
476 | pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword); | ||
477 | pld_info->shape = ACPI_PLD_GET_SHAPE(&dword); | ||
478 | pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword); | ||
479 | pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword); | ||
480 | pld_info->group_position = ACPI_PLD_GET_POSITION(&dword); | ||
481 | pld_info->bay = ACPI_PLD_GET_BAY(&dword); | ||
482 | |||
483 | /* Fourth 32-bit DWord */ | ||
484 | |||
485 | ACPI_MOVE_32_TO_32(&dword, &buffer[3]); | ||
486 | pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword); | ||
487 | pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword); | ||
488 | pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword); | ||
489 | pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword); | ||
490 | pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword); | ||
491 | pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword); | ||
492 | pld_info->order = ACPI_PLD_GET_ORDER(&dword); | ||
493 | |||
494 | if (length >= ACPI_PLD_BUFFER_SIZE) { | ||
495 | |||
496 | /* Fifth 32-bit DWord (Revision 2 of _PLD) */ | ||
497 | |||
498 | ACPI_MOVE_32_TO_32(&dword, &buffer[4]); | ||
499 | pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword); | ||
500 | pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword); | ||
501 | } | ||
502 | |||
503 | *return_buffer = pld_info; | ||
504 | return (AE_OK); | ||
505 | } | ||
506 | |||
507 | ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer) | ||