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>
This commit is contained in:
Bob Moore
2012-08-17 13:07:54 +08:00
کامیت شده توسط Len Brown
والد 4e2f9c278a
کامیت be030a5768
10فایلهای تغییر یافته به همراه360 افزوده شده و 24 حذف شده

مشاهده پرونده

@@ -418,3 +418,90 @@ acpi_check_address_range(acpi_adr_space_type space_id,
ACPI_EXPORT_SYMBOL(acpi_check_address_range)
#endif /* !ACPI_ASL_COMPILER */
/*******************************************************************************
*
* FUNCTION: acpi_decode_pld_buffer
*
* PARAMETERS: in_buffer - Buffer returned by _PLD method
* length - Length of the in_buffer
* return_buffer - Where the decode buffer is returned
*
* RETURN: Status and the decoded _PLD buffer. User must deallocate
* the buffer via ACPI_FREE.
*
* DESCRIPTION: Decode the bit-packed buffer returned by the _PLD method into
* a local struct that is much more useful to an ACPI driver.
*
******************************************************************************/
acpi_status
acpi_decode_pld_buffer(u8 *in_buffer,
acpi_size length, struct acpi_pld_info ** return_buffer)
{
struct acpi_pld_info *pld_info;
u32 *buffer = ACPI_CAST_PTR(u32, in_buffer);
u32 dword;
/* Parameter validation */
if (!in_buffer || !return_buffer || (length < 16)) {
return (AE_BAD_PARAMETER);
}
pld_info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pld_info));
if (!pld_info) {
return (AE_NO_MEMORY);
}
/* First 32-bit DWord */
ACPI_MOVE_32_TO_32(&dword, &buffer[0]);
pld_info->revision = ACPI_PLD_GET_REVISION(&dword);
pld_info->ignore_color = ACPI_PLD_GET_IGNORE_COLOR(&dword);
pld_info->color = ACPI_PLD_GET_COLOR(&dword);
/* Second 32-bit DWord */
ACPI_MOVE_32_TO_32(&dword, &buffer[1]);
pld_info->width = ACPI_PLD_GET_WIDTH(&dword);
pld_info->height = ACPI_PLD_GET_HEIGHT(&dword);
/* Third 32-bit DWord */
ACPI_MOVE_32_TO_32(&dword, &buffer[2]);
pld_info->user_visible = ACPI_PLD_GET_USER_VISIBLE(&dword);
pld_info->dock = ACPI_PLD_GET_DOCK(&dword);
pld_info->lid = ACPI_PLD_GET_LID(&dword);
pld_info->panel = ACPI_PLD_GET_PANEL(&dword);
pld_info->vertical_position = ACPI_PLD_GET_VERTICAL(&dword);
pld_info->horizontal_position = ACPI_PLD_GET_HORIZONTAL(&dword);
pld_info->shape = ACPI_PLD_GET_SHAPE(&dword);
pld_info->group_orientation = ACPI_PLD_GET_ORIENTATION(&dword);
pld_info->group_token = ACPI_PLD_GET_TOKEN(&dword);
pld_info->group_position = ACPI_PLD_GET_POSITION(&dword);
pld_info->bay = ACPI_PLD_GET_BAY(&dword);
/* Fourth 32-bit DWord */
ACPI_MOVE_32_TO_32(&dword, &buffer[3]);
pld_info->ejectable = ACPI_PLD_GET_EJECTABLE(&dword);
pld_info->ospm_eject_required = ACPI_PLD_GET_OSPM_EJECT(&dword);
pld_info->cabinet_number = ACPI_PLD_GET_CABINET(&dword);
pld_info->card_cage_number = ACPI_PLD_GET_CARD_CAGE(&dword);
pld_info->reference = ACPI_PLD_GET_REFERENCE(&dword);
pld_info->rotation = ACPI_PLD_GET_ROTATION(&dword);
pld_info->order = ACPI_PLD_GET_ORDER(&dword);
if (length >= ACPI_PLD_BUFFER_SIZE) {
/* Fifth 32-bit DWord (Revision 2 of _PLD) */
ACPI_MOVE_32_TO_32(&dword, &buffer[4]);
pld_info->vertical_offset = ACPI_PLD_GET_VERT_OFFSET(&dword);
pld_info->horizontal_offset = ACPI_PLD_GET_HORIZ_OFFSET(&dword);
}
*return_buffer = pld_info;
return (AE_OK);
}
ACPI_EXPORT_SYMBOL(acpi_decode_pld_buffer)