From 5853a9f6dda244b4163b9daad663bdc41a74f596 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 2 Jun 2009 13:20:00 +0800 Subject: [PATCH 01/34] ACPICA: Fix several pointer casts to avoid possible compile warnings Fixes warnings with gcc -Wcast-qual flag. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/exdump.c | 6 +++--- drivers/acpi/acpica/nsutils.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c index ec524614e708..de3446372ddc 100644 --- a/drivers/acpi/acpica/exdump.c +++ b/drivers/acpi/acpica/exdump.c @@ -418,9 +418,9 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, case ACPI_EXD_REFERENCE: acpi_ex_out_string("Class Name", - (char *) - acpi_ut_get_reference_name - (obj_desc)); + ACPI_CAST_PTR(char, + acpi_ut_get_reference_name + (obj_desc))); acpi_ex_dump_reference_obj(obj_desc); break; diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c index 78277ed08339..ea55ab4f9849 100644 --- a/drivers/acpi/acpica/nsutils.c +++ b/drivers/acpi/acpica/nsutils.c @@ -88,7 +88,8 @@ acpi_ns_report_error(const char *module_name, /* There is a non-ascii character in the name */ - ACPI_MOVE_32_TO_32(&bad_name, internal_name); + ACPI_MOVE_32_TO_32(&bad_name, + ACPI_CAST_PTR(u32, internal_name)); acpi_os_printf("[0x%4.4X] (NON-ASCII)", bad_name); } else { /* Convert path to external format */ @@ -836,7 +837,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node, acpi_status status; char *internal_path; - ACPI_FUNCTION_TRACE_PTR(ns_get_node, pathname); + ACPI_FUNCTION_TRACE_PTR(ns_get_node, ACPI_CAST_PTR(char, pathname)); if (!pathname) { *return_node = prefix_node; From f8d80cdf40fe4d2393159012b38ce9f85a488686 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Tue, 2 Jun 2009 13:28:13 +0800 Subject: [PATCH 02/34] ACPICA: Remove duplicate extern declarations for public globals Some were defined twice, causes a warning with gcc -Wredundant-decls. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acglobal.h | 33 ++++++++++++++++++--------------- include/acpi/acpixf.h | 1 + 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 3d87362d17ed..0b73b31c1b53 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -58,6 +58,10 @@ #define ACPI_INIT_GLOBAL(a,b) a #endif +#ifdef DEFINE_ACPI_GLOBALS + +/* Public globals, available from outside ACPICA subsystem */ + /***************************************************************************** * * Runtime configuration (static defaults that can be overriden at runtime) @@ -78,7 +82,7 @@ * 5) Allow unresolved references (invalid target name) in package objects * 6) Enable warning messages for behavior that is not ACPI spec compliant */ -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); +u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); /* * Automatically serialize ALL control methods? Default is FALSE, meaning @@ -86,27 +90,36 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_interpreter_slack, FALSE); * Only change this if the ASL code is poorly written and cannot handle * reentrancy even though methods are marked "NotSerialized". */ -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); +u8 ACPI_INIT_GLOBAL(acpi_gbl_all_methods_serialized, FALSE); /* * Create the predefined _OSI method in the namespace? Default is TRUE * because ACPI CA is fully compatible with other ACPI implementations. * Changing this will revert ACPI CA (and machine ASL) to pre-OSI behavior. */ -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); +u8 ACPI_INIT_GLOBAL(acpi_gbl_create_osi_method, TRUE); /* * Disable wakeup GPEs during runtime? Default is TRUE because WAKE and * RUNTIME GPEs should never be shared, and WAKE GPEs should typically only * be enabled just before going to sleep. */ -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); +u8 ACPI_INIT_GLOBAL(acpi_gbl_leave_wake_gpes_disabled, TRUE); /* * Optionally use default values for the ACPI register widths. Set this to * TRUE to use the defaults, if an FADT contains incorrect widths/lengths. */ -ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); +u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); + +/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ + +struct acpi_table_fadt acpi_gbl_FADT; +u32 acpi_current_gpe_count; +u32 acpi_gbl_trace_flags; +acpi_name acpi_gbl_trace_method_name; + +#endif /***************************************************************************** * @@ -114,11 +127,6 @@ ACPI_EXTERN u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE); * ****************************************************************************/ -/* Runtime configuration of debug print levels */ - -extern u32 acpi_dbg_level; -extern u32 acpi_dbg_layer; - /* Procedure nesting level for debug output */ extern u32 acpi_gbl_nesting_level; @@ -127,10 +135,8 @@ extern u32 acpi_gbl_nesting_level; ACPI_EXTERN u32 acpi_gbl_original_dbg_level; ACPI_EXTERN u32 acpi_gbl_original_dbg_layer; -ACPI_EXTERN acpi_name acpi_gbl_trace_method_name; ACPI_EXTERN u32 acpi_gbl_trace_dbg_level; ACPI_EXTERN u32 acpi_gbl_trace_dbg_layer; -ACPI_EXTERN u32 acpi_gbl_trace_flags; /***************************************************************************** * @@ -142,10 +148,8 @@ ACPI_EXTERN u32 acpi_gbl_trace_flags; * acpi_gbl_root_table_list is the master list of ACPI tables found in the * RSDT/XSDT. * - * acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list; -ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT; ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS; /* These addresses are calculated from the FADT Event Block addresses */ @@ -340,7 +344,6 @@ ACPI_EXTERN struct acpi_fixed_event_handler ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; -ACPI_EXTERN u32 acpi_current_gpe_count; /***************************************************************************** * diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 82ec6a3c0500..2aecaa5cc06c 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -64,6 +64,7 @@ extern u8 acpi_gbl_enable_interpreter_slack; extern u8 acpi_gbl_all_methods_serialized; extern u8 acpi_gbl_create_osi_method; extern u8 acpi_gbl_leave_wake_gpes_disabled; +extern u8 acpi_gbl_use_default_register_widths; extern acpi_name acpi_gbl_trace_method_name; extern u32 acpi_gbl_trace_flags; From c6b5774caafa4c12b6019366e2fdaaff117e95a4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 09:44:06 +0800 Subject: [PATCH 03/34] ACPICA: Add 64-bit support to acpi_read and acpi_write Needed by drivers for new ACPi tables. Internal versions of these functions still use 32-bit max transfers, in order to minimize disruption and stack use for the standard ACPI registers (FADT-based). Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/achware.h | 8 ++ drivers/acpi/acpica/evgpe.c | 8 +- drivers/acpi/acpica/evgpeblk.c | 4 +- drivers/acpi/acpica/hwgpe.c | 34 +++--- drivers/acpi/acpica/hwregs.c | 206 +++++++++++++++++++++++++++++++-- drivers/acpi/acpica/hwtimer.c | 2 +- drivers/acpi/acpica/hwxface.c | 168 ++++++++++++++++----------- include/acpi/acpixf.h | 4 +- 8 files changed, 328 insertions(+), 106 deletions(-) diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 4afa3d8e0efb..36192f142fbb 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -62,6 +62,14 @@ u32 acpi_hw_get_mode(void); /* * hwregs - ACPI Register I/O */ +acpi_status +acpi_hw_validate_register(struct acpi_generic_address *reg, + u8 max_bit_width, u64 *address); + +acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg); + +acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg); + struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id); acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index b9d8ee69ca6c..afacf4416c73 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -424,8 +424,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Read the Status Register */ status = - acpi_read(&status_reg, - &gpe_register_info->status_address); + acpi_hw_read(&status_reg, + &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -433,8 +433,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) /* Read the Enable Register */ status = - acpi_read(&enable_reg, - &gpe_register_info->enable_address); + acpi_hw_read(&enable_reg, + &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7b3463639422..a60aaa7635f3 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -843,14 +843,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block) /* Disable all GPEs within this register */ - status = acpi_write(0x00, &this_register->enable_address); + status = acpi_hw_write(0x00, &this_register->enable_address); if (ACPI_FAILURE(status)) { goto error_exit; } /* Clear any pending GPE events within this register */ - status = acpi_write(0xFF, &this_register->status_address); + status = acpi_hw_write(0xFF, &this_register->status_address); if (ACPI_FAILURE(status)) { goto error_exit; } diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index d3b7e37c9eed..c28c41b3180b 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -82,7 +82,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) /* Get current value of the enable register that contains this GPE */ - status = acpi_read(&enable_mask, &gpe_register_info->enable_address); + status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -95,7 +95,7 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) /* Write the updated enable mask */ - status = acpi_write(enable_mask, &gpe_register_info->enable_address); + status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address); return (status); } @@ -130,8 +130,8 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) /* Write the entire GPE (runtime) enable register */ - status = acpi_write(gpe_register_info->enable_for_run, - &gpe_register_info->enable_address); + status = acpi_hw_write(gpe_register_info->enable_for_run, + &gpe_register_info->enable_address); return (status); } @@ -163,8 +163,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) * Write a one to the appropriate bit in the status register to * clear this GPE. */ - status = acpi_write(register_bit, - &gpe_event_info->register_info->status_address); + status = acpi_hw_write(register_bit, + &gpe_event_info->register_info->status_address); return (status); } @@ -222,7 +222,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* GPE currently active (status bit == 1)? */ - status = acpi_read(&in_byte, &gpe_register_info->status_address); + status = acpi_hw_read(&in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE(status)) { goto unlock_and_exit; } @@ -266,8 +266,8 @@ acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Disable all GPEs in this register */ status = - acpi_write(0x00, - &gpe_block->register_info[i].enable_address); + acpi_hw_write(0x00, + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -303,8 +303,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Clear status on all GPEs in this register */ status = - acpi_write(0xFF, - &gpe_block->register_info[i].status_address); + acpi_hw_write(0xFF, + &gpe_block->register_info[i].status_address); if (ACPI_FAILURE(status)) { return (status); } @@ -345,9 +345,9 @@ acpi_hw_enable_runtime_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Enable all "runtime" GPEs in this register */ - status = acpi_write(gpe_block->register_info[i].enable_for_run, - &gpe_block->register_info[i]. - enable_address); + status = + acpi_hw_write(gpe_block->register_info[i].enable_for_run, + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE(status)) { return (status); } @@ -387,9 +387,9 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /* Enable all "wake" GPEs in this register */ - status = acpi_write(gpe_block->register_info[i].enable_for_wake, - &gpe_block->register_info[i]. - enable_address); + status = + acpi_hw_write(gpe_block->register_info[i].enable_for_wake, + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE(status)) { return (status); } diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c index 23d5505cb1f7..15c9ed2be853 100644 --- a/drivers/acpi/acpica/hwregs.c +++ b/drivers/acpi/acpica/hwregs.c @@ -62,6 +62,184 @@ acpi_hw_write_multiple(u32 value, struct acpi_generic_address *register_a, struct acpi_generic_address *register_b); +/****************************************************************************** + * + * FUNCTION: acpi_hw_validate_register + * + * PARAMETERS: Reg - GAS register structure + * max_bit_width - Max bit_width supported (32 or 64) + * Address - Pointer to where the gas->address + * is returned + * + * RETURN: Status + * + * DESCRIPTION: Validate the contents of a GAS register. Checks the GAS + * pointer, Address, space_id, bit_width, and bit_offset. + * + ******************************************************************************/ + +acpi_status +acpi_hw_validate_register(struct acpi_generic_address *reg, + u8 max_bit_width, u64 *address) +{ + + /* Must have a valid pointer to a GAS structure */ + + if (!reg) { + return (AE_BAD_PARAMETER); + } + + /* + * Copy the target address. This handles possible alignment issues. + * Address must not be null. A null address also indicates an optional + * ACPI register that is not supported, so no error message. + */ + ACPI_MOVE_64_TO_64(address, ®->address); + if (!(*address)) { + return (AE_BAD_ADDRESS); + } + + /* Validate the space_iD */ + + if ((reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) && + (reg->space_id != ACPI_ADR_SPACE_SYSTEM_IO)) { + ACPI_ERROR((AE_INFO, + "Unsupported address space: 0x%X", reg->space_id)); + return (AE_SUPPORT); + } + + /* Validate the bit_width */ + + if ((reg->bit_width != 8) && + (reg->bit_width != 16) && + (reg->bit_width != 32) && (reg->bit_width != max_bit_width)) { + ACPI_ERROR((AE_INFO, + "Unsupported register bit width: 0x%X", + reg->bit_width)); + return (AE_SUPPORT); + } + + /* Validate the bit_offset. Just a warning for now. */ + + if (reg->bit_offset != 0) { + ACPI_WARNING((AE_INFO, + "Unsupported register bit offset: 0x%X", + reg->bit_offset)); + } + + return (AE_OK); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_read + * + * PARAMETERS: Value - Where the value is returned + * Reg - GAS register structure + * + * RETURN: Status + * + * DESCRIPTION: Read from either memory or IO space. This is a 32-bit max + * version of acpi_read, used internally since the overhead of + * 64-bit values is not needed. + * + * LIMITATIONS: + * bit_width must be exactly 8, 16, or 32. + * space_iD must be system_memory or system_iO. + * bit_offset and access_width are currently ignored, as there has + * not been a need to implement these. + * + ******************************************************************************/ + +acpi_status acpi_hw_read(u32 *value, struct acpi_generic_address *reg) +{ + u64 address; + acpi_status status; + + ACPI_FUNCTION_NAME(hw_read); + + /* Validate contents of the GAS register */ + + status = acpi_hw_validate_register(reg, 32, &address); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Initialize entire 32-bit return value to zero */ + + *value = 0; + + /* + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient + */ + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + status = acpi_os_read_memory((acpi_physical_address) + address, value, reg->bit_width); + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + + status = acpi_hw_read_port((acpi_io_address) + address, value, reg->bit_width); + } + + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", + *value, reg->bit_width, ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->space_id))); + + return (status); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_write + * + * PARAMETERS: Value - Value to be written + * Reg - GAS register structure + * + * RETURN: Status + * + * DESCRIPTION: Write to either memory or IO space. This is a 32-bit max + * version of acpi_write, used internally since the overhead of + * 64-bit values is not needed. + * + ******************************************************************************/ + +acpi_status acpi_hw_write(u32 value, struct acpi_generic_address *reg) +{ + u64 address; + acpi_status status; + + ACPI_FUNCTION_NAME(hw_write); + + /* Validate contents of the GAS register */ + + status = acpi_hw_validate_register(reg, 32, &address); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient + */ + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + status = acpi_os_write_memory((acpi_physical_address) + address, value, reg->bit_width); + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ + + status = acpi_hw_write_port((acpi_io_address) + address, value, reg->bit_width); + } + + ACPI_DEBUG_PRINT((ACPI_DB_IO, + "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", + value, reg->bit_width, ACPI_FORMAT_UINT64(address), + acpi_ut_get_region_name(reg->space_id))); + + return (status); +} + /******************************************************************************* * * FUNCTION: acpi_hw_clear_acpi_status @@ -152,15 +330,16 @@ acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control) ACPI_FUNCTION_TRACE(hw_write_pm1_control); - status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); + status = + acpi_hw_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } if (acpi_gbl_FADT.xpm1b_control_block.address) { status = - acpi_write(pm1b_control, - &acpi_gbl_FADT.xpm1b_control_block); + acpi_hw_write(pm1b_control, + &acpi_gbl_FADT.xpm1b_control_block); } return_ACPI_STATUS(status); } @@ -218,12 +397,13 @@ acpi_hw_register_read(u32 register_id, u32 * return_value) case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block); + status = + acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ @@ -340,7 +520,8 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) * as per the ACPI spec. */ status = - acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block); + acpi_hw_read(&read_value, + &acpi_gbl_FADT.xpm2_control_block); if (ACPI_FAILURE(status)) { goto exit; } @@ -350,12 +531,13 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value) ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS, read_value); - status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block); + status = + acpi_hw_write(value, &acpi_gbl_FADT.xpm2_control_block); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - status = acpi_write(value, &acpi_gbl_FADT.xpm_timer_block); + status = acpi_hw_write(value, &acpi_gbl_FADT.xpm_timer_block); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ @@ -401,7 +583,7 @@ acpi_hw_read_multiple(u32 *value, /* The first register is always required */ - status = acpi_read(&value_a, register_a); + status = acpi_hw_read(&value_a, register_a); if (ACPI_FAILURE(status)) { return (status); } @@ -409,7 +591,7 @@ acpi_hw_read_multiple(u32 *value, /* Second register is optional */ if (register_b->address) { - status = acpi_read(&value_b, register_b); + status = acpi_hw_read(&value_b, register_b); if (ACPI_FAILURE(status)) { return (status); } @@ -452,7 +634,7 @@ acpi_hw_write_multiple(u32 value, /* The first register is always required */ - status = acpi_write(value, register_a); + status = acpi_hw_write(value, register_a); if (ACPI_FAILURE(status)) { return (status); } @@ -470,7 +652,7 @@ acpi_hw_write_multiple(u32 value, * and writes have no side effects" */ if (register_b->address) { - status = acpi_write(value, register_b); + status = acpi_hw_write(value, register_b); } return (status); diff --git a/drivers/acpi/acpica/hwtimer.c b/drivers/acpi/acpica/hwtimer.c index b7f522c8f023..6b282e85d039 100644 --- a/drivers/acpi/acpica/hwtimer.c +++ b/drivers/acpi/acpica/hwtimer.c @@ -100,7 +100,7 @@ acpi_status acpi_get_timer(u32 * ticks) } status = - acpi_hw_low_level_read(32, ticks, &acpi_gbl_FADT.xpm_timer_block); + acpi_hw_read(ticks, &acpi_gbl_FADT.xpm_timer_block); return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 9829979f2bdd..4ead85f29215 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -80,7 +80,7 @@ acpi_status acpi_reset(void) /* Write the reset value to the reset register */ - status = acpi_write(acpi_gbl_FADT.reset_value, reset_reg); + status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); return_ACPI_STATUS(status); } @@ -97,67 +97,92 @@ ACPI_EXPORT_SYMBOL(acpi_reset) * * DESCRIPTION: Read from either memory or IO space. * + * LIMITATIONS: + * bit_width must be exactly 8, 16, 32, or 64. + * space_iD must be system_memory or system_iO. + * bit_offset and access_width are currently ignored, as there has + * not been a need to implement these. + * ******************************************************************************/ -acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg) +acpi_status acpi_read(u64 *return_value, struct acpi_generic_address *reg) { + u32 value; u32 width; u64 address; acpi_status status; ACPI_FUNCTION_NAME(acpi_read); - /* - * Must have a valid pointer to a GAS structure, and a non-zero address - * within. - */ - if (!reg) { + if (!return_value) { return (AE_BAD_PARAMETER); } - /* Get a local copy of the address. Handles possible alignment issues */ + /* Validate contents of the GAS register. Allow 64-bit transfers */ - ACPI_MOVE_64_TO_64(&address, ®->address); - if (!address) { - return (AE_BAD_ADDRESS); + status = acpi_hw_validate_register(reg, 64, &address); + if (ACPI_FAILURE(status)) { + return (status); } - /* Supported widths are 8/16/32 */ - width = reg->bit_width; - if ((width != 8) && (width != 16) && (width != 32)) { - return (AE_SUPPORT); + if (width == 64) { + width = 32; /* Break into two 32-bit transfers */ } - /* Initialize entire 32-bit return value to zero */ + /* Initialize entire 64-bit return value to zero */ - *value = 0; + *return_value = 0; + value = 0; /* * Two address spaces supported: Memory or IO. PCI_Config is * not supported here because the GAS structure is insufficient */ - switch (reg->space_id) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + status = acpi_os_read_memory((acpi_physical_address) + address, &value, width); + if (ACPI_FAILURE(status)) { + return (status); + } + *return_value = value; - status = acpi_os_read_memory((acpi_physical_address) address, - value, width); - break; + if (reg->bit_width == 64) { - case ACPI_ADR_SPACE_SYSTEM_IO: + /* Read the top 32 bits */ - status = - acpi_hw_read_port((acpi_io_address) address, value, width); - break; + status = acpi_os_read_memory((acpi_physical_address) + (address + 4), &value, 32); + if (ACPI_FAILURE(status)) { + return (status); + } + *return_value |= ((u64)value << 32); + } + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ - default: - ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); - return (AE_BAD_PARAMETER); + status = acpi_hw_read_port((acpi_io_address) + address, &value, width); + if (ACPI_FAILURE(status)) { + return (status); + } + *return_value = value; + + if (reg->bit_width == 64) { + + /* Read the top 32 bits */ + + status = acpi_hw_read_port((acpi_io_address) + (address + 4), &value, 32); + if (ACPI_FAILURE(status)) { + return (status); + } + *return_value |= ((u64)value << 32); + } } ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Read: %8.8X width %2d from %8.8X%8.8X (%s)\n", - *value, width, ACPI_FORMAT_UINT64(address), + "Read: %8.8X%8.8X width %2d from %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64(*return_value), reg->bit_width, + ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); @@ -169,7 +194,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) * * FUNCTION: acpi_write * - * PARAMETERS: Value - To be written + * PARAMETERS: Value - Value to be written * Reg - GAS register structure * * RETURN: Status @@ -177,7 +202,7 @@ ACPI_EXPORT_SYMBOL(acpi_read) * DESCRIPTION: Write to either memory or IO space. * ******************************************************************************/ -acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) +acpi_status acpi_write(u64 value, struct acpi_generic_address *reg) { u32 width; u64 address; @@ -185,54 +210,61 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg) ACPI_FUNCTION_NAME(acpi_write); - /* - * Must have a valid pointer to a GAS structure, and a non-zero address - * within. - */ - if (!reg) { - return (AE_BAD_PARAMETER); + /* Validate contents of the GAS register. Allow 64-bit transfers */ + + status = acpi_hw_validate_register(reg, 64, &address); + if (ACPI_FAILURE(status)) { + return (status); } - /* Get a local copy of the address. Handles possible alignment issues */ - - ACPI_MOVE_64_TO_64(&address, ®->address); - if (!address) { - return (AE_BAD_ADDRESS); - } - - /* Supported widths are 8/16/32 */ - width = reg->bit_width; - if ((width != 8) && (width != 16) && (width != 32)) { - return (AE_SUPPORT); + if (width == 64) { + width = 32; /* Break into two 32-bit transfers */ } /* - * Two address spaces supported: Memory or IO. - * PCI_Config is not supported here because the GAS struct is insufficient + * Two address spaces supported: Memory or IO. PCI_Config is + * not supported here because the GAS structure is insufficient */ - switch (reg->space_id) { - case ACPI_ADR_SPACE_SYSTEM_MEMORY: + if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + status = acpi_os_write_memory((acpi_physical_address) + address, ACPI_LODWORD(value), + width); + if (ACPI_FAILURE(status)) { + return (status); + } - status = acpi_os_write_memory((acpi_physical_address) address, - value, width); - break; + if (reg->bit_width == 64) { + status = acpi_os_write_memory((acpi_physical_address) + (address + 4), + ACPI_HIDWORD(value), 32); + if (ACPI_FAILURE(status)) { + return (status); + } + } + } else { /* ACPI_ADR_SPACE_SYSTEM_IO, validated earlier */ - case ACPI_ADR_SPACE_SYSTEM_IO: - - status = acpi_hw_write_port((acpi_io_address) address, value, + status = acpi_hw_write_port((acpi_io_address) + address, ACPI_LODWORD(value), width); - break; + if (ACPI_FAILURE(status)) { + return (status); + } - default: - ACPI_ERROR((AE_INFO, - "Unsupported address space: %X", reg->space_id)); - return (AE_BAD_PARAMETER); + if (reg->bit_width == 64) { + status = acpi_hw_write_port((acpi_io_address) + (address + 4), + ACPI_HIDWORD(value), 32); + if (ACPI_FAILURE(status)) { + return (status); + } + } } ACPI_DEBUG_PRINT((ACPI_DB_IO, - "Wrote: %8.8X width %2d to %8.8X%8.8X (%s)\n", - value, width, ACPI_FORMAT_UINT64(address), + "Wrote: %8.8X%8.8X width %2d to %8.8X%8.8X (%s)\n", + ACPI_FORMAT_UINT64(value), reg->bit_width, + ACPI_FORMAT_UINT64(address), acpi_ut_get_region_name(reg->space_id))); return (status); diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2aecaa5cc06c..b450a195319a 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -360,9 +360,9 @@ acpi_status acpi_set_firmware_waking_vector(u32 physical_address); acpi_status acpi_set_firmware_waking_vector64(u64 physical_address); #endif -acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg); +acpi_status acpi_read(u64 *value, struct acpi_generic_address *reg); -acpi_status acpi_write(u32 value, struct acpi_generic_address *reg); +acpi_status acpi_write(u64 value, struct acpi_generic_address *reg); acpi_status acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); From 9c61b34cf7078da72cce276ff8cfae5d6e9955bc Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 09:45:17 +0800 Subject: [PATCH 04/34] ACPICA: Remove duplicate prototypes from header Two duplicates in acdebug.h. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acdebug.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/acpi/acpica/acdebug.h b/drivers/acpi/acpica/acdebug.h index 62c59df3b86c..a4fb001d96f1 100644 --- a/drivers/acpi/acpica/acdebug.h +++ b/drivers/acpi/acpica/acdebug.h @@ -154,10 +154,6 @@ void acpi_db_display_argument_object(union acpi_operand_object *obj_desc, struct acpi_walk_state *walk_state); -void acpi_db_check_predefined_names(void); - -void acpi_db_batch_execute(void); - /* * dbexec - debugger control method execution */ From 15b8dd53f5ffaf8e2d9095c423f713423f576c0f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 29 Jun 2009 13:39:29 +0800 Subject: [PATCH 05/34] ACPICA: Major update for acpi_get_object_info external interface Completed a major update for the acpi_get_object_info external interface. Changes include: - Support for variable, unlimited length HID, UID, and CID strings - Support Processor objects the same as Devices (HID,UID,CID,ADR,STA, etc.) - Call the _SxW power methods on behalf of a device object - Determine if a device is a PCI root bridge - Change the ACPI_BUFFER parameter to ACPI_DEVICE_INFO. These changes will require an update to all callers of this interface. See the ACPICA Programmer Reference for details. Also, update all invocations of acpi_get_object_info interface Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- arch/ia64/hp/common/sba_iommu.c | 7 +- drivers/acpi/acpi_memhotplug.c | 11 +- drivers/acpi/acpica/Makefile | 2 +- drivers/acpi/acpica/acconfig.h | 5 + drivers/acpi/acpica/acglobal.h | 3 +- drivers/acpi/acpica/acinterp.h | 4 +- drivers/acpi/acpica/acutils.h | 30 ++- drivers/acpi/acpica/evrgnini.c | 45 +--- drivers/acpi/acpica/exutils.c | 53 ++-- drivers/acpi/acpica/nsdumpdv.c | 7 +- drivers/acpi/acpica/nsxfeval.c | 23 +- drivers/acpi/acpica/nsxfname.c | 237 +++++++++++++----- drivers/acpi/acpica/uteval.c | 375 ++++------------------------ drivers/acpi/acpica/utglobal.c | 10 +- drivers/acpi/acpica/utids.c | 382 +++++++++++++++++++++++++++++ drivers/acpi/acpica/utmisc.c | 28 +++ drivers/acpi/container.c | 11 +- drivers/acpi/dock.c | 8 +- drivers/acpi/glue.c | 6 +- drivers/acpi/scan.c | 157 +++++++----- drivers/char/agp/hp-agp.c | 9 +- drivers/ide/ide-acpi.c | 5 +- drivers/pci/hotplug/acpiphp_ibm.c | 12 +- drivers/platform/x86/sony-laptop.c | 7 +- drivers/pnp/pnpacpi/core.c | 6 +- include/acpi/acpi_bus.h | 8 +- include/acpi/acpixf.h | 3 +- include/acpi/actypes.h | 87 ++++--- 28 files changed, 906 insertions(+), 635 deletions(-) create mode 100644 drivers/acpi/acpica/utids.c diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index 8cfb001092ab..674a8374c6d9 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -2026,24 +2026,21 @@ acpi_sba_ioc_add(struct acpi_device *device) struct ioc *ioc; acpi_status status; u64 hpa, length; - struct acpi_buffer buffer; struct acpi_device_info *dev_info; status = hp_acpi_csr_space(device->handle, &hpa, &length); if (ACPI_FAILURE(status)) return 1; - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_get_object_info(device->handle, &buffer); + status = acpi_get_object_info(device->handle, &dev_info); if (ACPI_FAILURE(status)) return 1; - dev_info = buffer.pointer; /* * For HWP0001, only SBA appears in ACPI namespace. It encloses the PCI * root bridges, and its CSR space includes the IOC function. */ - if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0) { + if (strncmp("HWP0001", dev_info->hardware_id.string, 7) == 0) { hpa += ZX1_IOC_OFFSET; /* zx1 based systems default to kernel page size iommu pages */ if (!iovp_shift) diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 9a62224cc278..80eacbe157e2 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -481,26 +481,23 @@ static acpi_status is_memory_device(acpi_handle handle) { char *hardware_id; acpi_status status; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_device_info *info; - - status = acpi_get_object_info(handle, &buffer); + status = acpi_get_object_info(handle, &info); if (ACPI_FAILURE(status)) return status; - info = buffer.pointer; if (!(info->valid & ACPI_VALID_HID)) { - kfree(buffer.pointer); + kfree(info); return AE_ERROR; } - hardware_id = info->hardware_id.value; + hardware_id = info->hardware_id.string; if ((hardware_id == NULL) || (strcmp(hardware_id, ACPI_MEMORY_DEVICE_HID))) status = AE_ERROR; - kfree(buffer.pointer); + kfree(info); return status; } diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 72ac28da14e3..0e7d56185f6d 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -44,4 +44,4 @@ acpi-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o acpi-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \ utcopy.o utdelete.o utglobal.o utmath.o utobject.o \ - utstate.o utmutex.o utobject.o utresrc.o utlock.o + utstate.o utmutex.o utobject.o utresrc.o utlock.o utids.o diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index e6777fb883d2..6c1fb2d9f4d5 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -203,6 +203,11 @@ #define ACPI_SMBUS_BUFFER_SIZE 34 +/* _sx_d and _sx_w control methods */ + +#define ACPI_NUM_sx_d_METHODS 4 +#define ACPI_NUM_sx_w_METHODS 5 + /****************************************************************************** * * ACPI AML Debugger diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 0b73b31c1b53..6389f7c1de59 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -265,7 +265,8 @@ ACPI_EXTERN u8 acpi_gbl_osi_data; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_startup_flags; extern const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT]; -extern const char *acpi_gbl_highest_dstate_names[4]; +extern const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS]; +extern const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS]; extern const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES]; extern const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS]; diff --git a/drivers/acpi/acpica/acinterp.h b/drivers/acpi/acpica/acinterp.h index e8db7a3143a5..5db9f2916f7c 100644 --- a/drivers/acpi/acpica/acinterp.h +++ b/drivers/acpi/acpica/acinterp.h @@ -461,9 +461,9 @@ void acpi_ex_acquire_global_lock(u32 rule); void acpi_ex_release_global_lock(u32 rule); -void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string); +void acpi_ex_eisa_id_to_string(char *dest, acpi_integer compressed_id); -void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string); +void acpi_ex_integer_to_string(char *dest, acpi_integer value); /* * exregion - default op_region handlers diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index 897810ba0ccc..b0add85de308 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -324,26 +324,30 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer * address); + acpi_integer *value); acpi_status +acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 *status_flags); + +acpi_status +acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, + const char **method_names, + u8 method_count, u8 *out_values); + +/* + * utids - device ID support + */ +acpi_status acpi_ut_execute_HID(struct acpi_namespace_node *device_node, - struct acpica_device_id *hid); - -acpi_status -acpi_ut_execute_CID(struct acpi_namespace_node *device_node, - struct acpi_compatible_id_list **return_cid_list); - -acpi_status -acpi_ut_execute_STA(struct acpi_namespace_node *device_node, - u32 * status_flags); + struct acpica_device_id **return_id); acpi_status acpi_ut_execute_UID(struct acpi_namespace_node *device_node, - struct acpica_device_id *uid); + struct acpica_device_id **return_id); acpi_status -acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest); +acpi_ut_execute_CID(struct acpi_namespace_node *device_node, + struct acpica_device_id_list **return_cid_list); /* * utlock - reader/writer locks @@ -445,6 +449,8 @@ acpi_ut_short_divide(acpi_integer in_dividend, */ const char *acpi_ut_validate_exception(acpi_status status); +u8 acpi_ut_is_pci_root_bridge(char *id); + u8 acpi_ut_is_aml_table(struct acpi_table_header *table); acpi_status acpi_ut_allocate_owner_id(acpi_owner_id * owner_id); diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c index 284a7becbe96..cf29c4953028 100644 --- a/drivers/acpi/acpica/evrgnini.c +++ b/drivers/acpi/acpica/evrgnini.c @@ -50,8 +50,6 @@ ACPI_MODULE_NAME("evrgnini") /* Local prototypes */ -static u8 acpi_ev_match_pci_root_bridge(char *id); - static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node); /******************************************************************************* @@ -330,37 +328,6 @@ acpi_ev_pci_config_region_setup(acpi_handle handle, return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_match_pci_root_bridge - * - * PARAMETERS: Id - The HID/CID in string format - * - * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge - * - * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. - * - ******************************************************************************/ - -static u8 acpi_ev_match_pci_root_bridge(char *id) -{ - - /* - * Check if this is a PCI root. - * ACPI 3.0+: check for a PCI Express root also. - */ - if (!(ACPI_STRNCMP(id, - PCI_ROOT_HID_STRING, - sizeof(PCI_ROOT_HID_STRING))) || - !(ACPI_STRNCMP(id, - PCI_EXPRESS_ROOT_HID_STRING, - sizeof(PCI_EXPRESS_ROOT_HID_STRING)))) { - return (TRUE); - } - - return (FALSE); -} - /******************************************************************************* * * FUNCTION: acpi_ev_is_pci_root_bridge @@ -377,9 +344,10 @@ static u8 acpi_ev_match_pci_root_bridge(char *id) static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) { acpi_status status; - struct acpica_device_id hid; - struct acpi_compatible_id_list *cid; + struct acpica_device_id *hid; + struct acpica_device_id_list *cid; u32 i; + u8 match; /* Get the _HID and check for a PCI Root Bridge */ @@ -388,7 +356,10 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) return (FALSE); } - if (acpi_ev_match_pci_root_bridge(hid.value)) { + match = acpi_ut_is_pci_root_bridge(hid->string); + ACPI_FREE(hid); + + if (match) { return (TRUE); } @@ -402,7 +373,7 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) /* Check all _CIDs in the returned list */ for (i = 0; i < cid->count; i++) { - if (acpi_ev_match_pci_root_bridge(cid->id[i].value)) { + if (acpi_ut_is_pci_root_bridge(cid->ids[i].string)) { ACPI_FREE(cid); return (TRUE); } diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c index 87730e944132..7d41f99f7052 100644 --- a/drivers/acpi/acpica/exutils.c +++ b/drivers/acpi/acpica/exutils.c @@ -358,50 +358,67 @@ static u32 acpi_ex_digits_needed(acpi_integer value, u32 base) * * FUNCTION: acpi_ex_eisa_id_to_string * - * PARAMETERS: numeric_id - EISA ID to be converted + * PARAMETERS: compressed_id - EISAID to be converted * out_string - Where to put the converted string (8 bytes) * * RETURN: None * - * DESCRIPTION: Convert a numeric EISA ID to string representation + * DESCRIPTION: Convert a numeric EISAID to string representation. Return + * buffer must be large enough to hold the string. The string + * returned is always exactly of length ACPI_EISAID_STRING_SIZE + * (includes null terminator). The EISAID is always 32 bits. * ******************************************************************************/ -void acpi_ex_eisa_id_to_string(u32 numeric_id, char *out_string) +void acpi_ex_eisa_id_to_string(char *out_string, acpi_integer compressed_id) { - u32 eisa_id; + u32 swapped_id; ACPI_FUNCTION_ENTRY(); + /* The EISAID should be a 32-bit integer */ + + if (compressed_id > ACPI_UINT32_MAX) { + ACPI_WARNING((AE_INFO, + "Expected EISAID is larger than 32 bits: 0x%8.8X%8.8X, truncating", + ACPI_FORMAT_UINT64(compressed_id))); + } + /* Swap ID to big-endian to get contiguous bits */ - eisa_id = acpi_ut_dword_byte_swap(numeric_id); + swapped_id = acpi_ut_dword_byte_swap((u32)compressed_id); - out_string[0] = (char)('@' + (((unsigned long)eisa_id >> 26) & 0x1f)); - out_string[1] = (char)('@' + ((eisa_id >> 21) & 0x1f)); - out_string[2] = (char)('@' + ((eisa_id >> 16) & 0x1f)); - out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 12); - out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 8); - out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 4); - out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer) eisa_id, 0); + /* First 3 bytes are uppercase letters. Next 4 bytes are hexadecimal */ + + out_string[0] = + (char)(0x40 + (((unsigned long)swapped_id >> 26) & 0x1F)); + out_string[1] = (char)(0x40 + ((swapped_id >> 21) & 0x1F)); + out_string[2] = (char)(0x40 + ((swapped_id >> 16) & 0x1F)); + out_string[3] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 12); + out_string[4] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 8); + out_string[5] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 4); + out_string[6] = acpi_ut_hex_to_ascii_char((acpi_integer)swapped_id, 0); out_string[7] = 0; } /******************************************************************************* * - * FUNCTION: acpi_ex_unsigned_integer_to_string + * FUNCTION: acpi_ex_integer_to_string * - * PARAMETERS: Value - Value to be converted - * out_string - Where to put the converted string (8 bytes) + * PARAMETERS: out_string - Where to put the converted string. At least + * 21 bytes are needed to hold the largest + * possible 64-bit integer. + * Value - Value to be converted * * RETURN: None, string * - * DESCRIPTION: Convert a number to string representation. Assumes string - * buffer is large enough to hold the string. + * DESCRIPTION: Convert a 64-bit integer to decimal string representation. + * Assumes string buffer is large enough to hold the string. The + * largest string is (ACPI_MAX64_DECIMAL_DIGITS + 1). * ******************************************************************************/ -void acpi_ex_unsigned_integer_to_string(acpi_integer value, char *out_string) +void acpi_ex_integer_to_string(char *out_string, acpi_integer value) { u32 count; u32 digits_needed; diff --git a/drivers/acpi/acpica/nsdumpdv.c b/drivers/acpi/acpica/nsdumpdv.c index 41994fe7fbb8..0fe87f1aef16 100644 --- a/drivers/acpi/acpica/nsdumpdv.c +++ b/drivers/acpi/acpica/nsdumpdv.c @@ -70,7 +70,6 @@ static acpi_status acpi_ns_dump_one_device(acpi_handle obj_handle, u32 level, void *context, void **return_value) { - struct acpi_buffer buffer; struct acpi_device_info *info; acpi_status status; u32 i; @@ -80,17 +79,15 @@ acpi_ns_dump_one_device(acpi_handle obj_handle, status = acpi_ns_dump_one_object(obj_handle, level, context, return_value); - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_get_object_info(obj_handle, &buffer); + status = acpi_get_object_info(obj_handle, &info); if (ACPI_SUCCESS(status)) { - info = buffer.pointer; for (i = 0; i < level; i++) { ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " ")); } ACPI_DEBUG_PRINT_RAW((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", - info->hardware_id.value, + info->hardware_id.string, ACPI_FORMAT_UINT64(info->address), info->current_status)); ACPI_FREE(info); diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index daf4ad37896d..4929dbdbc8f0 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -535,10 +535,11 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, acpi_status status; struct acpi_namespace_node *node; u32 flags; - struct acpica_device_id hid; - struct acpi_compatible_id_list *cid; + struct acpica_device_id *hid; + struct acpica_device_id_list *cid; u32 i; - int found; + u8 found; + int no_match; status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { @@ -582,10 +583,14 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, return (AE_CTRL_DEPTH); } - if (ACPI_STRNCMP(hid.value, info->hid, sizeof(hid.value)) != 0) { - - /* Get the list of Compatible IDs */ + no_match = ACPI_STRCMP(hid->string, info->hid); + ACPI_FREE(hid); + if (no_match) { + /* + * HID does not match, attempt match within the + * list of Compatible IDs (CIDs) + */ status = acpi_ut_execute_CID(node, &cid); if (status == AE_NOT_FOUND) { return (AE_OK); @@ -597,10 +602,8 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, found = 0; for (i = 0; i < cid->count; i++) { - if (ACPI_STRNCMP(cid->id[i].value, info->hid, - sizeof(struct - acpi_compatible_id)) == - 0) { + if (ACPI_STRCMP(cid->ids[i].string, info->hid) + == 0) { found = 1; break; } diff --git a/drivers/acpi/acpica/nsxfname.c b/drivers/acpi/acpica/nsxfname.c index f23593d6add4..ddc84af6336e 100644 --- a/drivers/acpi/acpica/nsxfname.c +++ b/drivers/acpi/acpica/nsxfname.c @@ -51,6 +51,11 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nsxfname") +/* Local prototypes */ +static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, + struct acpica_device_id *source, + char *string_area); + /****************************************************************************** * * FUNCTION: acpi_get_handle @@ -68,6 +73,7 @@ ACPI_MODULE_NAME("nsxfname") * namespace handle. * ******************************************************************************/ + acpi_status acpi_get_handle(acpi_handle parent, acpi_string pathname, acpi_handle * ret_handle) @@ -208,12 +214,40 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer * buffer) ACPI_EXPORT_SYMBOL(acpi_get_name) +/****************************************************************************** + * + * FUNCTION: acpi_ns_copy_device_id + * + * PARAMETERS: Dest - Pointer to the destination DEVICE_ID + * Source - Pointer to the source DEVICE_ID + * string_area - Pointer to where to copy the dest string + * + * RETURN: Pointer to the next string area + * + * DESCRIPTION: Copy a single DEVICE_ID, including the string data. + * + ******************************************************************************/ +static char *acpi_ns_copy_device_id(struct acpica_device_id *dest, + struct acpica_device_id *source, + char *string_area) +{ + /* Create the destination DEVICE_ID */ + + dest->string = string_area; + dest->length = source->length; + + /* Copy actual string and return a pointer to the next string area */ + + ACPI_MEMCPY(string_area, source->string, source->length); + return (string_area + source->length); +} + /****************************************************************************** * * FUNCTION: acpi_get_object_info * - * PARAMETERS: Handle - Object Handle - * Buffer - Where the info is returned + * PARAMETERS: Handle - Object Handle + * return_buffer - Where the info is returned * * RETURN: Status * @@ -221,33 +255,37 @@ ACPI_EXPORT_SYMBOL(acpi_get_name) * namespace node and possibly by running several standard * control methods (Such as in the case of a device.) * + * For Device and Processor objects, run the Device _HID, _UID, _CID, _STA, + * _ADR, _sx_w, and _sx_d methods. + * + * Note: Allocates the return buffer, must be freed by the caller. + * ******************************************************************************/ + acpi_status -acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) +acpi_get_object_info(acpi_handle handle, + struct acpi_device_info **return_buffer) { - acpi_status status; struct acpi_namespace_node *node; struct acpi_device_info *info; - struct acpi_device_info *return_info; - struct acpi_compatible_id_list *cid_list = NULL; - acpi_size size; + struct acpica_device_id_list *cid_list = NULL; + struct acpica_device_id *hid = NULL; + struct acpica_device_id *uid = NULL; + char *next_id_string; + acpi_object_type type; + acpi_name name; + u8 param_count = 0; + u8 valid = 0; + u32 info_size; + u32 i; + acpi_status status; /* Parameter validation */ - if (!handle || !buffer) { + if (!handle || !return_buffer) { return (AE_BAD_PARAMETER); } - status = acpi_ut_validate_buffer(buffer); - if (ACPI_FAILURE(status)) { - return (status); - } - - info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_device_info)); - if (!info) { - return (AE_NO_MEMORY); - } - status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { goto cleanup; @@ -256,66 +294,91 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) node = acpi_ns_map_handle_to_node(handle); if (!node) { (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); - status = AE_BAD_PARAMETER; - goto cleanup; + return (AE_BAD_PARAMETER); } - /* Init return structure */ + /* Get the namespace node data while the namespace is locked */ - size = sizeof(struct acpi_device_info); - - info->type = node->type; - info->name = node->name.integer; - info->valid = 0; + info_size = sizeof(struct acpi_device_info); + type = node->type; + name = node->name.integer; if (node->type == ACPI_TYPE_METHOD) { - info->param_count = node->object->method.param_count; + param_count = node->object->method.param_count; } status = acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); if (ACPI_FAILURE(status)) { - goto cleanup; + return (status); } - /* If not a device, we are all done */ - - if (info->type == ACPI_TYPE_DEVICE) { + if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { /* - * Get extra info for ACPI Devices objects only: - * Run the Device _HID, _UID, _CID, _STA, _ADR and _sx_d methods. + * Get extra info for ACPI Device/Processor objects only: + * Run the Device _HID, _UID, and _CID methods. * * Note: none of these methods are required, so they may or may - * not be present for this device. The Info->Valid bitfield is used - * to indicate which methods were found and ran successfully. + * not be present for this device. The Info->Valid bitfield is used + * to indicate which methods were found and run successfully. */ /* Execute the Device._HID method */ - status = acpi_ut_execute_HID(node, &info->hardware_id); + status = acpi_ut_execute_HID(node, &hid); if (ACPI_SUCCESS(status)) { - info->valid |= ACPI_VALID_HID; + info_size += hid->length; + valid |= ACPI_VALID_HID; } /* Execute the Device._UID method */ - status = acpi_ut_execute_UID(node, &info->unique_id); + status = acpi_ut_execute_UID(node, &uid); if (ACPI_SUCCESS(status)) { - info->valid |= ACPI_VALID_UID; + info_size += uid->length; + valid |= ACPI_VALID_UID; } /* Execute the Device._CID method */ status = acpi_ut_execute_CID(node, &cid_list); if (ACPI_SUCCESS(status)) { - size += cid_list->size; - info->valid |= ACPI_VALID_CID; + + /* Add size of CID strings and CID pointer array */ + + info_size += + (cid_list->list_size - + sizeof(struct acpica_device_id_list)); + valid |= ACPI_VALID_CID; } + } + + /* + * Now that we have the variable-length data, we can allocate the + * return buffer + */ + info = ACPI_ALLOCATE_ZEROED(info_size); + if (!info) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Get the fixed-length data */ + + if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) { + /* + * Get extra info for ACPI Device/Processor objects only: + * Run the _STA, _ADR and, sx_w, and _sx_d methods. + * + * Note: none of these methods are required, so they may or may + * not be present for this device. The Info->Valid bitfield is used + * to indicate which methods were found and run successfully. + */ /* Execute the Device._STA method */ status = acpi_ut_execute_STA(node, &info->current_status); if (ACPI_SUCCESS(status)) { - info->valid |= ACPI_VALID_STA; + valid |= ACPI_VALID_STA; } /* Execute the Device._ADR method */ @@ -323,36 +386,100 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer) status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, node, &info->address); if (ACPI_SUCCESS(status)) { - info->valid |= ACPI_VALID_ADR; + valid |= ACPI_VALID_ADR; + } + + /* Execute the Device._sx_w methods */ + + status = acpi_ut_execute_power_methods(node, + acpi_gbl_lowest_dstate_names, + ACPI_NUM_sx_w_METHODS, + info->lowest_dstates); + if (ACPI_SUCCESS(status)) { + valid |= ACPI_VALID_SXWS; } /* Execute the Device._sx_d methods */ - status = acpi_ut_execute_sxds(node, info->highest_dstates); + status = acpi_ut_execute_power_methods(node, + acpi_gbl_highest_dstate_names, + ACPI_NUM_sx_d_METHODS, + info->highest_dstates); if (ACPI_SUCCESS(status)) { - info->valid |= ACPI_VALID_SXDS; + valid |= ACPI_VALID_SXDS; } } - /* Validate/Allocate/Clear caller buffer */ + /* + * Create a pointer to the string area of the return buffer. + * Point to the end of the base struct acpi_device_info structure. + */ + next_id_string = ACPI_CAST_PTR(char, info->compatible_id_list.ids); + if (cid_list) { - status = acpi_ut_initialize_buffer(buffer, size); - if (ACPI_FAILURE(status)) { - goto cleanup; + /* Point past the CID DEVICE_ID array */ + + next_id_string += + ((acpi_size) cid_list->count * + sizeof(struct acpica_device_id)); } - /* Populate the return buffer */ + /* + * Copy the HID, UID, and CIDs to the return buffer. The variable-length + * strings are copied to the reserved area at the end of the buffer. + * + * For HID and CID, check if the ID is a PCI Root Bridge. + */ + if (hid) { + next_id_string = acpi_ns_copy_device_id(&info->hardware_id, + hid, next_id_string); - return_info = buffer->pointer; - ACPI_MEMCPY(return_info, info, sizeof(struct acpi_device_info)); + if (acpi_ut_is_pci_root_bridge(hid->string)) { + info->flags |= ACPI_PCI_ROOT_BRIDGE; + } + } + + if (uid) { + next_id_string = acpi_ns_copy_device_id(&info->unique_id, + uid, next_id_string); + } if (cid_list) { - ACPI_MEMCPY(&return_info->compatibility_id, cid_list, - cid_list->size); + info->compatible_id_list.count = cid_list->count; + info->compatible_id_list.list_size = cid_list->list_size; + + /* Copy each CID */ + + for (i = 0; i < cid_list->count; i++) { + next_id_string = + acpi_ns_copy_device_id(&info->compatible_id_list. + ids[i], &cid_list->ids[i], + next_id_string); + + if (acpi_ut_is_pci_root_bridge(cid_list->ids[i].string)) { + info->flags |= ACPI_PCI_ROOT_BRIDGE; + } + } } + /* Copy the fixed-length data */ + + info->info_size = info_size; + info->type = type; + info->name = name; + info->param_count = param_count; + info->valid = valid; + + *return_buffer = info; + status = AE_OK; + cleanup: - ACPI_FREE(info); + if (hid) { + ACPI_FREE(hid); + } + if (uid) { + ACPI_FREE(uid); + } if (cid_list) { ACPI_FREE(cid_list); } diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 006b16c26017..5503307b8bb7 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -44,19 +44,10 @@ #include #include "accommon.h" #include "acnamesp.h" -#include "acinterp.h" #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("uteval") -/* Local prototypes */ -static void -acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length); - -static acpi_status -acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, - struct acpi_compatible_id *one_cid); - /* * Strings supported by the _OSI predefined (internal) method. * @@ -213,7 +204,7 @@ acpi_status acpi_osi_invalidate(char *interface) * RETURN: Status * * DESCRIPTION: Evaluates a namespace object and verifies the type of the - * return object. Common code that simplifies accessing objects + * return object. Common code that simplifies accessing objects * that have required return objects of fixed types. * * NOTE: Internal function, no parameter validation @@ -298,7 +289,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, if ((acpi_gbl_enable_interpreter_slack) && (!expected_return_btypes)) { /* - * We received a return object, but one was not expected. This can + * We received a return object, but one was not expected. This can * happen frequently if the "implicit return" feature is enabled. * Just delete the return object and return AE_OK. */ @@ -340,12 +331,12 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, * * PARAMETERS: object_name - Object name to be evaluated * device_node - Node for the device - * Address - Where the value is returned + * Value - Where the value is returned * * RETURN: Status * * DESCRIPTION: Evaluates a numeric namespace object for a selected device - * and stores result in *Address. + * and stores result in *Value. * * NOTE: Internal function, no parameter validation * @@ -354,7 +345,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node, acpi_status acpi_ut_evaluate_numeric_object(char *object_name, struct acpi_namespace_node *device_node, - acpi_integer * address) + acpi_integer *value) { union acpi_operand_object *obj_desc; acpi_status status; @@ -369,295 +360,7 @@ acpi_ut_evaluate_numeric_object(char *object_name, /* Get the returned Integer */ - *address = obj_desc->integer.value; - - /* On exit, we must delete the return object */ - - acpi_ut_remove_reference(obj_desc); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_copy_id_string - * - * PARAMETERS: Destination - Where to copy the string - * Source - Source string - * max_length - Length of the destination buffer - * - * RETURN: None - * - * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. - * Performs removal of a leading asterisk if present -- workaround - * for a known issue on a bunch of machines. - * - ******************************************************************************/ - -static void -acpi_ut_copy_id_string(char *destination, char *source, acpi_size max_length) -{ - - /* - * Workaround for ID strings that have a leading asterisk. This construct - * is not allowed by the ACPI specification (ID strings must be - * alphanumeric), but enough existing machines have this embedded in their - * ID strings that the following code is useful. - */ - if (*source == '*') { - source++; - } - - /* Do the actual copy */ - - ACPI_STRNCPY(destination, source, max_length); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_execute_HID - * - * PARAMETERS: device_node - Node for the device - * Hid - Where the HID is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _HID control method that returns the hardware - * ID of the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -acpi_status -acpi_ut_execute_HID(struct acpi_namespace_node *device_node, - struct acpica_device_id *hid) -{ - union acpi_operand_object *obj_desc; - acpi_status status; - - ACPI_FUNCTION_TRACE(ut_execute_HID); - - status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, - &obj_desc); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - - /* Convert the Numeric HID to string */ - - acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, - hid->value); - } else { - /* Copy the String HID from the returned object */ - - acpi_ut_copy_id_string(hid->value, obj_desc->string.pointer, - sizeof(hid->value)); - } - - /* On exit, we must delete the return object */ - - acpi_ut_remove_reference(obj_desc); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_translate_one_cid - * - * PARAMETERS: obj_desc - _CID object, must be integer or string - * one_cid - Where the CID string is returned - * - * RETURN: Status - * - * DESCRIPTION: Return a numeric or string _CID value as a string. - * (Compatible ID) - * - * NOTE: Assumes a maximum _CID string length of - * ACPI_MAX_CID_LENGTH. - * - ******************************************************************************/ - -static acpi_status -acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc, - struct acpi_compatible_id *one_cid) -{ - - switch (obj_desc->common.type) { - case ACPI_TYPE_INTEGER: - - /* Convert the Numeric CID to string */ - - acpi_ex_eisa_id_to_string((u32) obj_desc->integer.value, - one_cid->value); - return (AE_OK); - - case ACPI_TYPE_STRING: - - if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { - return (AE_AML_STRING_LIMIT); - } - - /* Copy the String CID from the returned object */ - - acpi_ut_copy_id_string(one_cid->value, obj_desc->string.pointer, - ACPI_MAX_CID_LENGTH); - return (AE_OK); - - default: - - return (AE_TYPE); - } -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_execute_CID - * - * PARAMETERS: device_node - Node for the device - * return_cid_list - Where the CID list is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _CID control method that returns one or more - * compatible hardware IDs for the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -acpi_status -acpi_ut_execute_CID(struct acpi_namespace_node * device_node, - struct acpi_compatible_id_list ** return_cid_list) -{ - union acpi_operand_object *obj_desc; - acpi_status status; - u32 count; - u32 size; - struct acpi_compatible_id_list *cid_list; - u32 i; - - ACPI_FUNCTION_TRACE(ut_execute_CID); - - /* Evaluate the _CID method for this device */ - - status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING - | ACPI_BTYPE_PACKAGE, &obj_desc); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Get the number of _CIDs returned */ - - count = 1; - if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - count = obj_desc->package.count; - } - - /* Allocate a worst-case buffer for the _CIDs */ - - size = (((count - 1) * sizeof(struct acpi_compatible_id)) + - sizeof(struct acpi_compatible_id_list)); - - cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); - if (!cid_list) { - return_ACPI_STATUS(AE_NO_MEMORY); - } - - /* Init CID list */ - - cid_list->count = count; - cid_list->size = size; - - /* - * A _CID can return either a single compatible ID or a package of - * compatible IDs. Each compatible ID can be one of the following: - * 1) Integer (32 bit compressed EISA ID) or - * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") - */ - - /* The _CID object can be either a single CID or a package (list) of CIDs */ - - if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { - - /* Translate each package element */ - - for (i = 0; i < count; i++) { - status = - acpi_ut_translate_one_cid(obj_desc->package. - elements[i], - &cid_list->id[i]); - if (ACPI_FAILURE(status)) { - break; - } - } - } else { - /* Only one CID, translate to a string */ - - status = acpi_ut_translate_one_cid(obj_desc, cid_list->id); - } - - /* Cleanup on error */ - - if (ACPI_FAILURE(status)) { - ACPI_FREE(cid_list); - } else { - *return_cid_list = cid_list; - } - - /* On exit, we must delete the _CID return object */ - - acpi_ut_remove_reference(obj_desc); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ut_execute_UID - * - * PARAMETERS: device_node - Node for the device - * Uid - Where the UID is returned - * - * RETURN: Status - * - * DESCRIPTION: Executes the _UID control method that returns the hardware - * ID of the device. - * - * NOTE: Internal function, no parameter validation - * - ******************************************************************************/ - -acpi_status -acpi_ut_execute_UID(struct acpi_namespace_node *device_node, - struct acpica_device_id *uid) -{ - union acpi_operand_object *obj_desc; - acpi_status status; - - ACPI_FUNCTION_TRACE(ut_execute_UID); - - status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, - &obj_desc); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - if (obj_desc->common.type == ACPI_TYPE_INTEGER) { - - /* Convert the Numeric UID to string */ - - acpi_ex_unsigned_integer_to_string(obj_desc->integer.value, - uid->value); - } else { - /* Copy the String UID from the returned object */ - - acpi_ut_copy_id_string(uid->value, obj_desc->string.pointer, - sizeof(uid->value)); - } + *value = obj_desc->integer.value; /* On exit, we must delete the return object */ @@ -716,60 +419,64 @@ acpi_ut_execute_STA(struct acpi_namespace_node *device_node, u32 * flags) /******************************************************************************* * - * FUNCTION: acpi_ut_execute_Sxds + * FUNCTION: acpi_ut_execute_power_methods * * PARAMETERS: device_node - Node for the device - * Flags - Where the status flags are returned + * method_names - Array of power method names + * method_count - Number of methods to execute + * out_values - Where the power method values are returned * - * RETURN: Status + * RETURN: Status, out_values * - * DESCRIPTION: Executes _STA for selected device and stores results in - * *Flags. + * DESCRIPTION: Executes the specified power methods for the device and returns + * the result(s). * * NOTE: Internal function, no parameter validation * - ******************************************************************************/ +******************************************************************************/ acpi_status -acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest) +acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, + const char **method_names, + u8 method_count, u8 *out_values) { union acpi_operand_object *obj_desc; acpi_status status; + acpi_status final_status = AE_NOT_FOUND; u32 i; - ACPI_FUNCTION_TRACE(ut_execute_sxds); + ACPI_FUNCTION_TRACE(ut_execute_power_methods); - for (i = 0; i < 4; i++) { - highest[i] = 0xFF; + for (i = 0; i < method_count; i++) { + /* + * Execute the power method (_sx_d or _sx_w). The only allowable + * return type is an Integer. + */ status = acpi_ut_evaluate_object(device_node, ACPI_CAST_PTR(char, - acpi_gbl_highest_dstate_names - [i]), + method_names[i]), ACPI_BTYPE_INTEGER, &obj_desc); - if (ACPI_FAILURE(status)) { - if (status != AE_NOT_FOUND) { - ACPI_DEBUG_PRINT((ACPI_DB_EXEC, - "%s on Device %4.4s, %s\n", - ACPI_CAST_PTR(char, - acpi_gbl_highest_dstate_names - [i]), - acpi_ut_get_node_name - (device_node), - acpi_format_exception - (status))); - - return_ACPI_STATUS(status); - } - } else { - /* Extract the Dstate value */ - - highest[i] = (u8) obj_desc->integer.value; + if (ACPI_SUCCESS(status)) { + out_values[i] = (u8)obj_desc->integer.value; /* Delete the return object */ acpi_ut_remove_reference(obj_desc); + final_status = AE_OK; /* At least one value is valid */ + continue; } + + out_values[i] = ACPI_UINT8_MAX; + if (status == AE_NOT_FOUND) { + continue; /* Ignore if not found */ + } + + ACPI_DEBUG_PRINT((ACPI_DB_EXEC, + "Failed %s on Device %4.4s, %s\n", + ACPI_CAST_PTR(char, method_names[i]), + acpi_ut_get_node_name(device_node), + acpi_format_exception(status))); } - return_ACPI_STATUS(AE_OK); + return_ACPI_STATUS(final_status); } diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 59e46f257c02..ed7a33c67fbe 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -90,7 +90,15 @@ const char *acpi_gbl_sleep_state_names[ACPI_S_STATE_COUNT] = { "\\_S5_" }; -const char *acpi_gbl_highest_dstate_names[4] = { +const char *acpi_gbl_lowest_dstate_names[ACPI_NUM_sx_w_METHODS] = { + "_S0W", + "_S1W", + "_S2W", + "_S3W", + "_S4W" +}; + +const char *acpi_gbl_highest_dstate_names[ACPI_NUM_sx_d_METHODS] = { "_S1D", "_S2D", "_S3D", diff --git a/drivers/acpi/acpica/utids.c b/drivers/acpi/acpica/utids.c new file mode 100644 index 000000000000..52eaae404554 --- /dev/null +++ b/drivers/acpi/acpica/utids.c @@ -0,0 +1,382 @@ +/****************************************************************************** + * + * Module Name: utids - support for device IDs - HID, UID, CID + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2009, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "acinterp.h" + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME("utids") + +/* Local prototypes */ +static void acpi_ut_copy_id_string(char *destination, char *source); + +/******************************************************************************* + * + * FUNCTION: acpi_ut_copy_id_string + * + * PARAMETERS: Destination - Where to copy the string + * Source - Source string + * + * RETURN: None + * + * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. + * Performs removal of a leading asterisk if present -- workaround + * for a known issue on a bunch of machines. + * + ******************************************************************************/ + +static void acpi_ut_copy_id_string(char *destination, char *source) +{ + + /* + * Workaround for ID strings that have a leading asterisk. This construct + * is not allowed by the ACPI specification (ID strings must be + * alphanumeric), but enough existing machines have this embedded in their + * ID strings that the following code is useful. + */ + if (*source == '*') { + source++; + } + + /* Do the actual copy */ + + ACPI_STRCPY(destination, source); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_HID + * + * PARAMETERS: device_node - Node for the device + * return_id - Where the string HID is returned + * + * RETURN: Status + * + * DESCRIPTION: Executes the _HID control method that returns the hardware + * ID of the device. The HID is either an 32-bit encoded EISAID + * Integer or a String. A string is always returned. An EISAID + * is converted to a string. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_HID(struct acpi_namespace_node *device_node, + struct acpica_device_id **return_id) +{ + union acpi_operand_object *obj_desc; + struct acpica_device_id *hid; + u32 length; + acpi_status status; + + ACPI_FUNCTION_TRACE(ut_execute_HID); + + status = acpi_ut_evaluate_object(device_node, METHOD_NAME__HID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, + &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the size of the String to be returned, includes null terminator */ + + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { + length = ACPI_EISAID_STRING_SIZE; + } else { + length = obj_desc->string.length + 1; + } + + /* Allocate a buffer for the HID */ + + hid = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + + (acpi_size) length); + if (!hid) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Area for the string starts after DEVICE_ID struct */ + + hid->string = ACPI_ADD_PTR(char, hid, sizeof(struct acpica_device_id)); + + /* Convert EISAID to a string or simply copy existing string */ + + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { + acpi_ex_eisa_id_to_string(hid->string, obj_desc->integer.value); + } else { + acpi_ut_copy_id_string(hid->string, obj_desc->string.pointer); + } + + hid->length = length; + *return_id = hid; + +cleanup: + + /* On exit, we must delete the return object */ + + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_UID + * + * PARAMETERS: device_node - Node for the device + * return_id - Where the string UID is returned + * + * RETURN: Status + * + * DESCRIPTION: Executes the _UID control method that returns the unique + * ID of the device. The UID is either a 64-bit Integer (NOT an + * EISAID) or a string. Always returns a string. A 64-bit integer + * is converted to a decimal string. + * + * NOTE: Internal function, no parameter validation + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_UID(struct acpi_namespace_node *device_node, + struct acpica_device_id **return_id) +{ + union acpi_operand_object *obj_desc; + struct acpica_device_id *uid; + u32 length; + acpi_status status; + + ACPI_FUNCTION_TRACE(ut_execute_UID); + + status = acpi_ut_evaluate_object(device_node, METHOD_NAME__UID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING, + &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Get the size of the String to be returned, includes null terminator */ + + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { + length = ACPI_MAX64_DECIMAL_DIGITS + 1; + } else { + length = obj_desc->string.length + 1; + } + + /* Allocate a buffer for the UID */ + + uid = + ACPI_ALLOCATE_ZEROED(sizeof(struct acpica_device_id) + + (acpi_size) length); + if (!uid) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Area for the string starts after DEVICE_ID struct */ + + uid->string = ACPI_ADD_PTR(char, uid, sizeof(struct acpica_device_id)); + + /* Convert an Integer to string, or just copy an existing string */ + + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { + acpi_ex_integer_to_string(uid->string, obj_desc->integer.value); + } else { + acpi_ut_copy_id_string(uid->string, obj_desc->string.pointer); + } + + uid->length = length; + *return_id = uid; + +cleanup: + + /* On exit, we must delete the return object */ + + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ut_execute_CID + * + * PARAMETERS: device_node - Node for the device + * return_cid_list - Where the CID list is returned + * + * RETURN: Status, list of CID strings + * + * DESCRIPTION: Executes the _CID control method that returns one or more + * compatible hardware IDs for the device. + * + * NOTE: Internal function, no parameter validation + * + * A _CID method can return either a single compatible ID or a package of + * compatible IDs. Each compatible ID can be one of the following: + * 1) Integer (32 bit compressed EISA ID) or + * 2) String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss") + * + * The Integer CIDs are converted to string format by this function. + * + ******************************************************************************/ + +acpi_status +acpi_ut_execute_CID(struct acpi_namespace_node *device_node, + struct acpica_device_id_list **return_cid_list) +{ + union acpi_operand_object **cid_objects; + union acpi_operand_object *obj_desc; + struct acpica_device_id_list *cid_list; + char *next_id_string; + u32 string_area_size; + u32 length; + u32 cid_list_size; + acpi_status status; + u32 count; + u32 i; + + ACPI_FUNCTION_TRACE(ut_execute_CID); + + /* Evaluate the _CID method for this device */ + + status = acpi_ut_evaluate_object(device_node, METHOD_NAME__CID, + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING + | ACPI_BTYPE_PACKAGE, &obj_desc); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* + * Get the count and size of the returned _CIDs. _CID can return either + * a Package of Integers/Strings or a single Integer or String. + * Note: This section also validates that all CID elements are of the + * correct type (Integer or String). + */ + if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { + count = obj_desc->package.count; + cid_objects = obj_desc->package.elements; + } else { /* Single Integer or String CID */ + + count = 1; + cid_objects = &obj_desc; + } + + string_area_size = 0; + for (i = 0; i < count; i++) { + + /* String lengths include null terminator */ + + switch (cid_objects[i]->common.type) { + case ACPI_TYPE_INTEGER: + string_area_size += ACPI_EISAID_STRING_SIZE; + break; + + case ACPI_TYPE_STRING: + string_area_size += cid_objects[i]->string.length + 1; + break; + + default: + status = AE_TYPE; + goto cleanup; + } + } + + /* + * Now that we know the length of the CIDs, allocate return buffer: + * 1) Size of the base structure + + * 2) Size of the CID DEVICE_ID array + + * 3) Size of the actual CID strings + */ + cid_list_size = sizeof(struct acpica_device_id_list) + + ((count - 1) * sizeof(struct acpica_device_id)) + string_area_size; + + cid_list = ACPI_ALLOCATE_ZEROED(cid_list_size); + if (!cid_list) { + status = AE_NO_MEMORY; + goto cleanup; + } + + /* Area for CID strings starts after the CID DEVICE_ID array */ + + next_id_string = ACPI_CAST_PTR(char, cid_list->ids) + + ((acpi_size) count * sizeof(struct acpica_device_id)); + + /* Copy/convert the CIDs to the return buffer */ + + for (i = 0; i < count; i++) { + if (cid_objects[i]->common.type == ACPI_TYPE_INTEGER) { + + /* Convert the Integer (EISAID) CID to a string */ + + acpi_ex_eisa_id_to_string(next_id_string, + cid_objects[i]->integer. + value); + length = ACPI_EISAID_STRING_SIZE; + } else { /* ACPI_TYPE_STRING */ + + /* Copy the String CID from the returned object */ + + acpi_ut_copy_id_string(next_id_string, + cid_objects[i]->string.pointer); + length = cid_objects[i]->string.length + 1; + } + + cid_list->ids[i].string = next_id_string; + cid_list->ids[i].length = length; + next_id_string += length; + } + + /* Finish the CID list */ + + cid_list->count = count; + cid_list->list_size = cid_list_size; + *return_cid_list = cid_list; + +cleanup: + + /* On exit, we must delete the _CID return object */ + + acpi_ut_remove_reference(obj_desc); + return_ACPI_STATUS(status); +} diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index fbe782348b0b..9cd65334ca75 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -118,6 +118,34 @@ const char *acpi_ut_validate_exception(acpi_status status) return (ACPI_CAST_PTR(const char, exception)); } +/******************************************************************************* + * + * FUNCTION: acpi_ut_is_pci_root_bridge + * + * PARAMETERS: Id - The HID/CID in string format + * + * RETURN: TRUE if the Id is a match for a PCI/PCI-Express Root Bridge + * + * DESCRIPTION: Determine if the input ID is a PCI Root Bridge ID. + * + ******************************************************************************/ + +u8 acpi_ut_is_pci_root_bridge(char *id) +{ + + /* + * Check if this is a PCI root bridge. + * ACPI 3.0+: check for a PCI Express root also. + */ + if (!(ACPI_STRCMP(id, + PCI_ROOT_HID_STRING)) || + !(ACPI_STRCMP(id, PCI_EXPRESS_ROOT_HID_STRING))) { + return (TRUE); + } + + return (FALSE); +} + /******************************************************************************* * * FUNCTION: acpi_ut_is_aml_table diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index fe0cdf83641a..2aee8c24dc56 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -200,20 +200,17 @@ container_walk_namespace_cb(acpi_handle handle, u32 lvl, void *context, void **rv) { char *hid = NULL; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_device_info *info; acpi_status status; int *action = context; - - status = acpi_get_object_info(handle, &buffer); - if (ACPI_FAILURE(status) || !buffer.pointer) { + status = acpi_get_object_info(handle, &info); + if (ACPI_FAILURE(status)) { return AE_OK; } - info = buffer.pointer; if (info->valid & ACPI_VALID_HID) - hid = info->hardware_id.value; + hid = info->hardware_id.string; if (hid == NULL) { goto end; @@ -240,7 +237,7 @@ container_walk_namespace_cb(acpi_handle handle, } end: - kfree(buffer.pointer); + kfree(info); return AE_OK; } diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index efb959d6c8a9..39536b80bce7 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c @@ -231,18 +231,16 @@ static int is_ata(acpi_handle handle) static int is_battery(acpi_handle handle) { struct acpi_device_info *info; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; int ret = 1; - if (!ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) + if (!ACPI_SUCCESS(acpi_get_object_info(handle, &info))) return 0; - info = buffer.pointer; if (!(info->valid & ACPI_VALID_HID)) ret = 0; else - ret = !strcmp("PNP0C0A", info->hardware_id.value); + ret = !strcmp("PNP0C0A", info->hardware_id.string); - kfree(buffer.pointer); + kfree(info); return ret; } diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index a8a5c29958c8..27a7072347ea 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -93,15 +93,13 @@ do_acpi_find_child(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; struct acpi_device_info *info; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_find_child *find = context; - status = acpi_get_object_info(handle, &buffer); + status = acpi_get_object_info(handle, &info); if (ACPI_SUCCESS(status)) { - info = buffer.pointer; if (info->address == find->address) find->handle = handle; - kfree(buffer.pointer); + kfree(info); } return AE_OK; } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 781435d7e369..0ab526de7c55 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -60,13 +60,13 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias, } if (acpi_dev->flags.compatible_ids) { - struct acpi_compatible_id_list *cid_list; + struct acpica_device_id_list *cid_list; int i; cid_list = acpi_dev->pnp.cid_list; for (i = 0; i < cid_list->count; i++) { count = snprintf(&modalias[len], size, "%s:", - cid_list->id[i].value); + cid_list->ids[i].string); if (count < 0 || count >= size) { printk(KERN_ERR PREFIX "%s cid[%i] exceeds event buffer size", acpi_dev->pnp.device_name, i); @@ -287,14 +287,14 @@ int acpi_match_device_ids(struct acpi_device *device, } if (device->flags.compatible_ids) { - struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; + struct acpica_device_id_list *cid_list = device->pnp.cid_list; int i; for (id = ids; id->id[0]; id++) { /* compare multiple _CID entries against driver ids */ for (i = 0; i < cid_list->count; i++) { if (!strcmp((char*)id->id, - cid_list->id[i].value)) + cid_list->ids[i].string)) return 0; } } @@ -999,33 +999,89 @@ static int acpi_dock_match(struct acpi_device *device) return acpi_get_handle(device->handle, "_DCK", &tmp); } +static struct acpica_device_id_list* +acpi_add_cid( + struct acpi_device_info *info, + struct acpica_device_id *new_cid) +{ + struct acpica_device_id_list *cid; + char *next_id_string; + acpi_size cid_length; + acpi_size new_cid_length; + u32 i; + + + /* Allocate new CID list with room for the new CID */ + + if (!new_cid) + new_cid_length = info->compatible_id_list.list_size; + else if (info->compatible_id_list.list_size) + new_cid_length = info->compatible_id_list.list_size + + new_cid->length + sizeof(struct acpica_device_id); + else + new_cid_length = sizeof(struct acpica_device_id_list) + new_cid->length; + + cid = ACPI_ALLOCATE_ZEROED(new_cid_length); + if (!cid) { + return NULL; + } + + cid->list_size = new_cid_length; + cid->count = info->compatible_id_list.count; + if (new_cid) + cid->count++; + next_id_string = (char *) cid->ids + (cid->count * sizeof(struct acpica_device_id)); + + /* Copy all existing CIDs */ + + for (i = 0; i < info->compatible_id_list.count; i++) { + cid_length = info->compatible_id_list.ids[i].length; + cid->ids[i].string = next_id_string; + cid->ids[i].length = cid_length; + + ACPI_MEMCPY(next_id_string, info->compatible_id_list.ids[i].string, + cid_length); + + next_id_string += cid_length; + } + + /* Append the new CID */ + + if (new_cid) { + cid->ids[i].string = next_id_string; + cid->ids[i].length = new_cid->length; + + ACPI_MEMCPY(next_id_string, new_cid->string, new_cid->length); + } + + return cid; +} + static void acpi_device_set_id(struct acpi_device *device, struct acpi_device *parent, acpi_handle handle, int type) { - struct acpi_device_info *info; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_device_info *info = NULL; char *hid = NULL; char *uid = NULL; - struct acpi_compatible_id_list *cid_list = NULL; - const char *cid_add = NULL; + struct acpica_device_id_list *cid_list = NULL; + char *cid_add = NULL; acpi_status status; switch (type) { case ACPI_BUS_TYPE_DEVICE: - status = acpi_get_object_info(handle, &buffer); + status = acpi_get_object_info(handle, &info); if (ACPI_FAILURE(status)) { printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__); return; } - info = buffer.pointer; if (info->valid & ACPI_VALID_HID) - hid = info->hardware_id.value; + hid = info->hardware_id.string; if (info->valid & ACPI_VALID_UID) - uid = info->unique_id.value; + uid = info->unique_id.string; if (info->valid & ACPI_VALID_CID) - cid_list = &info->compatibility_id; + cid_list = &info->compatible_id_list; if (info->valid & ACPI_VALID_ADR) { device->pnp.bus_address = info->address; device->flags.bus_address = 1; @@ -1076,55 +1132,44 @@ static void acpi_device_set_id(struct acpi_device *device, } if (hid) { - strcpy(device->pnp.hardware_id, hid); - device->flags.hardware_id = 1; - } - if (uid) { - strcpy(device->pnp.unique_id, uid); - device->flags.unique_id = 1; - } - if (cid_list || cid_add) { - struct acpi_compatible_id_list *list; - int size = 0; - int count = 0; - - if (cid_list) { - size = cid_list->size; - } else if (cid_add) { - size = sizeof(struct acpi_compatible_id_list); - cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size); - if (!cid_list) { - printk(KERN_ERR "Memory allocation error\n"); - kfree(buffer.pointer); - return; - } else { - cid_list->count = 0; - cid_list->size = size; - } + device->pnp.hardware_id = ACPI_ALLOCATE_ZEROED(strlen (hid) + 1); + if (device->pnp.hardware_id) { + strcpy(device->pnp.hardware_id, hid); + device->flags.hardware_id = 1; + } + } else + device->pnp.hardware_id = NULL; + + if (uid) { + device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); + if (device->pnp.unique_id) { + strcpy(device->pnp.unique_id, uid); + device->flags.unique_id = 1; + } + } else + device->pnp.unique_id = NULL; + + if (cid_list || cid_add) { + struct acpica_device_id_list *list; + + if (cid_add) { + struct acpica_device_id cid; + cid.length = strlen (cid_add) + 1; + cid.string = cid_add; + + list = acpi_add_cid(info, &cid); + } else { + list = acpi_add_cid(info, NULL); } - if (cid_add) - size += sizeof(struct acpi_compatible_id); - list = kmalloc(size, GFP_KERNEL); if (list) { - if (cid_list) { - memcpy(list, cid_list, cid_list->size); - count = cid_list->count; - } - if (cid_add) { - strncpy(list->id[count].value, cid_add, - ACPI_MAX_CID_LENGTH); - count++; - device->flags.compatible_ids = 1; - } - list->size = size; - list->count = count; device->pnp.cid_list = list; - } else - printk(KERN_ERR PREFIX "Memory allocation error\n"); + if (cid_add) + device->flags.compatible_ids = 1; + } } - kfree(buffer.pointer); + kfree(info); } static int acpi_device_set_context(struct acpi_device *device, int type) diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index 8f3d4c184914..7bead4c816ca 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -478,7 +478,6 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) { acpi_handle handle, parent; acpi_status status; - struct acpi_buffer buffer; struct acpi_device_info *info; u64 lba_hpa, sba_hpa, length; int match; @@ -490,13 +489,11 @@ zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret) /* Look for an enclosing IOC scope and find its CSR space */ handle = obj; do { - buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; - status = acpi_get_object_info(handle, &buffer); + status = acpi_get_object_info(handle, &info); if (ACPI_SUCCESS(status)) { /* TBD check _CID also */ - info = buffer.pointer; - info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0'; - match = (strcmp(info->hardware_id.value, "HWP0001") == 0); + info->hardware_id.string[sizeof(info->hardware_id.length)-1] = '\0'; + match = (strcmp(info->hardware_id.string, "HWP0001") == 0); kfree(info); if (match) { status = hp_acpi_csr_space(handle, &sba_hpa, &length); diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index c509c9916464..c0cf45a11b93 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -114,8 +114,6 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, unsigned int bus, devnum, func; acpi_integer addr; acpi_handle dev_handle; - struct acpi_buffer buffer = {.length = ACPI_ALLOCATE_BUFFER, - .pointer = NULL}; acpi_status status; struct acpi_device_info *dinfo = NULL; int ret = -ENODEV; @@ -134,12 +132,11 @@ static int ide_get_dev_handle(struct device *dev, acpi_handle *handle, goto err; } - status = acpi_get_object_info(dev_handle, &buffer); + status = acpi_get_object_info(dev_handle, &dinfo); if (ACPI_FAILURE(status)) { DEBPRINT("get_object_info for device failed\n"); goto err; } - dinfo = buffer.pointer; if (dinfo && (dinfo->valid & ACPI_VALID_ADR) && dinfo->address == addr) { *pcidevfn = addr; diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 5befa7e379b7..a9d926b7d805 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -398,23 +398,21 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, acpi_handle *phandle = (acpi_handle *)context; acpi_status status; struct acpi_device_info *info; - struct acpi_buffer info_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; int retval = 0; - status = acpi_get_object_info(handle, &info_buffer); + status = acpi_get_object_info(handle, &info); if (ACPI_FAILURE(status)) { err("%s: Failed to get device information status=0x%x\n", __func__, status); return retval; } - info = info_buffer.pointer; - info->hardware_id.value[sizeof(info->hardware_id.value) - 1] = '\0'; + info->hardware_id.string[sizeof(info->hardware_id.length) - 1] = '\0'; if (info->current_status && (info->valid & ACPI_VALID_HID) && - (!strcmp(info->hardware_id.value, IBM_HARDWARE_ID1) || - !strcmp(info->hardware_id.value, IBM_HARDWARE_ID2))) { + (!strcmp(info->hardware_id.string, IBM_HARDWARE_ID1) || + !strcmp(info->hardware_id.string, IBM_HARDWARE_ID2))) { dbg("found hardware: %s, handle: %p\n", - info->hardware_id.value, handle); + info->hardware_id.string, handle); *phandle = handle; /* returning non-zero causes the search to stop * and returns this value to the caller of diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index dafaa4a92df5..f9f68e0e7344 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -976,15 +976,12 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level, void *context, void **return_value) { struct acpi_device_info *info; - struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; - - if (ACPI_SUCCESS(acpi_get_object_info(handle, &buffer))) { - info = buffer.pointer; + if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) { printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n", (char *)&info->name, info->param_count); - kfree(buffer.pointer); + kfree(info); } return AE_OK; diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 9496494f340e..c07fdb94d665 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -194,13 +194,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device) pnpacpi_parse_resource_option_data(dev); if (device->flags.compatible_ids) { - struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; + struct acpica_device_id_list *cid_list = device->pnp.cid_list; int i; for (i = 0; i < cid_list->count; i++) { - if (!ispnpidacpi(cid_list->id[i].value)) + if (!ispnpidacpi(cid_list->ids[i].string)) continue; - pnp_add_id(dev, cid_list->id[i].value); + pnp_add_id(dev, cid_list->ids[i].string); } } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c65e4ce6c3af..b91420b52c6f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -173,17 +173,15 @@ struct acpi_device_dir { typedef char acpi_bus_id[8]; typedef unsigned long acpi_bus_address; -typedef char acpi_hardware_id[15]; -typedef char acpi_unique_id[9]; typedef char acpi_device_name[40]; typedef char acpi_device_class[20]; struct acpi_device_pnp { acpi_bus_id bus_id; /* Object name */ acpi_bus_address bus_address; /* _ADR */ - acpi_hardware_id hardware_id; /* _HID */ - struct acpi_compatible_id_list *cid_list; /* _CIDs */ - acpi_unique_id unique_id; /* _UID */ + char *hardware_id; /* _HID */ + struct acpica_device_id_list *cid_list; /* _CIDs */ + char *unique_id; /* _UID */ acpi_device_name device_name; /* Driver-determined */ acpi_device_class device_class; /* " */ }; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index b450a195319a..04904c7f1aa1 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -200,7 +200,8 @@ acpi_evaluate_object_typed(acpi_handle object, acpi_object_type return_type); acpi_status -acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer); +acpi_get_object_info(acpi_handle handle, + struct acpi_device_info **return_buffer); acpi_status acpi_install_method(u8 *buffer); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 37ba576d06e8..7a4ff79e238c 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -338,7 +338,7 @@ typedef u32 acpi_physical_address; /* PM Timer ticks per second (HZ) */ -#define PM_TIMER_FREQUENCY 3579545 +#define PM_TIMER_FREQUENCY 3579545 /******************************************************************************* * @@ -969,38 +969,60 @@ acpi_status(*acpi_walk_callback) (acpi_handle obj_handle, #define ACPI_INTERRUPT_NOT_HANDLED 0x00 #define ACPI_INTERRUPT_HANDLED 0x01 -/* Length of _HID, _UID, _CID, and UUID values */ +/* Length of 32-bit EISAID values when converted back to a string */ + +#define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ + +/* Length of UUID (string) values */ -#define ACPI_DEVICE_ID_LENGTH 0x09 -#define ACPI_MAX_CID_LENGTH 48 #define ACPI_UUID_LENGTH 16 -/* Common string version of device HIDs and UIDs */ +/* Structures used for device/processor HID, UID, CID */ struct acpica_device_id { - char value[ACPI_DEVICE_ID_LENGTH]; + u32 length; /* Length of string + null */ + char *string; }; -/* Common string version of device CIDs */ - -struct acpi_compatible_id { - char value[ACPI_MAX_CID_LENGTH]; +struct acpica_device_id_list { + u32 count; /* Number of IDs in Ids array */ + u32 list_size; /* Size of list, including ID strings */ + struct acpica_device_id ids[1]; /* ID array */ }; -struct acpi_compatible_id_list { - u32 count; - u32 size; - struct acpi_compatible_id id[1]; +/* + * Structure returned from acpi_get_object_info. + * Optimized for both 32- and 64-bit builds + */ +struct acpi_device_info { + u32 info_size; /* Size of info, including ID strings */ + u32 name; /* ACPI object Name */ + acpi_object_type type; /* ACPI object Type */ + u8 param_count; /* If a method, required parameter count */ + u8 valid; /* Indicates which optional fields are valid */ + u8 flags; /* Miscellaneous info */ + u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ + u8 lowest_dstates[5]; /* _sx_w values: 0xFF indicates not valid */ + u32 current_status; /* _STA value */ + acpi_integer address; /* _ADR value */ + struct acpica_device_id hardware_id; /* _HID value */ + struct acpica_device_id unique_id; /* _UID value */ + struct acpica_device_id_list compatible_id_list; /* _CID list */ }; -/* Structure and flags for acpi_get_object_info */ +/* Values for Flags field above (acpi_get_object_info) */ -#define ACPI_VALID_STA 0x0001 -#define ACPI_VALID_ADR 0x0002 -#define ACPI_VALID_HID 0x0004 -#define ACPI_VALID_UID 0x0008 -#define ACPI_VALID_CID 0x0010 -#define ACPI_VALID_SXDS 0x0020 +#define ACPI_PCI_ROOT_BRIDGE 0x01 + +/* Flags for Valid field above (acpi_get_object_info) */ + +#define ACPI_VALID_STA 0x01 +#define ACPI_VALID_ADR 0x02 +#define ACPI_VALID_HID 0x04 +#define ACPI_VALID_UID 0x08 +#define ACPI_VALID_CID 0x10 +#define ACPI_VALID_SXDS 0x20 +#define ACPI_VALID_SXWS 0x40 /* Flags for _STA method */ @@ -1011,29 +1033,6 @@ struct acpi_compatible_id_list { #define ACPI_STA_DEVICE_OK 0x08 /* Synonym */ #define ACPI_STA_BATTERY_PRESENT 0x10 -#define ACPI_COMMON_OBJ_INFO \ - acpi_object_type type; /* ACPI object type */ \ - acpi_name name /* ACPI object Name */ - -struct acpi_obj_info_header { - ACPI_COMMON_OBJ_INFO; -}; - -/* Structure returned from Get Object Info */ - -struct acpi_device_info { - ACPI_COMMON_OBJ_INFO; - - u32 param_count; /* If a method, required parameter count */ - u32 valid; /* Indicates which fields below are valid */ - u32 current_status; /* _STA value */ - acpi_integer address; /* _ADR value if any */ - struct acpica_device_id hardware_id; /* _HID value if any */ - struct acpica_device_id unique_id; /* _UID value if any */ - u8 highest_dstates[4]; /* _sx_d values: 0xFF indicates not valid */ - struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */ -}; - /* Context structs for address space handlers */ struct acpi_pci_id { From dbdc8f02fe8339686623c84745ba15b0f4f889a1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 11:22:22 +0800 Subject: [PATCH 06/34] ACPICA: Fix possible memory leak in nspredef Fixed a possible leak when an attempt is made to repair a return object. The only current repair is an automatic buffer to string conversion. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/nspredef.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 7f8e066b12a3..abbb855e1b9a 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -1046,22 +1046,25 @@ acpi_ns_repair_object(u32 expected_btypes, ACPI_MEMCPY(new_object->string.pointer, return_object->buffer.pointer, length); - /* Install the new return object */ + /* + * If the original object is a package element, we need to: + * 1. Set the reference count of the new object to match the + * reference count of the old object. + * 2. Decrement the reference count of the original object. + */ + if (package_index != ACPI_NOT_PACKAGE) { + new_object->common.reference_count = + return_object->common.reference_count; + + if (return_object->common.reference_count > 1) { + return_object->common.reference_count--; + } + } + + /* Delete old object, install the new return object */ acpi_ut_remove_reference(return_object); *return_object_ptr = new_object; - - /* - * If the object is a package element, we need to: - * 1. Decrement the reference count of the orignal object, it was - * incremented when building the package - * 2. Increment the reference count of the new object, it will be - * decremented when releasing the package - */ - if (package_index != ACPI_NOT_PACKAGE) { - acpi_ut_remove_reference(return_object); - acpi_ut_add_reference(new_object); - } return (AE_OK); default: From 3db20bed579bc4e7fe581c48ad1bde853aa9ff68 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 24 Jun 2009 11:25:17 +0800 Subject: [PATCH 07/34] ACPICA: ACPI 4.0: iASL/Disassembler - IPMI keyword support. Adds support for the new IPMI operation region keyword. ACPICA BZ 771, 772. http://acpica.org/bugzilla/show_bug.cgi?id=771 http://acpica.org/bugzilla/show_bug.cgi?id=772 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/acpica/acconfig.h | 2 +- drivers/acpi/acpica/amlcode.h | 1 + drivers/acpi/acpica/utglobal.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 6c1fb2d9f4d5..9123d5a11627 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -183,7 +183,7 @@ /* Operation regions */ -#define ACPI_NUM_PREDEFINED_REGIONS 8 +#define ACPI_NUM_PREDEFINED_REGIONS 9 #define ACPI_USER_REGION_BEGIN 0x80 /* Maximum space_ids for Operation Regions */ diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h index 067f967eb389..4940249f2524 100644 --- a/drivers/acpi/acpica/amlcode.h +++ b/drivers/acpi/acpica/amlcode.h @@ -404,6 +404,7 @@ typedef enum { REGION_SMBUS, REGION_CMOS, REGION_PCI_BAR, + REGION_IPMI, REGION_DATA_TABLE, /* Internal use only */ REGION_FIXED_HW = 0x7F } AML_REGION_TYPES; diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index ed7a33c67fbe..9e33b6261939 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -359,6 +359,7 @@ const char *acpi_gbl_region_types[ACPI_NUM_PREDEFINED_REGIONS] = { "SMBus", "SystemCMOS", "PCIBARTarget", + "IPMI", "DataTable" }; From 6557a49a443a347d24aed58076365432ded30edc Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Wed, 24 Jun 2009 11:32:04 +0800 Subject: [PATCH 08/34] ACPICA: ACPI 4.0: Interpreter support for IPMI. Adds support for IPMI which is similar to SMBus and uses a bi-directional data buffer. ACPICA BZ 773. http://acpica.org/bugzilla/show_bug.cgi?id=773 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/acpica/acconfig.h | 3 +- drivers/acpi/acpica/exfield.c | 82 +++++++++++++++++++++++----------- drivers/acpi/acpica/exfldio.c | 7 +-- include/acpi/actypes.h | 3 +- 4 files changed, 63 insertions(+), 32 deletions(-) diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 9123d5a11627..8e679ef5b231 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -199,9 +199,10 @@ #define ACPI_RSDP_CHECKSUM_LENGTH 20 #define ACPI_RSDP_XCHECKSUM_LENGTH 36 -/* SMBus bidirectional buffer size */ +/* SMBus and IPMI bidirectional buffer size */ #define ACPI_SMBUS_BUFFER_SIZE 34 +#define ACPI_IPMI_BUFFER_SIZE 66 /* _sx_d and _sx_w control methods */ diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 546dcdd86785..0b33d6c887b9 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c @@ -72,6 +72,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, union acpi_operand_object *buffer_desc; acpi_size length; void *buffer; + u32 function; ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); @@ -97,13 +98,27 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, } } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && (obj_desc->field.region_obj->region.space_id == - ACPI_ADR_SPACE_SMBUS)) { + ACPI_ADR_SPACE_SMBUS + || obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_IPMI)) { /* - * This is an SMBus read. We must create a buffer to hold the data - * and directly access the region handler. + * This is an SMBus or IPMI read. We must create a buffer to hold + * the data and then directly access the region handler. + * + * Note: Smbus protocol value is passed in upper 16-bits of Function */ - buffer_desc = - acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_SMBUS) { + length = ACPI_SMBUS_BUFFER_SIZE; + function = + ACPI_READ | (obj_desc->field.attribute << 16); + } else { /* IPMI */ + + length = ACPI_IPMI_BUFFER_SIZE; + function = ACPI_READ; + } + + buffer_desc = acpi_ut_create_buffer_object(length); if (!buffer_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } @@ -112,16 +127,13 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags); - /* - * Perform the read. - * Note: Smbus protocol value is passed in upper 16-bits of Function - */ + /* Call the region handler for the read */ + status = acpi_ex_access_region(obj_desc, 0, ACPI_CAST_PTR(acpi_integer, buffer_desc-> buffer.pointer), - ACPI_READ | (obj_desc->field. - attribute << 16)); + function); acpi_ex_release_global_lock(obj_desc->common_field.field_flags); goto exit; } @@ -212,6 +224,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, u32 length; void *buffer; union acpi_operand_object *buffer_desc; + u32 function; ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); @@ -234,39 +247,56 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, } } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) && (obj_desc->field.region_obj->region.space_id == - ACPI_ADR_SPACE_SMBUS)) { + ACPI_ADR_SPACE_SMBUS + || obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_IPMI)) { /* - * This is an SMBus write. We will bypass the entire field mechanism - * and handoff the buffer directly to the handler. + * This is an SMBus or IPMI write. We will bypass the entire field + * mechanism and handoff the buffer directly to the handler. For + * these address spaces, the buffer is bi-directional; on a write, + * return data is returned in the same buffer. * - * Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE). + * Source must be a buffer of sufficient size: + * ACPI_SMBUS_BUFFER_SIZE or ACPI_IPMI_BUFFER_SIZE. + * + * Note: SMBus protocol type is passed in upper 16-bits of Function */ if (source_desc->common.type != ACPI_TYPE_BUFFER) { ACPI_ERROR((AE_INFO, - "SMBus write requires Buffer, found type %s", + "SMBus or IPMI write requires Buffer, found type %s", acpi_ut_get_object_type_name(source_desc))); return_ACPI_STATUS(AE_AML_OPERAND_TYPE); } - if (source_desc->buffer.length < ACPI_SMBUS_BUFFER_SIZE) { + if (obj_desc->field.region_obj->region.space_id == + ACPI_ADR_SPACE_SMBUS) { + length = ACPI_SMBUS_BUFFER_SIZE; + function = + ACPI_WRITE | (obj_desc->field.attribute << 16); + } else { /* IPMI */ + + length = ACPI_IPMI_BUFFER_SIZE; + function = ACPI_WRITE; + } + + if (source_desc->buffer.length < length) { ACPI_ERROR((AE_INFO, - "SMBus write requires Buffer of length %X, found length %X", - ACPI_SMBUS_BUFFER_SIZE, - source_desc->buffer.length)); + "SMBus or IPMI write requires Buffer of length %X, found length %X", + length, source_desc->buffer.length)); return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); } - buffer_desc = - acpi_ut_create_buffer_object(ACPI_SMBUS_BUFFER_SIZE); + /* Create the bi-directional buffer */ + + buffer_desc = acpi_ut_create_buffer_object(length); if (!buffer_desc) { return_ACPI_STATUS(AE_NO_MEMORY); } buffer = buffer_desc->buffer.pointer; - ACPI_MEMCPY(buffer, source_desc->buffer.pointer, - ACPI_SMBUS_BUFFER_SIZE); + ACPI_MEMCPY(buffer, source_desc->buffer.pointer, length); /* Lock entire transaction if requested */ @@ -275,12 +305,10 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, /* * Perform the write (returns status and perhaps data in the * same buffer) - * Note: SMBus protocol type is passed in upper 16-bits of Function. */ status = acpi_ex_access_region(obj_desc, 0, (acpi_integer *) buffer, - ACPI_WRITE | (obj_desc->field. - attribute << 16)); + function); acpi_ex_release_global_lock(obj_desc->common_field.field_flags); *result_desc = buffer_desc; diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c index 6687be167f5f..d7b3b418fb45 100644 --- a/drivers/acpi/acpica/exfldio.c +++ b/drivers/acpi/acpica/exfldio.c @@ -120,12 +120,13 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc, } /* - * Exit now for SMBus address space, it has a non-linear address space + * Exit now for SMBus or IPMI address space, it has a non-linear address space * and the request cannot be directly validated */ - if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS) { + if (rgn_desc->region.space_id == ACPI_ADR_SPACE_SMBUS || + rgn_desc->region.space_id == ACPI_ADR_SPACE_IPMI) { - /* SMBus has a non-linear address space */ + /* SMBus or IPMI has a non-linear address space */ return_ACPI_STATUS(AE_OK); } diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 7a4ff79e238c..4371805d2def 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -732,7 +732,8 @@ typedef u8 acpi_adr_space_type; #define ACPI_ADR_SPACE_SMBUS (acpi_adr_space_type) 4 #define ACPI_ADR_SPACE_CMOS (acpi_adr_space_type) 5 #define ACPI_ADR_SPACE_PCI_BAR_TARGET (acpi_adr_space_type) 6 -#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 7 +#define ACPI_ADR_SPACE_IPMI (acpi_adr_space_type) 7 +#define ACPI_ADR_SPACE_DATA_TABLE (acpi_adr_space_type) 8 #define ACPI_ADR_SPACE_FIXED_HARDWARE (acpi_adr_space_type) 127 /* From 8e4319c425077c4cc540696a5bb6c4d12f017dcd Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 29 Jun 2009 13:43:27 +0800 Subject: [PATCH 09/34] ACPICA: Fix several acpi_attach_data problems Handler was never invoked. Now invoked if/when host node is deleted. Data object was not automatically deleted when host node was deleted. Interface to handler had an unused parameter, removed it. ACPICA BZ 778. http://acpica.org/bugzilla/show_bug.cgi?id=778 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acnamesp.h | 2 + drivers/acpi/acpica/nsalloc.c | 88 +++++++++++++++++++++++----------- drivers/acpi/acpica/nsload.c | 3 +- drivers/acpi/bus.c | 2 +- drivers/acpi/glue.c | 2 +- drivers/acpi/scan.c | 2 +- include/acpi/acpi_bus.h | 4 +- include/acpi/actypes.h | 2 +- 8 files changed, 70 insertions(+), 35 deletions(-) diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 94cdc2b8cb93..a78e02f62d5e 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -144,6 +144,8 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name); void acpi_ns_delete_node(struct acpi_namespace_node *node); +void acpi_ns_remove_node(struct acpi_namespace_node *node); + void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_handle); diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c index efc971ab7d65..8a58a1b85aa0 100644 --- a/drivers/acpi/acpica/nsalloc.c +++ b/drivers/acpi/acpica/nsalloc.c @@ -96,17 +96,68 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name) * * RETURN: None * - * DESCRIPTION: Delete a namespace node + * DESCRIPTION: Delete a namespace node. All node deletions must come through + * here. Detaches any attached objects, including any attached + * data. If a handler is associated with attached data, it is + * invoked before the node is deleted. * ******************************************************************************/ void acpi_ns_delete_node(struct acpi_namespace_node *node) +{ + union acpi_operand_object *obj_desc; + + ACPI_FUNCTION_NAME(ns_delete_node); + + /* Detach an object if there is one */ + + acpi_ns_detach_object(node); + + /* + * Delete an attached data object if present (an object that was created + * and attached via acpi_attach_data). Note: After any normal object is + * detached above, the only possible remaining object is a data object. + */ + obj_desc = node->object; + if (obj_desc && (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) { + + /* Invoke the attached data deletion handler if present */ + + if (obj_desc->data.handler) { + obj_desc->data.handler(node, obj_desc->data.pointer); + } + + acpi_ut_remove_reference(obj_desc); + } + + /* Now we can delete the node */ + + (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); + + ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); + ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, "Node %p, Remaining %X\n", + node, acpi_gbl_current_node_count)); +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_remove_node + * + * PARAMETERS: Node - Node to be removed/deleted + * + * RETURN: None + * + * DESCRIPTION: Remove (unlink) and delete a namespace node + * + ******************************************************************************/ + +void acpi_ns_remove_node(struct acpi_namespace_node *node) { struct acpi_namespace_node *parent_node; struct acpi_namespace_node *prev_node; struct acpi_namespace_node *next_node; - ACPI_FUNCTION_TRACE_PTR(ns_delete_node, node); + ACPI_FUNCTION_TRACE_PTR(ns_remove_node, node); parent_node = acpi_ns_get_parent_node(node); @@ -142,12 +193,9 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node) } } - ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); + /* Delete the node and any attached objects */ - /* Detach an object if there is one, then delete the node */ - - acpi_ns_detach_object(node); - (void)acpi_os_release_object(acpi_gbl_namespace_cache, node); + acpi_ns_delete_node(node); return_VOID; } @@ -273,25 +321,11 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node) parent_node, child_node)); } - /* Now we can free this child object */ - - ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++); - - ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS, - "Object %p, Remaining %X\n", child_node, - acpi_gbl_current_node_count)); - - /* Detach an object if there is one, then free the child node */ - - acpi_ns_detach_object(child_node); - - /* Now we can delete the node */ - - (void)acpi_os_release_object(acpi_gbl_namespace_cache, - child_node); - - /* And move on to the next child in the list */ - + /* + * Delete this child node and move on to the next child in the list. + * No need to unlink the node since we are deleting the entire branch. + */ + acpi_ns_delete_node(child_node); child_node = next_node; } while (!(flags & ANOBJ_END_OF_PEER_LIST)); @@ -433,7 +467,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id) if (deletion_node) { acpi_ns_delete_children(deletion_node); - acpi_ns_delete_node(deletion_node); + acpi_ns_remove_node(deletion_node); deletion_node = NULL; } diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c index dcd7a6adbbbc..a7234e60e985 100644 --- a/drivers/acpi/acpica/nsload.c +++ b/drivers/acpi/acpica/nsload.c @@ -270,8 +270,7 @@ static acpi_status acpi_ns_delete_subtree(acpi_handle start_handle) /* Now delete the starting object, and we are done */ - acpi_ns_delete_node(child_handle); - + acpi_ns_remove_node(child_handle); return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 2876fc70c3a9..620183f13e5e 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -141,7 +141,7 @@ int acpi_bus_get_status(struct acpi_device *device) EXPORT_SYMBOL(acpi_bus_get_status); void acpi_bus_private_data_handler(acpi_handle handle, - u32 function, void *context) + void *context) { return; } diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 27a7072347ea..9a4ce33f137e 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -119,7 +119,7 @@ EXPORT_SYMBOL(acpi_get_child); /* Link ACPI devices with physical devices */ static void acpi_glue_data_handler(acpi_handle handle, - u32 function, void *context) + void *context) { /* we provide an empty handler */ } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 0ab526de7c55..9606af13d3b8 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -687,7 +687,7 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd) } EXPORT_SYMBOL_GPL(acpi_bus_get_ejd); -void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context) +void acpi_bus_data_handler(acpi_handle handle, void *context) { /* TBD */ diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index b91420b52c6f..6e83a68fbd7b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -312,7 +312,7 @@ struct acpi_bus_event { extern struct kobject *acpi_kobj; extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); -void acpi_bus_private_data_handler(acpi_handle, u32, void *); +void acpi_bus_private_data_handler(acpi_handle, void *); int acpi_bus_get_private_data(acpi_handle, void **); extern int acpi_notifier_call_chain(struct acpi_device *, u32, u32); extern int register_acpi_notifier(struct notifier_block *); @@ -325,7 +325,7 @@ extern void unregister_acpi_bus_notifier(struct notifier_block *nb); */ int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device); -void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); +void acpi_bus_data_handler(acpi_handle handle, void *context); int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 4371805d2def..ef4601149f49 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -922,7 +922,7 @@ typedef void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context); typedef -void (*acpi_object_handler) (acpi_handle object, u32 function, void *data); +void (*acpi_object_handler) (acpi_handle object, void *data); typedef acpi_status(*acpi_init_handler) (acpi_handle object, u32 function); From cf02cd47d4747abf8ff0617e15fc05a00202e6d5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 11:38:46 +0800 Subject: [PATCH 10/34] ACPICA: Dump table header - suppress output of non-printable characters Function acpi_tb_print_table_header. Some ACPI tables contain non-printable characters in one of the string fields of the the header - Signature, OemId, OemTableId, or CompilerId. Invalid characters are replaced by '?'. ACPICA BZ 788. http://acpica.org/bugzilla/show_bug.cgi?id=788 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/tbutils.c | 82 ++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c index ef7d2c2d8f0b..1f15497f00d1 100644 --- a/drivers/acpi/acpica/tbutils.c +++ b/drivers/acpi/acpica/tbutils.c @@ -49,6 +49,12 @@ ACPI_MODULE_NAME("tbutils") /* Local prototypes */ +static void acpi_tb_fix_string(char *string, acpi_size length); + +static void +acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, + struct acpi_table_header *header); + static acpi_physical_address acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size); @@ -159,6 +165,59 @@ u8 acpi_tb_tables_loaded(void) return (FALSE); } +/******************************************************************************* + * + * FUNCTION: acpi_tb_fix_string + * + * PARAMETERS: String - String to be repaired + * Length - Maximum length + * + * RETURN: None + * + * DESCRIPTION: Replace every non-printable or non-ascii byte in the string + * with a question mark '?'. + * + ******************************************************************************/ + +static void acpi_tb_fix_string(char *string, acpi_size length) +{ + + while (length && *string) { + if (!ACPI_IS_PRINT(*string)) { + *string = '?'; + } + string++; + length--; + } +} + +/******************************************************************************* + * + * FUNCTION: acpi_tb_cleanup_table_header + * + * PARAMETERS: out_header - Where the cleaned header is returned + * Header - Input ACPI table header + * + * RETURN: Returns the cleaned header in out_header + * + * DESCRIPTION: Copy the table header and ensure that all "string" fields in + * the header consist of printable characters. + * + ******************************************************************************/ + +static void +acpi_tb_cleanup_table_header(struct acpi_table_header *out_header, + struct acpi_table_header *header) +{ + + ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header)); + + acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE); + acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE); + acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE); + acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE); +} + /******************************************************************************* * * FUNCTION: acpi_tb_print_table_header @@ -176,6 +235,7 @@ void acpi_tb_print_table_header(acpi_physical_address address, struct acpi_table_header *header) { + struct acpi_table_header local_header; /* * The reason that the Address is cast to a void pointer is so that we @@ -192,6 +252,11 @@ acpi_tb_print_table_header(acpi_physical_address address, /* RSDP has no common fields */ + ACPI_MEMCPY(local_header.oem_id, + ACPI_CAST_PTR(struct acpi_table_rsdp, + header)->oem_id, ACPI_OEM_ID_SIZE); + acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE); + ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)", ACPI_CAST_PTR (void, address), (ACPI_CAST_PTR(struct acpi_table_rsdp, header)-> @@ -200,18 +265,21 @@ acpi_tb_print_table_header(acpi_physical_address address, header)->length : 20, ACPI_CAST_PTR(struct acpi_table_rsdp, header)->revision, - ACPI_CAST_PTR(struct acpi_table_rsdp, - header)->oem_id)); + local_header.oem_id)); } else { /* Standard ACPI table with full common header */ + acpi_tb_cleanup_table_header(&local_header, header); + ACPI_INFO((AE_INFO, "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)", - header->signature, ACPI_CAST_PTR (void, address), - header->length, header->revision, header->oem_id, - header->oem_table_id, header->oem_revision, - header->asl_compiler_id, - header->asl_compiler_revision)); + local_header.signature, ACPI_CAST_PTR(void, address), + local_header.length, local_header.revision, + local_header.oem_id, local_header.oem_table_id, + local_header.oem_revision, + local_header.asl_compiler_id, + local_header.asl_compiler_revision)); + } } From 0444e8f6d72d6e38f92d48884bc90bbc6c22fd5a Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 13:38:02 +0800 Subject: [PATCH 11/34] ACPICA: Fix: Predefined object repair executed only once This fixes a problem where the code that attempts to repair/convert an object of incorrect type is only executed on the first time the predefined method is called. The mechanism that disables warnings on subsequent calls was interfering with the repair mechanism. ACPICA BZ 781. http://acpica.org/bugzilla/show_bug.cgi?id=781 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 13 ++ drivers/acpi/acpica/acmacros.h | 2 + drivers/acpi/acpica/acutils.h | 6 + drivers/acpi/acpica/nspredef.c | 369 ++++++++++++++++++--------------- drivers/acpi/acpica/utmisc.c | 57 ++++- 5 files changed, 277 insertions(+), 170 deletions(-) diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index ee986edfa0da..ff6689eba917 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -369,6 +369,19 @@ union acpi_predefined_info { struct acpi_package_info3 ret_info3; }; +/* Data block used during object validation */ + +struct acpi_predefined_data { + char *pathname; + const union acpi_predefined_info *predefined; + u32 flags; + u8 node_flags; +}; + +/* Defines for Flags field above */ + +#define ACPI_OBJECT_REPAIRED 1 + /* * Bitmapped return value types * Note: the actual data types must be contiguous, a loop in nspredef.c diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h index 91ac7d7b4402..3acd9c6760ea 100644 --- a/drivers/acpi/acpica/acmacros.h +++ b/drivers/acpi/acpica/acmacros.h @@ -340,6 +340,7 @@ */ #define ACPI_ERROR_NAMESPACE(s, e) acpi_ns_report_error (AE_INFO, s, e); #define ACPI_ERROR_METHOD(s, n, p, e) acpi_ns_report_method_error (AE_INFO, s, n, p, e); +#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist #else @@ -347,6 +348,7 @@ #define ACPI_ERROR_NAMESPACE(s, e) #define ACPI_ERROR_METHOD(s, n, p, e) +#define ACPI_WARN_PREDEFINED(plist) #endif /* ACPI_NO_ERROR_MESSAGES */ /* diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h index b0add85de308..863a264b829e 100644 --- a/drivers/acpi/acpica/acutils.h +++ b/drivers/acpi/acpica/acutils.h @@ -475,6 +475,12 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position); acpi_status acpi_ut_strtoul64(char *string, u32 base, acpi_integer * ret_integer); +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...); + /* Values for Base above (16=Hex, 10=Decimal) */ #define ACPI_ANY_BASE 0 diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index abbb855e1b9a..1dc1a4737aa9 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -72,31 +72,33 @@ ACPI_MODULE_NAME("nspredef") ******************************************************************************/ /* Local prototypes */ static acpi_status -acpi_ns_check_package(char *pathname, - union acpi_operand_object **return_object_ptr, - const union acpi_predefined_info *predefined); +acpi_ns_check_package(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr); static acpi_status -acpi_ns_check_package_elements(char *pathname, +acpi_ns_check_package_elements(struct acpi_predefined_data *data, union acpi_operand_object **elements, u8 type1, u32 count1, u8 type2, u32 count2, u32 start_index); static acpi_status -acpi_ns_check_object_type(char *pathname, +acpi_ns_check_object_type(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index); static acpi_status -acpi_ns_check_reference(char *pathname, +acpi_ns_check_reference(struct acpi_predefined_data *data, union acpi_operand_object *return_object); static acpi_status -acpi_ns_repair_object(u32 expected_btypes, +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr); +static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); + /* * Names for the types that can be returned by the predefined objects. * Used for warning messages. Must be in the same order as the ACPI_RTYPEs @@ -109,13 +111,21 @@ static const char *acpi_rtype_names[] = { "/Reference", }; -#define ACPI_NOT_PACKAGE ACPI_UINT32_MAX +/* Object is not a package element */ + +#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX + +/* Always emit warning message, not dependent on node flags */ + +#define ACPI_WARN_ALWAYS 0 /******************************************************************************* * * FUNCTION: acpi_ns_check_predefined_names * * PARAMETERS: Node - Namespace node for the method/object + * user_param_count - Number of parameters actually passed + * return_status - Status from the object evaluation * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * @@ -135,12 +145,13 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, acpi_status status = AE_OK; const union acpi_predefined_info *predefined; char *pathname; + struct acpi_predefined_data *data; /* Match the name for this method/object against the predefined list */ predefined = acpi_ns_check_for_predefined_name(node); - /* Get the full pathname to the object, for use in error messages */ + /* Get the full pathname to the object, for use in warning messages */ pathname = acpi_ns_get_external_pathname(node); if (!pathname) { @@ -158,28 +169,17 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, /* If not a predefined name, we cannot validate the return object */ if (!predefined) { - goto exit; - } - - /* If the method failed, we cannot validate the return object */ - - if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { - goto exit; + goto cleanup; } /* - * Only validate the return value on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. + * If the method failed or did not actually return an object, we cannot + * validate the return object */ - if (node->flags & ANOBJ_EVALUATED) { - goto exit; + if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) { + goto cleanup; } - /* Mark the node as having been successfully evaluated */ - - node->flags |= ANOBJ_EVALUATED; - /* * If there is no return value, check if we require a return value for * this predefined name. Either one return value is expected, or none, @@ -190,46 +190,63 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, if (!return_object) { if ((predefined->info.expected_btypes) && (!(predefined->info.expected_btypes & ACPI_RTYPE_NONE))) { - ACPI_ERROR((AE_INFO, - "%s: Missing expected return value", - pathname)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Missing expected return value")); status = AE_AML_NO_RETURN_VALUE; } - goto exit; + goto cleanup; } /* * We have a return value, but if one wasn't expected, just exit, this is - * not a problem - * - * For example, if the "Implicit Return" feature is enabled, methods will - * always return a value + * not a problem. For example, if the "Implicit Return" feature is + * enabled, methods will always return a value. */ if (!predefined->info.expected_btypes) { - goto exit; + goto cleanup; } + /* Create the parameter data block for object validation */ + + data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data)); + if (!data) { + goto cleanup; + } + data->predefined = predefined; + data->node_flags = node->flags; + data->pathname = pathname; + /* * Check that the type of the return object is what is expected for * this predefined name */ - status = acpi_ns_check_object_type(pathname, return_object_ptr, + status = acpi_ns_check_object_type(data, return_object_ptr, predefined->info.expected_btypes, - ACPI_NOT_PACKAGE); + ACPI_NOT_PACKAGE_ELEMENT); if (ACPI_FAILURE(status)) { - goto exit; + goto check_validation_status; } /* For returned Package objects, check the type of all sub-objects */ if (return_object->common.type == ACPI_TYPE_PACKAGE) { - status = - acpi_ns_check_package(pathname, return_object_ptr, - predefined); + status = acpi_ns_check_package(data, return_object_ptr); } - exit: +check_validation_status: + /* + * If the object validation failed or if we successfully repaired one + * or more objects, mark the parent node to suppress further warning + * messages during the next evaluation of the same method/object. + */ + if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) { + node->flags |= ANOBJ_EVALUATED; + } + ACPI_FREE(data); + +cleanup: ACPI_FREE(pathname); return (status); } @@ -268,64 +285,58 @@ acpi_ns_check_parameter_count(char *pathname, param_count = node->object->method.param_count; } - /* Argument count check for non-predefined methods/objects */ - if (!predefined) { /* + * Check the parameter count for non-predefined methods/objects. + * * Warning if too few or too many arguments have been passed by the * caller. An incorrect number of arguments may not cause the method * to fail. However, the method will fail if there are too few * arguments and the method attempts to use one of the missing ones. */ if (user_param_count < param_count) { - ACPI_WARNING((AE_INFO, - "%s: Insufficient arguments - needs %d, found %d", - pathname, param_count, user_param_count)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Insufficient arguments - needs %u, found %u", + param_count, user_param_count)); } else if (user_param_count > param_count) { - ACPI_WARNING((AE_INFO, - "%s: Excess arguments - needs %d, found %d", - pathname, param_count, user_param_count)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Excess arguments - needs %u, found %u", + param_count, user_param_count)); } return; } - /* Allow two different legal argument counts (_SCP, etc.) */ - + /* + * Validate the user-supplied parameter count. + * Allow two different legal argument counts (_SCP, etc.) + */ required_params_current = predefined->info.param_count & 0x0F; required_params_old = predefined->info.param_count >> 4; if (user_param_count != ACPI_UINT32_MAX) { - - /* Validate the user-supplied parameter count */ - if ((user_param_count != required_params_current) && (user_param_count != required_params_old)) { - ACPI_WARNING((AE_INFO, - "%s: Parameter count mismatch - " - "caller passed %d, ACPI requires %d", - pathname, user_param_count, - required_params_current)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, + ACPI_WARN_ALWAYS, + "Parameter count mismatch - " + "caller passed %u, ACPI requires %u", + user_param_count, + required_params_current)); } } - /* - * Only validate the argument count on the first successful evaluation of - * the method. This ensures that any warnings will only be emitted during - * the very first evaluation of the method/object. - */ - if (node->flags & ANOBJ_EVALUATED) { - return; - } - /* * Check that the ASL-defined parameter count is what is expected for - * this predefined name. + * this predefined name (parameter count as defined by the ACPI + * specification) */ if ((param_count != required_params_current) && (param_count != required_params_old)) { - ACPI_WARNING((AE_INFO, - "%s: Parameter count mismatch - ASL declared %d, ACPI requires %d", - pathname, param_count, required_params_current)); + ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags, + "Parameter count mismatch - ASL declared %u, ACPI requires %u", + param_count, required_params_current)); } } @@ -358,9 +369,6 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct this_name = predefined_names; while (this_name->info.name[0]) { if (ACPI_COMPARE_NAME(node->name.ascii, this_name->info.name)) { - - /* Return pointer to this table entry */ - return (this_name); } @@ -375,17 +383,16 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct this_name++; } - return (NULL); + return (NULL); /* Not found */ } /******************************************************************************* * * FUNCTION: acpi_ns_check_package * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object - * Predefined - Pointer to entry in predefined name table * * RETURN: Status * @@ -395,9 +402,8 @@ const union acpi_predefined_info *acpi_ns_check_for_predefined_name(struct ******************************************************************************/ static acpi_status -acpi_ns_check_package(char *pathname, - union acpi_operand_object **return_object_ptr, - const union acpi_predefined_info *predefined) +acpi_ns_check_package(struct acpi_predefined_data *data, + union acpi_operand_object **return_object_ptr) { union acpi_operand_object *return_object = *return_object_ptr; const union acpi_predefined_info *package; @@ -414,11 +420,11 @@ acpi_ns_check_package(char *pathname, /* The package info for this name is in the next table entry */ - package = predefined + 1; + package = data->predefined + 1; ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s Validating return Package of Type %X, Count %X\n", - pathname, package->ret_info.type, + data->pathname, package->ret_info.type, return_object->package.count)); /* Extract package count and elements array */ @@ -429,9 +435,8 @@ acpi_ns_check_package(char *pathname, /* The package must have at least one element, else invalid */ if (!count) { - ACPI_WARNING((AE_INFO, - "%s: Return Package has no elements (empty)", - pathname)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package has no elements (empty)")); return (AE_AML_OPERAND_VALUE); } @@ -456,15 +461,16 @@ acpi_ns_check_package(char *pathname, if (count < expected_count) { goto package_too_small; } else if (count > expected_count) { - ACPI_WARNING((AE_INFO, - "%s: Return Package is larger than needed - " - "found %u, expected %u", pathname, count, - expected_count)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Return Package is larger than needed - " + "found %u, expected %u", count, + expected_count)); } /* Validate all elements of the returned package */ - status = acpi_ns_check_package_elements(pathname, elements, + status = acpi_ns_check_package_elements(data, elements, package->ret_info. object_type1, package->ret_info. @@ -485,7 +491,7 @@ acpi_ns_check_package(char *pathname, * elements must be of the same type */ for (i = 0; i < count; i++) { - status = acpi_ns_check_object_type(pathname, elements, + status = acpi_ns_check_object_type(data, elements, package->ret_info. object_type1, i); if (ACPI_FAILURE(status)) { @@ -517,8 +523,7 @@ acpi_ns_check_package(char *pathname, /* These are the required package elements (0, 1, or 2) */ status = - acpi_ns_check_object_type(pathname, - elements, + acpi_ns_check_object_type(data, elements, package-> ret_info3. object_type[i], @@ -530,8 +535,7 @@ acpi_ns_check_package(char *pathname, /* These are the optional package elements */ status = - acpi_ns_check_object_type(pathname, - elements, + acpi_ns_check_object_type(data, elements, package-> ret_info3. tail_object_type, @@ -548,7 +552,7 @@ acpi_ns_check_package(char *pathname, /* First element is the (Integer) count of sub-packages to follow */ - status = acpi_ns_check_object_type(pathname, elements, + status = acpi_ns_check_object_type(data, elements, ACPI_RTYPE_INTEGER, 0); if (ACPI_FAILURE(status)) { return (status); @@ -585,9 +589,9 @@ acpi_ns_check_package(char *pathname, /* Each sub-object must be of type Package */ - status = - acpi_ns_check_object_type(pathname, &sub_package, - ACPI_RTYPE_PACKAGE, i); + status = acpi_ns_check_object_type(data, &sub_package, + ACPI_RTYPE_PACKAGE, + i); if (ACPI_FAILURE(status)) { return (status); } @@ -610,7 +614,7 @@ acpi_ns_check_package(char *pathname, } status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, sub_elements, package-> ret_info. @@ -643,7 +647,7 @@ acpi_ns_check_package(char *pathname, for (j = 0; j < expected_count; j++) { status = - acpi_ns_check_object_type(pathname, + acpi_ns_check_object_type(data, &sub_elements[j], package->ret_info2.object_type[j], j); if (ACPI_FAILURE(status)) { @@ -665,7 +669,7 @@ acpi_ns_check_package(char *pathname, /* Check the type of each sub-package element */ status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, sub_elements, package-> ret_info. @@ -684,7 +688,7 @@ acpi_ns_check_package(char *pathname, /* First element is the (Integer) count of elements to follow */ status = - acpi_ns_check_object_type(pathname, + acpi_ns_check_object_type(data, sub_elements, ACPI_RTYPE_INTEGER, 0); @@ -704,7 +708,7 @@ acpi_ns_check_package(char *pathname, /* Check the type of each sub-package element */ status = - acpi_ns_check_package_elements(pathname, + acpi_ns_check_package_elements(data, (sub_elements + 1), package-> @@ -730,9 +734,9 @@ acpi_ns_check_package(char *pathname, /* Should not get here if predefined info table is correct */ - ACPI_WARNING((AE_INFO, - "%s: Invalid internal return type in table entry: %X", - pathname, package->ret_info.type)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Invalid internal return type in table entry: %X", + package->ret_info.type)); return (AE_AML_INTERNAL); } @@ -743,9 +747,9 @@ acpi_ns_check_package(char *pathname, /* Error exit for the case with an incorrect package count */ - ACPI_WARNING((AE_INFO, "%s: Return Package is too small - " - "found %u, expected %u", pathname, count, - expected_count)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package is too small - found %u, expected %u", + count, expected_count)); return (AE_AML_OPERAND_VALUE); } @@ -754,7 +758,7 @@ acpi_ns_check_package(char *pathname, * * FUNCTION: acpi_ns_check_package_elements * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * Elements - Pointer to the package elements array * Type1 - Object type for first group * Count1 - Count for first group @@ -770,7 +774,7 @@ acpi_ns_check_package(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_package_elements(char *pathname, +acpi_ns_check_package_elements(struct acpi_predefined_data *data, union acpi_operand_object **elements, u8 type1, u32 count1, @@ -786,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname, * The second group can have a count of zero. */ for (i = 0; i < count1; i++) { - status = acpi_ns_check_object_type(pathname, this_element, + status = acpi_ns_check_object_type(data, this_element, type1, i + start_index); if (ACPI_FAILURE(status)) { return (status); @@ -795,7 +799,7 @@ acpi_ns_check_package_elements(char *pathname, } for (i = 0; i < count2; i++) { - status = acpi_ns_check_object_type(pathname, this_element, + status = acpi_ns_check_object_type(data, this_element, type2, (i + count1 + start_index)); if (ACPI_FAILURE(status)) { @@ -811,12 +815,13 @@ acpi_ns_check_package_elements(char *pathname, * * FUNCTION: acpi_ns_check_object_type * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * expected_btypes - Bitmap of expected return type(s) * package_index - Index of object within parent package (if - * applicable - ACPI_NOT_PACKAGE otherwise) + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * * RETURN: Status * @@ -826,7 +831,7 @@ acpi_ns_check_package_elements(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_object_type(char *pathname, +acpi_ns_check_object_type(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr, u32 expected_btypes, u32 package_index) { @@ -834,9 +839,6 @@ acpi_ns_check_object_type(char *pathname, acpi_status status = AE_OK; u32 return_btype; char type_buffer[48]; /* Room for 5 types */ - u32 this_rtype; - u32 i; - u32 j; /* * If we get a NULL return_object here, it is a NULL package element, @@ -849,10 +851,11 @@ acpi_ns_check_object_type(char *pathname, /* A Namespace node should not get here, but make sure */ if (ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) { - ACPI_WARNING((AE_INFO, - "%s: Invalid return type - Found a Namespace node [%4.4s] type %s", - pathname, return_object->node.name.ascii, - acpi_ut_get_type_name(return_object->node.type))); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Invalid return type - Found a Namespace node [%4.4s] type %s", + return_object->node.name.ascii, + acpi_ut_get_type_name(return_object->node. + type))); return (AE_AML_OPERAND_TYPE); } @@ -897,10 +900,11 @@ acpi_ns_check_object_type(char *pathname, /* Type mismatch -- attempt repair of the returned object */ - status = acpi_ns_repair_object(expected_btypes, package_index, + status = acpi_ns_repair_object(data, expected_btypes, + package_index, return_object_ptr); if (ACPI_SUCCESS(status)) { - return (status); + return (AE_OK); /* Repair was successful */ } goto type_error_exit; } @@ -908,7 +912,7 @@ acpi_ns_check_object_type(char *pathname, /* For reference objects, check that the reference type is correct */ if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) { - status = acpi_ns_check_reference(pathname, return_object); + status = acpi_ns_check_reference(data, return_object); } return (status); @@ -917,33 +921,19 @@ acpi_ns_check_object_type(char *pathname, /* Create a string with all expected types for this predefined object */ - j = 1; - type_buffer[0] = 0; - this_rtype = ACPI_RTYPE_INTEGER; + acpi_ns_get_expected_types(type_buffer, expected_btypes); - for (i = 0; i < ACPI_NUM_RTYPES; i++) { - - /* If one of the expected types, concatenate the name of this type */ - - if (expected_btypes & this_rtype) { - ACPI_STRCAT(type_buffer, &acpi_rtype_names[i][j]); - j = 0; /* Use name separator from now on */ - } - this_rtype <<= 1; /* Next Rtype */ - } - - if (package_index == ACPI_NOT_PACKAGE) { - ACPI_WARNING((AE_INFO, - "%s: Return type mismatch - found %s, expected %s", - pathname, - acpi_ut_get_object_type_name(return_object), - type_buffer)); + if (package_index == ACPI_NOT_PACKAGE_ELEMENT) { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return type mismatch - found %s, expected %s", + acpi_ut_get_object_type_name + (return_object), type_buffer)); } else { - ACPI_WARNING((AE_INFO, - "%s: Return Package type mismatch at index %u - " - "found %s, expected %s", pathname, package_index, - acpi_ut_get_object_type_name(return_object), - type_buffer)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Package type mismatch at index %u - " + "found %s, expected %s", package_index, + acpi_ut_get_object_type_name + (return_object), type_buffer)); } return (AE_AML_OPERAND_TYPE); @@ -953,7 +943,7 @@ acpi_ns_check_object_type(char *pathname, * * FUNCTION: acpi_ns_check_reference * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) + * PARAMETERS: Data - Pointer to validation data structure * return_object - Object returned from the evaluation of a * method or object * @@ -966,7 +956,7 @@ acpi_ns_check_object_type(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_check_reference(char *pathname, +acpi_ns_check_reference(struct acpi_predefined_data *data, union acpi_operand_object *return_object) { @@ -979,11 +969,10 @@ acpi_ns_check_reference(char *pathname, return (AE_OK); } - ACPI_WARNING((AE_INFO, - "%s: Return type mismatch - " - "unexpected reference object type [%s] %2.2X", - pathname, acpi_ut_get_reference_name(return_object), - return_object->reference.class)); + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return type mismatch - unexpected reference object type [%s] %2.2X", + acpi_ut_get_reference_name(return_object), + return_object->reference.class)); return (AE_AML_OPERAND_TYPE); } @@ -992,8 +981,11 @@ acpi_ns_check_reference(char *pathname, * * FUNCTION: acpi_ns_repair_object * - * PARAMETERS: Pathname - Full pathname to the node (for error msgs) - * package_index - Used to determine if target is in a package + * PARAMETERS: Data - Pointer to validation data structure + * expected_btypes - Object types expected + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) * return_object_ptr - Pointer to the object returned from the * evaluation of a method or object * @@ -1005,7 +997,8 @@ acpi_ns_check_reference(char *pathname, ******************************************************************************/ static acpi_status -acpi_ns_repair_object(u32 expected_btypes, +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, u32 package_index, union acpi_operand_object **return_object_ptr) { @@ -1016,6 +1009,8 @@ acpi_ns_repair_object(u32 expected_btypes, switch (return_object->common.type) { case ACPI_TYPE_BUFFER: + /* Does the method/object legally return a string? */ + if (!(expected_btypes & ACPI_RTYPE_STRING)) { return (AE_AML_OPERAND_TYPE); } @@ -1052,19 +1047,29 @@ acpi_ns_repair_object(u32 expected_btypes, * reference count of the old object. * 2. Decrement the reference count of the original object. */ - if (package_index != ACPI_NOT_PACKAGE) { + if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { new_object->common.reference_count = return_object->common.reference_count; if (return_object->common.reference_count > 1) { return_object->common.reference_count--; } + + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String at index %u", + package_index)); + } else { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String")); } /* Delete old object, install the new return object */ acpi_ut_remove_reference(return_object); *return_object_ptr = new_object; + data->flags |= ACPI_OBJECT_REPAIRED; return (AE_OK); default: @@ -1073,3 +1078,39 @@ acpi_ns_repair_object(u32 expected_btypes, return (AE_AML_OPERAND_TYPE); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_get_expected_types + * + * PARAMETERS: Buffer - Pointer to where the string is returned + * expected_btypes - Bitmap of expected return type(s) + * + * RETURN: Buffer is populated with type names. + * + * DESCRIPTION: Translate the expected types bitmap into a string of ascii + * names of expected types, for use in warning messages. + * + ******************************************************************************/ + +static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes) +{ + u32 this_rtype; + u32 i; + u32 j; + + j = 1; + buffer[0] = 0; + this_rtype = ACPI_RTYPE_INTEGER; + + for (i = 0; i < ACPI_NUM_RTYPES; i++) { + + /* If one of the expected types, concatenate the name of this type */ + + if (expected_btypes & this_rtype) { + ACPI_STRCAT(buffer, &acpi_rtype_names[i][j]); + j = 0; /* Use name separator from now on */ + } + this_rtype <<= 1; /* Next Rtype */ + } +} diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 9cd65334ca75..5bd29606dc61 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -50,6 +50,11 @@ #define _COMPONENT ACPI_UTILITIES ACPI_MODULE_NAME("utmisc") +/* + * Common suffix for messages + */ +#define ACPI_COMMON_MSG_SUFFIX \ + acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, line_number) /******************************************************************************* * * FUNCTION: acpi_ut_validate_exception @@ -1065,8 +1070,7 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...) va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1080,8 +1084,7 @@ acpi_exception(const char *module_name, va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1094,8 +1097,7 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...) va_start(args, format); acpi_os_vprintf(format, args); - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, - line_number); + ACPI_COMMON_MSG_SUFFIX; va_end(args); } @@ -1116,3 +1118,46 @@ ACPI_EXPORT_SYMBOL(acpi_error) ACPI_EXPORT_SYMBOL(acpi_exception) ACPI_EXPORT_SYMBOL(acpi_warning) ACPI_EXPORT_SYMBOL(acpi_info) + +/******************************************************************************* + * + * FUNCTION: acpi_ut_predefined_warning + * + * PARAMETERS: module_name - Caller's module name (for error output) + * line_number - Caller's line number (for error output) + * Pathname - Full pathname to the node + * node_flags - From Namespace node for the method/object + * Format - Printf format string + additional args + * + * RETURN: None + * + * DESCRIPTION: Warnings for the predefined validation module. Messages are + * only emitted the first time a problem with a particular + * method/object is detected. This prevents a flood of error + * messages for methods that are repeatedly evaluated. + * +******************************************************************************/ + +void ACPI_INTERNAL_VAR_XFACE +acpi_ut_predefined_warning(const char *module_name, + u32 line_number, + char *pathname, + u8 node_flags, const char *format, ...) +{ + va_list args; + + /* + * Warning messages for this method/object will be disabled after the + * first time a validation fails or an object is successfully repaired. + */ + if (node_flags & ANOBJ_EVALUATED) { + return; + } + + acpi_os_printf("ACPI Warning for %s: ", pathname); + + va_start(args, format); + acpi_os_vprintf(format, args); + ACPI_COMMON_MSG_SUFFIX; + va_end(args); +} From 8d590c7af1152685efcf302905baeb6dda3c2d2f Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 13:39:29 +0800 Subject: [PATCH 12/34] ACPICA: Clarify common suffix for error/warning messages Added parens around the acpica version/modulename/linenumber to clearly differentiate this group from the rest of the message. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/utmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c index 5bd29606dc61..61f6315fce9f 100644 --- a/drivers/acpi/acpica/utmisc.c +++ b/drivers/acpi/acpica/utmisc.c @@ -54,7 +54,7 @@ ACPI_MODULE_NAME("utmisc") * Common suffix for messages */ #define ACPI_COMMON_MSG_SUFFIX \ - acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name, line_number) + acpi_os_printf(" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number) /******************************************************************************* * * FUNCTION: acpi_ut_validate_exception From eb2289ba1ba994de25af0d94b5e80ba93d2c1c3c Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Wed, 24 Jun 2009 13:42:00 +0800 Subject: [PATCH 13/34] ACPICA: ACPI 4.0: Changes for existing ACPI tables. FACS: new flag and new OspmFlags field. SRAT: x2APIC - add ClockDomain field to descriptor #2 Includes header and disassembler support. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actbl.h | 19 +++++++++++++------ include/acpi/actbl1.h | 8 +++++--- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 222733d01f36..0649a5670026 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -161,17 +161,24 @@ struct acpi_table_facs { u32 flags; u64 xfirmware_waking_vector; /* 64-bit version of the Firmware Waking Vector (ACPI 2.0+) */ u8 version; /* Version of this table (ACPI 2.0+) */ - u8 reserved[31]; /* Reserved, must be zero */ + u8 reserved[3]; /* Reserved, must be zero */ + u32 ospm_flags; /* Flags to be set by OSPM (ACPI 4.0) */ + u8 reserved1[24]; /* Reserved, must be zero */ }; -/* Flag macros */ +/* global_lock flags */ -#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ +#define ACPI_GLOCK_PENDING (1) /* 00: Pending global lock ownership */ +#define ACPI_GLOCK_OWNED (1<<1) /* 01: Global lock is owned */ -/* Global lock flags */ +/* Flags */ -#define ACPI_GLOCK_PENDING 0x01 /* 00: Pending global lock ownership */ -#define ACPI_GLOCK_OWNED 0x02 /* 01: Global lock is owned */ +#define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ +#define ACPI_FACS_64BIT_WAKE (1<<1) /* 01: 64-bit wake vector supported (ACPI 4.0) */ + +/* ospm_flags */ + +#define ACPI_FACS_64BIT_ENVIRONMENT (1) /* 00: 64-bit wake environment is required (ACPI 4.0) */ /******************************************************************************* * diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 59ade0752473..ec36693f868c 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -1011,7 +1011,7 @@ struct acpi_madt_interrupt_source { #define ACPI_MADT_CPEI_OVERRIDE (1) -/* 9: Processor Local X2_APIC (07/2008) */ +/* 9: Processor Local X2APIC (ACPI 4.0) */ struct acpi_madt_local_x2apic { struct acpi_subtable_header header; @@ -1021,7 +1021,7 @@ struct acpi_madt_local_x2apic { u32 uid; /* ACPI processor UID */ }; -/* 10: Local X2APIC NMI (07/2008) */ +/* 10: Local X2APIC NMI (ACPI 4.0) */ struct acpi_madt_local_x2apic_nmi { struct acpi_subtable_header header; @@ -1211,7 +1211,7 @@ struct acpi_srat_mem_affinity { #define ACPI_SRAT_MEM_HOT_PLUGGABLE (1<<1) /* 01: Memory region is hot pluggable */ #define ACPI_SRAT_MEM_NON_VOLATILE (1<<2) /* 02: Memory region is non-volatile */ -/* 2: Processor Local X2_APIC Affinity (07/2008) */ +/* 2: Processor Local X2_APIC Affinity (ACPI 4.0) */ struct acpi_srat_x2apic_cpu_affinity { struct acpi_subtable_header header; @@ -1219,6 +1219,8 @@ struct acpi_srat_x2apic_cpu_affinity { u32 proximity_domain; u32 apic_id; u32 flags; + u32 clock_domain; + u32 reserved2; }; /* Flags for struct acpi_srat_cpu_affinity and struct acpi_srat_x2apic_cpu_affinity */ From 3ce804ed83827a7fd27190836f9421b29ac64512 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 25 Jun 2009 10:31:32 -0700 Subject: [PATCH 14/34] ACPICA: Update version to 20090625 Update version number. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 04904c7f1aa1..063e577e791e 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090521 +#define ACPI_CA_VERSION 0x20090625 #include "actypes.h" #include "actbl.h" From b2deadd53c3630786e73746fb0ad8450f4e015bf Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Jul 2009 10:56:43 +0800 Subject: [PATCH 15/34] ACPICA: Move predefined repair code to new file, no functional change New file is nsrepair.c. This is in preparation for additional errror correcting code. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/Makefile | 2 +- drivers/acpi/acpica/acnamesp.h | 17 ++++ drivers/acpi/acpica/nspredef.c | 120 +------------------------- drivers/acpi/acpica/nsrepair.c | 151 +++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+), 119 deletions(-) create mode 100644 drivers/acpi/acpica/nsrepair.c diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index 0e7d56185f6d..e7973bc16846 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile @@ -28,7 +28,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o acpi-y += nsaccess.o nsload.o nssearch.o nsxfeval.o \ nsalloc.o nseval.o nsnames.o nsutils.o nsxfname.o \ nsdump.o nsinit.o nsobject.o nswalk.o nsxfobj.o \ - nsparse.o nspredef.o + nsparse.o nspredef.o nsrepair.o acpi-$(ACPI_FUTURE_USAGE) += nsdumpdv.o diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index a78e02f62d5e..908cfdd3b895 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -73,6 +73,14 @@ #define ACPI_NS_WALK_UNLOCK 0x01 #define ACPI_NS_WALK_TEMP_NODES 0x02 +/* Object is not a package element */ + +#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX + +/* Always emit warning message, not dependent on node flags */ + +#define ACPI_WARN_ALWAYS 0 + /* * nsinit - Namespace initialization */ @@ -261,6 +269,15 @@ acpi_status acpi_ns_get_attached_data(struct acpi_namespace_node *node, acpi_object_handler handler, void **data); +/* + * nsrepair - return object repair for predefined methods/objects + */ +acpi_status +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr); + /* * nssearch - Namespace searching and entry */ diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 1dc1a4737aa9..e3f08dcb5275 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -91,12 +91,6 @@ static acpi_status acpi_ns_check_reference(struct acpi_predefined_data *data, union acpi_operand_object *return_object); -static acpi_status -acpi_ns_repair_object(struct acpi_predefined_data *data, - u32 expected_btypes, - u32 package_index, - union acpi_operand_object **return_object_ptr); - static void acpi_ns_get_expected_types(char *buffer, u32 expected_btypes); /* @@ -111,14 +105,6 @@ static const char *acpi_rtype_names[] = { "/Reference", }; -/* Object is not a package element */ - -#define ACPI_NOT_PACKAGE_ELEMENT ACPI_UINT32_MAX - -/* Always emit warning message, not dependent on node flags */ - -#define ACPI_WARN_ALWAYS 0 - /******************************************************************************* * * FUNCTION: acpi_ns_check_predefined_names @@ -580,8 +566,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data, case ACPI_PTYPE2_COUNT: /* - * These types all return a single package that consists of a variable - * number of sub-packages + * These types all return a single package that consists of a + * variable number of sub-packages. */ for (i = 0; i < count; i++) { sub_package = *elements; @@ -977,108 +963,6 @@ acpi_ns_check_reference(struct acpi_predefined_data *data, return (AE_AML_OPERAND_TYPE); } -/******************************************************************************* - * - * FUNCTION: acpi_ns_repair_object - * - * PARAMETERS: Data - Pointer to validation data structure - * expected_btypes - Object types expected - * package_index - Index of object within parent package (if - * applicable - ACPI_NOT_PACKAGE_ELEMENT - * otherwise) - * return_object_ptr - Pointer to the object returned from the - * evaluation of a method or object - * - * RETURN: Status. AE_OK if repair was successful. - * - * DESCRIPTION: Attempt to repair/convert a return object of a type that was - * not expected. - * - ******************************************************************************/ - -static acpi_status -acpi_ns_repair_object(struct acpi_predefined_data *data, - u32 expected_btypes, - u32 package_index, - union acpi_operand_object **return_object_ptr) -{ - union acpi_operand_object *return_object = *return_object_ptr; - union acpi_operand_object *new_object; - acpi_size length; - - switch (return_object->common.type) { - case ACPI_TYPE_BUFFER: - - /* Does the method/object legally return a string? */ - - if (!(expected_btypes & ACPI_RTYPE_STRING)) { - return (AE_AML_OPERAND_TYPE); - } - - /* - * Have a Buffer, expected a String, convert. Use a to_string - * conversion, no transform performed on the buffer data. The best - * example of this is the _BIF method, where the string data from - * the battery is often (incorrectly) returned as buffer object(s). - */ - length = 0; - while ((length < return_object->buffer.length) && - (return_object->buffer.pointer[length])) { - length++; - } - - /* Allocate a new string object */ - - new_object = acpi_ut_create_string_object(length); - if (!new_object) { - return (AE_NO_MEMORY); - } - - /* - * Copy the raw buffer data with no transform. String is already NULL - * terminated at Length+1. - */ - ACPI_MEMCPY(new_object->string.pointer, - return_object->buffer.pointer, length); - - /* - * If the original object is a package element, we need to: - * 1. Set the reference count of the new object to match the - * reference count of the old object. - * 2. Decrement the reference count of the original object. - */ - if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { - new_object->common.reference_count = - return_object->common.reference_count; - - if (return_object->common.reference_count > 1) { - return_object->common.reference_count--; - } - - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, - data->node_flags, - "Converted Buffer to expected String at index %u", - package_index)); - } else { - ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, - data->node_flags, - "Converted Buffer to expected String")); - } - - /* Delete old object, install the new return object */ - - acpi_ut_remove_reference(return_object); - *return_object_ptr = new_object; - data->flags |= ACPI_OBJECT_REPAIRED; - return (AE_OK); - - default: - break; - } - - return (AE_AML_OPERAND_TYPE); -} - /******************************************************************************* * * FUNCTION: acpi_ns_get_expected_types diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c new file mode 100644 index 000000000000..b64751eacc53 --- /dev/null +++ b/drivers/acpi/acpica/nsrepair.c @@ -0,0 +1,151 @@ +/****************************************************************************** + * + * Module Name: nsrepair - Repair for objects returned by predefined methods + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2009, Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include "accommon.h" +#include "acnamesp.h" +#include "acpredef.h" + +#define _COMPONENT ACPI_NAMESPACE +ACPI_MODULE_NAME("nsrepair") + +/******************************************************************************* + * + * FUNCTION: acpi_ns_repair_object + * + * PARAMETERS: Data - Pointer to validation data structure + * expected_btypes - Object types expected + * package_index - Index of object within parent package (if + * applicable - ACPI_NOT_PACKAGE_ELEMENT + * otherwise) + * return_object_ptr - Pointer to the object returned from the + * evaluation of a method or object + * + * RETURN: Status. AE_OK if repair was successful. + * + * DESCRIPTION: Attempt to repair/convert a return object of a type that was + * not expected. + * + ******************************************************************************/ +acpi_status +acpi_ns_repair_object(struct acpi_predefined_data *data, + u32 expected_btypes, + u32 package_index, + union acpi_operand_object **return_object_ptr) +{ + union acpi_operand_object *return_object = *return_object_ptr; + union acpi_operand_object *new_object; + acpi_size length; + + switch (return_object->common.type) { + case ACPI_TYPE_BUFFER: + + /* Does the method/object legally return a string? */ + + if (!(expected_btypes & ACPI_RTYPE_STRING)) { + return (AE_AML_OPERAND_TYPE); + } + + /* + * Have a Buffer, expected a String, convert. Use a to_string + * conversion, no transform performed on the buffer data. The best + * example of this is the _BIF method, where the string data from + * the battery is often (incorrectly) returned as buffer object(s). + */ + length = 0; + while ((length < return_object->buffer.length) && + (return_object->buffer.pointer[length])) { + length++; + } + + /* Allocate a new string object */ + + new_object = acpi_ut_create_string_object(length); + if (!new_object) { + return (AE_NO_MEMORY); + } + + /* + * Copy the raw buffer data with no transform. String is already NULL + * terminated at Length+1. + */ + ACPI_MEMCPY(new_object->string.pointer, + return_object->buffer.pointer, length); + + /* + * If the original object is a package element, we need to: + * 1. Set the reference count of the new object to match the + * reference count of the old object. + * 2. Decrement the reference count of the original object. + */ + if (package_index != ACPI_NOT_PACKAGE_ELEMENT) { + new_object->common.reference_count = + return_object->common.reference_count; + + if (return_object->common.reference_count > 1) { + return_object->common.reference_count--; + } + + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String at index %u", + package_index)); + } else { + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, + data->node_flags, + "Converted Buffer to expected String")); + } + + /* Delete old object, install the new return object */ + + acpi_ut_remove_reference(return_object); + *return_object_ptr = new_object; + data->flags |= ACPI_OBJECT_REPAIRED; + return (AE_OK); + + default: + break; + } + + return (AE_AML_OPERAND_TYPE); +} From e5f69d6ef7a6b0dbad8d4c00d83009960be02155 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Jul 2009 11:03:09 +0800 Subject: [PATCH 16/34] ACPICA: Add repair for predefined methods that return nested packages Fixes a problem where a predefined method is defined to return a variable-length Package of sub-packages. If the length is one, the BIOS code occasionally creates a simple single package with no sub-packages. This code attempts to fix the problem by wrapping a new package object around the existing package. ACPICA BZ 790. http://acpica.org/bugzilla/show_bug.cgi?id=790 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acnamesp.h | 4 +++ drivers/acpi/acpica/nspredef.c | 30 ++++++++++++++++++-- drivers/acpi/acpica/nsrepair.c | 52 ++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index 908cfdd3b895..f75a7a01b875 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -278,6 +278,10 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, u32 package_index, union acpi_operand_object **return_object_ptr); +acpi_status +acpi_ns_repair_package_list(struct acpi_predefined_data *data, + union acpi_operand_object **obj_desc_ptr); + /* * nssearch - Namespace searching and entry */ diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index e3f08dcb5275..0091504df074 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -566,9 +566,35 @@ acpi_ns_check_package(struct acpi_predefined_data *data, case ACPI_PTYPE2_COUNT: /* - * These types all return a single package that consists of a - * variable number of sub-packages. + * These types all return a single Package that consists of a + * variable number of sub-Packages. + * + * First, ensure that the first element is a sub-Package. If not, + * the BIOS may have incorrectly returned the object as a single + * package instead of a Package of Packages (a common error if + * there is only one entry). We may be able to repair this by + * wrapping the returned Package with a new outer Package. */ + if ((*elements)->common.type != ACPI_TYPE_PACKAGE) { + + /* Create the new outer package and populate it */ + + status = + acpi_ns_repair_package_list(data, + return_object_ptr); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Update locals to point to the new package (of 1 element) */ + + return_object = *return_object_ptr; + elements = return_object->package.elements; + count = 1; + } + + /* Validate each sub-Package in the parent Package */ + for (i = 0; i < count; i++) { sub_package = *elements; sub_elements = sub_package->package.elements; diff --git a/drivers/acpi/acpica/nsrepair.c b/drivers/acpi/acpica/nsrepair.c index b64751eacc53..db2b2a99c3a8 100644 --- a/drivers/acpi/acpica/nsrepair.c +++ b/drivers/acpi/acpica/nsrepair.c @@ -149,3 +149,55 @@ acpi_ns_repair_object(struct acpi_predefined_data *data, return (AE_AML_OPERAND_TYPE); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_repair_package_list + * + * PARAMETERS: Data - Pointer to validation data structure + * obj_desc_ptr - Pointer to the object to repair. The new + * package object is returned here, + * overwriting the old object. + * + * RETURN: Status, new object in *obj_desc_ptr + * + * DESCRIPTION: Repair a common problem with objects that are defined to return + * a variable-length Package of Packages. If the variable-length + * is one, some BIOS code mistakenly simply declares a single + * Package instead of a Package with one sub-Package. This + * function attempts to repair this error by wrapping a Package + * object around the original Package, creating the correct + * Package with one sub-Package. + * + * Names that can be repaired in this manner include: + * _ALR, _CSD, _HPX, _MLS, _PRT, _PSS, _TRT, TSS + * + ******************************************************************************/ + +acpi_status +acpi_ns_repair_package_list(struct acpi_predefined_data *data, + union acpi_operand_object **obj_desc_ptr) +{ + union acpi_operand_object *pkg_obj_desc; + + /* + * Create the new outer package and populate it. The new package will + * have a single element, the lone subpackage. + */ + pkg_obj_desc = acpi_ut_create_package_object(1); + if (!pkg_obj_desc) { + return (AE_NO_MEMORY); + } + + pkg_obj_desc->package.elements[0] = *obj_desc_ptr; + + /* Return the new object in the object pointer */ + + *obj_desc_ptr = pkg_obj_desc; + data->flags |= ACPI_OBJECT_REPAIRED; + + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Incorrectly formed Package, attempting repair")); + + return (AE_OK); +} From 53e9387bdd8bfef6cffff2d2eb6bd28eca812682 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Jul 2009 11:22:11 +0800 Subject: [PATCH 17/34] ACPICA: ACPI 4.0 : Add new return package type, restructure module. Added one new package type, a package that contains a revision number and a variable number of sub-packages. Restructured the module to put the sub-package list traversal in a separate function. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acpredef.h | 5 +- drivers/acpi/acpica/nspredef.c | 374 +++++++++++++++++++-------------- 2 files changed, 220 insertions(+), 159 deletions(-) diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 63f656ae3604..144b1f41663f 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -91,6 +91,8 @@ * ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length * (Used for _HPX) * + * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length + * *****************************************************************************/ enum acpi_return_package_types { @@ -101,7 +103,8 @@ enum acpi_return_package_types { ACPI_PTYPE2_COUNT = 5, ACPI_PTYPE2_PKG_COUNT = 6, ACPI_PTYPE2_FIXED = 7, - ACPI_PTYPE2_MIN = 8 + ACPI_PTYPE2_MIN = 8, + ACPI_PTYPE2_REV_FIXED = 9 }; /* diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 0091504df074..0b2cdb37a678 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -75,6 +75,11 @@ static acpi_status acpi_ns_check_package(struct acpi_predefined_data *data, union acpi_operand_object **return_object_ptr); +static acpi_status +acpi_ns_check_package_list(struct acpi_predefined_data *data, + const union acpi_predefined_info *package, + union acpi_operand_object **elements, u32 count); + static acpi_status acpi_ns_check_package_elements(struct acpi_predefined_data *data, union acpi_operand_object **elements, @@ -393,14 +398,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data, { union acpi_operand_object *return_object = *return_object_ptr; const union acpi_predefined_info *package; - union acpi_operand_object *sub_package; union acpi_operand_object **elements; - union acpi_operand_object **sub_elements; - acpi_status status; + acpi_status status = AE_OK; u32 expected_count; u32 count; u32 i; - u32 j; ACPI_FUNCTION_NAME(ns_check_package); @@ -465,9 +467,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data, object_type2, package->ret_info. count2, 0); - if (ACPI_FAILURE(status)) { - return (status); - } break; case ACPI_PTYPE1_VAR: @@ -534,6 +533,25 @@ acpi_ns_check_package(struct acpi_predefined_data *data, } break; + case ACPI_PTYPE2_REV_FIXED: + + /* First element is the (Integer) revision */ + + status = acpi_ns_check_object_type(data, elements, + ACPI_RTYPE_INTEGER, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + + elements++; + count--; + + /* Examine the sub-packages */ + + status = + acpi_ns_check_package_list(data, package, elements, count); + break; + case ACPI_PTYPE2_PKG_COUNT: /* First element is the (Integer) count of sub-packages to follow */ @@ -556,9 +574,11 @@ acpi_ns_check_package(struct acpi_predefined_data *data, count = expected_count; elements++; - /* Now we can walk the sub-packages */ + /* Examine the sub-packages */ - /*lint -fallthrough */ + status = + acpi_ns_check_package_list(data, package, elements, count); + break; case ACPI_PTYPE2: case ACPI_PTYPE2_FIXED: @@ -593,153 +613,10 @@ acpi_ns_check_package(struct acpi_predefined_data *data, count = 1; } - /* Validate each sub-Package in the parent Package */ + /* Examine the sub-packages */ - for (i = 0; i < count; i++) { - sub_package = *elements; - sub_elements = sub_package->package.elements; - - /* Each sub-object must be of type Package */ - - status = acpi_ns_check_object_type(data, &sub_package, - ACPI_RTYPE_PACKAGE, - i); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Examine the different types of sub-packages */ - - switch (package->ret_info.type) { - case ACPI_PTYPE2: - case ACPI_PTYPE2_PKG_COUNT: - - /* Each subpackage has a fixed number of elements */ - - expected_count = - package->ret_info.count1 + - package->ret_info.count2; - if (sub_package->package.count != - expected_count) { - count = sub_package->package.count; - goto package_too_small; - } - - status = - acpi_ns_check_package_elements(data, - sub_elements, - package-> - ret_info. - object_type1, - package-> - ret_info. - count1, - package-> - ret_info. - object_type2, - package-> - ret_info. - count2, 0); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_PTYPE2_FIXED: - - /* Each sub-package has a fixed length */ - - expected_count = package->ret_info2.count; - if (sub_package->package.count < expected_count) { - count = sub_package->package.count; - goto package_too_small; - } - - /* Check the type of each sub-package element */ - - for (j = 0; j < expected_count; j++) { - status = - acpi_ns_check_object_type(data, - &sub_elements[j], - package->ret_info2.object_type[j], j); - if (ACPI_FAILURE(status)) { - return (status); - } - } - break; - - case ACPI_PTYPE2_MIN: - - /* Each sub-package has a variable but minimum length */ - - expected_count = package->ret_info.count1; - if (sub_package->package.count < expected_count) { - count = sub_package->package.count; - goto package_too_small; - } - - /* Check the type of each sub-package element */ - - status = - acpi_ns_check_package_elements(data, - sub_elements, - package-> - ret_info. - object_type1, - sub_package-> - package. - count, 0, 0, - 0); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - case ACPI_PTYPE2_COUNT: - - /* First element is the (Integer) count of elements to follow */ - - status = - acpi_ns_check_object_type(data, - sub_elements, - ACPI_RTYPE_INTEGER, - 0); - if (ACPI_FAILURE(status)) { - return (status); - } - - /* Make sure package is large enough for the Count */ - - expected_count = - (u32) (*sub_elements)->integer.value; - if (sub_package->package.count < expected_count) { - count = sub_package->package.count; - goto package_too_small; - } - - /* Check the type of each sub-package element */ - - status = - acpi_ns_check_package_elements(data, - (sub_elements - + 1), - package-> - ret_info. - object_type1, - (expected_count - - 1), 0, 0, - 1); - if (ACPI_FAILURE(status)) { - return (status); - } - break; - - default: - break; - } - - elements++; - } + status = + acpi_ns_check_package_list(data, package, elements, count); break; default: @@ -753,19 +630,200 @@ acpi_ns_check_package(struct acpi_predefined_data *data, return (AE_AML_INTERNAL); } - return (AE_OK); + return (status); - package_too_small: +package_too_small: /* Error exit for the case with an incorrect package count */ ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, - "Return Package is too small - found %u, expected %u", + "Return Package is too small - found %u elements, expected %u", count, expected_count)); return (AE_AML_OPERAND_VALUE); } +/******************************************************************************* + * + * FUNCTION: acpi_ns_check_package_list + * + * PARAMETERS: Data - Pointer to validation data structure + * Package - Pointer to package-specific info for method + * Elements - Element list of parent package. All elements + * of this list should be of type Package. + * Count - Count of subpackages + * + * RETURN: Status + * + * DESCRIPTION: Examine a list of subpackages + * + ******************************************************************************/ + +static acpi_status +acpi_ns_check_package_list(struct acpi_predefined_data *data, + const union acpi_predefined_info *package, + union acpi_operand_object **elements, u32 count) +{ + union acpi_operand_object *sub_package; + union acpi_operand_object **sub_elements; + acpi_status status; + u32 expected_count; + u32 i; + u32 j; + + /* Validate each sub-Package in the parent Package */ + + for (i = 0; i < count; i++) { + sub_package = *elements; + sub_elements = sub_package->package.elements; + + /* Each sub-object must be of type Package */ + + status = acpi_ns_check_object_type(data, &sub_package, + ACPI_RTYPE_PACKAGE, i); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* Examine the different types of expected sub-packages */ + + switch (package->ret_info.type) { + case ACPI_PTYPE2: + case ACPI_PTYPE2_PKG_COUNT: + case ACPI_PTYPE2_REV_FIXED: + + /* Each subpackage has a fixed number of elements */ + + expected_count = + package->ret_info.count1 + package->ret_info.count2; + if (sub_package->package.count < expected_count) { + goto package_too_small; + } + + status = + acpi_ns_check_package_elements(data, sub_elements, + package->ret_info. + object_type1, + package->ret_info. + count1, + package->ret_info. + object_type2, + package->ret_info. + count2, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_PTYPE2_FIXED: + + /* Each sub-package has a fixed length */ + + expected_count = package->ret_info2.count; + if (sub_package->package.count < expected_count) { + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + for (j = 0; j < expected_count; j++) { + status = + acpi_ns_check_object_type(data, + &sub_elements[j], + package-> + ret_info2. + object_type[j], + j); + if (ACPI_FAILURE(status)) { + return (status); + } + } + break; + + case ACPI_PTYPE2_MIN: + + /* Each sub-package has a variable but minimum length */ + + expected_count = package->ret_info.count1; + if (sub_package->package.count < expected_count) { + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + status = + acpi_ns_check_package_elements(data, sub_elements, + package->ret_info. + object_type1, + sub_package->package. + count, 0, 0, 0); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + case ACPI_PTYPE2_COUNT: + + /* + * First element is the (Integer) count of elements, including + * the count field. + */ + status = acpi_ns_check_object_type(data, sub_elements, + ACPI_RTYPE_INTEGER, + 0); + if (ACPI_FAILURE(status)) { + return (status); + } + + /* + * Make sure package is large enough for the Count and is + * is as large as the minimum size + */ + expected_count = (u32)(*sub_elements)->integer.value; + if (sub_package->package.count < expected_count) { + goto package_too_small; + } + if (sub_package->package.count < + package->ret_info.count1) { + expected_count = package->ret_info.count1; + goto package_too_small; + } + + /* Check the type of each sub-package element */ + + status = + acpi_ns_check_package_elements(data, + (sub_elements + 1), + package->ret_info. + object_type1, + (expected_count - 1), + 0, 0, 1); + if (ACPI_FAILURE(status)) { + return (status); + } + break; + + default: /* Should not get here, type was validated by caller */ + + return (AE_AML_INTERNAL); + } + + elements++; + } + + return (AE_OK); + +package_too_small: + + /* The sub-package count was smaller than required */ + + ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags, + "Return Sub-Package[%u] is too small - found %u elements, expected %u", + i, sub_package->package.count, expected_count)); + + return (AE_AML_OPERAND_VALUE); +} + /******************************************************************************* * * FUNCTION: acpi_ns_check_package_elements From 2f977b36e5f175e5126f280e7a94f0c53d1b1a16 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Jul 2009 11:25:16 +0800 Subject: [PATCH 18/34] ACPICA: Fix fault if acpi_terminate is called twice Fixes a problem with the mechanism that prevents problems if the acpi_terminate interface is inadvertently called more than once before the ACPICA code is re-initialized. ACPICA BZ 795. http://acpica.org/bugzilla/show_bug.cgi?id=795 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/utinit.c | 22 ++++------------------ drivers/acpi/acpica/utxface.c | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/acpi/acpica/utinit.c b/drivers/acpi/acpica/utinit.c index a54ca84eb362..9d0919ebf7b0 100644 --- a/drivers/acpi/acpica/utinit.c +++ b/drivers/acpi/acpica/utinit.c @@ -99,33 +99,19 @@ static void acpi_ut_terminate(void) * * FUNCTION: acpi_ut_subsystem_shutdown * - * PARAMETERS: none + * PARAMETERS: None * - * RETURN: none + * RETURN: None * - * DESCRIPTION: Shutdown the various subsystems. Don't delete the mutex - * objects here -- because the AML debugger may be still running. + * DESCRIPTION: Shutdown the various components. Do not delete the mutex + * objects here, because the AML debugger may be still running. * ******************************************************************************/ void acpi_ut_subsystem_shutdown(void) { - ACPI_FUNCTION_TRACE(ut_subsystem_shutdown); - /* Just exit if subsystem is already shutdown */ - - if (acpi_gbl_shutdown) { - ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); - return_VOID; - } - - /* Subsystem appears active, go ahead and shut it down */ - - acpi_gbl_shutdown = TRUE; - acpi_gbl_startup_flags = 0; - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); - #ifndef ACPI_ASL_COMPILER /* Close the acpi_event Handling */ diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 078a22728c6b..483edbb3f441 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -318,7 +318,7 @@ ACPI_EXPORT_SYMBOL(acpi_initialize_objects) * * RETURN: Status * - * DESCRIPTION: Shutdown the ACPI subsystem. Release all resources. + * DESCRIPTION: Shutdown the ACPICA subsystem and release all resources. * ******************************************************************************/ acpi_status acpi_terminate(void) @@ -327,6 +327,19 @@ acpi_status acpi_terminate(void) ACPI_FUNCTION_TRACE(acpi_terminate); + /* Just exit if subsystem is already shutdown */ + + if (acpi_gbl_shutdown) { + ACPI_ERROR((AE_INFO, "ACPI Subsystem is already terminated")); + return_ACPI_STATUS(AE_OK); + } + + /* Subsystem appears active, go ahead and shut it down */ + + acpi_gbl_shutdown = TRUE; + acpi_gbl_startup_flags = 0; + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Shutting down ACPI Subsystem\n")); + /* Terminate the AML Debugger if present */ ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = TRUE); @@ -353,6 +366,7 @@ acpi_status acpi_terminate(void) } ACPI_EXPORT_SYMBOL(acpi_terminate) + #ifndef ACPI_ASL_COMPILER #ifdef ACPI_FUTURE_USAGE /******************************************************************************* From b24aad44438d5bc21cbbfb94a99d9bf710d8295b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 24 Jul 2009 13:30:17 +0800 Subject: [PATCH 19/34] ACPICA: Split large ACPI table header Split out the non-acpi-defined ACPI tables into the existing (but empty) actbl2.h file. Preparation for new ACPI 4.0 tables. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actbl.h | 35 ++- include/acpi/actbl1.h | 553 +-------------------------------------- include/acpi/actbl2.h | 585 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 611 insertions(+), 562 deletions(-) create mode 100644 include/acpi/actbl2.h diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 0649a5670026..55fcfc6725b2 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -44,6 +44,19 @@ #ifndef __ACTBL_H__ #define __ACTBL_H__ +/******************************************************************************* + * + * Fundamental ACPI tables + * + * This file contains definitions for the ACPI tables that are directly consumed + * by ACPICA. All other tables are consumed by the OS-dependent ACPI-related + * device drivers and other OS support code. + * + * The RSDP and FACS do not use the common ACPI table header. All other ACPI + * tables use the header. + * + ******************************************************************************/ + /* * Values for description table header signatures. Useful because they make * it more difficult to inadvertently type in the wrong signature. @@ -65,11 +78,6 @@ #pragma pack(1) /* - * These are the ACPI tables that are directly consumed by the subsystem. - * - * The RSDP and FACS do not use the common ACPI table header. All other ACPI - * tables use the header. - * * Note about bitfields: The u8 type is used for bitfields in ACPI tables. * This is the only type that is even remotely portable. Anything else is not * portable, so do not use any other bitfield types. @@ -77,9 +85,8 @@ /******************************************************************************* * - * ACPI Table Header. This common header is used by all tables except the - * RSDP and FACS. The define is used for direct inclusion of header into - * other ACPI tables + * Master ACPI Table Header. This common header is used by all ACPI tables + * except the RSDP and FACS. * ******************************************************************************/ @@ -95,13 +102,16 @@ struct acpi_table_header { u32 asl_compiler_revision; /* ASL compiler version */ }; -/* +/******************************************************************************* + * * GAS - Generic Address Structure (ACPI 2.0+) * * Note: Since this structure is used in the ACPI tables, it is byte aligned. - * If misalignment is not supported, access to the Address field must be - * performed with care. - */ + * If misaliged access is not supported by the hardware, accesses to the + * 64-bit Address field must be performed with care. + * + ******************************************************************************/ + struct acpi_generic_address { u8 space_id; /* Address space where struct or register exists */ u8 bit_width; /* Size in bits of given register */ @@ -325,5 +335,6 @@ struct acpi_table_desc { */ #include +#include #endif /* __ACTBL_H__ */ diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index ec36693f868c..582af1fcb8f5 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -46,41 +46,29 @@ /******************************************************************************* * - * Additional ACPI Tables + * Additional ACPI Tables (1) * * These tables are not consumed directly by the ACPICA subsystem, but are * included here to support device drivers and the AML disassembler. * + * The tables in this file are fully defined within the ACPI specification. + * ******************************************************************************/ /* * Values for description table header signatures. Useful because they make * it more difficult to inadvertently type in the wrong signature. */ -#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ -#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ -#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ -#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ #define ACPI_SIG_ECDT "ECDT" /* Embedded Controller Boot Resources Table */ #define ACPI_SIG_EINJ "EINJ" /* Error Injection table */ #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ -#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ -#define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ -#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ -#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ -#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ -#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ -#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ -#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ -#define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ -#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ /* * All tables must be byte-packed to match the ACPI specification, since @@ -113,115 +101,6 @@ struct acpi_whea_header { u64 mask; /* Bitmask required for this register instruction */ }; -/******************************************************************************* - * - * ASF - Alert Standard Format table (Signature "ASF!") - * - * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 - * - ******************************************************************************/ - -struct acpi_table_asf { - struct acpi_table_header header; /* Common ACPI table header */ -}; - -/* ASF subtable header */ - -struct acpi_asf_header { - u8 type; - u8 reserved; - u16 length; -}; - -/* Values for Type field above */ - -enum acpi_asf_type { - ACPI_ASF_TYPE_INFO = 0, - ACPI_ASF_TYPE_ALERT = 1, - ACPI_ASF_TYPE_CONTROL = 2, - ACPI_ASF_TYPE_BOOT = 3, - ACPI_ASF_TYPE_ADDRESS = 4, - ACPI_ASF_TYPE_RESERVED = 5 -}; - -/* - * ASF subtables - */ - -/* 0: ASF Information */ - -struct acpi_asf_info { - struct acpi_asf_header header; - u8 min_reset_value; - u8 min_poll_interval; - u16 system_id; - u32 mfg_id; - u8 flags; - u8 reserved2[3]; -}; - -/* 1: ASF Alerts */ - -struct acpi_asf_alert { - struct acpi_asf_header header; - u8 assert_mask; - u8 deassert_mask; - u8 alerts; - u8 data_length; -}; - -struct acpi_asf_alert_data { - u8 address; - u8 command; - u8 mask; - u8 value; - u8 sensor_type; - u8 type; - u8 offset; - u8 source_type; - u8 severity; - u8 sensor_number; - u8 entity; - u8 instance; -}; - -/* 2: ASF Remote Control */ - -struct acpi_asf_remote { - struct acpi_asf_header header; - u8 controls; - u8 data_length; - u16 reserved2; -}; - -struct acpi_asf_control_data { - u8 function; - u8 address; - u8 command; - u8 value; -}; - -/* 3: ASF RMCP Boot Options */ - -struct acpi_asf_rmcp { - struct acpi_asf_header header; - u8 capabilities[7]; - u8 completion_code; - u32 enterprise_id; - u8 command; - u16 parameter; - u16 boot_options; - u16 oem_parameters; -}; - -/* 4: ASF Address */ - -struct acpi_asf_address { - struct acpi_asf_header header; - u8 eprom_address; - u8 devices; -}; - /******************************************************************************* * * BERT - Boot Error Record Table @@ -251,18 +130,6 @@ struct acpi_bert_region { #define ACPI_BERT_MULTIPLE_UNCORRECTABLE (4) #define ACPI_BERT_MULTIPLE_CORRECTABLE (8) -/******************************************************************************* - * - * BOOT - Simple Boot Flag Table - * - ******************************************************************************/ - -struct acpi_table_boot { - struct acpi_table_header header; /* Common ACPI table header */ - u8 cmos_index; /* Index in CMOS RAM for the boot register */ - u8 reserved[3]; -}; - /******************************************************************************* * * CPEP - Corrected Platform Error Polling table @@ -284,123 +151,6 @@ struct acpi_cpep_polling { u32 interval; /* Polling interval (msec) */ }; -/******************************************************************************* - * - * DBGP - Debug Port table - * - ******************************************************************************/ - -struct acpi_table_dbgp { - struct acpi_table_header header; /* Common ACPI table header */ - u8 type; /* 0=full 16550, 1=subset of 16550 */ - u8 reserved[3]; - struct acpi_generic_address debug_port; -}; - -/******************************************************************************* - * - * DMAR - DMA Remapping table - * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 - * - ******************************************************************************/ - -struct acpi_table_dmar { - struct acpi_table_header header; /* Common ACPI table header */ - u8 width; /* Host Address Width */ - u8 flags; - u8 reserved[10]; -}; - -/* Flags */ - -#define ACPI_DMAR_INTR_REMAP (1) - -/* DMAR subtable header */ - -struct acpi_dmar_header { - u16 type; - u16 length; -}; - -/* Values for subtable type in struct acpi_dmar_header */ - -enum acpi_dmar_type { - ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, - ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, - ACPI_DMAR_TYPE_ATSR = 2, - ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */ -}; - -struct acpi_dmar_device_scope { - u8 entry_type; - u8 length; - u16 reserved; - u8 enumeration_id; - u8 bus; -}; - -/* Values for entry_type in struct acpi_dmar_device_scope */ - -enum acpi_dmar_scope_type { - ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, - ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, - ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, - ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, - ACPI_DMAR_SCOPE_TYPE_HPET = 4, - ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ -}; - -struct acpi_dmar_pci_path { - u8 dev; - u8 fn; -}; - -/* - * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header - */ - -/* 0: Hardware Unit Definition */ - -struct acpi_dmar_hardware_unit { - struct acpi_dmar_header header; - u8 flags; - u8 reserved; - u16 segment; - u64 address; /* Register Base Address */ -}; - -/* Flags */ - -#define ACPI_DMAR_INCLUDE_ALL (1) - -/* 1: Reserved Memory Defininition */ - -struct acpi_dmar_reserved_memory { - struct acpi_dmar_header header; - u16 reserved; - u16 segment; - u64 base_address; /* 4_k aligned base address */ - u64 end_address; /* 4_k aligned limit address */ -}; - -/* Flags */ - -#define ACPI_DMAR_ALLOW_ALL (1) - - -/* 2: Root Port ATS Capability Reporting Structure */ - -struct acpi_dmar_atsr { - struct acpi_dmar_header header; - u8 flags; - u8 reserved; - u16 segment; -}; - -/* Flags */ - -#define ACPI_DMAR_ALL_PORTS (1) - /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table @@ -762,119 +512,6 @@ struct acpi_hest_generic { u32 error_status_block_length; }; -/******************************************************************************* - * - * HPET - High Precision Event Timer table - * - ******************************************************************************/ - -struct acpi_table_hpet { - struct acpi_table_header header; /* Common ACPI table header */ - u32 id; /* Hardware ID of event timer block */ - struct acpi_generic_address address; /* Address of event timer block */ - u8 sequence; /* HPET sequence number */ - u16 minimum_tick; /* Main counter min tick, periodic mode */ - u8 flags; -}; - -/*! Flags */ - -#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ -#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ -#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ - -/*! [End] no source code translation !*/ - -/******************************************************************************* - * - * IBFT - Boot Firmware Table - * - ******************************************************************************/ - -struct acpi_table_ibft { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved[12]; -}; - -/* IBFT common subtable header */ - -struct acpi_ibft_header { - u8 type; - u8 version; - u16 length; - u8 index; - u8 flags; -}; - -/* Values for Type field above */ - -enum acpi_ibft_type { - ACPI_IBFT_TYPE_NOT_USED = 0, - ACPI_IBFT_TYPE_CONTROL = 1, - ACPI_IBFT_TYPE_INITIATOR = 2, - ACPI_IBFT_TYPE_NIC = 3, - ACPI_IBFT_TYPE_TARGET = 4, - ACPI_IBFT_TYPE_EXTENSIONS = 5, - ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ -}; - -/* IBFT subtables */ - -struct acpi_ibft_control { - struct acpi_ibft_header header; - u16 extensions; - u16 initiator_offset; - u16 nic0_offset; - u16 target0_offset; - u16 nic1_offset; - u16 target1_offset; -}; - -struct acpi_ibft_initiator { - struct acpi_ibft_header header; - u8 sns_server[16]; - u8 slp_server[16]; - u8 primary_server[16]; - u8 secondary_server[16]; - u16 name_length; - u16 name_offset; -}; - -struct acpi_ibft_nic { - struct acpi_ibft_header header; - u8 ip_address[16]; - u8 subnet_mask_prefix; - u8 origin; - u8 gateway[16]; - u8 primary_dns[16]; - u8 secondary_dns[16]; - u8 dhcp[16]; - u16 vlan; - u8 mac_address[6]; - u16 pci_address; - u16 name_length; - u16 name_offset; -}; - -struct acpi_ibft_target { - struct acpi_ibft_header header; - u8 target_ip_address[16]; - u16 target_ip_socket; - u8 target_boot_lun[8]; - u8 chap_type; - u8 nic_association; - u16 target_name_length; - u16 target_name_offset; - u16 chap_name_length; - u16 chap_name_offset; - u16 chap_secret_length; - u16 chap_secret_offset; - u16 reverse_chap_name_length; - u16 reverse_chap_name_offset; - u16 reverse_chap_secret_length; - u16 reverse_chap_secret_offset; -}; - /******************************************************************************* * * MADT - Multiple APIC Description Table @@ -1056,27 +693,6 @@ struct acpi_madt_local_x2apic_nmi { #define ACPI_MADT_TRIGGER_RESERVED (2<<2) #define ACPI_MADT_TRIGGER_LEVEL (3<<2) -/******************************************************************************* - * - * MCFG - PCI Memory Mapped Configuration table and sub-table - * - ******************************************************************************/ - -struct acpi_table_mcfg { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved[8]; -}; - -/* Subtable */ - -struct acpi_mcfg_allocation { - u64 address; /* Base address, processor-relative */ - u16 pci_segment; /* PCI segment group number */ - u8 start_bus_number; /* Starting PCI Bus number */ - u8 end_bus_number; /* Final PCI Bus number */ - u32 reserved; -}; - /******************************************************************************* * * SBST - Smart Battery Specification Table @@ -1102,59 +718,6 @@ struct acpi_table_slit { u8 entry[1]; /* Real size = localities^2 */ }; -/******************************************************************************* - * - * SPCR - Serial Port Console Redirection table - * - ******************************************************************************/ - -struct acpi_table_spcr { - struct acpi_table_header header; /* Common ACPI table header */ - u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ - u8 reserved[3]; - struct acpi_generic_address serial_port; - u8 interrupt_type; - u8 pc_interrupt; - u32 interrupt; - u8 baud_rate; - u8 parity; - u8 stop_bits; - u8 flow_control; - u8 terminal_type; - u8 reserved1; - u16 pci_device_id; - u16 pci_vendor_id; - u8 pci_bus; - u8 pci_device; - u8 pci_function; - u32 pci_flags; - u8 pci_segment; - u32 reserved2; -}; - -/******************************************************************************* - * - * SPMI - Server Platform Management Interface table - * - ******************************************************************************/ - -struct acpi_table_spmi { - struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved; - u8 interface_type; - u16 spec_revision; /* Version of IPMI */ - u8 interrupt_type; - u8 gpe_number; /* GPE assigned */ - u8 reserved1; - u8 pci_device_flag; - u32 interrupt; - struct acpi_generic_address ipmi_register; - u8 pci_segment; - u8 pci_bus; - u8 pci_device; - u8 pci_function; -}; - /******************************************************************************* * * SRAT - System Resource Affinity Table @@ -1227,116 +790,6 @@ struct acpi_srat_x2apic_cpu_affinity { #define ACPI_SRAT_CPU_ENABLED (1) /* 00: Use affinity structure */ -/******************************************************************************* - * - * TCPA - Trusted Computing Platform Alliance table - * - ******************************************************************************/ - -struct acpi_table_tcpa { - struct acpi_table_header header; /* Common ACPI table header */ - u16 reserved; - u32 max_log_length; /* Maximum length for the event log area */ - u64 log_address; /* Address of the event log area */ -}; - -/******************************************************************************* - * - * UEFI - UEFI Boot optimization Table - * - ******************************************************************************/ - -struct acpi_table_uefi { - struct acpi_table_header header; /* Common ACPI table header */ - u8 identifier[16]; /* UUID identifier */ - u16 data_offset; /* Offset of remaining data in table */ - u8 data; -}; - -/******************************************************************************* - * - * WDAT - Watchdog Action Table - * - ******************************************************************************/ - -struct acpi_table_wdat { - struct acpi_table_header header; /* Common ACPI table header */ - u32 header_length; /* Watchdog Header Length */ - u16 pci_segment; /* PCI Segment number */ - u8 pci_bus; /* PCI Bus number */ - u8 pci_device; /* PCI Device number */ - u8 pci_function; /* PCI Function number */ - u8 reserved[3]; - u32 timer_period; /* Period of one timer count (msec) */ - u32 max_count; /* Maximum counter value supported */ - u32 min_count; /* Minimum counter value */ - u8 flags; - u8 reserved2[3]; - u32 entries; /* Number of watchdog entries that follow */ -}; - -/* WDAT Instruction Entries (actions) */ - -struct acpi_wdat_entry { - struct acpi_whea_header whea_header; /* Common header for WHEA tables */ -}; - -/* Values for Action field above */ - -enum acpi_wdat_actions { - ACPI_WDAT_RESET = 1, - ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, - ACPI_WDAT_GET_COUNTDOWN = 5, - ACPI_WDAT_SET_COUNTDOWN = 6, - ACPI_WDAT_GET_RUNNING_STATE = 8, - ACPI_WDAT_SET_RUNNING_STATE = 9, - ACPI_WDAT_GET_STOPPED_STATE = 10, - ACPI_WDAT_SET_STOPPED_STATE = 11, - ACPI_WDAT_GET_REBOOT = 16, - ACPI_WDAT_SET_REBOOT = 17, - ACPI_WDAT_GET_SHUTDOWN = 18, - ACPI_WDAT_SET_SHUTDOWN = 19, - ACPI_WDAT_GET_STATUS = 32, - ACPI_WDAT_SET_STATUS = 33, - ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ -}; - -/* Values for Instruction field above */ - -enum acpi_wdat_instructions { - ACPI_WDAT_READ_VALUE = 0, - ACPI_WDAT_READ_COUNTDOWN = 1, - ACPI_WDAT_WRITE_VALUE = 2, - ACPI_WDAT_WRITE_COUNTDOWN = 3, - ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ - ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ -}; - -/******************************************************************************* - * - * WDRT - Watchdog Resource Table - * - ******************************************************************************/ - -struct acpi_table_wdrt { - struct acpi_table_header header; /* Common ACPI table header */ - u32 header_length; /* Watchdog Header Length */ - u8 pci_segment; /* PCI Segment number */ - u8 pci_bus; /* PCI Bus number */ - u8 pci_device; /* PCI Device number */ - u8 pci_function; /* PCI Function number */ - u32 timer_period; /* Period of one timer count (msec) */ - u32 max_count; /* Maximum counter value supported */ - u32 min_count; /* Minimum counter value */ - u8 flags; - u8 reserved[3]; - u32 entries; /* Number of watchdog entries that follow */ -}; - -/* Flags */ - -#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ - /* Reset to default packing */ #pragma pack() diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h new file mode 100644 index 000000000000..b271aba0e524 --- /dev/null +++ b/include/acpi/actbl2.h @@ -0,0 +1,585 @@ +#ifndef __ACTBL2_H__ +#define __ACTBL2_H__ + +/******************************************************************************* + * + * Additional ACPI Tables (2) + * + * These tables are not consumed directly by the ACPICA subsystem, but are + * included here to support device drivers and the AML disassembler. + * + * The tables in this file are defined by third-party specifications, and are + * not defined directly by the ACPI specification itself. + * + ******************************************************************************/ + +/* + * Values for description table header signatures. Useful because they make + * it more difficult to inadvertently type in the wrong signature. + */ +#define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ +#define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ +#define ACPI_SIG_DBGP "DBGP" /* Debug Port table */ +#define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ +#define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ +#define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ +#define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ +#define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ +#define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ +#define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ +#define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ +#define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ +#define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ +#define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ + +/* + * All tables must be byte-packed to match the ACPI specification, since + * the tables are provided by the system BIOS. + */ +#pragma pack(1) + +/* + * Note about bitfields: The u8 type is used for bitfields in ACPI tables. + * This is the only type that is even remotely portable. Anything else is not + * portable, so do not use any other bitfield types. + */ + +/******************************************************************************* + * + * ASF - Alert Standard Format table (Signature "ASF!") + * + * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 + * + ******************************************************************************/ + +struct acpi_table_asf { + struct acpi_table_header header; /* Common ACPI table header */ +}; + +/* ASF subtable header */ + +struct acpi_asf_header { + u8 type; + u8 reserved; + u16 length; +}; + +/* Values for Type field above */ + +enum acpi_asf_type { + ACPI_ASF_TYPE_INFO = 0, + ACPI_ASF_TYPE_ALERT = 1, + ACPI_ASF_TYPE_CONTROL = 2, + ACPI_ASF_TYPE_BOOT = 3, + ACPI_ASF_TYPE_ADDRESS = 4, + ACPI_ASF_TYPE_RESERVED = 5 +}; + +/* + * ASF subtables + */ + +/* 0: ASF Information */ + +struct acpi_asf_info { + struct acpi_asf_header header; + u8 min_reset_value; + u8 min_poll_interval; + u16 system_id; + u32 mfg_id; + u8 flags; + u8 reserved2[3]; +}; + +/* 1: ASF Alerts */ + +struct acpi_asf_alert { + struct acpi_asf_header header; + u8 assert_mask; + u8 deassert_mask; + u8 alerts; + u8 data_length; +}; + +struct acpi_asf_alert_data { + u8 address; + u8 command; + u8 mask; + u8 value; + u8 sensor_type; + u8 type; + u8 offset; + u8 source_type; + u8 severity; + u8 sensor_number; + u8 entity; + u8 instance; +}; + +/* 2: ASF Remote Control */ + +struct acpi_asf_remote { + struct acpi_asf_header header; + u8 controls; + u8 data_length; + u16 reserved2; +}; + +struct acpi_asf_control_data { + u8 function; + u8 address; + u8 command; + u8 value; +}; + +/* 3: ASF RMCP Boot Options */ + +struct acpi_asf_rmcp { + struct acpi_asf_header header; + u8 capabilities[7]; + u8 completion_code; + u32 enterprise_id; + u8 command; + u16 parameter; + u16 boot_options; + u16 oem_parameters; +}; + +/* 4: ASF Address */ + +struct acpi_asf_address { + struct acpi_asf_header header; + u8 eprom_address; + u8 devices; +}; + +/******************************************************************************* + * + * BOOT - Simple Boot Flag Table + * + ******************************************************************************/ + +struct acpi_table_boot { + struct acpi_table_header header; /* Common ACPI table header */ + u8 cmos_index; /* Index in CMOS RAM for the boot register */ + u8 reserved[3]; +}; + +/******************************************************************************* + * + * DBGP - Debug Port table + * + ******************************************************************************/ + +struct acpi_table_dbgp { + struct acpi_table_header header; /* Common ACPI table header */ + u8 type; /* 0=full 16550, 1=subset of 16550 */ + u8 reserved[3]; + struct acpi_generic_address debug_port; +}; + +/******************************************************************************* + * + * DMAR - DMA Remapping table + * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 + * + ******************************************************************************/ + +struct acpi_table_dmar { + struct acpi_table_header header; /* Common ACPI table header */ + u8 width; /* Host Address Width */ + u8 flags; + u8 reserved[10]; +}; + +/* Flags */ + +#define ACPI_DMAR_INTR_REMAP (1) + +/* DMAR subtable header */ + +struct acpi_dmar_header { + u16 type; + u16 length; +}; + +/* Values for subtable type in struct acpi_dmar_header */ + +enum acpi_dmar_type { + ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, + ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, + ACPI_DMAR_TYPE_ATSR = 2, + ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */ +}; + +struct acpi_dmar_device_scope { + u8 entry_type; + u8 length; + u16 reserved; + u8 enumeration_id; + u8 bus; +}; + +/* Values for entry_type in struct acpi_dmar_device_scope */ + +enum acpi_dmar_scope_type { + ACPI_DMAR_SCOPE_TYPE_NOT_USED = 0, + ACPI_DMAR_SCOPE_TYPE_ENDPOINT = 1, + ACPI_DMAR_SCOPE_TYPE_BRIDGE = 2, + ACPI_DMAR_SCOPE_TYPE_IOAPIC = 3, + ACPI_DMAR_SCOPE_TYPE_HPET = 4, + ACPI_DMAR_SCOPE_TYPE_RESERVED = 5 /* 5 and greater are reserved */ +}; + +struct acpi_dmar_pci_path { + u8 dev; + u8 fn; +}; + +/* + * DMAR Sub-tables, correspond to Type in struct acpi_dmar_header + */ + +/* 0: Hardware Unit Definition */ + +struct acpi_dmar_hardware_unit { + struct acpi_dmar_header header; + u8 flags; + u8 reserved; + u16 segment; + u64 address; /* Register Base Address */ +}; + +/* Flags */ + +#define ACPI_DMAR_INCLUDE_ALL (1) + +/* 1: Reserved Memory Defininition */ + +struct acpi_dmar_reserved_memory { + struct acpi_dmar_header header; + u16 reserved; + u16 segment; + u64 base_address; /* 4_k aligned base address */ + u64 end_address; /* 4_k aligned limit address */ +}; + +/* Flags */ + +#define ACPI_DMAR_ALLOW_ALL (1) + +/* 2: Root Port ATS Capability Reporting Structure */ + +struct acpi_dmar_atsr { + struct acpi_dmar_header header; + u8 flags; + u8 reserved; + u16 segment; +}; + +/* Flags */ + +#define ACPI_DMAR_ALL_PORTS (1) + +/******************************************************************************* + * + * HPET - High Precision Event Timer table + * + ******************************************************************************/ + +struct acpi_table_hpet { + struct acpi_table_header header; /* Common ACPI table header */ + u32 id; /* Hardware ID of event timer block */ + struct acpi_generic_address address; /* Address of event timer block */ + u8 sequence; /* HPET sequence number */ + u16 minimum_tick; /* Main counter min tick, periodic mode */ + u8 flags; +}; + +/*! Flags */ + +#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ +#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ +#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ + +/*! [End] no source code translation !*/ + +/******************************************************************************* + * + * IBFT - Boot Firmware Table + * + ******************************************************************************/ + +struct acpi_table_ibft { + struct acpi_table_header header; /* Common ACPI table header */ + u8 reserved[12]; +}; + +/* IBFT common subtable header */ + +struct acpi_ibft_header { + u8 type; + u8 version; + u16 length; + u8 index; + u8 flags; +}; + +/* Values for Type field above */ + +enum acpi_ibft_type { + ACPI_IBFT_TYPE_NOT_USED = 0, + ACPI_IBFT_TYPE_CONTROL = 1, + ACPI_IBFT_TYPE_INITIATOR = 2, + ACPI_IBFT_TYPE_NIC = 3, + ACPI_IBFT_TYPE_TARGET = 4, + ACPI_IBFT_TYPE_EXTENSIONS = 5, + ACPI_IBFT_TYPE_RESERVED = 6 /* 6 and greater are reserved */ +}; + +/* IBFT subtables */ + +struct acpi_ibft_control { + struct acpi_ibft_header header; + u16 extensions; + u16 initiator_offset; + u16 nic0_offset; + u16 target0_offset; + u16 nic1_offset; + u16 target1_offset; +}; + +struct acpi_ibft_initiator { + struct acpi_ibft_header header; + u8 sns_server[16]; + u8 slp_server[16]; + u8 primary_server[16]; + u8 secondary_server[16]; + u16 name_length; + u16 name_offset; +}; + +struct acpi_ibft_nic { + struct acpi_ibft_header header; + u8 ip_address[16]; + u8 subnet_mask_prefix; + u8 origin; + u8 gateway[16]; + u8 primary_dns[16]; + u8 secondary_dns[16]; + u8 dhcp[16]; + u16 vlan; + u8 mac_address[6]; + u16 pci_address; + u16 name_length; + u16 name_offset; +}; + +struct acpi_ibft_target { + struct acpi_ibft_header header; + u8 target_ip_address[16]; + u16 target_ip_socket; + u8 target_boot_lun[8]; + u8 chap_type; + u8 nic_association; + u16 target_name_length; + u16 target_name_offset; + u16 chap_name_length; + u16 chap_name_offset; + u16 chap_secret_length; + u16 chap_secret_offset; + u16 reverse_chap_name_length; + u16 reverse_chap_name_offset; + u16 reverse_chap_secret_length; + u16 reverse_chap_secret_offset; +}; + +/******************************************************************************* + * + * MCFG - PCI Memory Mapped Configuration table and sub-table + * + ******************************************************************************/ + +struct acpi_table_mcfg { + struct acpi_table_header header; /* Common ACPI table header */ + u8 reserved[8]; +}; + +/* Subtable */ + +struct acpi_mcfg_allocation { + u64 address; /* Base address, processor-relative */ + u16 pci_segment; /* PCI segment group number */ + u8 start_bus_number; /* Starting PCI Bus number */ + u8 end_bus_number; /* Final PCI Bus number */ + u32 reserved; +}; + +/******************************************************************************* + * + * SPCR - Serial Port Console Redirection table + * + ******************************************************************************/ + +struct acpi_table_spcr { + struct acpi_table_header header; /* Common ACPI table header */ + u8 interface_type; /* 0=full 16550, 1=subset of 16550 */ + u8 reserved[3]; + struct acpi_generic_address serial_port; + u8 interrupt_type; + u8 pc_interrupt; + u32 interrupt; + u8 baud_rate; + u8 parity; + u8 stop_bits; + u8 flow_control; + u8 terminal_type; + u8 reserved1; + u16 pci_device_id; + u16 pci_vendor_id; + u8 pci_bus; + u8 pci_device; + u8 pci_function; + u32 pci_flags; + u8 pci_segment; + u32 reserved2; +}; + +/******************************************************************************* + * + * SPMI - Server Platform Management Interface table + * + ******************************************************************************/ + +struct acpi_table_spmi { + struct acpi_table_header header; /* Common ACPI table header */ + u8 reserved; + u8 interface_type; + u16 spec_revision; /* Version of IPMI */ + u8 interrupt_type; + u8 gpe_number; /* GPE assigned */ + u8 reserved1; + u8 pci_device_flag; + u32 interrupt; + struct acpi_generic_address ipmi_register; + u8 pci_segment; + u8 pci_bus; + u8 pci_device; + u8 pci_function; +}; + +/******************************************************************************* + * + * TCPA - Trusted Computing Platform Alliance table + * + ******************************************************************************/ + +struct acpi_table_tcpa { + struct acpi_table_header header; /* Common ACPI table header */ + u16 reserved; + u32 max_log_length; /* Maximum length for the event log area */ + u64 log_address; /* Address of the event log area */ +}; + +/******************************************************************************* + * + * UEFI - UEFI Boot optimization Table + * + ******************************************************************************/ + +struct acpi_table_uefi { + struct acpi_table_header header; /* Common ACPI table header */ + u8 identifier[16]; /* UUID identifier */ + u16 data_offset; /* Offset of remaining data in table */ + u8 data; +}; + +/******************************************************************************* + * + * WDAT - Watchdog Action Table + * + ******************************************************************************/ + +struct acpi_table_wdat { + struct acpi_table_header header; /* Common ACPI table header */ + u32 header_length; /* Watchdog Header Length */ + u16 pci_segment; /* PCI Segment number */ + u8 pci_bus; /* PCI Bus number */ + u8 pci_device; /* PCI Device number */ + u8 pci_function; /* PCI Function number */ + u8 reserved[3]; + u32 timer_period; /* Period of one timer count (msec) */ + u32 max_count; /* Maximum counter value supported */ + u32 min_count; /* Minimum counter value */ + u8 flags; + u8 reserved2[3]; + u32 entries; /* Number of watchdog entries that follow */ +}; + +/* WDAT Instruction Entries (actions) */ + +struct acpi_wdat_entry { + struct acpi_whea_header whea_header; /* Common header for WHEA tables */ +}; + +/* Values for Action field above */ + +enum acpi_wdat_actions { + ACPI_WDAT_RESET = 1, + ACPI_WDAT_GET_CURRENT_COUNTDOWN = 4, + ACPI_WDAT_GET_COUNTDOWN = 5, + ACPI_WDAT_SET_COUNTDOWN = 6, + ACPI_WDAT_GET_RUNNING_STATE = 8, + ACPI_WDAT_SET_RUNNING_STATE = 9, + ACPI_WDAT_GET_STOPPED_STATE = 10, + ACPI_WDAT_SET_STOPPED_STATE = 11, + ACPI_WDAT_GET_REBOOT = 16, + ACPI_WDAT_SET_REBOOT = 17, + ACPI_WDAT_GET_SHUTDOWN = 18, + ACPI_WDAT_SET_SHUTDOWN = 19, + ACPI_WDAT_GET_STATUS = 32, + ACPI_WDAT_SET_STATUS = 33, + ACPI_WDAT_ACTION_RESERVED = 34 /* 34 and greater are reserved */ +}; + +/* Values for Instruction field above */ + +enum acpi_wdat_instructions { + ACPI_WDAT_READ_VALUE = 0, + ACPI_WDAT_READ_COUNTDOWN = 1, + ACPI_WDAT_WRITE_VALUE = 2, + ACPI_WDAT_WRITE_COUNTDOWN = 3, + ACPI_WDAT_INSTRUCTION_RESERVED = 4, /* 4 and greater are reserved */ + ACPI_WDAT_PRESERVE_REGISTER = 0x80 /* Except for this value */ +}; + +/******************************************************************************* + * + * WDRT - Watchdog Resource Table + * + ******************************************************************************/ + +struct acpi_table_wdrt { + struct acpi_table_header header; /* Common ACPI table header */ + u32 header_length; /* Watchdog Header Length */ + u8 pci_segment; /* PCI Segment number */ + u8 pci_bus; /* PCI Bus number */ + u8 pci_device; /* PCI Device number */ + u8 pci_function; /* PCI Function number */ + u32 timer_period; /* Period of one timer count (msec) */ + u32 max_count; /* Maximum counter value supported */ + u32 min_count; /* Minimum counter value */ + u8 flags; + u8 reserved[3]; + u32 entries; /* Number of watchdog entries that follow */ +}; + +/* Flags */ + +#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ + +/* Reset to default packing */ + +#pragma pack() + +#endif /* __ACTBL2_H__ */ From 6e2d5ebd0d36199920676fdceaff4f4bfe66297b Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 27 Jul 2009 10:53:00 +0800 Subject: [PATCH 20/34] ACPICA: ACPI 4: Update headers for new and changed ACPI tables. Add IVRS,MSCT,UEFI,WAET,WDAT. Updated several existing tables for ACPI 4.0-related changes. Added document references for all tables not defined in ACPI spec. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actbl.h | 30 ++-- include/acpi/actbl1.h | 339 ++++++++++++++++++++++++++++-------------- include/acpi/actbl2.h | 339 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 557 insertions(+), 151 deletions(-) diff --git a/include/acpi/actbl.h b/include/acpi/actbl.h index 55fcfc6725b2..1b6587952604 100644 --- a/include/acpi/actbl.h +++ b/include/acpi/actbl.h @@ -58,8 +58,9 @@ ******************************************************************************/ /* - * Values for description table header signatures. Useful because they make - * it more difficult to inadvertently type in the wrong signature. + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. */ #define ACPI_SIG_DSDT "DSDT" /* Differentiated System Description Table */ #define ACPI_SIG_FADT "FACP" /* Fixed ACPI Description Table */ @@ -123,6 +124,7 @@ struct acpi_generic_address { /******************************************************************************* * * RSDP - Root System Description Pointer (Signature is "RSD PTR ") + * Version 2 * ******************************************************************************/ @@ -143,6 +145,7 @@ struct acpi_table_rsdp { /******************************************************************************* * * RSDT/XSDT - Root System Description Tables + * Version 1 (both) * ******************************************************************************/ @@ -176,23 +179,24 @@ struct acpi_table_facs { u8 reserved1[24]; /* Reserved, must be zero */ }; -/* global_lock flags */ +/* Masks for global_lock flag field above */ #define ACPI_GLOCK_PENDING (1) /* 00: Pending global lock ownership */ #define ACPI_GLOCK_OWNED (1<<1) /* 01: Global lock is owned */ -/* Flags */ +/* Masks for Flags field above */ #define ACPI_FACS_S4_BIOS_PRESENT (1) /* 00: S4BIOS support is present */ #define ACPI_FACS_64BIT_WAKE (1<<1) /* 01: 64-bit wake vector supported (ACPI 4.0) */ -/* ospm_flags */ +/* Masks for ospm_flags field above */ #define ACPI_FACS_64BIT_ENVIRONMENT (1) /* 00: 64-bit wake environment is required (ACPI 4.0) */ /******************************************************************************* * * FADT - Fixed ACPI Description Table (Signature "FACP") + * Version 4 * ******************************************************************************/ @@ -253,7 +257,7 @@ struct acpi_table_fadt { struct acpi_generic_address xgpe1_block; /* 64-bit Extended General Purpose Event 1 Reg Blk address */ }; -/* FADT Boot Architecture Flags (boot_flags) */ +/* Masks for FADT Boot Architecture Flags (boot_flags) */ #define ACPI_FADT_LEGACY_DEVICES (1) /* 00: [V2] System has LPC or ISA bus devices */ #define ACPI_FADT_8042 (1<<1) /* 01: [V3] System has an 8042 controller on port 60/64 */ @@ -263,7 +267,7 @@ struct acpi_table_fadt { #define FADT2_REVISION_ID 3 -/* FADT flags */ +/* Masks for FADT flags */ #define ACPI_FADT_WBINVD (1) /* 00: [V1] The wbinvd instruction works properly */ #define ACPI_FADT_WBINVD_FLUSH (1<<1) /* 01: [V1] wbinvd flushes but does not invalidate caches */ @@ -286,7 +290,7 @@ struct acpi_table_fadt { #define ACPI_FADT_APIC_CLUSTER (1<<18) /* 18: [V4] All local APICs must use cluster model (ACPI 3.0) */ #define ACPI_FADT_APIC_PHYSICAL (1<<19) /* 19: [V4] All local x_aPICs must use physical dest mode (ACPI 3.0) */ -/* FADT Prefered Power Management Profiles */ +/* Values for preferred_profile (Prefered Power Management Profiles) */ enum acpi_prefered_pm_profiles { PM_UNSPECIFIED = 0, @@ -304,14 +308,16 @@ enum acpi_prefered_pm_profiles { #define ACPI_FADT_OFFSET(f) (u8) ACPI_OFFSET (struct acpi_table_fadt, f) +/* + * Internal table-related structures + */ union acpi_name_union { u32 integer; char ascii[4]; }; -/* - * Internal ACPI Table Descriptor. One per ACPI table - */ +/* Internal ACPI Table Descriptor. One per ACPI table. */ + struct acpi_table_desc { acpi_physical_address address; struct acpi_table_header *pointer; @@ -321,7 +327,7 @@ struct acpi_table_desc { u8 flags; }; -/* Flags for above */ +/* Masks for Flags field above */ #define ACPI_TABLE_ORIGIN_UNKNOWN (0) #define ACPI_TABLE_ORIGIN_MAPPED (1) diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 582af1fcb8f5..0417f2abc44b 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -56,8 +56,9 @@ ******************************************************************************/ /* - * Values for description table header signatures. Useful because they make - * it more difficult to inadvertently type in the wrong signature. + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. */ #define ACPI_SIG_BERT "BERT" /* Boot Error Record Table */ #define ACPI_SIG_CPEP "CPEP" /* Corrected Platform Error Polling table */ @@ -66,6 +67,7 @@ #define ACPI_SIG_ERST "ERST" /* Error Record Serialization Table */ #define ACPI_SIG_HEST "HEST" /* Hardware Error Source Table */ #define ACPI_SIG_MADT "APIC" /* Multiple APIC Description Table */ +#define ACPI_SIG_MSCT "MSCT" /* Maximum System Characteristics Table */ #define ACPI_SIG_SBST "SBST" /* Smart Battery Specification Table */ #define ACPI_SIG_SLIT "SLIT" /* System Locality Distance Information Table */ #define ACPI_SIG_SRAT "SRAT" /* System Resource Affinity Table */ @@ -82,14 +84,20 @@ * portable, so do not use any other bitfield types. */ -/* Common Subtable header (used in MADT, SRAT, etc.) */ +/******************************************************************************* + * + * Common subtable headers + * + ******************************************************************************/ + +/* Generic subtable header (used in MADT, SRAT, etc.) */ struct acpi_subtable_header { u8 type; u8 length; }; -/* Common Subtable header for WHEA tables (EINJ, ERST, WDAT) */ +/* Subtable header for WHEA tables (EINJ, ERST, WDAT) */ struct acpi_whea_header { u8 action; @@ -103,7 +111,8 @@ struct acpi_whea_header { /******************************************************************************* * - * BERT - Boot Error Record Table + * BERT - Boot Error Record Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -113,26 +122,43 @@ struct acpi_table_bert { u64 address; /* Physical addresss of the error region */ }; -/* Boot Error Region */ +/* Boot Error Region (not a subtable, pointed to by Address field above) */ struct acpi_bert_region { - u32 block_status; - u32 raw_data_offset; - u32 raw_data_length; - u32 data_length; - u32 error_severity; + u32 block_status; /* Type of error information */ + u32 raw_data_offset; /* Offset to raw error data */ + u32 raw_data_length; /* Length of raw error data */ + u32 data_length; /* Length of generic error data */ + u32 error_severity; /* Severity code */ }; -/* block_status Flags */ +/* Values for block_status flags above */ #define ACPI_BERT_UNCORRECTABLE (1) -#define ACPI_BERT_CORRECTABLE (2) -#define ACPI_BERT_MULTIPLE_UNCORRECTABLE (4) -#define ACPI_BERT_MULTIPLE_CORRECTABLE (8) +#define ACPI_BERT_CORRECTABLE (1<<1) +#define ACPI_BERT_MULTIPLE_UNCORRECTABLE (1<<2) +#define ACPI_BERT_MULTIPLE_CORRECTABLE (1<<3) +#define ACPI_BERT_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ + +/* Values for error_severity above */ + +enum acpi_bert_error_severity { + ACPI_BERT_ERROR_CORRECTABLE = 0, + ACPI_BERT_ERROR_FATAL = 1, + ACPI_BERT_ERROR_CORRECTED = 2, + ACPI_BERT_ERROR_NONE = 3, + ACPI_BERT_ERROR_RESERVED = 4 /* 4 and greater are reserved */ +}; + +/* + * Note: The generic error data that follows the error_severity field above + * uses the struct acpi_hest_generic_data defined under the HEST table below + */ /******************************************************************************* * - * CPEP - Corrected Platform Error Polling table + * CPEP - Corrected Platform Error Polling table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -144,8 +170,7 @@ struct acpi_table_cpep { /* Subtable */ struct acpi_cpep_polling { - u8 type; - u8 length; + struct acpi_subtable_header header; u8 id; /* Processor ID */ u8 eid; /* Processor EID */ u32 interval; /* Polling interval (msec) */ @@ -154,6 +179,7 @@ struct acpi_cpep_polling { /******************************************************************************* * * ECDT - Embedded Controller Boot Resources Table + * Version 1 * ******************************************************************************/ @@ -168,14 +194,16 @@ struct acpi_table_ecdt { /******************************************************************************* * - * EINJ - Error Injection Table + * EINJ - Error Injection Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ struct acpi_table_einj { struct acpi_table_header header; /* Common ACPI table header */ u32 header_length; - u32 reserved; + u8 flags; + u8 reserved[3]; u32 entries; }; @@ -185,6 +213,10 @@ struct acpi_einj_entry { struct acpi_whea_header whea_header; /* Common header for WHEA tables */ }; +/* Masks for Flags field above */ + +#define ACPI_EINJ_PRESERVE (1) + /* Values for Action field above */ enum acpi_einj_actions { @@ -220,9 +252,34 @@ struct acpi_einj_trigger { u32 entry_count; }; +/* Command status return values */ + +enum acpi_einj_command_status { + ACPI_EINJ_SUCCESS = 0, + ACPI_EINJ_FAILURE = 1, + ACPI_EINJ_INVALID_ACCESS = 2, + ACPI_EINJ_STATUS_RESERVED = 3 /* 3 and greater are reserved */ +}; + +/* Error types returned from ACPI_EINJ_GET_ERROR_TYPE (bitfield) */ + +#define ACPI_EINJ_PROCESSOR_CORRECTABLE (1) +#define ACPI_EINJ_PROCESSOR_UNCORRECTABLE (1<<1) +#define ACPI_EINJ_PROCESSOR_FATAL (1<<2) +#define ACPI_EINJ_MEMORY_CORRECTABLE (1<<3) +#define ACPI_EINJ_MEMORY_UNCORRECTABLE (1<<4) +#define ACPI_EINJ_MEMORY_FATAL (1<<5) +#define ACPI_EINJ_PCIX_CORRECTABLE (1<<6) +#define ACPI_EINJ_PCIX_UNCORRECTABLE (1<<7) +#define ACPI_EINJ_PCIX_FATAL (1<<8) +#define ACPI_EINJ_PLATFORM_CORRECTABLE (1<<9) +#define ACPI_EINJ_PLATFORM_UNCORRECTABLE (1<<10) +#define ACPI_EINJ_PLATFORM_FATAL (1<<11) + /******************************************************************************* * - * ERST - Error Record Serialization Table + * ERST - Error Record Serialization Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -239,19 +296,23 @@ struct acpi_erst_entry { struct acpi_whea_header whea_header; /* Common header for WHEA tables */ }; +/* Masks for Flags field above */ + +#define ACPI_ERST_PRESERVE (1) + /* Values for Action field above */ enum acpi_erst_actions { - ACPI_ERST_BEGIN_WRITE_OPERATION = 0, - ACPI_ERST_BEGIN_READ_OPERATION = 1, - ACPI_ERST_BETGIN_CLEAR_OPERATION = 2, - ACPI_ERST_END_OPERATION = 3, + ACPI_ERST_BEGIN_WRITE = 0, + ACPI_ERST_BEGIN_READ = 1, + ACPI_ERST_BEGIN_CLEAR = 2, + ACPI_ERST_END = 3, ACPI_ERST_SET_RECORD_OFFSET = 4, ACPI_ERST_EXECUTE_OPERATION = 5, ACPI_ERST_CHECK_BUSY_STATUS = 6, ACPI_ERST_GET_COMMAND_STATUS = 7, - ACPI_ERST_GET_RECORD_IDENTIFIER = 8, - ACPI_ERST_SET_RECORD_IDENTIFIER = 9, + ACPI_ERST_GET_RECORD_ID = 8, + ACPI_ERST_SET_RECORD_ID = 9, ACPI_ERST_GET_RECORD_COUNT = 10, ACPI_ERST_BEGIN_DUMMY_WRIITE = 11, ACPI_ERST_NOT_USED = 12, @@ -286,9 +347,29 @@ enum acpi_erst_instructions { ACPI_ERST_INSTRUCTION_RESERVED = 19 /* 19 and greater are reserved */ }; +/* Command status return values */ + +enum acpi_erst_command_status { + ACPI_ERST_SUCESS = 0, + ACPI_ERST_NO_SPACE = 1, + ACPI_ERST_NOT_AVAILABLE = 2, + ACPI_ERST_FAILURE = 3, + ACPI_ERST_RECORD_EMPTY = 4, + ACPI_ERST_NOT_FOUND = 5, + ACPI_ERST_STATUS_RESERVED = 6 /* 6 and greater are reserved */ +}; + +/* Error Record Serialization Information */ + +struct acpi_erst_info { + u16 signature; /* Should be "ER" */ + u8 data[48]; +}; + /******************************************************************************* * - * HEST - Hardware Error Source Table + * HEST - Hardware Error Source Table (ACPI 4.0) + * Version 1 * ******************************************************************************/ @@ -301,70 +382,49 @@ struct acpi_table_hest { struct acpi_hest_header { u16 type; + u16 source_id; }; /* Values for Type field above for subtables */ enum acpi_hest_types { - ACPI_HEST_TYPE_XPF_MACHINE_CHECK = 0, - ACPI_HEST_TYPE_XPF_CORRECTED_MACHINE_CHECK = 1, - ACPI_HEST_TYPE_XPF_UNUSED = 2, - ACPI_HEST_TYPE_XPF_NON_MASKABLE_INTERRUPT = 3, - ACPI_HEST_TYPE_IPF_CORRECTED_MACHINE_CHECK = 4, - ACPI_HEST_TYPE_IPF_CORRECTED_PLATFORM_ERROR = 5, + ACPI_HEST_TYPE_IA32_CHECK = 0, + ACPI_HEST_TYPE_IA32_CORRECTED_CHECK = 1, + ACPI_HEST_TYPE_IA32_NMI = 2, + ACPI_HEST_TYPE_NOT_USED3 = 3, + ACPI_HEST_TYPE_NOT_USED4 = 4, + ACPI_HEST_TYPE_NOT_USED5 = 5, ACPI_HEST_TYPE_AER_ROOT_PORT = 6, ACPI_HEST_TYPE_AER_ENDPOINT = 7, ACPI_HEST_TYPE_AER_BRIDGE = 8, - ACPI_HEST_TYPE_GENERIC_HARDWARE_ERROR_SOURCE = 9, + ACPI_HEST_TYPE_GENERIC_ERROR = 9, ACPI_HEST_TYPE_RESERVED = 10 /* 10 and greater are reserved */ }; /* - * HEST Sub-subtables + * HEST substructures contained in subtables */ -/* XPF Machine Check Error Bank */ - -struct acpi_hest_xpf_error_bank { +/* + * IA32 Error Bank(s) - Follows the struct acpi_hest_ia_machine_check and + * struct acpi_hest_ia_corrected structures. + */ +struct acpi_hest_ia_error_bank { u8 bank_number; u8 clear_status_on_init; u8 status_format; - u8 config_write_enable; + u8 reserved; u32 control_register; - u64 control_init_data; + u64 control_data; u32 status_register; u32 address_register; u32 misc_register; }; -/* Generic Error Status */ - -struct acpi_hest_generic_status { - u32 block_status; - u32 raw_data_offset; - u32 raw_data_length; - u32 data_length; - u32 error_severity; -}; - -/* Generic Error Data */ - -struct acpi_hest_generic_data { - u8 section_type[16]; - u32 error_severity; - u16 revision; - u8 validation_bits; - u8 flags; - u32 error_data_length; - u8 fru_id[16]; - u8 fru_text[20]; -}; - -/* Common HEST structure for PCI/AER types below (6,7,8) */ +/* Common HEST sub-structure for PCI/AER structures below (6,7,8) */ struct acpi_hest_aer_common { - u16 source_id; - u16 config_write_enable; + u16 reserved1; u8 flags; u8 enabled; u32 records_to_pre_allocate; @@ -373,13 +433,18 @@ struct acpi_hest_aer_common { u16 device; u16 function; u16 device_control; - u16 reserved; + u16 reserved2; u32 uncorrectable_error_mask; u32 uncorrectable_error_severity; u32 correctable_error_mask; u32 advanced_error_capabilities; }; +/* Masks for HEST Flags fields */ + +#define ACPI_HEST_FIRMWARE_FIRST (1) +#define ACPI_HEST_GLOBAL (1<<1) + /* Hardware Error Notification */ struct acpi_hest_notify { @@ -405,71 +470,59 @@ enum acpi_hest_notify_types { ACPI_HEST_NOTIFY_RESERVED = 5 /* 5 and greater are reserved */ }; +/* Values for config_write_enable bitfield above */ + +#define ACPI_HEST_TYPE (1) +#define ACPI_HEST_POLL_INTERVAL (1<<1) +#define ACPI_HEST_POLL_THRESHOLD_VALUE (1<<2) +#define ACPI_HEST_POLL_THRESHOLD_WINDOW (1<<3) +#define ACPI_HEST_ERR_THRESHOLD_VALUE (1<<4) +#define ACPI_HEST_ERR_THRESHOLD_WINDOW (1<<5) + /* * HEST subtables - * - * From WHEA Design Document, 16 May 2007. - * Note: There is no subtable type 2 in this version of the document, - * and there are two different subtable type 3s. */ - /* 0: XPF Machine Check Exception */ +/* 0: IA32 Machine Check Exception */ -struct acpi_hest_xpf_machine_check { +struct acpi_hest_ia_machine_check { struct acpi_hest_header header; - u16 source_id; - u16 config_write_enable; + u16 reserved1; u8 flags; - u8 reserved1; + u8 enabled; u32 records_to_pre_allocate; u32 max_sections_per_record; u64 global_capability_data; u64 global_control_data; u8 num_hardware_banks; - u8 reserved2[7]; + u8 reserved3[7]; }; -/* 1: XPF Corrected Machine Check */ +/* 1: IA32 Corrected Machine Check */ -struct acpi_table_hest_xpf_corrected { +struct acpi_table_hest_ia_corrected { struct acpi_hest_header header; - u16 source_id; - u16 config_write_enable; + u16 reserved1; u8 flags; u8 enabled; u32 records_to_pre_allocate; u32 max_sections_per_record; struct acpi_hest_notify notify; u8 num_hardware_banks; - u8 reserved[3]; + u8 reserved2[3]; }; -/* 3: XPF Non-Maskable Interrupt */ +/* 2: IA32 Non-Maskable Interrupt */ -struct acpi_hest_xpf_nmi { +struct acpi_hest_ia_nmi { struct acpi_hest_header header; - u16 source_id; u32 reserved; u32 records_to_pre_allocate; u32 max_sections_per_record; u32 max_raw_data_length; }; -/* 4: IPF Corrected Machine Check */ - -struct acpi_hest_ipf_corrected { - struct acpi_hest_header header; - u8 enabled; - u8 reserved; -}; - -/* 5: IPF Corrected Platform Error */ - -struct acpi_hest_ipf_corrected_platform { - struct acpi_hest_header header; - u8 enabled; - u8 reserved; -}; +/* 3,4,5: Not used */ /* 6: PCI Express Root Port AER */ @@ -491,30 +544,61 @@ struct acpi_hest_aer { struct acpi_hest_aer_bridge { struct acpi_hest_header header; struct acpi_hest_aer_common aer; - u32 secondary_uncorrectable_error_mask; - u32 secondary_uncorrectable_error_severity; - u32 secondary_advanced_capabilities; + u32 second_uncorrectable_error_mask; + u32 second_uncorrectable_error_severity; + u32 second_advanced_capabilities; }; /* 9: Generic Hardware Error Source */ struct acpi_hest_generic { struct acpi_hest_header header; - u16 source_id; u16 related_source_id; - u8 config_write_enable; + u8 reserved; u8 enabled; u32 records_to_pre_allocate; u32 max_sections_per_record; u32 max_raw_data_length; struct acpi_generic_address error_status_address; struct acpi_hest_notify notify; - u32 error_status_block_length; + u32 error_block_length; +}; + +/* Generic Error Status block */ + +struct acpi_hest_generic_status { + u32 block_status; + u32 raw_data_offset; + u32 raw_data_length; + u32 data_length; + u32 error_severity; +}; + +/* Values for block_status flags above */ + +#define ACPI_HEST_UNCORRECTABLE (1) +#define ACPI_HEST_CORRECTABLE (1<<1) +#define ACPI_HEST_MULTIPLE_UNCORRECTABLE (1<<2) +#define ACPI_HEST_MULTIPLE_CORRECTABLE (1<<3) +#define ACPI_HEST_ERROR_ENTRY_COUNT (0xFF<<4) /* 8 bits, error count */ + +/* Generic Error Data entry */ + +struct acpi_hest_generic_data { + u8 section_type[16]; + u32 error_severity; + u16 revision; + u8 validation_bits; + u8 flags; + u32 error_data_length; + u8 fru_id[16]; + u8 fru_text[20]; }; /******************************************************************************* * * MADT - Multiple APIC Description Table + * Version 3 * ******************************************************************************/ @@ -524,16 +608,16 @@ struct acpi_table_madt { u32 flags; }; -/* Flags */ +/* Masks for Flags field above */ -#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ +#define ACPI_MADT_PCAT_COMPAT (1) /* 00: System also has dual 8259s */ /* Values for PCATCompat flag */ #define ACPI_MADT_DUAL_PIC 0 #define ACPI_MADT_MULTIPLE_APIC 1 -/* Values for subtable type in struct acpi_subtable_header */ +/* Values for MADT subtable type in struct acpi_subtable_header */ enum acpi_madt_type { ACPI_MADT_TYPE_LOCAL_APIC = 0, @@ -644,7 +728,7 @@ struct acpi_madt_interrupt_source { u32 flags; /* Interrupt Source Flags */ }; -/* Flags field above */ +/* Masks for Flags field above */ #define ACPI_MADT_CPEI_OVERRIDE (1) @@ -693,9 +777,36 @@ struct acpi_madt_local_x2apic_nmi { #define ACPI_MADT_TRIGGER_RESERVED (2<<2) #define ACPI_MADT_TRIGGER_LEVEL (3<<2) +/******************************************************************************* + * + * MSCT - Maximum System Characteristics Table (ACPI 4.0) + * Version 1 + * + ******************************************************************************/ + +struct acpi_table_msct { + struct acpi_table_header header; /* Common ACPI table header */ + u32 proximity_offset; /* Location of proximity info struct(s) */ + u32 max_proximity_domains; /* Max number of proximity domains */ + u32 max_clock_domains; /* Max number of clock domains */ + u64 max_address; /* Max physical address in system */ +}; + +/* Subtable - Maximum Proximity Domain Information. Version 1 */ + +struct acpi_msct_proximity { + u8 revision; + u8 length; + u32 range_start; /* Start of domain range */ + u32 range_end; /* End of domain range */ + u32 processor_capacity; + u64 memory_capacity; /* In bytes */ +}; + /******************************************************************************* * * SBST - Smart Battery Specification Table + * Version 1 * ******************************************************************************/ @@ -709,6 +820,7 @@ struct acpi_table_sbst { /******************************************************************************* * * SLIT - System Locality Distance Information Table + * Version 1 * ******************************************************************************/ @@ -721,6 +833,7 @@ struct acpi_table_slit { /******************************************************************************* * * SRAT - System Resource Affinity Table + * Version 3 * ******************************************************************************/ @@ -755,6 +868,10 @@ struct acpi_srat_cpu_affinity { u32 reserved; /* Reserved, must be zero */ }; +/* Flags */ + +#define ACPI_SRAT_CPU_USE_AFFINITY (1) /* 00: Use affinity structure */ + /* 1: Memory Affinity */ struct acpi_srat_mem_affinity { diff --git a/include/acpi/actbl2.h b/include/acpi/actbl2.h index b271aba0e524..6f3dce9991e1 100644 --- a/include/acpi/actbl2.h +++ b/include/acpi/actbl2.h @@ -14,8 +14,9 @@ ******************************************************************************/ /* - * Values for description table header signatures. Useful because they make - * it more difficult to inadvertently type in the wrong signature. + * Values for description table header signatures for tables defined in this + * file. Useful because they make it more difficult to inadvertently type in + * the wrong signature. */ #define ACPI_SIG_ASF "ASF!" /* Alert Standard Format table */ #define ACPI_SIG_BOOT "BOOT" /* Simple Boot Flag Table */ @@ -23,12 +24,14 @@ #define ACPI_SIG_DMAR "DMAR" /* DMA Remapping table */ #define ACPI_SIG_HPET "HPET" /* High Precision Event Timer table */ #define ACPI_SIG_IBFT "IBFT" /* i_sCSI Boot Firmware Table */ +#define ACPI_SIG_IVRS "IVRS" /* I/O Virtualization Reporting Structure */ #define ACPI_SIG_MCFG "MCFG" /* PCI Memory Mapped Configuration table */ #define ACPI_SIG_SLIC "SLIC" /* Software Licensing Description Table */ #define ACPI_SIG_SPCR "SPCR" /* Serial Port Console Redirection table */ #define ACPI_SIG_SPMI "SPMI" /* Server Platform Management Interface table */ #define ACPI_SIG_TCPA "TCPA" /* Trusted Computing Platform Alliance table */ #define ACPI_SIG_UEFI "UEFI" /* Uefi Boot Optimization Table */ +#define ACPI_SIG_WAET "WAET" /* Windows ACPI Emulated devices Table */ #define ACPI_SIG_WDAT "WDAT" /* Watchdog Action Table */ #define ACPI_SIG_WDRT "WDRT" /* Watchdog Resource Table */ @@ -47,6 +50,7 @@ /******************************************************************************* * * ASF - Alert Standard Format table (Signature "ASF!") + * Revision 0x10 * * Conforms to the Alert Standard Format Specification V2.0, 23 April 2003 * @@ -91,6 +95,10 @@ struct acpi_asf_info { u8 reserved2[3]; }; +/* Masks for Flags field above */ + +#define ACPI_ASF_SMBUS_PROTOCOLS (1) + /* 1: ASF Alerts */ struct acpi_asf_alert { @@ -156,6 +164,9 @@ struct acpi_asf_address { /******************************************************************************* * * BOOT - Simple Boot Flag Table + * Version 1 + * + * Conforms to the "Simple Boot Flag Specification", Version 2.1 * ******************************************************************************/ @@ -168,6 +179,9 @@ struct acpi_table_boot { /******************************************************************************* * * DBGP - Debug Port table + * Version 1 + * + * Conforms to the "Debug Port Specification", Version 1.00, 2/9/2000 * ******************************************************************************/ @@ -181,7 +195,10 @@ struct acpi_table_dbgp { /******************************************************************************* * * DMAR - DMA Remapping table - * From "Intel Virtualization Technology for Directed I/O", Sept. 2007 + * Version 1 + * + * Conforms to "Intel Virtualization Technology for Directed I/O", + * Version 1.2, Sept. 2008 * ******************************************************************************/ @@ -192,7 +209,7 @@ struct acpi_table_dmar { u8 reserved[10]; }; -/* Flags */ +/* Masks for Flags field above */ #define ACPI_DMAR_INTR_REMAP (1) @@ -209,9 +226,12 @@ enum acpi_dmar_type { ACPI_DMAR_TYPE_HARDWARE_UNIT = 0, ACPI_DMAR_TYPE_RESERVED_MEMORY = 1, ACPI_DMAR_TYPE_ATSR = 2, - ACPI_DMAR_TYPE_RESERVED = 3 /* 3 and greater are reserved */ + ACPI_DMAR_HARDWARE_AFFINITY = 3, + ACPI_DMAR_TYPE_RESERVED = 4 /* 4 and greater are reserved */ }; +/* DMAR Device Scope structure */ + struct acpi_dmar_device_scope { u8 entry_type; u8 length; @@ -250,7 +270,7 @@ struct acpi_dmar_hardware_unit { u64 address; /* Register Base Address */ }; -/* Flags */ +/* Masks for Flags field above */ #define ACPI_DMAR_INCLUDE_ALL (1) @@ -264,7 +284,7 @@ struct acpi_dmar_reserved_memory { u64 end_address; /* 4_k aligned limit address */ }; -/* Flags */ +/* Masks for Flags field above */ #define ACPI_DMAR_ALLOW_ALL (1) @@ -277,13 +297,26 @@ struct acpi_dmar_atsr { u16 segment; }; -/* Flags */ +/* Masks for Flags field above */ #define ACPI_DMAR_ALL_PORTS (1) +/* 3: Remapping Hardware Static Affinity Structure */ + +struct acpi_dmar_rhsa { + struct acpi_dmar_header header; + u32 reserved; + u64 base_address; + u32 proximity_domain; +}; + /******************************************************************************* * * HPET - High Precision Event Timer table + * Version 1 + * + * Conforms to "IA-PC HPET (High Precision Event Timers) Specification", + * Version 1.0a, October 2004 * ******************************************************************************/ @@ -296,17 +329,28 @@ struct acpi_table_hpet { u8 flags; }; -/*! Flags */ +/* Masks for Flags field above */ -#define ACPI_HPET_PAGE_PROTECT (1) /* 00: No page protection */ -#define ACPI_HPET_PAGE_PROTECT_4 (1<<1) /* 01: 4KB page protected */ -#define ACPI_HPET_PAGE_PROTECT_64 (1<<2) /* 02: 64KB page protected */ +#define ACPI_HPET_PAGE_PROTECT_MASK (3) -/*! [End] no source code translation !*/ +/* Values for Page Protect flags */ + +enum acpi_hpet_page_protect { + ACPI_HPET_NO_PAGE_PROTECT = 0, + ACPI_HPET_PAGE_PROTECT4 = 1, + ACPI_HPET_PAGE_PROTECT64 = 2 +}; /******************************************************************************* * * IBFT - Boot Firmware Table + * Version 1 + * + * Conforms to "iSCSI Boot Firmware Table (iBFT) as Defined in ACPI 3.0b + * Specification", Version 1.01, March 1, 2007 + * + * Note: It appears that this table is not intended to appear in the RSDT/XSDT. + * Therefore, it is not currently supported by the disassembler. * ******************************************************************************/ @@ -394,9 +438,184 @@ struct acpi_ibft_target { u16 reverse_chap_secret_offset; }; +/******************************************************************************* + * + * IVRS - I/O Virtualization Reporting Structure + * Version 1 + * + * Conforms to "AMD I/O Virtualization Technology (IOMMU) Specification", + * Revision 1.26, February 2009. + * + ******************************************************************************/ + +struct acpi_table_ivrs { + struct acpi_table_header header; /* Common ACPI table header */ + u32 info; /* Common virtualization info */ + u64 reserved; +}; + +/* Values for Info field above */ + +#define ACPI_IVRS_PHYSICAL_SIZE 0x00007F00 /* 7 bits, physical address size */ +#define ACPI_IVRS_VIRTUAL_SIZE 0x003F8000 /* 7 bits, virtual address size */ +#define ACPI_IVRS_ATS_RESERVED 0x00400000 /* ATS address translation range reserved */ + +/* IVRS subtable header */ + +struct acpi_ivrs_header { + u8 type; /* Subtable type */ + u8 flags; + u16 length; /* Subtable length */ + u16 device_id; /* ID of IOMMU */ +}; + +/* Values for subtable Type above */ + +enum acpi_ivrs_type { + ACPI_IVRS_TYPE_HARDWARE = 0x10, + ACPI_IVRS_TYPE_MEMORY1 = 0x20, + ACPI_IVRS_TYPE_MEMORY2 = 0x21, + ACPI_IVRS_TYPE_MEMORY3 = 0x22 +}; + +/* Masks for Flags field above for IVHD subtable */ + +#define ACPI_IVHD_TT_ENABLE (1) +#define ACPI_IVHD_PASS_PW (1<<1) +#define ACPI_IVHD_RES_PASS_PW (1<<2) +#define ACPI_IVHD_ISOC (1<<3) +#define ACPI_IVHD_IOTLB (1<<4) + +/* Masks for Flags field above for IVMD subtable */ + +#define ACPI_IVMD_UNITY (1) +#define ACPI_IVMD_READ (1<<1) +#define ACPI_IVMD_WRITE (1<<2) +#define ACPI_IVMD_EXCLUSION_RANGE (1<<3) + +/* + * IVRS subtables, correspond to Type in struct acpi_ivrs_header + */ + +/* 0x10: I/O Virtualization Hardware Definition Block (IVHD) */ + +struct acpi_ivrs_hardware { + struct acpi_ivrs_header header; + u16 capability_offset; /* Offset for IOMMU control fields */ + u64 base_address; /* IOMMU control registers */ + u16 pci_segment_group; + u16 info; /* MSI number and unit ID */ + u32 reserved; +}; + +/* Masks for Info field above */ + +#define ACPI_IVHD_MSI_NUMBER_MASK 0x001F /* 5 bits, MSI message number */ +#define ACPI_IVHD_UNIT_ID_MASK 0x1F00 /* 5 bits, unit_iD */ + +/* + * Device Entries for IVHD subtable, appear after struct acpi_ivrs_hardware structure. + * Upper two bits of the Type field are the (encoded) length of the structure. + * Currently, only 4 and 8 byte entries are defined. 16 and 32 byte entries + * are reserved for future use but not defined. + */ +struct acpi_ivrs_de_header { + u8 type; + u16 id; + u8 data_setting; +}; + +/* Length of device entry is in the top two bits of Type field above */ + +#define ACPI_IVHD_ENTRY_LENGTH 0xC0 + +/* Values for device entry Type field above */ + +enum acpi_ivrs_device_entry_type { + /* 4-byte device entries, all use struct acpi_ivrs_device4 */ + + ACPI_IVRS_TYPE_PAD4 = 0, + ACPI_IVRS_TYPE_ALL = 1, + ACPI_IVRS_TYPE_SELECT = 2, + ACPI_IVRS_TYPE_START = 3, + ACPI_IVRS_TYPE_END = 4, + + /* 8-byte device entries */ + + ACPI_IVRS_TYPE_PAD8 = 64, + ACPI_IVRS_TYPE_NOT_USED = 65, + ACPI_IVRS_TYPE_ALIAS_SELECT = 66, /* Uses struct acpi_ivrs_device8a */ + ACPI_IVRS_TYPE_ALIAS_START = 67, /* Uses struct acpi_ivrs_device8a */ + ACPI_IVRS_TYPE_EXT_SELECT = 70, /* Uses struct acpi_ivrs_device8b */ + ACPI_IVRS_TYPE_EXT_START = 71, /* Uses struct acpi_ivrs_device8b */ + ACPI_IVRS_TYPE_SPECIAL = 72 /* Uses struct acpi_ivrs_device8c */ +}; + +/* Values for Data field above */ + +#define ACPI_IVHD_INIT_PASS (1) +#define ACPI_IVHD_EINT_PASS (1<<1) +#define ACPI_IVHD_NMI_PASS (1<<2) +#define ACPI_IVHD_SYSTEM_MGMT (3<<4) +#define ACPI_IVHD_LINT0_PASS (1<<6) +#define ACPI_IVHD_LINT1_PASS (1<<7) + +/* Types 0-4: 4-byte device entry */ + +struct acpi_ivrs_device4 { + struct acpi_ivrs_de_header header; +}; + +/* Types 66-67: 8-byte device entry */ + +struct acpi_ivrs_device8a { + struct acpi_ivrs_de_header header; + u8 reserved1; + u16 used_id; + u8 reserved2; +}; + +/* Types 70-71: 8-byte device entry */ + +struct acpi_ivrs_device8b { + struct acpi_ivrs_de_header header; + u32 extended_data; +}; + +/* Values for extended_data above */ + +#define ACPI_IVHD_ATS_DISABLED (1<<31) + +/* Type 72: 8-byte device entry */ + +struct acpi_ivrs_device8c { + struct acpi_ivrs_de_header header; + u8 handle; + u16 used_id; + u8 variety; +}; + +/* Values for Variety field above */ + +#define ACPI_IVHD_IOAPIC 1 +#define ACPI_IVHD_HPET 2 + +/* 0x20, 0x21, 0x22: I/O Virtualization Memory Definition Block (IVMD) */ + +struct acpi_ivrs_memory { + struct acpi_ivrs_header header; + u16 aux_data; + u64 reserved; + u64 start_address; + u64 memory_length; +}; + /******************************************************************************* * * MCFG - PCI Memory Mapped Configuration table and sub-table + * Version 1 + * + * Conforms to "PCI Firmware Specification", Revision 3.0, June 20, 2005 * ******************************************************************************/ @@ -418,6 +637,10 @@ struct acpi_mcfg_allocation { /******************************************************************************* * * SPCR - Serial Port Console Redirection table + * Version 1 + * + * Conforms to "Serial Port Console Redirection Table", + * Version 1.00, January 11, 2002 * ******************************************************************************/ @@ -445,16 +668,25 @@ struct acpi_table_spcr { u32 reserved2; }; +/* Masks for pci_flags field above */ + +#define ACPI_SPCR_DO_NOT_DISABLE (1) + /******************************************************************************* * * SPMI - Server Platform Management Interface table + * Version 5 + * + * Conforms to "Intelligent Platform Management Interface Specification + * Second Generation v2.0", Document Revision 1.0, February 12, 2004 with + * June 12, 2009 markup. * ******************************************************************************/ struct acpi_table_spmi { struct acpi_table_header header; /* Common ACPI table header */ - u8 reserved; u8 interface_type; + u8 reserved; /* Must be 1 */ u16 spec_revision; /* Version of IPMI */ u8 interrupt_type; u8 gpe_number; /* GPE assigned */ @@ -466,11 +698,27 @@ struct acpi_table_spmi { u8 pci_bus; u8 pci_device; u8 pci_function; + u8 reserved2; +}; + +/* Values for interface_type above */ + +enum acpi_spmi_interface_types { + ACPI_SPMI_NOT_USED = 0, + ACPI_SPMI_KEYBOARD = 1, + ACPI_SPMI_SMI = 2, + ACPI_SPMI_BLOCK_TRANSFER = 3, + ACPI_SPMI_SMBUS = 4, + ACPI_SPMI_RESERVED = 5 /* 5 and above are reserved */ }; /******************************************************************************* * * TCPA - Trusted Computing Platform Alliance table + * Version 1 + * + * Conforms to "TCG PC Specific Implementation Specification", + * Version 1.1, August 18, 2003 * ******************************************************************************/ @@ -484,6 +732,10 @@ struct acpi_table_tcpa { /******************************************************************************* * * UEFI - UEFI Boot optimization Table + * Version 1 + * + * Conforms to "Unified Extensible Firmware Interface Specification", + * Version 2.3, May 8, 2009 * ******************************************************************************/ @@ -491,12 +743,34 @@ struct acpi_table_uefi { struct acpi_table_header header; /* Common ACPI table header */ u8 identifier[16]; /* UUID identifier */ u16 data_offset; /* Offset of remaining data in table */ - u8 data; }; +/******************************************************************************* + * + * WAET - Windows ACPI Emulated devices Table + * Version 1 + * + * Conforms to "Windows ACPI Emulated Devices Table", version 1.0, April 6, 2009 + * + ******************************************************************************/ + +struct acpi_table_waet { + struct acpi_table_header header; /* Common ACPI table header */ + u32 flags; +}; + +/* Masks for Flags field above */ + +#define ACPI_WAET_RTC_NO_ACK (1) /* RTC requires no int acknowledge */ +#define ACPI_WAET_TIMER_ONE_READ (1<<1) /* PM timer requires only one read */ + /******************************************************************************* * * WDAT - Watchdog Action Table + * Version 1 + * + * Conforms to "Hardware Watchdog Timers Design Specification", + * Copyright 2006 Microsoft Corporation. * ******************************************************************************/ @@ -516,10 +790,20 @@ struct acpi_table_wdat { u32 entries; /* Number of watchdog entries that follow */ }; +/* Masks for Flags field above */ + +#define ACPI_WDAT_ENABLED (1) +#define ACPI_WDAT_STOPPED 0x80 + /* WDAT Instruction Entries (actions) */ struct acpi_wdat_entry { - struct acpi_whea_header whea_header; /* Common header for WHEA tables */ + u8 action; + u8 instruction; + u16 reserved; + struct acpi_generic_address register_region; + u32 value; /* Value used with Read/Write register */ + u32 mask; /* Bitmask required for this register instruction */ }; /* Values for Action field above */ @@ -556,28 +840,27 @@ enum acpi_wdat_instructions { /******************************************************************************* * * WDRT - Watchdog Resource Table + * Version 1 + * + * Conforms to "Watchdog Timer Hardware Requirements for Windows Server 2003", + * Version 1.01, August 28, 2006 * ******************************************************************************/ struct acpi_table_wdrt { struct acpi_table_header header; /* Common ACPI table header */ - u32 header_length; /* Watchdog Header Length */ - u8 pci_segment; /* PCI Segment number */ + struct acpi_generic_address control_register; + struct acpi_generic_address count_register; + u16 pci_device_id; + u16 pci_vendor_id; u8 pci_bus; /* PCI Bus number */ u8 pci_device; /* PCI Device number */ u8 pci_function; /* PCI Function number */ - u32 timer_period; /* Period of one timer count (msec) */ - u32 max_count; /* Maximum counter value supported */ - u32 min_count; /* Minimum counter value */ - u8 flags; - u8 reserved[3]; - u32 entries; /* Number of watchdog entries that follow */ + u8 pci_segment; /* PCI Segment number */ + u16 max_count; /* Maximum counter value supported */ + u8 units; }; -/* Flags */ - -#define ACPI_WDRT_TIMER_ENABLED (1) /* 00: Timer enabled */ - /* Reset to default packing */ #pragma pack() From d9adc2e031bd22d5d9607a53a8d3b30e0b675f39 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Mon, 27 Jul 2009 11:31:10 +0800 Subject: [PATCH 21/34] ACPICA: reformat predefined method table, no functional change Reformatted the methods that return package objects. Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acpredef.h | 497 +++++++++++++++++++-------------- 1 file changed, 290 insertions(+), 207 deletions(-) diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index 144b1f41663f..c81f14b69270 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -139,123 +139,180 @@ enum acpi_return_package_types { * is saved here (rather than in a separate table) in order to minimize the * overall size of the stored data. */ -static const union acpi_predefined_info predefined_names[] = { - {.info = {"_AC0", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC1", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC2", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC3", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC4", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC5", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC6", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC7", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC8", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AC9", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_ADR", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_AL0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL3", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL4", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL5", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL6", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL7", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL8", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_AL9", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_ALC", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_ALI", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_ALP", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_ALR", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* variable (Pkgs) each 2 (Ints) */ - {.info = {"_ALT", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_BBN", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_BCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ - {.info = {"_BCM", 1, 0}}, - {.info = {"_BDN", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_BFS", 1, 0}}, - {.info = {"_BIF", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, - 9, - ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER, 4, 0}}, /* fixed (9 Int),(4 Str) */ - {.info = {"_BLT", 3, 0}}, - {.info = {"_BMC", 1, 0}}, - {.info = {"_BMD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* fixed (5 Int) */ - {.info = {"_BQC", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_BST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ - {.info = {"_BTM", 1, ACPI_RTYPE_INTEGER}}, - {.info = {"_BTP", 1, 0}}, - {.info = {"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* see PCI firmware spec 3.0 */ - {.info = {"_CID", 0, - ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, - {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0, 0, 0, 0}}, /* variable (Ints/Strs) */ - {.info = {"_CRS", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_CRT", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_CSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (1 Int(n), n-1 Int) */ - {.info = {"_CST", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_PKG_COUNT, - ACPI_RTYPE_BUFFER, 1, - ACPI_RTYPE_INTEGER, 3, 0}}, /* variable (1 Int(n), n Pkg (1 Buf/3 Int) */ - {.info = {"_DCK", 1, ACPI_RTYPE_INTEGER}}, - {.info = {"_DCS", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, - {.info = {"_DDN", 0, ACPI_RTYPE_STRING}}, - {.info = {"_DGS", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_DIS", 0, 0}}, - {.info = {"_DMA", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_DOD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ - {.info = {"_DOS", 1, 0}}, - {.info = {"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ - {.info = {"_DSS", 1, 0}}, - {.info = {"_DSW", 3, 0}}, - {.info = {"_EC_", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_EDL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_EJ0", 1, 0}}, - {.info = {"_EJ1", 1, 0}}, - {.info = {"_EJ2", 1, 0}}, - {.info = {"_EJ3", 1, 0}}, - {.info = {"_EJ4", 1, 0}}, - {.info = {"_EJD", 0, ACPI_RTYPE_STRING}}, - {.info = {"_FDE", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_FDI", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, 0, 0, 0}}, /* fixed (16 Int) */ - {.info = {"_FDM", 1, 0}}, - {.info = {"_FIX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Ints) */ - {.info = {"_GLK", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_GPD", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ - {.info = {"_GSB", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_GTF", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_GTM", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_GTS", 1, 0}}, - {.info = {"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, - {.info = {"_HOT", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_HPP", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ +static const union acpi_predefined_info predefined_names[] = +{ + {{"_AC0", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC1", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC2", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC3", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC4", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC5", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC6", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC7", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC8", 0, ACPI_RTYPE_INTEGER}}, + {{"_AC9", 0, ACPI_RTYPE_INTEGER}}, + {{"_ADR", 0, ACPI_RTYPE_INTEGER}}, + {{"_AL0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL4", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL5", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL6", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL7", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL8", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_AL9", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_ALC", 0, ACPI_RTYPE_INTEGER}}, + {{"_ALI", 0, ACPI_RTYPE_INTEGER}}, + {{"_ALP", 0, ACPI_RTYPE_INTEGER}}, + {{"_ALR", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2 (Ints) */ + {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, + + {{"_ALT", 0, ACPI_RTYPE_INTEGER}}, + {{"_BBN", 0, ACPI_RTYPE_INTEGER}}, + {{"_BCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + + {{"_BCM", 1, 0}}, + {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, + {{"_BFS", 1, 0}}, + {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, + + {{"_BLT", 3, 0}}, + {{"_BMC", 1, 0}}, + {{"_BMD", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (5 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + + {{"_BQC", 0, ACPI_RTYPE_INTEGER}}, + {{"_BST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, + + {{"_BTM", 1, ACPI_RTYPE_INTEGER}}, + {{"_BTP", 1, 0}}, + {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */ + {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, + + {{"_CRS", 0, ACPI_RTYPE_BUFFER}}, + {{"_CRT", 0, ACPI_RTYPE_INTEGER}}, + {{"_CSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n-1 Int) */ + {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + + {{"_CST", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(n), n Pkg (1 Buf/3 Int) */ + {{{ACPI_PTYPE2_PKG_COUNT,ACPI_RTYPE_BUFFER, 1, ACPI_RTYPE_INTEGER}, 3,0}}, + + {{"_DCK", 1, ACPI_RTYPE_INTEGER}}, + {{"_DCS", 0, ACPI_RTYPE_INTEGER}}, + {{"_DDC", 1, ACPI_RTYPE_INTEGER | ACPI_RTYPE_BUFFER}}, + {{"_DDN", 0, ACPI_RTYPE_STRING}}, + {{"_DGS", 0, ACPI_RTYPE_INTEGER}}, + {{"_DIS", 0, 0}}, + {{"_DMA", 0, ACPI_RTYPE_BUFFER}}, + {{"_DOD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + + {{"_DOS", 1, 0}}, + {{"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ + {{"_DSS", 1, 0}}, + {{"_DSW", 3, 0}}, + {{"_EC_", 0, ACPI_RTYPE_INTEGER}}, + {{"_EDL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs)*/ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_EJ0", 1, 0}}, + {{"_EJ1", 1, 0}}, + {{"_EJ2", 1, 0}}, + {{"_EJ3", 1, 0}}, + {{"_EJ4", 1, 0}}, + {{"_EJD", 0, ACPI_RTYPE_STRING}}, + {{"_FDE", 0, ACPI_RTYPE_BUFFER}}, + {{"_FDI", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, + + {{"_FDM", 1, 0}}, + {{"_FIX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + + {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, + {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, + {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ + {{"_GSB", 0, ACPI_RTYPE_INTEGER}}, + {{"_GTF", 0, ACPI_RTYPE_BUFFER}}, + {{"_GTM", 0, ACPI_RTYPE_BUFFER}}, + {{"_GTS", 1, 0}}, + {{"_HID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, + {{"_HOT", 0, ACPI_RTYPE_INTEGER}}, + {{"_HPP", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, /* - * For _HPX, a single package is returned, containing a variable number of sub-packages. - * Each sub-package contains a PCI record setting. There are several different type of - * record settings, of different lengths, but all elements of all settings are Integers. + * For _HPX, a single package is returned, containing a Variable-length number + * of sub-packages. Each sub-package contains a PCI record setting. + * There are several different type of record settings, of different + * lengths, but all elements of all settings are Integers. */ - {.info = {"_HPX", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each (var Ints) */ - {.info = {"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ - {.info = {"_INI", 0, 0}}, - {.info = {"_IRC", 0, 0}}, - {.info = {"_LCK", 1, 0}}, - {.info = {"_LID", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_MAT", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_MLS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_STRING, 2, 0, 0, 0}}, /* variable (Pkgs) each (2 Str) */ - {.info = {"_MSG", 1, 0}}, - {.info = {"_OFF", 0, 0}}, - {.info = {"_ON_", 0, 0}}, - {.info = {"_OS_", 0, ACPI_RTYPE_STRING}}, - {.info = {"_OSC", 4, ACPI_RTYPE_BUFFER}}, - {.info = {"_OST", 3, 0}}, - {.info = {"_PCL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_PCT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ - {.info = {"_PDC", 1, 0}}, - {.info = {"_PIC", 1, 0}}, - {.info = {"_PLD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0, 0, 0, 0}}, /* variable (Bufs) */ - {.info = {"_PPC", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* see dig64 spec */ - {.info = {"_PR0", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_PR1", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_PR2", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_PRS", 0, ACPI_RTYPE_BUFFER}}, + {{"_HPX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (var Ints) */ + {{{ACPI_PTYPE2_MIN, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + + {{"_IFT", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ + {{"_INI", 0, 0}}, + {{"_IRC", 0, 0}}, + {{"_LCK", 1, 0}}, + {{"_LID", 0, ACPI_RTYPE_INTEGER}}, + {{"_MAT", 0, ACPI_RTYPE_BUFFER}}, + {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */ + {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}}, + + {{"_MSG", 1, 0}}, + {{"_OFF", 0, 0}}, + {{"_ON_", 0, 0}}, + {{"_OS_", 0, ACPI_RTYPE_STRING}}, + {{"_OSC", 4, ACPI_RTYPE_BUFFER}}, + {{"_OST", 3, 0}}, + {{"_PCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PCT", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, + + {{"_PDC", 1, 0}}, + {{"_PIC", 1, 0}}, + {{"_PLD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Bufs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0}, 0,0}}, + + {{"_PPC", 0, ACPI_RTYPE_INTEGER}}, + {{"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* See dig64 spec */ + {{"_PR0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PR1", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PR2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PRS", 0, ACPI_RTYPE_BUFFER}}, /* * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there @@ -263,115 +320,141 @@ static const union acpi_predefined_info predefined_names[] = { * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE * type to the 2nd element (index 1) in the statement below. */ - {.info = {"_PRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_FIXED, 4, - ACPI_RTYPE_INTEGER, - ACPI_RTYPE_INTEGER, - ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, ACPI_RTYPE_INTEGER}}, /* variable (Pkgs) each (4): Int,Int,Int/Ref,Int */ + {{"_PRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */ + {{{ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER,ACPI_RTYPE_INTEGER}, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE,ACPI_RTYPE_INTEGER}}, - {.info = {"_PRW", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_OPTION, 2, - ACPI_RTYPE_INTEGER | - ACPI_RTYPE_PACKAGE, - ACPI_RTYPE_INTEGER, ACPI_RTYPE_REFERENCE, 0}}, /* variable (Pkgs) each: Pkg/Int,Int,[variable Refs] (Pkg is Ref/Int) */ + {{"_PRW", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */ + {{{ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE, + ACPI_RTYPE_INTEGER}, ACPI_RTYPE_REFERENCE,0}}, - {.info = {"_PS0", 0, 0}}, - {.info = {"_PS1", 0, 0}}, - {.info = {"_PS2", 0, 0}}, - {.info = {"_PS3", 0, 0}}, - {.info = {"_PSC", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_PSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 0, 0, 0, 0}}, /* variable (Pkgs) each (5 Int) with count */ - {.info = {"_PSL", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_PSR", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_PSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6, 0, 0, 0}}, /* variable (Pkgs) each (6 Int) */ - {.info = {"_PSV", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_PSW", 1, 0}}, - {.info = {"_PTC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2, 0, 0, 0}}, /* fixed (2 Buf) */ - {.info = {"_PTS", 1, 0}}, - {.info = {"_PXM", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_REG", 2, 0}}, - {.info = {"_REV", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_RMV", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_ROM", 2, ACPI_RTYPE_BUFFER}}, - {.info = {"_RTV", 0, ACPI_RTYPE_INTEGER}}, + {{"_PS0", 0, 0}}, + {{"_PS1", 0, 0}}, + {{"_PS2", 0, 0}}, + {{"_PS3", 0, 0}}, + {{"_PSC", 0, ACPI_RTYPE_INTEGER}}, + {{"_PSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (5 Int) with count */ + {{{ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER,0,0}, 0,0}}, + + {{"_PSL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_PSR", 0, ACPI_RTYPE_INTEGER}}, + {{"_PSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (6 Int) */ + {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 6,0}, 0,0}}, + + {{"_PSV", 0, ACPI_RTYPE_INTEGER}}, + {{"_PSW", 1, 0}}, + {{"_PTC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, + + {{"_PTS", 1, 0}}, + {{"_PXM", 0, ACPI_RTYPE_INTEGER}}, + {{"_REG", 2, 0}}, + {{"_REV", 0, ACPI_RTYPE_INTEGER}}, + {{"_RMV", 0, ACPI_RTYPE_INTEGER}}, + {{"_ROM", 2, ACPI_RTYPE_BUFFER}}, + {{"_RTV", 0, ACPI_RTYPE_INTEGER}}, /* - * For _S0_ through _S5_, the ACPI spec defines a return Package containing 1 Integer, - * but most DSDTs have it wrong - 2,3, or 4 integers. Allow this by making the objects "variable length", - * but all elements must be Integers. + * For _S0_ through _S5_, the ACPI spec defines a return Package + * containing 1 Integer, but most DSDTs have it wrong - 2,3, or 4 integers. + * Allow this by making the objects "Variable-length length", but all elements + * must be Integers. */ - {.info = {"_S0_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ - {.info = {"_S1_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ - {.info = {"_S2_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ - {.info = {"_S3_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ - {.info = {"_S4_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ - {.info = {"_S5_", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1, 0, 0, 0}}, /* fixed (1 Int) */ + {{"_S0_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, - {.info = {"_S1D", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S2D", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S3D", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S4D", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S0W", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S1W", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S2W", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S3W", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_S4W", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_SBS", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ - /* Note: the 3-arg definition may be removed for ACPI 4.0 */ - {.info = {"_SDD", 1, 0}}, - {.info = {"_SEG", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_SLI", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_SPD", 1, ACPI_RTYPE_INTEGER}}, - {.info = {"_SRS", 1, 0}}, - {.info = {"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* see IPMI spec */ - {.info = {"_SST", 1, 0}}, - {.info = {"_STA", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_STM", 3, 0}}, - {.info = {"_STR", 0, ACPI_RTYPE_BUFFER}}, - {.info = {"_SUN", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_SWS", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TC1", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TC2", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TMP", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TPC", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TPT", 1, 0}}, - {.info = {"_TRT", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, - ACPI_RTYPE_INTEGER, 6, 0}}, /* variable (Pkgs) each 2_ref/6_int */ - {.info = {"_TSD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2_COUNT, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int with count */ - {.info = {"_TSP", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TSS", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5, 0, 0, 0}}, /* variable (Pkgs) each 5_int */ - {.info = {"_TST", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_TTS", 1, 0}}, - {.info = {"_TZD", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0, 0, 0}}, /* variable (Refs) */ - {.info = {"_TZM", 0, ACPI_RTYPE_REFERENCE}}, - {.info = {"_TZP", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, - {.info = {"_UPC", 0, ACPI_RTYPE_PACKAGE}}, {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0, 0, 0}}, /* fixed (4 Int) */ - {.info = {"_UPD", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_UPP", 0, ACPI_RTYPE_INTEGER}}, - {.info = {"_VPO", 0, ACPI_RTYPE_INTEGER}}, + {{"_S1_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, + + {{"_S2_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, + + {{"_S3_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, + + {{"_S4_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, + + {{"_S5_", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (1 Int) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 1,0}, 0,0}}, + + {{"_S1D", 0, ACPI_RTYPE_INTEGER}}, + {{"_S2D", 0, ACPI_RTYPE_INTEGER}}, + {{"_S3D", 0, ACPI_RTYPE_INTEGER}}, + {{"_S4D", 0, ACPI_RTYPE_INTEGER}}, + {{"_S0W", 0, ACPI_RTYPE_INTEGER}}, + {{"_S1W", 0, ACPI_RTYPE_INTEGER}}, + {{"_S2W", 0, ACPI_RTYPE_INTEGER}}, + {{"_S3W", 0, ACPI_RTYPE_INTEGER}}, + {{"_S4W", 0, ACPI_RTYPE_INTEGER}}, + {{"_SBS", 0, ACPI_RTYPE_INTEGER}}, + {{"_SCP", 0x13, 0}}, /* Acpi 1.0 allowed 1 arg. Acpi 3.0 expanded to 3 args. Allow both. */ + /* Note: the 3-arg definition may be removed for ACPI 4.0 */ + {{"_SDD", 1, 0}}, + {{"_SEG", 0, ACPI_RTYPE_INTEGER}}, + {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, + {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, + {{"_SRS", 1, 0}}, + {{"_SRV", 0, ACPI_RTYPE_INTEGER}}, /* See IPMI spec */ + {{"_SST", 1, 0}}, + {{"_STA", 0, ACPI_RTYPE_INTEGER}}, + {{"_STM", 3, 0}}, + {{"_STR", 0, ACPI_RTYPE_BUFFER}}, + {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, + {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, + {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, + {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, + {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, + {{"_TPC", 0, ACPI_RTYPE_INTEGER}}, + {{"_TPT", 1, 0}}, + {{"_TRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 2_ref/6_int */ + {{{ACPI_PTYPE2, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, 6, 0}}, + + {{"_TSD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int with count */ + {{{ACPI_PTYPE2_COUNT,ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + + {{"_TSP", 0, ACPI_RTYPE_INTEGER}}, + {{"_TSS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each 5_int */ + {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + + {{"_TST", 0, ACPI_RTYPE_INTEGER}}, + {{"_TTS", 1, 0}}, + {{"_TZD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + + {{"_TZM", 0, ACPI_RTYPE_REFERENCE}}, + {{"_TZP", 0, ACPI_RTYPE_INTEGER}}, + {{"_UID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING}}, + {{"_UPC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, + + {{"_UPD", 0, ACPI_RTYPE_INTEGER}}, + {{"_UPP", 0, ACPI_RTYPE_INTEGER}}, + {{"_VPO", 0, ACPI_RTYPE_INTEGER}}, /* Acpi 1.0 defined _WAK with no return value. Later, it was changed to return a package */ - {.info = {"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, - {.ret_info = {ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0, 0, 0}}, /* fixed (2 Int), but is optional */ - {.ret_info = {0, 0, 0, 0, 0, 0}} /* Table terminator */ + {{"_WAK", 1, ACPI_RTYPE_NONE | ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE}}, + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, /* Fixed-length (2 Int), but is optional */ + + {{{0,0,0,0}, 0,0}} /* Table terminator */ }; #if 0 /* Not implemented */ -{ -"_WDG", 0, ACPI_RTYPE_BUFFER}, /* MS Extension */ + {{"_WDG", 0, ACPI_RTYPE_BUFFER}}, /* MS Extension */ + {{"_WED", 1, ACPI_RTYPE_PACKAGE}}, /* MS Extension */ -{ -"_WED", 1, ACPI_RTYPE_PACKAGE}, /* MS Extension */ + /* This is an internally implemented control method, no need to check */ + {{"_OSI", 1, ACPI_RTYPE_INTEGER}}, - /* This is an internally implemented control method, no need to check */ -{ -"_OSI", 1, ACPI_RTYPE_INTEGER}, + /* TBD: */ - /* TBD: */ - _PRT - currently ignore reversed entries.attempt to fix here ? - think about code that attempts to fix package elements like _BIF, etc. + _PRT - currently ignore reversed entries. attempt to fix here? + think about possibly fixing package elements like _BIF, etc. #endif + #endif From 999e08f99846a1fd6ee9642ec306a2d318925116 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 13 Aug 2009 14:30:16 +0800 Subject: [PATCH 22/34] ACPICA: ACPI 4: Add validation for new predefined names. Added 31 new names for ACPI 4.0. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/acpredef.h | 78 +++++++++++++++++++++++++++++++--- drivers/acpi/acpica/nspredef.c | 2 + 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index c81f14b69270..cd80d1dd1950 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h @@ -64,8 +64,8 @@ * (Used for _PRW) * * - * 2) PTYPE2 packages contain a variable number of sub-packages. Each of the - * different types describe the contents of each of the sub-packages. + * 2) PTYPE2 packages contain a Variable-length number of sub-packages. Each + * of the different types describe the contents of each of the sub-packages. * * ACPI_PTYPE2: Each subpackage contains 1 or 2 object types: * object type @@ -92,6 +92,7 @@ * (Used for _HPX) * * ACPI_PTYPE2_REV_FIXED: Revision at start, each subpackage is Fixed-length + * (Used for _ART, _FPS) * *****************************************************************************/ @@ -107,6 +108,7 @@ enum acpi_return_package_types { ACPI_PTYPE2_REV_FIXED = 9 }; +#ifdef ACPI_CREATE_PREDEFINED_TABLE /* * Predefined method/object information table. * @@ -189,21 +191,32 @@ static const union acpi_predefined_info predefined_names[] = {{{ACPI_PTYPE2, ACPI_RTYPE_INTEGER, 2,0}, 0,0}}, {{"_ALT", 0, ACPI_RTYPE_INTEGER}}, + {{"_ART", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (2 Ref/11 Int) */ + {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_REFERENCE, 2, ACPI_RTYPE_INTEGER}, + 11, 0}}, + {{"_BBN", 0, ACPI_RTYPE_INTEGER}}, {{"_BCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, {{"_BCM", 1, 0}}, + {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, {{"_BFS", 1, 0}}, {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, + {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, + 0}}, + {{"_BLT", 3, 0}}, + {{"_BMA", 1, ACPI_RTYPE_INTEGER}}, {{"_BMC", 1, 0}}, {{"_BMD", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (5 Int) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 5,0}, 0,0}}, + {{"_BMS", 1, ACPI_RTYPE_INTEGER}}, {{"_BQC", 0, ACPI_RTYPE_INTEGER}}, {{"_BST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4,0}, 0,0}}, @@ -211,6 +224,7 @@ static const union acpi_predefined_info predefined_names[] = {{"_BTM", 1, ACPI_RTYPE_INTEGER}}, {{"_BTP", 1, 0}}, {{"_CBA", 0, ACPI_RTYPE_INTEGER}}, /* See PCI firmware spec 3.0 */ + {{"_CDM", 0, ACPI_RTYPE_INTEGER}}, {{"_CID", 0, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING | ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints/Strs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER | ACPI_RTYPE_STRING, 0,0}, 0,0}}, @@ -236,6 +250,7 @@ static const union acpi_predefined_info predefined_names[] = {{"_DSM", 4, ACPI_RTYPE_ALL}}, /* Must return a type, but it can be of any type */ {{"_DSS", 1, 0}}, {{"_DSW", 3, 0}}, + {{"_DTI", 1, 0}}, {{"_EC_", 0, ACPI_RTYPE_INTEGER}}, {{"_EDL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs)*/ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, @@ -251,9 +266,21 @@ static const union acpi_predefined_info predefined_names[] = {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16,0}, 0,0}}, {{"_FDM", 1, 0}}, + {{"_FIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (4 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 4, 0}, 0, 0}}, + {{"_FIX", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Ints) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_INTEGER, 0,0}, 0,0}}, + {{"_FPS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (1 Int(rev), n Pkg (5 Int) */ + {{{ACPI_PTYPE2_REV_FIXED, ACPI_RTYPE_INTEGER, 5, 0}, 0, 0}}, + + {{"_FSL", 1, 0}}, + {{"_FST", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, 0}, 0, 0}}, + + {{"_GAI", 0, ACPI_RTYPE_INTEGER}}, + {{"_GHL", 0, ACPI_RTYPE_INTEGER}}, {{"_GLK", 0, ACPI_RTYPE_INTEGER}}, {{"_GPD", 0, ACPI_RTYPE_INTEGER}}, {{"_GPE", 0, ACPI_RTYPE_INTEGER}}, /* _GPE method, not _GPE scope */ @@ -281,15 +308,21 @@ static const union acpi_predefined_info predefined_names[] = {{"_LCK", 1, 0}}, {{"_LID", 0, ACPI_RTYPE_INTEGER}}, {{"_MAT", 0, ACPI_RTYPE_BUFFER}}, + {{"_MBM", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (8 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 8, 0}, 0, 0}}, + {{"_MLS", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (2 Str) */ {{{ACPI_PTYPE2, ACPI_RTYPE_STRING, 2,0}, 0,0}}, {{"_MSG", 1, 0}}, + {{"_MSM", 4, ACPI_RTYPE_INTEGER}}, + {{"_NTT", 0, ACPI_RTYPE_INTEGER}}, {{"_OFF", 0, 0}}, {{"_ON_", 0, 0}}, {{"_OS_", 0, ACPI_RTYPE_STRING}}, {{"_OSC", 4, ACPI_RTYPE_BUFFER}}, {{"_OST", 3, 0}}, + {{"_PAI", 1, ACPI_RTYPE_INTEGER}}, {{"_PCL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, @@ -297,10 +330,22 @@ static const union acpi_predefined_info predefined_names[] = {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, {{"_PDC", 1, 0}}, + {{"_PDL", 0, ACPI_RTYPE_INTEGER}}, {{"_PIC", 1, 0}}, + {{"_PIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (3 Int),(3 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 3, ACPI_RTYPE_STRING}, 3, 0}}, + {{"_PLD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Bufs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_BUFFER, 0,0}, 0,0}}, + {{"_PMC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (11 Int),(3 Str) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 11, ACPI_RTYPE_STRING}, 3, + 0}}, + + {{"_PMD", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, + + {{"_PMM", 0, ACPI_RTYPE_INTEGER}}, {{"_PPC", 0, ACPI_RTYPE_INTEGER}}, {{"_PPE", 0, ACPI_RTYPE_INTEGER}}, /* See dig64 spec */ {{"_PR0", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ @@ -312,17 +357,26 @@ static const union acpi_predefined_info predefined_names[] = {{"_PR2", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0,0}, 0,0}}, + {{"_PR3", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, + + {{"_PRL", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Refs) */ + {{{ACPI_PTYPE1_VAR, ACPI_RTYPE_REFERENCE, 0, 0}, 0, 0}}, + {{"_PRS", 0, ACPI_RTYPE_BUFFER}}, /* - * For _PRT, many BIOSs reverse the 2nd and 3rd Package elements. This bug is so prevalent that there - * is code in the ACPICA Resource Manager to detect this and switch them back. For now, do not allow - * and issue a warning. To allow this and eliminate the warning, add the ACPI_RTYPE_REFERENCE - * type to the 2nd element (index 1) in the statement below. + * For _PRT, many BIOSs reverse the 3rd and 4th Package elements (Source + * and source_index). This bug is so prevalent that there is code in the + * ACPICA Resource Manager to detect this and switch them back. For now, + * do not allow and issue a warning. To allow this and eliminate the + * warning, add the ACPI_RTYPE_REFERENCE type to the 4th element (index 3) + * in the statement below. */ {{"_PRT", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each (4): Int,Int,Int/Ref,Int */ {{{ACPI_PTYPE2_FIXED, 4, ACPI_RTYPE_INTEGER,ACPI_RTYPE_INTEGER}, - ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE,ACPI_RTYPE_INTEGER}}, + ACPI_RTYPE_INTEGER | ACPI_RTYPE_REFERENCE, + ACPI_RTYPE_INTEGER}}, {{"_PRW", 0, ACPI_RTYPE_PACKAGE}}, /* Variable-length (Pkgs) each: Pkg/Int,Int,[Variable-length Refs] (Pkg is Ref/Int) */ {{{ACPI_PTYPE1_OPTION, 2, ACPI_RTYPE_INTEGER | ACPI_RTYPE_PACKAGE, @@ -348,7 +402,11 @@ static const union acpi_predefined_info predefined_names[] = {{"_PTC", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Buf) */ {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_BUFFER, 2,0}, 0,0}}, + {{"_PTP", 2, ACPI_RTYPE_INTEGER}}, {{"_PTS", 1, 0}}, + {{"_PUR", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (2 Int) */ + {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 2, 0}, 0, 0}}, + {{"_PXM", 0, ACPI_RTYPE_INTEGER}}, {{"_REG", 2, 0}}, {{"_REV", 0, ACPI_RTYPE_INTEGER}}, @@ -394,6 +452,7 @@ static const union acpi_predefined_info predefined_names[] = /* Note: the 3-arg definition may be removed for ACPI 4.0 */ {{"_SDD", 1, 0}}, {{"_SEG", 0, ACPI_RTYPE_INTEGER}}, + {{"_SHL", 1, ACPI_RTYPE_INTEGER}}, {{"_SLI", 0, ACPI_RTYPE_BUFFER}}, {{"_SPD", 1, ACPI_RTYPE_INTEGER}}, {{"_SRS", 1, 0}}, @@ -401,11 +460,15 @@ static const union acpi_predefined_info predefined_names[] = {{"_SST", 1, 0}}, {{"_STA", 0, ACPI_RTYPE_INTEGER}}, {{"_STM", 3, 0}}, + {{"_STP", 2, ACPI_RTYPE_INTEGER}}, {{"_STR", 0, ACPI_RTYPE_BUFFER}}, + {{"_STV", 2, ACPI_RTYPE_INTEGER}}, {{"_SUN", 0, ACPI_RTYPE_INTEGER}}, {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, + {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, + {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, {{"_TPC", 0, ACPI_RTYPE_INTEGER}}, {{"_TPT", 1, 0}}, @@ -458,3 +521,4 @@ static const union acpi_predefined_info predefined_names[] = #endif #endif +#endif diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 0b2cdb37a678..8314e6a9e726 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -42,6 +42,8 @@ * POSSIBILITY OF SUCH DAMAGES. */ +#define ACPI_CREATE_PREDEFINED_TABLE + #include #include "accommon.h" #include "acnamesp.h" From 7f0c826a437157d2b19662977e9cf3b472cf24a6 Mon Sep 17 00:00:00 2001 From: Lin Ming Date: Thu, 13 Aug 2009 14:03:15 +0800 Subject: [PATCH 23/34] ACPICA: Add support for module-level executable AML code Add limited support for executable AML code that exists outside of any control method. This type of code has been illegal since ACPI 2.0. The code must exist in an If/Else/While block. All AML tables are supported, including tables that are dynamically loaded. ACPICA BZ 762. http://acpica.org/bugzilla/show_bug.cgi?id=762 Signed-off-by: Lin Ming Signed-off-by: Bob Moore Signed-off-by: Len Brown --- drivers/acpi/acpica/acglobal.h | 1 + drivers/acpi/acpica/acnamesp.h | 2 + drivers/acpi/acpica/acobject.h | 1 + drivers/acpi/acpica/acparser.h | 2 + drivers/acpi/acpica/dsfield.c | 18 +++-- drivers/acpi/acpica/dsmethod.c | 15 +++- drivers/acpi/acpica/dswload.c | 41 ++-------- drivers/acpi/acpica/exconfig.c | 7 ++ drivers/acpi/acpica/nseval.c | 137 +++++++++++++++++++++++++++++++++ drivers/acpi/acpica/psloop.c | 119 ++++++++++++++++++++++++++-- drivers/acpi/acpica/psxface.c | 4 + drivers/acpi/acpica/utglobal.c | 1 + drivers/acpi/acpica/utxface.c | 10 +++ 13 files changed, 306 insertions(+), 52 deletions(-) diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 6389f7c1de59..29ba66d5a790 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -295,6 +295,7 @@ extern char const *acpi_gbl_exception_names_ctrl[]; ACPI_EXTERN struct acpi_namespace_node acpi_gbl_root_node_struct; ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_root_node; ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_fadt_gpe_device; +ACPI_EXTERN union acpi_operand_object *acpi_gbl_module_code_list; extern const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES]; extern const struct acpi_predefined_names diff --git a/drivers/acpi/acpica/acnamesp.h b/drivers/acpi/acpica/acnamesp.h index f75a7a01b875..09a2764c734b 100644 --- a/drivers/acpi/acpica/acnamesp.h +++ b/drivers/acpi/acpica/acnamesp.h @@ -196,6 +196,8 @@ acpi_ns_dump_objects(acpi_object_type type, */ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info); +void acpi_ns_exec_module_code_list(void); + /* * nspredef - Support for predefined/reserved names */ diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index eb6f038b03d9..b39d682a2140 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -98,6 +98,7 @@ #define AOPOBJ_SETUP_COMPLETE 0x10 #define AOPOBJ_SINGLE_DATUM 0x20 #define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */ +#define AOPOBJ_MODULE_LEVEL 0x80 /****************************************************************************** * diff --git a/drivers/acpi/acpica/acparser.h b/drivers/acpi/acpica/acparser.h index 23ee0fbf5619..22881e8ce229 100644 --- a/drivers/acpi/acpica/acparser.h +++ b/drivers/acpi/acpica/acparser.h @@ -62,6 +62,8 @@ #define ACPI_PARSE_DEFERRED_OP 0x0100 #define ACPI_PARSE_DISASSEMBLE 0x0200 +#define ACPI_PARSE_MODULE_LEVEL 0x0400 + /****************************************************************************** * * Parser interfaces diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index 53e27bc5a734..54a225e56a64 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -123,9 +123,12 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op, flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; - /* Mark node temporary if we are executing a method */ - - if (walk_state->method_node) { + /* + * Mark node temporary if we are executing a normal control + * method. (Don't mark if this is a module-level code method) + */ + if (walk_state->method_node && + !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { flags |= ACPI_NS_TEMPORARY; } @@ -456,9 +459,12 @@ acpi_ds_init_field_objects(union acpi_parse_object *op, flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND; - /* Mark node(s) temporary if we are executing a method */ - - if (walk_state->method_node) { + /* + * Mark node(s) temporary if we are executing a normal control + * method. (Don't mark if this is a module-level code method) + */ + if (walk_state->method_node && + !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) { flags |= ACPI_NS_TEMPORARY; } diff --git a/drivers/acpi/acpica/dsmethod.c b/drivers/acpi/acpica/dsmethod.c index 14b8b8ed8023..567a4899a018 100644 --- a/drivers/acpi/acpica/dsmethod.c +++ b/drivers/acpi/acpica/dsmethod.c @@ -578,10 +578,15 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, } /* - * Delete any namespace objects created anywhere within - * the namespace by the execution of this method + * Delete any namespace objects created anywhere within the + * namespace by the execution of this method. Unless this method + * is a module-level executable code method, in which case we + * want make the objects permanent. */ - acpi_ns_delete_namespace_by_owner(method_desc->method.owner_id); + if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { + acpi_ns_delete_namespace_by_owner(method_desc->method. + owner_id); + } } /* Decrement the thread count on the method */ @@ -622,7 +627,9 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc, /* No more threads, we can free the owner_id */ - acpi_ut_release_owner_id(&method_desc->method.owner_id); + if (!(method_desc->method.flags & AOPOBJ_MODULE_LEVEL)) { + acpi_ut_release_owner_id(&method_desc->method.owner_id); + } } return_VOID; diff --git a/drivers/acpi/acpica/dswload.c b/drivers/acpi/acpica/dswload.c index 3023ceaa8d54..6de3a99d4cd4 100644 --- a/drivers/acpi/acpica/dswload.c +++ b/drivers/acpi/acpica/dswload.c @@ -581,21 +581,6 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) || (!(walk_state->op_info->flags & AML_NAMED))) { -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || - (walk_state->op_info->class == AML_CLASS_CONTROL)) { - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "Begin/EXEC: %s (fl %8.8X)\n", - walk_state->op_info->name, - walk_state->op_info->flags)); - - /* Executing a type1 or type2 opcode outside of a method */ - - status = - acpi_ds_exec_begin_op(walk_state, out_op); - return_ACPI_STATUS(status); - } -#endif return_ACPI_STATUS(AE_OK); } @@ -768,7 +753,13 @@ acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state, /* Execution mode, node cannot already exist, node is temporary */ - flags |= (ACPI_NS_ERROR_IF_FOUND | ACPI_NS_TEMPORARY); + flags |= ACPI_NS_ERROR_IF_FOUND; + + if (! + (walk_state-> + parse_flags & ACPI_PARSE_MODULE_LEVEL)) { + flags |= ACPI_NS_TEMPORARY; + } } /* Add new entry or lookup existing entry */ @@ -851,24 +842,6 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) /* Check if opcode had an associated namespace object */ if (!(walk_state->op_info->flags & AML_NSOBJECT)) { -#ifndef ACPI_NO_METHOD_EXECUTION -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - /* No namespace object. Executable opcode? */ - - if ((walk_state->op_info->class == AML_CLASS_EXECUTE) || - (walk_state->op_info->class == AML_CLASS_CONTROL)) { - ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, - "End/EXEC: %s (fl %8.8X)\n", - walk_state->op_info->name, - walk_state->op_info->flags)); - - /* Executing a type1 or type2 opcode outside of a method */ - - status = acpi_ds_exec_end_op(walk_state); - return_ACPI_STATUS(status); - } -#endif -#endif return_ACPI_STATUS(AE_OK); } diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c index 277fd609611a..24afef81af39 100644 --- a/drivers/acpi/acpica/exconfig.c +++ b/drivers/acpi/acpica/exconfig.c @@ -110,8 +110,15 @@ acpi_ex_add_table(u32 table_index, if (ACPI_FAILURE(status)) { acpi_ut_remove_reference(obj_desc); *ddb_handle = NULL; + return_ACPI_STATUS(status); } + /* Execute any module-level code that was found in the table */ + + acpi_ex_exit_interpreter(); + acpi_ns_exec_module_code_list(); + acpi_ex_enter_interpreter(); + return_ACPI_STATUS(status); } diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c index 8e7dec1176c9..846d1132feb1 100644 --- a/drivers/acpi/acpica/nseval.c +++ b/drivers/acpi/acpica/nseval.c @@ -50,6 +50,11 @@ #define _COMPONENT ACPI_NAMESPACE ACPI_MODULE_NAME("nseval") +/* Local prototypes */ +static void +acpi_ns_exec_module_code(union acpi_operand_object *method_obj, + struct acpi_evaluate_info *info); + /******************************************************************************* * * FUNCTION: acpi_ns_evaluate @@ -76,6 +81,7 @@ ACPI_MODULE_NAME("nseval") * MUTEX: Locks interpreter * ******************************************************************************/ + acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) { acpi_status status; @@ -276,3 +282,134 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info) */ return_ACPI_STATUS(status); } + +/******************************************************************************* + * + * FUNCTION: acpi_ns_exec_module_code_list + * + * PARAMETERS: None + * + * RETURN: None. Exceptions during method execution are ignored, since + * we cannot abort a table load. + * + * DESCRIPTION: Execute all elements of the global module-level code list. + * Each element is executed as a single control method. + * + ******************************************************************************/ + +void acpi_ns_exec_module_code_list(void) +{ + union acpi_operand_object *prev; + union acpi_operand_object *next; + struct acpi_evaluate_info *info; + u32 method_count = 0; + + ACPI_FUNCTION_TRACE(ns_exec_module_code_list); + + /* Exit now if the list is empty */ + + next = acpi_gbl_module_code_list; + if (!next) { + return_VOID; + } + + /* Allocate the evaluation information block */ + + info = ACPI_ALLOCATE(sizeof(struct acpi_evaluate_info)); + if (!info) { + return_VOID; + } + + /* Walk the list, executing each "method" */ + + while (next) { + prev = next; + next = next->method.mutex; + + /* Clear the link field and execute the method */ + + prev->method.mutex = NULL; + acpi_ns_exec_module_code(prev, info); + method_count++; + + /* Delete the (temporary) method object */ + + acpi_ut_remove_reference(prev); + } + + ACPI_INFO((AE_INFO, + "Executed %u blocks of module-level executable AML code", + method_count)); + + ACPI_FREE(info); + acpi_gbl_module_code_list = NULL; + return_VOID; +} + +/******************************************************************************* + * + * FUNCTION: acpi_ns_exec_module_code + * + * PARAMETERS: method_obj - Object container for the module-level code + * Info - Info block for method evaluation + * + * RETURN: None. Exceptions during method execution are ignored, since + * we cannot abort a table load. + * + * DESCRIPTION: Execute a control method containing a block of module-level + * executable AML code. The control method is temporarily + * installed to the root node, then evaluated. + * + ******************************************************************************/ + +static void +acpi_ns_exec_module_code(union acpi_operand_object *method_obj, + struct acpi_evaluate_info *info) +{ + union acpi_operand_object *root_obj; + acpi_status status; + + ACPI_FUNCTION_TRACE(ns_exec_module_code); + + /* Initialize the evaluation information block */ + + ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info)); + info->prefix_node = acpi_gbl_root_node; + + /* + * Get the currently attached root object. Add a reference, because the + * ref count will be decreased when the method object is installed to + * the root node. + */ + root_obj = acpi_ns_get_attached_object(acpi_gbl_root_node); + acpi_ut_add_reference(root_obj); + + /* Install the method (module-level code) in the root node */ + + status = acpi_ns_attach_object(acpi_gbl_root_node, method_obj, + ACPI_TYPE_METHOD); + if (ACPI_FAILURE(status)) { + goto exit; + } + + /* Execute the root node as a control method */ + + status = acpi_ns_evaluate(info); + + ACPI_DEBUG_PRINT((ACPI_DB_INIT, "Executed module-level code at %p\n", + method_obj->method.aml_start)); + + /* Detach the temporary method object */ + + acpi_ns_detach_object(acpi_gbl_root_node); + + /* Restore the original root object */ + + status = + acpi_ns_attach_object(acpi_gbl_root_node, root_obj, + ACPI_TYPE_DEVICE); + + exit: + acpi_ut_remove_reference(root_obj); + return_VOID; +} diff --git a/drivers/acpi/acpica/psloop.c b/drivers/acpi/acpica/psloop.c index c5f6ce19a401..cd7995b3aed4 100644 --- a/drivers/acpi/acpica/psloop.c +++ b/drivers/acpi/acpica/psloop.c @@ -86,6 +86,9 @@ static acpi_status acpi_ps_complete_final_op(struct acpi_walk_state *walk_state, union acpi_parse_object *op, acpi_status status); +static void +acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id); + /******************************************************************************* * * FUNCTION: acpi_ps_get_aml_opcode @@ -390,6 +393,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, { acpi_status status = AE_OK; union acpi_parse_object *arg = NULL; + const struct acpi_opcode_info *op_info; ACPI_FUNCTION_TRACE_PTR(ps_get_arguments, walk_state); @@ -449,13 +453,11 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, INCREMENT_ARG_LIST(walk_state->arg_types); } - /* Special processing for certain opcodes */ - - /* TBD (remove): Temporary mechanism to disable this code if needed */ - -#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE - - if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS1) && + /* + * Handle executable code at "module-level". This refers to + * executable opcodes that appear outside of any control method. + */ + if ((walk_state->pass_number <= ACPI_IMODE_LOAD_PASS2) && ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) == 0)) { /* * We want to skip If/Else/While constructs during Pass1 because we @@ -469,6 +471,23 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, case AML_ELSE_OP: case AML_WHILE_OP: + /* + * Currently supported module-level opcodes are: + * IF/ELSE/WHILE. These appear to be the most common, + * and easiest to support since they open an AML + * package. + */ + if (walk_state->pass_number == + ACPI_IMODE_LOAD_PASS1) { + acpi_ps_link_module_code(aml_op_start, + walk_state-> + parser_state. + pkg_end - + aml_op_start, + walk_state-> + owner_id); + } + ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Pass1: Skipping an If/Else/While body\n")); @@ -480,10 +499,34 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, break; default: + /* + * Check for an unsupported executable opcode at module + * level. We must be in PASS1, the parent must be a SCOPE, + * The opcode class must be EXECUTE, and the opcode must + * not be an argument to another opcode. + */ + if ((walk_state->pass_number == + ACPI_IMODE_LOAD_PASS1) + && (op->common.parent->common.aml_opcode == + AML_SCOPE_OP)) { + op_info = + acpi_ps_get_opcode_info(op->common. + aml_opcode); + if ((op_info->class == + AML_CLASS_EXECUTE) && (!arg)) { + ACPI_WARNING((AE_INFO, + "Detected an unsupported executable opcode " + "at module-level: [0x%.4X] at table offset 0x%.4X", + op->common.aml_opcode, + (u32)((aml_op_start - walk_state->parser_state.aml_start) + + sizeof(struct acpi_table_header)))); + } + } break; } } -#endif + + /* Special processing for certain opcodes */ switch (op->common.aml_opcode) { case AML_METHOD_OP: @@ -551,6 +594,66 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state, return_ACPI_STATUS(AE_OK); } +/******************************************************************************* + * + * FUNCTION: acpi_ps_link_module_code + * + * PARAMETERS: aml_start - Pointer to the AML + * aml_length - Length of executable AML + * owner_id - owner_id of module level code + * + * RETURN: None. + * + * DESCRIPTION: Wrap the module-level code with a method object and link the + * object to the global list. Note, the mutex field of the method + * object is used to link multiple module-level code objects. + * + ******************************************************************************/ + +static void +acpi_ps_link_module_code(u8 *aml_start, u32 aml_length, acpi_owner_id owner_id) +{ + union acpi_operand_object *prev; + union acpi_operand_object *next; + union acpi_operand_object *method_obj; + + /* Get the tail of the list */ + + prev = next = acpi_gbl_module_code_list; + while (next) { + prev = next; + next = next->method.mutex; + } + + /* + * Insert the module level code into the list. Merge it if it is + * adjacent to the previous element. + */ + if (!prev || + ((prev->method.aml_start + prev->method.aml_length) != aml_start)) { + + /* Create, initialize, and link a new temporary method object */ + + method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD); + if (!method_obj) { + return; + } + + method_obj->method.aml_start = aml_start; + method_obj->method.aml_length = aml_length; + method_obj->method.owner_id = owner_id; + method_obj->method.flags |= AOPOBJ_MODULE_LEVEL; + + if (!prev) { + acpi_gbl_module_code_list = method_obj; + } else { + prev->method.mutex = method_obj; + } + } else { + prev->method.aml_length += aml_length; + } +} + /******************************************************************************* * * FUNCTION: acpi_ps_complete_op diff --git a/drivers/acpi/acpica/psxface.c b/drivers/acpi/acpica/psxface.c index ff06032c0f06..dd9731c29a79 100644 --- a/drivers/acpi/acpica/psxface.c +++ b/drivers/acpi/acpica/psxface.c @@ -280,6 +280,10 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info) goto cleanup; } + if (info->obj_desc->method.flags & AOPOBJ_MODULE_LEVEL) { + walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL; + } + /* Invoke an internal method if necessary */ if (info->obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) { diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index 9e33b6261939..3f2c68f4e959 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c @@ -807,6 +807,7 @@ acpi_status acpi_ut_init_globals(void) /* Namespace */ + acpi_gbl_module_code_list = NULL; acpi_gbl_root_node = NULL; acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME; acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED; diff --git a/drivers/acpi/acpica/utxface.c b/drivers/acpi/acpica/utxface.c index 483edbb3f441..b1f5f680bc78 100644 --- a/drivers/acpi/acpica/utxface.c +++ b/drivers/acpi/acpica/utxface.c @@ -250,6 +250,16 @@ acpi_status acpi_initialize_objects(u32 flags) } } + /* + * Execute any module-level code that was detected during the table load + * phase. Although illegal since ACPI 2.0, there are many machines that + * contain this type of code. Each block of detected executable AML code + * outside of any control method is wrapped with a temporary control + * method object and placed on a global list. The methods on this list + * are executed below. + */ + acpi_ns_exec_module_code_list(); + /* * Initialize the objects that remain uninitialized. This runs the * executable AML that may be part of the declaration of these objects: From c276e3884163355464a76e60ed9e272b52b4acc2 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Mon, 27 Jul 2009 14:55:02 +0800 Subject: [PATCH 24/34] ACPICA: Update definitions for HEST table Eliminate duplicated code in disassembler. Shorten identifiers that were too long. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actbl1.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 0417f2abc44b..34b10c06bcfd 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -427,17 +427,17 @@ struct acpi_hest_aer_common { u16 reserved1; u8 flags; u8 enabled; - u32 records_to_pre_allocate; + u32 records_to_preallocate; u32 max_sections_per_record; u32 bus; u16 device; u16 function; u16 device_control; u16 reserved2; - u32 uncorrectable_error_mask; - u32 uncorrectable_error_severity; - u32 correctable_error_mask; - u32 advanced_error_capabilities; + u32 uncorrectable_mask; + u32 uncorrectable_severity; + u32 correctable_mask; + u32 advanced_capabilities; }; /* Masks for HEST Flags fields */ @@ -490,7 +490,7 @@ struct acpi_hest_ia_machine_check { u16 reserved1; u8 flags; u8 enabled; - u32 records_to_pre_allocate; + u32 records_to_preallocate; u32 max_sections_per_record; u64 global_capability_data; u64 global_control_data; @@ -505,7 +505,7 @@ struct acpi_table_hest_ia_corrected { u16 reserved1; u8 flags; u8 enabled; - u32 records_to_pre_allocate; + u32 records_to_preallocate; u32 max_sections_per_record; struct acpi_hest_notify notify; u8 num_hardware_banks; @@ -517,7 +517,7 @@ struct acpi_table_hest_ia_corrected { struct acpi_hest_ia_nmi { struct acpi_hest_header header; u32 reserved; - u32 records_to_pre_allocate; + u32 records_to_preallocate; u32 max_sections_per_record; u32 max_raw_data_length; }; @@ -544,9 +544,9 @@ struct acpi_hest_aer { struct acpi_hest_aer_bridge { struct acpi_hest_header header; struct acpi_hest_aer_common aer; - u32 second_uncorrectable_error_mask; - u32 second_uncorrectable_error_severity; - u32 second_advanced_capabilities; + u32 uncorrectable_mask2; + u32 uncorrectable_severity2; + u32 advanced_capabilities2; }; /* 9: Generic Hardware Error Source */ @@ -556,7 +556,7 @@ struct acpi_hest_generic { u16 related_source_id; u8 reserved; u8 enabled; - u32 records_to_pre_allocate; + u32 records_to_preallocate; u32 max_sections_per_record; u32 max_raw_data_length; struct acpi_generic_address error_status_address; From 1872bbc94b2d092ece22a8fbf1c3e81f0fba0052 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 13 Aug 2009 13:31:00 +0800 Subject: [PATCH 25/34] ACPICA: Fix typo for HEST ACPI table Problem with the name of one of the subtables. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/actbl1.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index 34b10c06bcfd..0b9b430b092b 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -500,7 +500,7 @@ struct acpi_hest_ia_machine_check { /* 1: IA32 Corrected Machine Check */ -struct acpi_table_hest_ia_corrected { +struct acpi_hest_ia_corrected { struct acpi_hest_header header; u16 reserved1; u8 flags; From 8a964236800839263b3dddd7f7851d666e7d53e1 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 13 Aug 2009 13:42:19 +0800 Subject: [PATCH 26/34] ACPICA: acpi_reset: Bypass port validation mechanism Allow writes to reserved ports. This change may eventually be driven down in to acpi_write and acpi_read. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/hwxface.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c index 4ead85f29215..647c7b6e6756 100644 --- a/drivers/acpi/acpica/hwxface.c +++ b/drivers/acpi/acpica/hwxface.c @@ -78,9 +78,22 @@ acpi_status acpi_reset(void) return_ACPI_STATUS(AE_NOT_EXIST); } - /* Write the reset value to the reset register */ + if (reset_reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) { + /* + * For I/O space, write directly to the OSL. This bypasses the port + * validation mechanism, which may block a valid write to the reset + * register. + */ + status = + acpi_os_write_port((acpi_io_address) reset_reg->address, + acpi_gbl_FADT.reset_value, + reset_reg->bit_width); + } else { + /* Write the reset value to the reset register */ + + status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); + } - status = acpi_hw_write(acpi_gbl_FADT.reset_value, reset_reg); return_ACPI_STATUS(status); } From 49ae80c9944401222e47108883c486b5a5a24006 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 13 Aug 2009 13:43:12 +0800 Subject: [PATCH 27/34] ACPICA: Update version to 20090730 Version 20090730. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 063e577e791e..f3b358b7432f 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090625 +#define ACPI_CA_VERSION 0x20090730 #include "actypes.h" #include "actbl.h" From 718fb0de8ff88f71b3b91a8ee8e42e60c88e5128 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 6 Aug 2009 23:18:12 +0000 Subject: [PATCH 28/34] ACPI: fix NULL bug for HID/UID string acpi_device->pnp.hardware_id and unique_id are now allocated pointers, replacing the previous arrays. acpi_device_install_notify_handler() oopsed on the NULL hid when probing the video device, and perhaps other uses are vulnerable too. So initialize those pointers to empty strings when there is no hid or uid. Also, free hardware_id and unique_id when when acpi_device is going to be freed. http://bugzilla.kernel.org/show_bug.cgi?id=14096 Signed-off-by: Hugh Dickins Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/scan.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 9606af13d3b8..dc14421b93f1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -309,6 +309,10 @@ static void acpi_device_release(struct device *dev) struct acpi_device *acpi_dev = to_acpi_device(dev); kfree(acpi_dev->pnp.cid_list); + if (acpi_dev->flags.hardware_id) + kfree(acpi_dev->pnp.hardware_id); + if (acpi_dev->flags.unique_id) + kfree(acpi_dev->pnp.unique_id); kfree(acpi_dev); } @@ -1137,8 +1141,9 @@ static void acpi_device_set_id(struct acpi_device *device, strcpy(device->pnp.hardware_id, hid); device->flags.hardware_id = 1; } - } else - device->pnp.hardware_id = NULL; + } + if (!device->flags.hardware_id) + device->pnp.hardware_id = ""; if (uid) { device->pnp.unique_id = ACPI_ALLOCATE_ZEROED(strlen (uid) + 1); @@ -1146,8 +1151,9 @@ static void acpi_device_set_id(struct acpi_device *device, strcpy(device->pnp.unique_id, uid); device->flags.unique_id = 1; } - } else - device->pnp.unique_id = NULL; + } + if (!device->flags.unique_id) + device->pnp.unique_id = ""; if (cid_list || cid_add) { struct acpica_device_id_list *list; @@ -1362,10 +1368,8 @@ acpi_add_single_object(struct acpi_device **child, end: if (!result) *child = device; - else { - kfree(device->pnp.cid_list); - kfree(device); - } + else + acpi_device_release(&device->dev); return result; } From 307a042416dfc2216251a85b79e8578b65fdc0e7 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 3 Sep 2009 09:55:40 +0800 Subject: [PATCH 29/34] ACPICA: Fix extraneous warning if _DSM returns a package _DSM can return any type of object, so validation on the return type cannot be performed. ACPICA BZ 802. http://www.acpica.org/bugzilla/show_bug.cgi?id=802 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/nspredef.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 8314e6a9e726..f8427afeebdf 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -193,11 +193,15 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, } /* - * We have a return value, but if one wasn't expected, just exit, this is + * 1) We have a return value, but if one wasn't expected, just exit, this is * not a problem. For example, if the "Implicit Return" feature is * enabled, methods will always return a value. + * + * 2) If the return value can be of any type, then we cannot perform any + * validation, exit. */ - if (!predefined->info.expected_btypes) { + if ((!predefined->info.expected_btypes) || + (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { goto cleanup; } From e678902ee899f6b0ab48166b410cdc9f1c27a350 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 3 Sep 2009 09:58:14 +0800 Subject: [PATCH 30/34] ACPICA: Remove error message for Store(Localx,Localx) We silently ignore this construct for Windows compatibility ACPICA BZ 785. http://www.acpica.org/bugzilla/show_bug.cgi?id=785 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/dsmthdat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c index 22b1a3ce2c94..7d077bb2f525 100644 --- a/drivers/acpi/acpica/dsmthdat.c +++ b/drivers/acpi/acpica/dsmthdat.c @@ -433,10 +433,10 @@ acpi_ds_method_data_get_value(u8 type, case ACPI_REFCLASS_LOCAL: - ACPI_ERROR((AE_INFO, - "Uninitialized Local[%d] at node %p", - index, node)); - + /* + * No error message for this case, will be trapped again later to + * detect and ignore cases of Store(local_x,local_x) + */ return_ACPI_STATUS(AE_AML_UNINITIALIZED_LOCAL); default: From e3fe0913b8e732ae636cf23afca76cf2c30718e5 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 3 Sep 2009 10:03:37 +0800 Subject: [PATCH 31/34] ACPICA: Fix memory leak for ill-formed Package objects Fixes a possible memory leak in the interpreter for package objects if the package initializer list is longer than the defined size of the package. This apparently can only happen if the BIOS changes the package size on the fly (seen in a _PSS object), as both iASL and the other compiler do not allow this. The interpreter will truncate the package to the defined size (and issue an error message), but can leave the extra objects undeleted if they have been pre-created during the argument processing (such is the case if the package consists of a number of sub-packages as in the _PSS.) ACPICA BZ 805. http://www.acpica.org/bugzilla/show_bug.cgi?id=805 Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/dsobject.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c index 02e6caad4a76..507e1f0bbdfd 100644 --- a/drivers/acpi/acpica/dsobject.c +++ b/drivers/acpi/acpica/dsobject.c @@ -482,14 +482,27 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, if (arg) { /* * num_elements was exhausted, but there are remaining elements in the - * package_list. + * package_list. Truncate the package to num_elements. * * Note: technically, this is an error, from ACPI spec: "It is an error * for NumElements to be less than the number of elements in the - * PackageList". However, for now, we just print an error message and - * no exception is returned. + * PackageList". However, we just print an error message and + * no exception is returned. This provides Windows compatibility. Some + * BIOSs will alter the num_elements on the fly, creating this type + * of ill-formed package object. */ while (arg) { + /* + * We must delete any package elements that were created earlier + * and are not going to be used because of the package truncation. + */ + if (arg->common.node) { + acpi_ut_remove_reference(ACPI_CAST_PTR + (union + acpi_operand_object, + arg->common.node)); + arg->common.node = NULL; + } /* Find out how many elements there really are */ @@ -498,7 +511,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, } ACPI_WARNING((AE_INFO, - "Package List length (%X) larger than NumElements count (%X), truncated\n", + "Package List length (0x%X) larger than NumElements count (0x%X), truncated\n", i, element_count)); } else if (i < element_count) { /* @@ -506,7 +519,7 @@ acpi_ds_build_internal_package_obj(struct acpi_walk_state *walk_state, * Note: this is not an error, the package is padded out with NULLs. */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, - "Package List length (%X) smaller than NumElements count (%X), padded with null elements\n", + "Package List length (0x%X) smaller than NumElements count (0x%X), padded with null elements\n", i, element_count)); } From eb752552464dbb7a99f8a975ec3b9355893cedd4 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 3 Sep 2009 10:05:08 +0800 Subject: [PATCH 32/34] ACPICA: Update _OSI with new Windows OS strings Added strings for Windows server 2008, Windows Vista SP1, Windows 7, and Windows server 2008 R2. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/aclocal.h | 3 +++ drivers/acpi/acpica/uteval.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index ff6689eba917..81e64f478679 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h @@ -898,6 +898,9 @@ struct acpi_bit_register_info { #define ACPI_OSI_WIN_XP_SP2 0x05 #define ACPI_OSI_WINSRV_2003_SP1 0x06 #define ACPI_OSI_WIN_VISTA 0x07 +#define ACPI_OSI_WINSRV_2008 0x08 +#define ACPI_OSI_WIN_VISTA_SP1 0x09 +#define ACPI_OSI_WIN_7 0x0A #define ACPI_ALWAYS_ILLEGAL 0x00 diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c index 5503307b8bb7..5d54e36ab453 100644 --- a/drivers/acpi/acpica/uteval.c +++ b/drivers/acpi/acpica/uteval.c @@ -69,6 +69,9 @@ static struct acpi_interface_info acpi_interfaces_supported[] = { {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */ {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */ {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */ + {"Windows 2006.1", ACPI_OSI_WINSRV_2008}, /* Windows Server 2008 - Added 09/2009 */ + {"Windows 2006 SP1", ACPI_OSI_WIN_VISTA_SP1}, /* Windows Vista SP1 - Added 09/2009 */ + {"Windows 2009", ACPI_OSI_WIN_7}, /* Windows 7 and Server 2008 R2 - Added 09/2009 */ /* Feature Group Strings */ From 9e64155eb1b6ab78980db58cfd21385fa5f6b024 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Thu, 3 Sep 2009 10:21:03 +0800 Subject: [PATCH 33/34] ACPICA: Windows compatibility: autoexecute root _INI method Add support for execution of an _INI method at the namespace root. Although not defined in the ACPI specification, this support was added to Windows around the Vista timeframe. It is added here for Windows compatibility. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- drivers/acpi/acpica/nsinit.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 2adfcf329e15..1d5b360eb25b 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -170,6 +170,21 @@ acpi_status acpi_ns_initialize_devices(void) goto error_exit; } + /* + * Execute the "global" _INI method that may appear at the root. This + * support is provided for Windows compatibility (Vista+) and is not + * part of the ACPI specification. + */ + info.evaluate_info->prefix_node = acpi_gbl_root_node; + info.evaluate_info->pathname = METHOD_NAME__INI; + info.evaluate_info->parameters = NULL; + info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE; + + status = acpi_ns_evaluate(info.evaluate_info); + if (ACPI_SUCCESS(status)) { + info.num_INI++; + } + /* Walk namespace to execute all _INIs on present devices */ status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, From c9766237afa92e8d7f27bbcd4964f1b43fa0bce8 Mon Sep 17 00:00:00 2001 From: Bob Moore Date: Fri, 4 Sep 2009 08:56:17 +0800 Subject: [PATCH 34/34] ACPICA: Update version to 20090903. Version 20090903. Signed-off-by: Bob Moore Signed-off-by: Lin Ming Signed-off-by: Len Brown --- include/acpi/acpixf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index f3b358b7432f..e723b0fd8e41 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20090730 +#define ACPI_CA_VERSION 0x20090903 #include "actypes.h" #include "actbl.h"