diff options
Diffstat (limited to 'drivers/acpi')
39 files changed, 1175 insertions, 993 deletions
diff --git a/drivers/acpi/acpi_ksyms.c b/drivers/acpi/acpi_ksyms.c index 8e1774c9a99d..e28333d3a200 100644 --- a/drivers/acpi/acpi_ksyms.c +++ b/drivers/acpi/acpi_ksyms.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> diff --git a/drivers/acpi/cmbatt.c b/drivers/acpi/cmbatt.c index d17f87d97685..8d9cb376864c 100644 --- a/drivers/acpi/cmbatt.c +++ b/drivers/acpi/cmbatt.c @@ -24,6 +24,8 @@ * - parse returned data from _BST and _BIF * Andy Grover <andrew.grover@intel.com> 2000-12-8 * - improved proc interface + * Pavel Machek <pavel@suse.cz> 2001-1-31 + * - fixed oops on NULLs in return from _BIF */ #include <linux/kernel.h> @@ -44,6 +46,8 @@ #define MAX_CM_BATTERIES 0x8 #define MAX_BATT_STRLEN 0x20 +#define Xstrncpy(a, b, c) if (b) strncpy(a,b,c); else strncpy(a, "unknown", c) + struct cmbatt_info { u32 power_unit; @@ -163,9 +167,7 @@ acpi_get_battery_info(ACPI_HANDLE handle, struct cmbatt_info *result) result->battery_capacity_granularity_1=objs[7].integer.value; result->battery_capacity_granularity_2=objs[8].integer.value; -#define Xstrncpy(a, b, c) if (b) strncpy(a,b,c); else strncpy(a, "unknown", c); - - /* BUG: trailing NULL issue */ + /* BUG: trailing NULL issue */ Xstrncpy(result->model_number, objs[9].string.pointer, MAX_BATT_STRLEN-1); Xstrncpy(result->serial_number, objs[10].string.pointer, MAX_BATT_STRLEN-1); Xstrncpy(result->battery_type, objs[11].string.pointer, MAX_BATT_STRLEN-1); @@ -248,38 +250,32 @@ proc_read_batt_info(char *page, char **start, off_t off, goto end; } - if (info->last_full_capacity == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Unknown last full capacity\n"); - else - p += sprintf(p, "Last Full Capacity %x %s /hr\n", + if (info->last_full_capacity != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Last Full Capacity: %d %sh\n", info->last_full_capacity, batt_list[batt_num].power_unit); - if (info->design_capacity == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Unknown Design Capacity\n"); - else - p += sprintf(p, "Design Capacity %x %s /hr\n", + if (info->design_capacity != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Design Capacity: %d %sh\n", info->design_capacity, batt_list[batt_num].power_unit); if (info->battery_technology) - p += sprintf(p, "Secondary Battery Technology\n"); + p += sprintf(p, "Battery Technology: Secondary\n"); else - p += sprintf(p, "Primary Battery Technology\n"); + p += sprintf(p, "Battery Technology: Primary\n"); - if (info->design_voltage == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Unknown Design Voltage\n"); - else - p += sprintf(p, "Design Voltage %x mV\n", + if (info->design_voltage != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Design Voltage: %d mV\n", info->design_voltage); - p += sprintf(p, "Design Capacity Warning %d\n", - info->design_capacity_warning); - p += sprintf(p, "Design Capacity Low %d\n", - info->design_capacity_low); - p += sprintf(p, "Battery Capacity Granularity 1 %d\n", + p += sprintf(p, "Design Capacity Warning: %d %sh\n", + info->design_capacity_warning, batt_list[batt_num].power_unit); + p += sprintf(p, "Design Capacity Low: %d %sh\n", + info->design_capacity_low, batt_list[batt_num].power_unit); + p += sprintf(p, "Battery Capacity Granularity 1: %d\n", info->battery_capacity_granularity_1); - p += sprintf(p, "Battery Capacity Granularity 2 %d\n", + p += sprintf(p, "Battery Capacity Granularity 2: %d\n", info->battery_capacity_granularity_2); - p += sprintf(p, "model number %s\nserial number %s\nbattery type %s\nOEM info %s\n", + p += sprintf(p, "Model number; %s\nSerial number: %s\nBattery type: %s\nOEM info: %s\n", info->model_number,info->serial_number, info->battery_type,info->oem_info); end: @@ -310,38 +306,28 @@ proc_read_batt_status(char *page, char **start, off_t off, goto end; } - printk("getting batt status\n"); - if (acpi_get_battery_status(batt_list[batt_num].handle, &status) != AE_OK) { printk(KERN_ERR "Cmbatt: acpi_get_battery_status failed\n"); goto end; } - p += sprintf(p, "Remaining Capacity: %x\n", status.remaining_capacity); - - if (status.state & 0x1) - p += sprintf(p, "Battery discharging\n"); - if (status.state & 0x2) - p += sprintf(p, "Battery charging\n"); - if (status.state & 0x4) - p += sprintf(p, "Battery critically low\n"); + p += sprintf(p, "Battery discharging: %s\n", + (status.state & 0x1)?"yes":"no"); + p += sprintf(p, "Battery charging: %s\n", + (status.state & 0x2)?"yes":"no"); + p += sprintf(p, "Battery critically low: %s\n", + (status.state & 0x4)?"yes":"no"); - if (status.present_rate == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Battery rate unknown\n"); - else - p += sprintf(p, "Battery rate %x\n", - status.present_rate); + if (status.present_rate != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery rate: %d %s\n", + status.present_rate, batt_list[batt_num].power_unit); - if (status.remaining_capacity == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Battery capacity unknown\n"); - else - p += sprintf(p, "Battery capacity %x %s\n", + if (status.remaining_capacity != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery capacity: %d %sh\n", status.remaining_capacity, batt_list[batt_num].power_unit); - if (status.present_voltage == ACPI_BATT_UNKNOWN) - p += sprintf(p, "Battery voltage unknown\n"); - else - p += sprintf(p, "Battery voltage %x volts\n", + if (status.present_voltage != ACPI_BATT_UNKNOWN) + p += sprintf(p, "Battery voltage: %d mV\n", status.present_voltage); end: diff --git a/drivers/acpi/common/cmcopy.c b/drivers/acpi/common/cmcopy.c index da3851c17828..3f1a7b36cd15 100644 --- a/drivers/acpi/common/cmcopy.c +++ b/drivers/acpi/common/cmcopy.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmcopy - Internal to external object translation utilities - * $Revision: 62 $ + * $Revision: 66 $ * *****************************************************************************/ @@ -27,51 +27,39 @@ #include "acpi.h" #include "acinterp.h" #include "acnamesp.h" +#include "amlcode.h" #define _COMPONENT MISCELLANEOUS MODULE_NAME ("cmcopy") -typedef struct search_st -{ - ACPI_OPERAND_OBJECT *internal_obj; - u32 index; - ACPI_OBJECT *external_obj; - -} PKG_SEARCH_INFO; - - -/* Used to traverse nested packages */ - -PKG_SEARCH_INFO level[MAX_PACKAGE_DEPTH]; - -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_external_simple_object + * FUNCTION: Acpi_cm_copy_isimple_to_esimple * - * PARAMETERS: *Internal_obj - Pointer to the object we are examining - * *Buffer - Where the object is returned - * *Space_used - Where the data length is returned + * PARAMETERS: *Internal_object - Pointer to the object we are examining + * *Buffer - Where the object is returned + * *Space_used - Where the data length is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to place a simple object in a user - * buffer. + * buffer. * * The buffer is assumed to have sufficient space for the object. * ******************************************************************************/ static ACPI_STATUS -acpi_cm_build_external_simple_object ( - ACPI_OPERAND_OBJECT *internal_obj, - ACPI_OBJECT *external_obj, +acpi_cm_copy_isimple_to_esimple ( + ACPI_OPERAND_OBJECT *internal_object, + ACPI_OBJECT *external_object, u8 *data_space, u32 *buffer_space_used) { u32 length = 0; - u8 *source_ptr = NULL; + ACPI_STATUS status = AE_OK; /* @@ -79,116 +67,221 @@ acpi_cm_build_external_simple_object ( * package element */ - if (!internal_obj) { + if (!internal_object) { *buffer_space_used = 0; return (AE_OK); } /* Always clear the external object */ - MEMSET (external_obj, 0, sizeof (ACPI_OBJECT)); + MEMSET (external_object, 0, sizeof (ACPI_OBJECT)); /* * In general, the external object will be the same type as * the internal object */ - external_obj->type = internal_obj->common.type; + external_object->type = internal_object->common.type; /* However, only a limited number of external types are supported */ - switch (external_obj->type) + switch (internal_object->common.type) { case ACPI_TYPE_STRING: - length = internal_obj->string.length + 1; - external_obj->string.length = internal_obj->string.length; - external_obj->string.pointer = (NATIVE_CHAR *) data_space; - source_ptr = (u8 *) internal_obj->string.pointer; + length = internal_object->string.length + 1; + external_object->string.length = internal_object->string.length; + external_object->string.pointer = (NATIVE_CHAR *) data_space; + MEMCPY ((void *) data_space, (void *) internal_object->string.pointer, length); break; case ACPI_TYPE_BUFFER: - length = internal_obj->buffer.length; - external_obj->buffer.length = internal_obj->buffer.length; - external_obj->buffer.pointer = data_space; - source_ptr = (u8 *) internal_obj->buffer.pointer; + length = internal_object->buffer.length; + external_object->buffer.length = internal_object->buffer.length; + external_object->buffer.pointer = data_space; + MEMCPY ((void *) data_space, (void *) internal_object->buffer.pointer, length); break; case ACPI_TYPE_INTEGER: - external_obj->integer.value= internal_obj->integer.value; + external_object->integer.value= internal_object->integer.value; break; case INTERNAL_TYPE_REFERENCE: /* - * This is an object reference. We use the object type of "Any" - * to indicate a reference object containing a handle to an ACPI - * named object. + * This is an object reference. Attempt to dereference it. */ - external_obj->type = ACPI_TYPE_ANY; - external_obj->reference.handle = internal_obj->reference.node; + switch (internal_object->reference.op_code) + { + case AML_ZERO_OP: + external_object->type = ACPI_TYPE_INTEGER; + external_object->integer.value = 0; + break; + + case AML_ONE_OP: + external_object->type = ACPI_TYPE_INTEGER; + external_object->integer.value = 1; + break; + + case AML_ONES_OP: + external_object->type = ACPI_TYPE_INTEGER; + external_object->integer.value = ACPI_INTEGER_MAX; + break; + + case AML_NAMEPATH_OP: + /* + * This is a named reference, get the string. We already know that + * we have room for it, use max length + */ + length = MAX_STRING_LENGTH; + external_object->type = ACPI_TYPE_STRING; + external_object->string.pointer = (NATIVE_CHAR *) data_space; + status = acpi_ns_handle_to_pathname ((ACPI_HANDLE *) internal_object->reference.node, + &length, (char *) data_space); + break; + + default: + /* + * Use the object type of "Any" to indicate a reference + * to object containing a handle to an ACPI named object. + */ + external_object->type = ACPI_TYPE_ANY; + external_object->reference.handle = internal_object->reference.node; + break; + } break; case ACPI_TYPE_PROCESSOR: - external_obj->processor.proc_id = - internal_obj->processor.proc_id; - - external_obj->processor.pblk_address = - internal_obj->processor.address; - - external_obj->processor.pblk_length = - internal_obj->processor.length; + external_object->processor.proc_id = internal_object->processor.proc_id; + external_object->processor.pblk_address = internal_object->processor.address; + external_object->processor.pblk_length = internal_object->processor.length; break; + case ACPI_TYPE_POWER: - external_obj->power_resource.system_level = - internal_obj->power_resource.system_level; + external_object->power_resource.system_level = + internal_object->power_resource.system_level; - external_obj->power_resource.resource_order = - internal_obj->power_resource.resource_order; + external_object->power_resource.resource_order = + internal_object->power_resource.resource_order; break; + default: - return (AE_CTRL_RETURN_VALUE); + /* + * There is no corresponding external object type + */ + return (AE_SUPPORT); break; } - /* Copy data if necessary (strings or buffers) */ + *buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length); + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_cm_copy_ielement_to_eelement + * + * PARAMETERS: ACPI_PKG_CALLBACK + * + * RETURN: Status + * + * DESCRIPTION: Copy one package element to another package element + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_copy_ielement_to_eelement ( + u8 object_type, + ACPI_OPERAND_OBJECT *source_object, + ACPI_GENERIC_STATE *state, + void *context) +{ + ACPI_STATUS status = AE_OK; + ACPI_PKG_INFO *info = (ACPI_PKG_INFO *) context; + u32 object_space; + u32 this_index; + ACPI_OBJECT *target_object; + + + this_index = state->pkg.index; + target_object = (ACPI_OBJECT *) + &((ACPI_OBJECT *)(state->pkg.dest_object))->package.elements[this_index]; + + + switch (object_type) + { + case 0: + + /* + * This is a simple or null object -- get the size + */ + + status = acpi_cm_copy_isimple_to_esimple (source_object, + target_object, info->free_space, &object_space); + if (ACPI_FAILURE (status)) { + return (status); + } + + break; + + case 1: - if (length) { /* - * Copy the return data to the caller's buffer + * Build the package object */ - MEMCPY ((void *) data_space, (void *) source_ptr, length); + target_object->type = ACPI_TYPE_PACKAGE; + target_object->package.count = source_object->package.count; + target_object->package.elements = (ACPI_OBJECT *) info->free_space; + + /* + * Pass the new package object back to the package walk routine + */ + state->pkg.this_target_obj = target_object; + + /* + * Save space for the array of objects (Package elements) + * update the buffer length counter + */ + object_space = (u32) ROUND_UP_TO_NATIVE_WORD ( + target_object->package.count * sizeof (ACPI_OBJECT)); + break; + + default: + return (AE_BAD_PARAMETER); } - *buffer_space_used = (u32) ROUND_UP_TO_NATIVE_WORD (length); + info->free_space += object_space; + info->length += object_space; - return (AE_OK); + return (status); } -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_external_package_object + * FUNCTION: Acpi_cm_copy_ipackage_to_epackage * - * PARAMETERS: *Internal_obj - Pointer to the object we are returning - * *Buffer - Where the object is returned - * *Space_used - Where the object length is returned + * PARAMETERS: *Internal_object - Pointer to the object we are returning + * *Buffer - Where the object is returned + * *Space_used - Where the object length is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to place a package object in a user * buffer. A package object by definition contains other objects. @@ -200,49 +293,33 @@ acpi_cm_build_external_simple_object ( ******************************************************************************/ static ACPI_STATUS -acpi_cm_build_external_package_object ( - ACPI_OPERAND_OBJECT *internal_obj, +acpi_cm_copy_ipackage_to_epackage ( + ACPI_OPERAND_OBJECT *internal_object, u8 *buffer, u32 *space_used) { - u8 *free_space; - ACPI_OBJECT *external_obj; - u32 current_depth = 0; + ACPI_OBJECT *external_object; ACPI_STATUS status; - u32 length = 0; - u32 this_index; - u32 object_space; - ACPI_OPERAND_OBJECT *this_internal_obj; - ACPI_OBJECT *this_external_obj; - PKG_SEARCH_INFO *level_ptr; + ACPI_PKG_INFO info; /* * First package at head of the buffer */ - external_obj = (ACPI_OBJECT *) buffer; + external_object = (ACPI_OBJECT *) buffer; /* * Free space begins right after the first package */ - free_space = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); + info.length = 0; + info.object_space = 0; + info.num_packages = 1; + info.free_space = buffer + ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); - /* - * Initialize the working variables - */ - - MEMSET ((void *) level, 0, sizeof (level)); - - level[0].internal_obj = internal_obj; - level[0].external_obj = external_obj; - level[0].index = 0; - level_ptr = &level[0]; - current_depth = 0; - - external_obj->type = internal_obj->common.type; - external_obj->package.count = internal_obj->package.count; - external_obj->package.elements = (ACPI_OBJECT *) free_space; + external_object->type = internal_object->common.type; + external_object->package.count = internal_object->package.count; + external_object->package.elements = (ACPI_OBJECT *) info.free_space; /* @@ -250,136 +327,27 @@ acpi_cm_build_external_package_object ( * and move the free space past it */ - free_space += external_obj->package.count * + info.free_space += external_object->package.count * ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)); - while (1) { - this_index = level_ptr->index; - this_internal_obj = - (ACPI_OPERAND_OBJECT *) - level_ptr->internal_obj->package.elements[this_index]; - this_external_obj = - (ACPI_OBJECT *) - &level_ptr->external_obj->package.elements[this_index]; - - - /* - * Check for - * 1) Null object -- OK, this can happen if package - * element is never initialized - * 2) Not an internal object - can be Node instead - * 3) Any internal object other than a package. - * - * The more complex package case is handled later - */ - - if ((!this_internal_obj) || - (!VALID_DESCRIPTOR_TYPE ( - this_internal_obj, ACPI_DESC_TYPE_INTERNAL)) || - (!IS_THIS_OBJECT_TYPE ( - this_internal_obj, ACPI_TYPE_PACKAGE))) - { - /* - * This is a simple or null object -- get the size - */ - - status = - acpi_cm_build_external_simple_object (this_internal_obj, - this_external_obj, - free_space, - &object_space); - if (ACPI_FAILURE (status)) { - return (status); - } - - free_space += object_space; - length += object_space; - - level_ptr->index++; - while (level_ptr->index >= - level_ptr->internal_obj->package.count) - { - /* - * We've handled all of the objects at this - * level. This means that we have just - * completed a package. That package may - * have contained one or more packages - * itself - */ - if (current_depth == 0) { - /* - * We have handled all of the objects - * in the top level package just add - * the length of the package objects - * and get out - */ - *space_used = length; - return (AE_OK); - } - - /* - * go back up a level and move the index - * past the just completed package object. - */ - current_depth--; - level_ptr = &level[current_depth]; - level_ptr->index++; - } - } - + status = acpi_cm_walk_package_tree (internal_object, external_object, + acpi_cm_copy_ielement_to_eelement, &info); - else { - /* - * This object is a package - * -- we must go one level deeper - */ - if (current_depth >= MAX_PACKAGE_DEPTH-1) { - /* - * Too many nested levels of packages - * for us to handle - */ - return (AE_LIMIT); - } + *space_used = info.length; - /* - * Build the package object - */ - this_external_obj->type = ACPI_TYPE_PACKAGE; - this_external_obj->package.count = - this_internal_obj->package.count; - this_external_obj->package.elements = - (ACPI_OBJECT *) free_space; + return (status); - /* - * Save space for the array of objects (Package elements) - * update the buffer length counter - */ - object_space = (u32) ROUND_UP_TO_NATIVE_WORD ( - this_external_obj->package.count * - sizeof (ACPI_OBJECT)); - - free_space += object_space; - length += object_space; - - current_depth++; - level_ptr = &level[current_depth]; - level_ptr->internal_obj = this_internal_obj; - level_ptr->external_obj = this_external_obj; - level_ptr->index = 0; - } - } } - -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_external_object + * FUNCTION: Acpi_cm_copy_iobject_to_eobject * - * PARAMETERS: *Internal_obj - The internal object to be converted - * *Buffer_ptr - Where the object is returned + * PARAMETERS: *Internal_object - The internal object to be converted + * *Buffer_ptr - Where the object is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to build an API object to be returned to * the caller. @@ -387,35 +355,31 @@ acpi_cm_build_external_package_object ( ******************************************************************************/ ACPI_STATUS -acpi_cm_build_external_object ( - ACPI_OPERAND_OBJECT *internal_obj, +acpi_cm_copy_iobject_to_eobject ( + ACPI_OPERAND_OBJECT *internal_object, ACPI_BUFFER *ret_buffer) { ACPI_STATUS status; - if (IS_THIS_OBJECT_TYPE (internal_obj, ACPI_TYPE_PACKAGE)) { + if (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE)) { /* - * Package objects contain other objects (which can be objects) - * buildpackage does it all + * Package object: Copy all subobjects (including + * nested packages) */ - status = - acpi_cm_build_external_package_object (internal_obj, - ret_buffer->pointer, - &ret_buffer->length); + status = acpi_cm_copy_ipackage_to_epackage (internal_object, + ret_buffer->pointer, &ret_buffer->length); } else { /* * Build a simple object (no nested objects) */ - status = - acpi_cm_build_external_simple_object (internal_obj, - (ACPI_OBJECT *) ret_buffer->pointer, - ((u8 *) ret_buffer->pointer + - ROUND_UP_TO_NATIVE_WORD ( - sizeof (ACPI_OBJECT))), - &ret_buffer->length); + status = acpi_cm_copy_isimple_to_esimple (internal_object, + (ACPI_OBJECT *) ret_buffer->pointer, + ((u8 *) ret_buffer->pointer + + ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT))), + &ret_buffer->length); /* * build simple does not include the object size in the length * so we add it in here @@ -427,14 +391,14 @@ acpi_cm_build_external_object ( } -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_internal_simple_object + * FUNCTION: Acpi_cm_copy_esimple_to_isimple * - * PARAMETERS: *External_obj - The external object to be converted - * *Internal_obj - Where the internal object is returned + * PARAMETERS: *External_object - The external object to be converted + * *Internal_object - Where the internal object is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function copies an external object to an internal one. * NOTE: Pointers can be copied, we don't need to copy data. @@ -444,28 +408,28 @@ acpi_cm_build_external_object ( ******************************************************************************/ ACPI_STATUS -acpi_cm_build_internal_simple_object ( - ACPI_OBJECT *external_obj, - ACPI_OPERAND_OBJECT *internal_obj) +acpi_cm_copy_esimple_to_isimple ( + ACPI_OBJECT *external_object, + ACPI_OPERAND_OBJECT *internal_object) { - internal_obj->common.type = (u8) external_obj->type; + internal_object->common.type = (u8) external_object->type; - switch (external_obj->type) + switch (external_object->type) { case ACPI_TYPE_STRING: - internal_obj->string.length = external_obj->string.length; - internal_obj->string.pointer = external_obj->string.pointer; + internal_object->string.length = external_object->string.length; + internal_object->string.pointer = external_object->string.pointer; break; case ACPI_TYPE_BUFFER: - internal_obj->buffer.length = external_obj->buffer.length; - internal_obj->buffer.pointer = external_obj->buffer.pointer; + internal_object->buffer.length = external_object->buffer.length; + internal_object->buffer.pointer = external_object->buffer.pointer; break; @@ -473,7 +437,7 @@ acpi_cm_build_internal_simple_object ( /* * Number is included in the object itself */ - internal_obj->integer.value = external_obj->integer.value; + internal_object->integer.value = external_object->integer.value; break; @@ -491,11 +455,11 @@ acpi_cm_build_internal_simple_object ( /* Code to convert packages that are parameters to control methods */ -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_internal_package_object + * FUNCTION: Acpi_cm_copy_epackage_to_ipackage * - * PARAMETERS: *Internal_obj - Pointer to the object we are returning + * PARAMETERS: *Internal_object - Pointer to the object we are returning * *Buffer - Where the object is returned * *Space_used - Where the length of the object is returned * @@ -511,26 +475,24 @@ acpi_cm_build_internal_simple_object ( ******************************************************************************/ static ACPI_STATUS -acpi_cm_build_internal_package_object ( - ACPI_OPERAND_OBJECT *internal_obj, +acpi_cm_copy_epackage_to_ipackage ( + ACPI_OPERAND_OBJECT *internal_object, u8 *buffer, u32 *space_used) { u8 *free_space; - ACPI_OBJECT *external_obj; - u32 current_depth = 0; + ACPI_OBJECT *external_object; u32 length = 0; u32 this_index; u32 object_space = 0; ACPI_OPERAND_OBJECT *this_internal_obj; ACPI_OBJECT *this_external_obj; - PKG_SEARCH_INFO *level_ptr; /* * First package at head of the buffer */ - external_obj = (ACPI_OBJECT *)buffer; + external_object = (ACPI_OBJECT *)buffer; /* * Free space begins right after the first package @@ -538,20 +500,9 @@ acpi_cm_build_internal_package_object ( free_space = buffer + sizeof(ACPI_OBJECT); - /* - * Initialize the working variables - */ - - MEMSET ((void *) level, 0, sizeof(level)); - - level[0].internal_obj = internal_obj; - level[0].external_obj = external_obj; - level_ptr = &level[0]; - current_depth = 0; - - external_obj->type = internal_obj->common.type; - external_obj->package.count = internal_obj->package.count; - external_obj->package.elements = (ACPI_OBJECT *)free_space; + external_object->type = internal_object->common.type; + external_object->package.count = internal_object->package.count; + external_object->package.elements = (ACPI_OBJECT *)free_space; /* @@ -559,100 +510,21 @@ acpi_cm_build_internal_package_object ( * and move the free space past it */ - free_space += external_obj->package.count * sizeof(ACPI_OBJECT); - - - while (1) { - this_index = level_ptr->index; + free_space += external_object->package.count * sizeof(ACPI_OBJECT); - this_internal_obj = (ACPI_OPERAND_OBJECT *) - &level_ptr->internal_obj->package.elements[this_index]; - - this_external_obj = (ACPI_OBJECT *) - &level_ptr->external_obj->package.elements[this_index]; - - if (IS_THIS_OBJECT_TYPE (this_internal_obj, ACPI_TYPE_PACKAGE)) { - /* - * If this object is a package then we go one deeper - */ - if (current_depth >= MAX_PACKAGE_DEPTH-1) { - /* - * Too many nested levels of packages for us to handle - */ - return (AE_LIMIT); - } - /* - * Build the package object - */ - this_external_obj->type = ACPI_TYPE_PACKAGE; - this_external_obj->package.count = this_internal_obj->package.count; - this_external_obj->package.elements = (ACPI_OBJECT *) free_space; + /* Call Walk_package */ - /* - * Save space for the array of objects (Package elements) - * update the buffer length counter - */ - object_space = this_external_obj->package.count * - sizeof (ACPI_OBJECT); - - free_space += object_space; - length += object_space; - - current_depth++; - level_ptr = &level[current_depth]; - level_ptr->internal_obj = this_internal_obj; - level_ptr->external_obj = this_external_obj; - level_ptr->index = 0; - - } /* if object is a package */ - - else { - free_space += object_space; - length += object_space; - - level_ptr->index++; - while (level_ptr->index >= - level_ptr->internal_obj->package.count) - { - /* - * We've handled all of the objects at - * this level, This means that we have - * just completed a package. That package - * may have contained one or more packages - * itself - */ - if (current_depth == 0) { - /* - * We have handled all of the objects - * in the top level package just add - * the length of the package objects - * and get out - */ - *space_used = length; - return (AE_OK); - } - - /* - * go back up a level and move the index - * past the just completed package object. - */ - current_depth--; - level_ptr = &level[current_depth]; - level_ptr->index++; - } - } /* else object is NOT a package */ - } /* while (1) */ } #endif /* Future implementation */ -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_build_internal_object + * FUNCTION: Acpi_cm_copy_eobject_to_iobject * - * PARAMETERS: *Internal_obj - The external object to be converted + * PARAMETERS: *Internal_object - The external object to be converted * *Buffer_ptr - Where the internal object is returned * * RETURN: Status - the status of the call @@ -662,14 +534,14 @@ acpi_cm_build_internal_package_object ( ******************************************************************************/ ACPI_STATUS -acpi_cm_build_internal_object ( - ACPI_OBJECT *external_obj, - ACPI_OPERAND_OBJECT *internal_obj) +acpi_cm_copy_eobject_to_iobject ( + ACPI_OBJECT *external_object, + ACPI_OPERAND_OBJECT *internal_object) { ACPI_STATUS status; - if (external_obj->type == ACPI_TYPE_PACKAGE) { + if (external_object->type == ACPI_TYPE_PACKAGE) { /* * Package objects contain other objects (which can be objects) * buildpackage does it all @@ -679,7 +551,7 @@ acpi_cm_build_internal_object ( * control methods only. This is a very, very rare case. */ /* - Status = Acpi_cm_build_internal_package_object(Internal_obj, + Status = Acpi_cm_copy_epackage_to_ipackage(Internal_object, Ret_buffer->Pointer, &Ret_buffer->Length); */ @@ -690,7 +562,7 @@ acpi_cm_build_internal_object ( /* * Build a simple object (no nested objects) */ - status = acpi_cm_build_internal_simple_object (external_obj, internal_obj); + status = acpi_cm_copy_esimple_to_isimple (external_object, internal_object); /* * build simple does not include the object size in the length * so we add it in here @@ -700,3 +572,137 @@ acpi_cm_build_internal_object ( return (status); } + +/******************************************************************************* + * + * FUNCTION: Acpi_cm_copy_ielement_to_ielement + * + * PARAMETERS: ACPI_PKG_CALLBACK + * + * RETURN: Status - the status of the call + * + * DESCRIPTION: Copy one package element to another package element + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_copy_ielement_to_ielement ( + u8 object_type, + ACPI_OPERAND_OBJECT *source_object, + ACPI_GENERIC_STATE *state, + void *context) +{ + ACPI_STATUS status = AE_OK; + u32 this_index; + ACPI_OPERAND_OBJECT **this_target_ptr; + ACPI_OPERAND_OBJECT *target_object; + + + this_index = state->pkg.index; + this_target_ptr = (ACPI_OPERAND_OBJECT **) + &state->pkg.dest_object->package.elements[this_index]; + + switch (object_type) + { + case 0: + + /* + * This is a simple object, just copy it + */ + target_object = acpi_cm_create_internal_object (source_object->common.type); + if (!target_object) { + return (AE_NO_MEMORY); + } + + status = acpi_aml_store_object_to_object (source_object, target_object, + (ACPI_WALK_STATE *) context); + if (ACPI_FAILURE (status)) { + return (status); + } + + *this_target_ptr = target_object; + break; + + + case 1: + /* + * This object is a package - go down another nesting level + * Create and build the package object + */ + target_object = acpi_cm_create_internal_object (ACPI_TYPE_PACKAGE); + if (!target_object) { + /* TBD: must delete package created up to this point */ + + return (AE_NO_MEMORY); + } + + target_object->package.count = source_object->package.count; + + /* + * Pass the new package object back to the package walk routine + */ + state->pkg.this_target_obj = target_object; + + /* + * Store the object pointer in the parent package object + */ + *this_target_ptr = target_object; + break; + + default: + return (AE_BAD_PARAMETER); + } + + + return (status); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_cm_copy_ipackage_to_ipackage + * + * PARAMETERS: *Source_obj - Pointer to the source package object + * *Dest_obj - Where the internal object is returned + * + * RETURN: Status - the status of the call + * + * DESCRIPTION: This function is called to copy an internal package object + * into another internal package object. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_copy_ipackage_to_ipackage ( + ACPI_OPERAND_OBJECT *source_obj, + ACPI_OPERAND_OBJECT *dest_obj, + ACPI_WALK_STATE *walk_state) +{ + ACPI_STATUS status = AE_OK; + + + dest_obj->common.type = source_obj->common.type; + dest_obj->package.count = source_obj->package.count; + + + /* + * Create the object array and walk the source package tree + */ + + dest_obj->package.elements = acpi_cm_callocate ((source_obj->package.count + 1) * + sizeof (void *)); + dest_obj->package.next_element = dest_obj->package.elements; + + if (!dest_obj->package.elements) { + REPORT_ERROR ( + ("Aml_build_copy_internal_package_object: Package allocation failure\n")); + return (AE_NO_MEMORY); + } + + + status = acpi_cm_walk_package_tree (source_obj, dest_obj, + acpi_cm_copy_ielement_to_ielement, walk_state); + + return (status); +} + diff --git a/drivers/acpi/common/cmobject.c b/drivers/acpi/common/cmobject.c index 5f73abaafcad..9c23eff7f689 100644 --- a/drivers/acpi/common/cmobject.c +++ b/drivers/acpi/common/cmobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmobject - ACPI object create/delete/size/cache routines - * $Revision: 35 $ + * $Revision: 36 $ * *****************************************************************************/ @@ -35,7 +35,7 @@ MODULE_NAME ("cmobject") -/****************************************************************************** +/******************************************************************************* * * FUNCTION: _Cm_create_internal_object * @@ -49,11 +49,11 @@ * * DESCRIPTION: Create and initialize a new internal object. * - * NOTE: - * We always allocate the worst-case object descriptor because these - * objects are cached, and we want them to be one-size-satisifies-any-request. - * This in itself may not be the most memory efficient, but the efficiency - * of the object cache should more than make up for this! + * NOTE: We always allocate the worst-case object descriptor because + * these objects are cached, and we want them to be + * one-size-satisifies-any-request. This in itself may not be + * the most memory efficient, but the efficiency of the object + * cache should more than make up for this! * ******************************************************************************/ @@ -91,7 +91,7 @@ _cm_create_internal_object ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_valid_internal_object * @@ -99,7 +99,7 @@ _cm_create_internal_object ( * * RETURN: Validate a pointer to be an ACPI_OPERAND_OBJECT * - *****************************************************************************/ + ******************************************************************************/ u8 acpi_cm_valid_internal_object ( @@ -136,7 +136,7 @@ acpi_cm_valid_internal_object ( } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: _Cm_allocate_object_desc * @@ -150,7 +150,7 @@ acpi_cm_valid_internal_object ( * DESCRIPTION: Allocate a new object descriptor. Gracefully handle * error conditions. * - ****************************************************************************/ + ******************************************************************************/ void * _cm_allocate_object_desc ( @@ -211,7 +211,7 @@ _cm_allocate_object_desc ( } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_object_desc * @@ -221,7 +221,7 @@ _cm_allocate_object_desc ( * * DESCRIPTION: Free an ACPI object descriptor or add it to the object cache * - ****************************************************************************/ + ******************************************************************************/ void acpi_cm_delete_object_desc ( @@ -274,7 +274,7 @@ acpi_cm_delete_object_desc ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_delete_object_cache * @@ -317,7 +317,7 @@ acpi_cm_delete_object_cache ( } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_init_static_object * @@ -329,7 +329,7 @@ acpi_cm_delete_object_cache ( * DESCRIPTION: Initialize a static object. Sets flags to disallow dynamic * deletion of the object. * - ****************************************************************************/ + ******************************************************************************/ void acpi_cm_init_static_object ( @@ -365,14 +365,14 @@ acpi_cm_init_static_object ( } -/****************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_cm_get_simple_object_size * - * PARAMETERS: *Internal_obj - Pointer to the object we are examining - * *Ret_length - Where the length is returned + * PARAMETERS: *Internal_object - Pointer to the object we are examining + * *Ret_length - Where the length is returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to determine the space required to * contain a simple object for return to an API user. @@ -384,7 +384,7 @@ acpi_cm_init_static_object ( ACPI_STATUS acpi_cm_get_simple_object_size ( - ACPI_OPERAND_OBJECT *internal_obj, + ACPI_OPERAND_OBJECT *internal_object, u32 *obj_length) { u32 length; @@ -393,7 +393,7 @@ acpi_cm_get_simple_object_size ( /* Handle a null object (Could be a uninitialized package element -- which is legal) */ - if (!internal_obj) { + if (!internal_object) { *obj_length = 0; return (AE_OK); } @@ -403,7 +403,7 @@ acpi_cm_get_simple_object_size ( length = sizeof (ACPI_OBJECT); - if (VALID_DESCRIPTOR_TYPE (internal_obj, ACPI_DESC_TYPE_NAMED)) { + if (VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_NAMED)) { /* Object is a named object (reference), just return the length */ *obj_length = (u32) ROUND_UP_TO_NATIVE_WORD (length); @@ -419,18 +419,18 @@ acpi_cm_get_simple_object_size ( * TBD:[Investigate] do strings and buffers require alignment also? */ - switch (internal_obj->common.type) + switch (internal_object->common.type) { case ACPI_TYPE_STRING: - length += internal_obj->string.length + 1; + length += internal_object->string.length + 1; break; case ACPI_TYPE_BUFFER: - length += internal_obj->buffer.length; + length += internal_object->buffer.length; break; @@ -450,7 +450,7 @@ acpi_cm_get_simple_object_size ( * The only type that should be here is opcode AML_NAMEPATH_OP -- since * this means an object reference */ - if (internal_obj->reference.op_code != AML_NAMEPATH_OP) { + if (internal_object->reference.op_code != AML_NAMEPATH_OP) { status = AE_TYPE; } break; @@ -475,149 +475,119 @@ acpi_cm_get_simple_object_size ( } -/****************************************************************************** +/******************************************************************************* * - * FUNCTION: Acpi_cm_get_package_object_size + * FUNCTION: Acpi_cm_copy_package_to_internal * - * PARAMETERS: *Internal_obj - Pointer to the object we are examining - * *Ret_length - Where the length is returned + * PARAMETERS: ACPI_PKG_CALLBACK * * RETURN: Status - the status of the call * - * DESCRIPTION: This function is called to determine the space required to contain - * a package object for return to an API user. - * - * This is moderately complex since a package contains other objects - * including packages. + * DESCRIPTION: * ******************************************************************************/ ACPI_STATUS -acpi_cm_get_package_object_size ( - ACPI_OPERAND_OBJECT *internal_obj, - u32 *obj_length) +acpi_cm_get_element_length ( + u8 object_type, + ACPI_OPERAND_OBJECT *source_object, + ACPI_GENERIC_STATE *state, + void *context) { - - ACPI_OPERAND_OBJECT *this_internal_obj; - ACPI_OPERAND_OBJECT *parent_obj[MAX_PACKAGE_DEPTH]; - ACPI_OPERAND_OBJECT *this_parent; - u32 this_index; - u32 index[MAX_PACKAGE_DEPTH]; - u32 length = 0; + ACPI_STATUS status = AE_OK; + ACPI_PKG_INFO *info = (ACPI_PKG_INFO *) context; u32 object_space; - u32 current_depth = 0; - u32 package_count = 1; - ACPI_STATUS status; - /* Init the package stack TBD: replace with linked list */ - - MEMSET(parent_obj, 0, MAX_PACKAGE_DEPTH); - MEMSET(index, 0, MAX_PACKAGE_DEPTH); + switch (object_type) + { + case 0: - parent_obj[0] = internal_obj; + /* + * Simple object - just get the size (Null object/entry is handled + * here also) and sum it into the running package length + */ + status = acpi_cm_get_simple_object_size (source_object, &object_space); + if (ACPI_FAILURE (status)) { + return (status); + } - while (1) { - this_parent = parent_obj[current_depth]; - this_index = index[current_depth]; - this_internal_obj = this_parent->package.elements[this_index]; + info->length += object_space; + break; - /* - * Check for 1) An uninitialized package element. It is completely - * legal to declare a package and leave it uninitialized - * 2) Any type other than a package. Packages are handled - * below. - */ + case 1: + /* Package - nothing much to do here, let the walk handle it */ - if ((!this_internal_obj) || - (!IS_THIS_OBJECT_TYPE (this_internal_obj, ACPI_TYPE_PACKAGE))) - { - /* - * Simple object - just get the size (Null object/entry handled - * also) - */ - - status = - acpi_cm_get_simple_object_size (this_internal_obj, &object_space); - - if (ACPI_FAILURE (status)) { - return (status); - } - - length += object_space; - - index[current_depth]++; - while (index[current_depth] >= - parent_obj[current_depth]->package.count) - { - /* - * We've handled all of the objects at - * this level, This means that we have - * just completed a package. That package - * may have contained one or more packages - * itself. - */ - if (current_depth == 0) { - /* - * We have handled all of the objects - * in the top level package just add the - * length of the package objects and - * get out. Round up to the next machine - * word. - */ - length += - ROUND_UP_TO_NATIVE_WORD ( - sizeof (ACPI_OBJECT)) * - package_count; - - *obj_length = length; - - return (AE_OK); - } - - /* - * Go back up a level and move the index - * past the just completed package object. - */ - current_depth--; - index[current_depth]++; - } - } + info->num_packages++; + state->pkg.this_target_obj = NULL; + break; - else { - /* - * This object is a package - * -- go one level deeper - */ - package_count++; - if (current_depth < MAX_PACKAGE_DEPTH-1) { - current_depth++; - parent_obj[current_depth] = this_internal_obj; - index[current_depth] = 0; - } - - else { - /* - * Too many nested levels of packages for us - * to handle - */ - - return (AE_LIMIT); - } - } + default: + return (AE_BAD_PARAMETER); } + + + return (status); } -/****************************************************************************** +/******************************************************************************* + * + * FUNCTION: Acpi_cm_get_package_object_size + * + * PARAMETERS: *Internal_object - Pointer to the object we are examining + * *Ret_length - Where the length is returned + * + * RETURN: Status + * + * DESCRIPTION: This function is called to determine the space required to + * contain a package object for return to an API user. + * + * This is moderately complex since a package contains other + * objects including packages. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_get_package_object_size ( + ACPI_OPERAND_OBJECT *internal_object, + u32 *obj_length) +{ + ACPI_STATUS status; + ACPI_PKG_INFO info; + + + info.length = 0; + info.object_space = 0; + info.num_packages = 1; + + status = acpi_cm_walk_package_tree (internal_object, NULL, + acpi_cm_get_element_length, &info); + + /* + * We have handled all of the objects in all levels of the package. + * just add the length of the package objects themselves. + * Round up to the next machine word. + */ + info.length += ROUND_UP_TO_NATIVE_WORD (sizeof (ACPI_OBJECT)) * + info.num_packages; + + /* Return the total package length */ + + *obj_length = info.length; + return (status); +} + + +/******************************************************************************* * * FUNCTION: Acpi_cm_get_object_size * - * PARAMETERS: *Internal_obj - Pointer to the object we are examining - * *Ret_length - Where the length will be returned + * PARAMETERS: *Internal_object - Pointer to the object we are examining + * *Ret_length - Where the length will be returned * - * RETURN: Status - the status of the call + * RETURN: Status * * DESCRIPTION: This function is called to determine the space required to * contain an object for return to an API user. @@ -626,22 +596,20 @@ acpi_cm_get_package_object_size ( ACPI_STATUS acpi_cm_get_object_size( - ACPI_OPERAND_OBJECT *internal_obj, + ACPI_OPERAND_OBJECT *internal_object, u32 *obj_length) { ACPI_STATUS status; - if ((VALID_DESCRIPTOR_TYPE (internal_obj, ACPI_DESC_TYPE_INTERNAL)) && - (IS_THIS_OBJECT_TYPE (internal_obj, ACPI_TYPE_PACKAGE))) + if ((VALID_DESCRIPTOR_TYPE (internal_object, ACPI_DESC_TYPE_INTERNAL)) && + (IS_THIS_OBJECT_TYPE (internal_object, ACPI_TYPE_PACKAGE))) { - status = - acpi_cm_get_package_object_size (internal_obj, obj_length); + status = acpi_cm_get_package_object_size (internal_object, obj_length); } else { - status = - acpi_cm_get_simple_object_size (internal_obj, obj_length); + status = acpi_cm_get_simple_object_size (internal_object, obj_length); } return (status); diff --git a/drivers/acpi/common/cmutils.c b/drivers/acpi/common/cmutils.c index b0ee8b4d9d00..2bbce16a299b 100644 --- a/drivers/acpi/common/cmutils.c +++ b/drivers/acpi/common/cmutils.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: cmutils - common utility procedures - * $Revision: 23 $ + * $Revision: 27 $ * ******************************************************************************/ @@ -340,6 +340,41 @@ acpi_cm_create_update_state_and_push ( /******************************************************************************* * + * FUNCTION: Acpi_cm_create_pkg_state_and_push + * + * PARAMETERS: *Object - Object to be added to the new state + * Action - Increment/Decrement + * State_list - List the state will be added to + * + * RETURN: None + * + * DESCRIPTION: Create a new state and push it + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_create_pkg_state_and_push ( + void *internal_object, + void *external_object, + u16 index, + ACPI_GENERIC_STATE **state_list) +{ + ACPI_GENERIC_STATE *state; + + + state = acpi_cm_create_pkg_state (internal_object, external_object, index); + if (!state) { + return (AE_NO_MEMORY); + } + + + acpi_cm_push_generic_state (state_list, state); + return (AE_OK); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_cm_push_generic_state * * PARAMETERS: List_head - Head of the state stack @@ -500,6 +535,49 @@ acpi_cm_create_update_state ( /******************************************************************************* * + * FUNCTION: Acpi_cm_create_pkg_state + * + * PARAMETERS: Object - Initial Object to be installed in the + * state + * Action - Update action to be performed + * + * RETURN: Status + * + * DESCRIPTION: Create an "Update State" - a flavor of the generic state used + * to update reference counts and delete complex objects such + * as packages. + * + ******************************************************************************/ + +ACPI_GENERIC_STATE * +acpi_cm_create_pkg_state ( + void *internal_object, + void *external_object, + u16 index) +{ + ACPI_GENERIC_STATE *state; + + + /* Create the generic state object */ + + state = acpi_cm_create_generic_state (); + if (!state) { + return (NULL); + } + + /* Init fields specific to the update struct */ + + state->pkg.source_object = (ACPI_OPERAND_OBJECT *) internal_object; + state->pkg.dest_object = external_object; + state->pkg.index = index; + state->pkg.num_packages = 1; + + return (state); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_cm_create_control_state * * PARAMETERS: None @@ -632,16 +710,20 @@ ACPI_STATUS acpi_cm_resolve_package_references ( ACPI_OPERAND_OBJECT *obj_desc) { - u32 count; - ACPI_OPERAND_OBJECT *sub_object; + u32 count; + ACPI_OPERAND_OBJECT *sub_object; + if (obj_desc->common.type != ACPI_TYPE_PACKAGE) { - /* Must be a package */ + /* The object must be a package */ REPORT_ERROR (("Must resolve Package Refs on a Package\n")); return(AE_ERROR); } + /* + * TBD: what about nested packages? */ + for (count = 0; count < obj_desc->package.count; count++) { sub_object = obj_desc->package.elements[count]; @@ -667,6 +749,130 @@ acpi_cm_resolve_package_references ( /******************************************************************************* * + * FUNCTION: Acpi_cm_walk_package_tree + * + * PARAMETERS: Obj_desc - The Package object on which to resolve refs + * + * RETURN: Status + * + * DESCRIPTION: Walk through a package + * + ******************************************************************************/ + +ACPI_STATUS +acpi_cm_walk_package_tree ( + ACPI_OPERAND_OBJECT *source_object, + void *target_object, + ACPI_PKG_CALLBACK walk_callback, + void *context) +{ + ACPI_STATUS status = AE_OK; + ACPI_GENERIC_STATE *state_list = NULL; + ACPI_GENERIC_STATE *state; + u32 this_index; + ACPI_OPERAND_OBJECT *this_source_obj; + + + state = acpi_cm_create_pkg_state (source_object, target_object, 0); + if (!state) { + return (AE_NO_MEMORY); + } + + while (state) { + this_index = state->pkg.index; + this_source_obj = (ACPI_OPERAND_OBJECT *) + state->pkg.source_object->package.elements[this_index]; + + /* + * Check for + * 1) An uninitialized package element. It is completely + * legal to declare a package and leave it uninitialized + * 2) Not an internal object - can be a namespace node instead + * 3) Any type other than a package. Packages are handled in else case below. + */ + if ((!this_source_obj) || + (!VALID_DESCRIPTOR_TYPE ( + this_source_obj, ACPI_DESC_TYPE_INTERNAL)) || + (!IS_THIS_OBJECT_TYPE ( + this_source_obj, ACPI_TYPE_PACKAGE))) + { + + status = walk_callback (0, this_source_obj, state, context); + if (ACPI_FAILURE (status)) { + /* TBD: must delete package created up to this point */ + + return (status); + } + + state->pkg.index++; + while (state->pkg.index >= state->pkg.source_object->package.count) { + /* + * We've handled all of the objects at this level, This means + * that we have just completed a package. That package may + * have contained one or more packages itself. + * + * Delete this state and pop the previous state (package). + */ + acpi_cm_delete_generic_state (state); + state = acpi_cm_pop_generic_state (&state_list); + + + /* Finished when there are no more states */ + + if (!state) { + /* + * We have handled all of the objects in the top level + * package just add the length of the package objects + * and exit + */ + return (AE_OK); + } + + /* + * Go back up a level and move the index past the just + * completed package object. + */ + state->pkg.index++; + } + } + + else { + /* This is a sub-object of type package */ + + status = walk_callback (1, this_source_obj, state, context); + if (ACPI_FAILURE (status)) { + /* TBD: must delete package created up to this point */ + + return (status); + } + + + /* + * The callback above returned a new target package object. + */ + + /* + * Push the current state and create a new one + */ + acpi_cm_push_generic_state (&state_list, state); + state = acpi_cm_create_pkg_state (this_source_obj, state->pkg.this_target_obj, 0); + if (!state) { + /* TBD: must delete package created up to this point */ + + return (AE_NO_MEMORY); + } + } + } + + /* We should never get here */ + + return (AE_AML_INTERNAL); + +} + + +/******************************************************************************* + * * FUNCTION: _Report_error * * PARAMETERS: Module_name - Caller's module name (for error output) @@ -676,7 +882,7 @@ acpi_cm_resolve_package_references ( * * RETURN: None * - * DESCRIPTION: Print error message from KD table + * DESCRIPTION: Print error message * ******************************************************************************/ @@ -703,7 +909,7 @@ _report_error ( * * RETURN: None * - * DESCRIPTION: Print warning message from KD table + * DESCRIPTION: Print warning message * ******************************************************************************/ @@ -729,7 +935,7 @@ _report_warning ( * * RETURN: None * - * DESCRIPTION: Print information message from KD table + * DESCRIPTION: Print information message * ******************************************************************************/ diff --git a/drivers/acpi/common/cmxface.c b/drivers/acpi/common/cmxface.c index ce87b50d273d..e566b7f21dfe 100644 --- a/drivers/acpi/common/cmxface.c +++ b/drivers/acpi/common/cmxface.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: cmxface - External interfaces for "global" ACPI functions - * $Revision: 62 $ + * $Revision: 64 $ * *****************************************************************************/ @@ -158,8 +158,7 @@ acpi_enable_subsystem ( if (!(flags & ACPI_NO_ACPI_ENABLE)) { status = acpi_enable (); if (ACPI_FAILURE (status)) { - /* TBD: workaround. Old Lions don't enable properly */ - /*return (Status);*/ + return (status); } } @@ -180,12 +179,11 @@ acpi_enable_subsystem ( /* * Initialize all device objects in the namespace - * This runs the _STA, _INI, and _HID methods, and detects - * the PCI root bus(es) + * This runs the _STA and _INI methods. */ if (!(flags & ACPI_NO_DEVICE_INIT)) { - status = acpi_ns_initialize_devices (flags & ACPI_NO_PCI_INIT); + status = acpi_ns_initialize_devices (); if (ACPI_FAILURE (status)) { return (status); } @@ -193,7 +191,7 @@ acpi_enable_subsystem ( /* - * Initialize the objects that remain unitialized. This + * Initialize the objects that remain uninitialized. This * runs the executable AML that is part of the declaration of Op_regions * and Fields. */ diff --git a/drivers/acpi/cpu.c b/drivers/acpi/cpu.c index 3e4adcee2b79..9f27080bb860 100644 --- a/drivers/acpi/cpu.c +++ b/drivers/acpi/cpu.c @@ -2,6 +2,7 @@ * cpu.c - Processor handling * * Copyright (C) 2000 Andrew Henroid + * Copyright (C) 2001 Andrew Grover * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,27 +29,37 @@ #define _COMPONENT OS_DEPENDENT MODULE_NAME ("cpu") -unsigned long acpi_c2_exit_latency = ACPI_INFINITE; -unsigned long acpi_c3_exit_latency = ACPI_INFINITE; -unsigned long acpi_c2_enter_latency = ACPI_INFINITE; -unsigned long acpi_c3_enter_latency = ACPI_INFINITE; +u32 acpi_c2_exit_latency = ACPI_INFINITE; +u32 acpi_c3_exit_latency = ACPI_INFINITE; +u32 acpi_c2_enter_latency = ACPI_INFINITE; +u32 acpi_c3_enter_latency = ACPI_INFINITE; +u32 acpi_use_idle = TRUE; -static unsigned long acpi_pblk = ACPI_INVALID; +u32 acpi_c1_count = 0; +u32 acpi_c2_count = 0; +u32 acpi_c3_count = 0; + +static u32 acpi_pblk = ACPI_INVALID; static int acpi_c2_tested = 0; static int acpi_c3_tested = 0; static int acpi_max_c_state = 1; -static int acpi_pm_tmr_len; +static int acpi_pm_tmr_len = 24; +#define CPU_POWER_STATES 3 #define MAX_C2_LATENCY 100 #define MAX_C3_LATENCY 1000 +#define ACPI_STATE_C1 0 +#define ACPI_STATE_C2 1 +#define ACPI_STATE_C3 2 + /* * Clear busmaster activity flag */ static inline void acpi_clear_bm_activity(void) { - acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 0); + acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, BM_STS, 1); } /* @@ -100,6 +111,7 @@ acpi_compare_pm_timers(u32 first, u32 second) } } + /* * Idle loop (uniprocessor only) */ @@ -109,14 +121,9 @@ acpi_idle(void) static int sleep_level = 1; FADT_DESCRIPTOR *fadt = &acpi_fadt; - if (!fadt - || (STRNCMP(fadt->header.signature, ACPI_FADT_SIGNATURE, ACPI_SIG_LEN) != 0) - || !fadt->Xpm_tmr_blk.address - || !acpi_pblk) - goto not_initialized; - /* - * start from the previous sleep level.. + * start from the previous sleep level. + * if not initialized, we goto sleep1 */ if (sleep_level == 1 || acpi_max_c_state < 2) @@ -126,7 +133,7 @@ acpi_idle(void) || acpi_max_c_state < 3) goto sleep2; - sleep3: +sleep3: sleep_level = 3; if (!acpi_c3_tested) { DEBUG_PRINT(ACPI_INFO, ("C3 works\n")); @@ -147,6 +154,7 @@ acpi_idle(void) goto sleep2; time = acpi_read_pm_timer(); + acpi_c3_count++; inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ acpi_read_pm_timer(); @@ -154,10 +162,10 @@ acpi_idle(void) __sti(); if (diff < acpi_c3_exit_latency) - goto sleep2; + goto sleep1; } - sleep3_with_arbiter: +sleep3_with_arbiter: for (;;) { unsigned long time; unsigned long diff; @@ -172,6 +180,7 @@ acpi_idle(void) /* Disable arbiter, park on CPU */ acpi_hw_register_bit_access(ACPI_WRITE, ACPI_MTX_LOCK, ARB_DIS, 1); + acpi_c3_count++; inb(acpi_pblk + ACPI_P_LVL3); /* Dummy read, force synchronization with the PMU */ acpi_read_pm_timer(); @@ -181,10 +190,10 @@ acpi_idle(void) __sti(); if (diff < acpi_c3_exit_latency) - goto sleep2; + goto sleep1; } - sleep2: +sleep2: sleep_level = 2; if (!acpi_c2_tested) { DEBUG_PRINT(ACPI_INFO, ("C2 works\n")); @@ -200,6 +209,7 @@ acpi_idle(void) goto out; time = acpi_read_pm_timer(); + acpi_c2_count++; inb(acpi_pblk + ACPI_P_LVL2); /* Dummy read, force synchronization with the PMU */ acpi_read_pm_timer(); @@ -217,7 +227,7 @@ acpi_idle(void) goto sleep3; } - sleep1: +sleep1: sleep_level = 1; acpi_sleep_on_busmaster(); for (;;) { @@ -228,6 +238,7 @@ acpi_idle(void) if (current->need_resched) goto out; time = acpi_read_pm_timer(); + acpi_c1_count++; safe_halt(); diff = acpi_compare_pm_timers(time, acpi_read_pm_timer()); if (diff > acpi_c2_enter_latency @@ -235,15 +246,7 @@ acpi_idle(void) goto sleep2; } - not_initialized: - for (;;) { - __cli(); - if (current->need_resched) - goto out; - safe_halt(); - } - - out: +out: __sti(); } @@ -278,17 +281,17 @@ acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) acpi_c2_exit_latency = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat); acpi_c2_enter_latency - = ACPI_MICROSEC_TO_TMR_TICKS(ACPI_TMR_HZ / 1000); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl2_lat * 4); acpi_max_c_state = 2; printk(KERN_INFO "ACPI: System firmware supports: C2"); - + if (acpi_fadt.plvl3_lat && acpi_fadt.plvl3_lat <= MAX_C3_LATENCY) { acpi_c3_exit_latency = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat); acpi_c3_enter_latency - = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 5); + = ACPI_MICROSEC_TO_TMR_TICKS(acpi_fadt.plvl3_lat * 12); acpi_max_c_state = 3; printk(" C3"); @@ -297,6 +300,10 @@ acpi_found_cpu(ACPI_HANDLE handle, u32 level, void *ctx, void **value) printk("\n"); } + printk(KERN_INFO "ACPI: plvl2lat=%d plvl3lat=%d\n", acpi_fadt.plvl2_lat, acpi_fadt.plvl3_lat); + printk(KERN_INFO "ACPI: C2 enter=%d C2 exit=%d\n", acpi_c2_enter_latency, acpi_c2_exit_latency); + printk(KERN_INFO "ACPI: C3 enter=%d C3 exit=%d\n", acpi_c3_enter_latency, acpi_c3_exit_latency); + return AE_OK; } @@ -328,13 +335,19 @@ acpi_cpu_init(void) acpi_pm_timer_init(); - + if (acpi_use_idle) { #ifdef CONFIG_SMP - if (smp_num_cpus == 1) - pm_idle = acpi_idle; + if (smp_num_cpus == 1) + pm_idle = acpi_idle; #else - pm_idle = acpi_idle; + pm_idle = acpi_idle; #endif + printk(KERN_INFO "ACPI: Using ACPI idle\n"); + printk(KERN_INFO "ACPI: If experiencing system slowness, try adding \"acpi=no-idle\" to cmdline\n"); + } + else { + printk(KERN_INFO "ACPI: Not using ACPI idle\n"); + } return 0; } diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 0a6c88b4d5fa..a3e0d7a4f4eb 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 56 $ + * $Revision: 57 $ * *****************************************************************************/ @@ -102,6 +102,7 @@ acpi_ds_init_one_object ( info->method_count++; + /* * Set the execution data width (32 or 64) based upon the * revision number of the parent ACPI table. diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index ba06cf4dba4e..12f8f34364ee 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -2,7 +2,7 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 30 $ + * $Revision: 32 $ * *****************************************************************************/ @@ -73,7 +73,6 @@ acpi_ds_get_field_unit_arguments ( extra_desc = obj_desc->field_unit.extra; node = obj_desc->field_unit.node; - /* * Allocate a new parser op to be the root of the parsed * Op_region tree diff --git a/drivers/acpi/driver.c b/drivers/acpi/driver.c index 241528fc6cb9..8863e468833f 100644 --- a/drivers/acpi/driver.c +++ b/drivers/acpi/driver.c @@ -60,6 +60,8 @@ static DECLARE_WAIT_QUEUE_HEAD(acpi_event_wait); static volatile int acpi_thread_pid = -1; +static int acpi_start = 1; + /************************************************/ /* DECLARE_TASK_QUEUE is defined in */ /* /usr/src/linux/include/linux/tqueue.h */ @@ -382,6 +384,19 @@ static struct ctl_table acpi_table[] = &acpi_c3_enter_latency, sizeof(acpi_c3_enter_latency), 0644, NULL, &acpi_do_ulong}, + {ACPI_C1_COUNT, "c1_count", + &acpi_c1_count, sizeof(acpi_c1_count), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_C2_COUNT, "c2_count", + &acpi_c2_count, sizeof(acpi_c2_count), + 0644, NULL, &acpi_do_ulong}, + + {ACPI_C3_COUNT, "c3_count", + &acpi_c3_count, sizeof(acpi_c3_count), + 0644, NULL, &acpi_do_ulong}, + + /* until it actually works */ /* {ACPI_SLEEP, "sleep", NULL, 0, 0600, NULL, &acpi_do_sleep},*/ @@ -540,10 +555,16 @@ acpi_thread(void *context) int __init acpi_init(void) { - acpi_thread_pid = kernel_thread(acpi_thread, + if (acpi_start) { + acpi_thread_pid = kernel_thread(acpi_thread, NULL, (CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD)); + } + else { + printk(KERN_INFO "ACPI: Disabled\n"); + } + return ((acpi_thread_pid >= 0) ? 0:-ENODEV); } @@ -571,3 +592,21 @@ acpi_exit(void) module_init(acpi_init); module_exit(acpi_exit); + +#ifndef MODULE +static int __init acpi_setup(char *str) +{ + while ((str != NULL) && (*str != '\0')) { + if (strncmp(str, "no-idle", 7) == 0) + acpi_use_idle = 0; + if (strncmp(str, "off", 3) == 0) + acpi_start = 0; + str = strchr(str, ','); + if (str != NULL) + str += strspn(str, ", \t"); + } + return 1; +} + +__setup("acpi=", acpi_setup); +#endif diff --git a/drivers/acpi/driver.h b/drivers/acpi/driver.h index 9abae5d56eb7..ca6b6dd1f7f3 100644 --- a/drivers/acpi/driver.h +++ b/drivers/acpi/driver.h @@ -37,10 +37,14 @@ int acpi_cpu_init(void); u32 acpi_read_pm_timer(void); -extern unsigned long acpi_c2_exit_latency; -extern unsigned long acpi_c3_exit_latency; -extern unsigned long acpi_c2_enter_latency; -extern unsigned long acpi_c3_enter_latency; +extern u32 acpi_c2_exit_latency; +extern u32 acpi_c3_exit_latency; +extern u32 acpi_c2_enter_latency; +extern u32 acpi_c3_enter_latency; +extern u32 acpi_use_idle; +extern u32 acpi_c1_count; +extern u32 acpi_c2_count; +extern u32 acpi_c3_count; /* * driver.c diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 5e42683c6ac2..f74a3b671089 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -554,7 +554,7 @@ found_ec( ec_cxt->need_global_lock = obj.integer.value; - printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,gpe %d GL %d)\n", + printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,GPE %d GL %d)\n", ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit, ec_cxt->need_global_lock); diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index afdd477db6e5..668bdf253c35 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -2,7 +2,7 @@ * * Module Name: evevent - Fixed and General Purpose Acpi_event * handling and dispatch - * $Revision: 33 $ + * $Revision: 34 $ * *****************************************************************************/ @@ -55,7 +55,7 @@ acpi_ev_initialize ( ACPI_STATUS status; - /* Make sure we've got ACPI tables */ + /* Make sure we have ACPI tables */ if (!acpi_gbl_DSDT) { return (AE_NO_ACPI_TABLES); @@ -704,7 +704,7 @@ u32 acpi_ev_gpe_dispatch ( u32 gpe_number) { - ACPI_GPE_LEVEL_INFO gpe_info; + ACPI_GPE_LEVEL_INFO gpe_info; /*DEBUG_INCREMENT_EVENT_COUNT (EVENT_GENERAL);*/ @@ -720,59 +720,58 @@ acpi_ev_gpe_dispatch ( */ acpi_hw_disable_gpe (gpe_number); - gpe_info = acpi_gbl_gpe_info [gpe_number]; - - /* - * Edge-Triggered? - * --------------- - * If edge-triggered, clear the GPE status bit now. Note that - * level-triggered events are cleared after the GPE is serviced. - */ - if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } + gpe_info = acpi_gbl_gpe_info [gpe_number]; + /* + * Edge-Triggered? + * --------------- + * If edge-triggered, clear the GPE status bit now. Note that + * level-triggered events are cleared after the GPE is serviced. + */ + if (gpe_info.type & ACPI_EVENT_EDGE_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); + } /* * Function Handler (e.g. EC)? */ - if (gpe_info.handler) { - /* Invoke function handler (at interrupt level). */ - gpe_info.handler (gpe_info.context); - - /* Level-Triggered? */ - if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } + if (gpe_info.handler) { + /* Invoke function handler (at interrupt level). */ + gpe_info.handler (gpe_info.context); - /* Enable GPE */ - acpi_hw_enable_gpe (gpe_number); + /* Level-Triggered? */ + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); } - /* - * Method Handler (e.g. _Exx/_Lxx)? - */ - else if (gpe_info.method_handle) { - if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE, + + /* Enable GPE */ + acpi_hw_enable_gpe (gpe_number); + } + /* + * Method Handler (e.g. _Exx/_Lxx)? + */ + else if (gpe_info.method_handle) { + if (ACPI_FAILURE(acpi_os_queue_for_execution (OSD_PRIORITY_GPE, acpi_ev_asynch_execute_gpe_method, (void*)(NATIVE_UINT)gpe_number))) - { - /* - * Shoudn't occur, but if it does report an error. Note that - * the GPE will remain disabled until the ACPI Core Subsystem - * is restarted, or the handler is removed/reinstalled. - */ - REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]\n", gpe_number)); - } + { + /* + * Shoudn't occur, but if it does report an error. Note that + * the GPE will remain disabled until the ACPI Core Subsystem + * is restarted, or the handler is removed/reinstalled. + */ + REPORT_ERROR (("Acpi_ev_gpe_dispatch: Unable to queue handler for GPE bit [%X]\n", gpe_number)); } - /* - * No Handler? Report an error and leave the GPE disabled. - */ - else { - REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]\n", gpe_number)); + } + /* + * No Handler? Report an error and leave the GPE disabled. + */ + else { + REPORT_ERROR (("Acpi_ev_gpe_dispatch: No installed handler for GPE [%X]\n", gpe_number)); - /* Level-Triggered? */ - if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { - acpi_hw_clear_gpe (gpe_number); - } + /* Level-Triggered? */ + if (gpe_info.type & ACPI_EVENT_LEVEL_TRIGGERED) { + acpi_hw_clear_gpe (gpe_number); } + } return (INTERRUPT_HANDLED); } diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 071639a27670..56539d515fb5 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch - * $Revision: 94 $ + * $Revision: 96 $ * *****************************************************************************/ diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 892c721c6a0d..5ab9b3784c9b 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: hwsleep.c - ACPI Hardware Sleep/Wake Interface - * $Revision: 5 $ + * $Revision: 7 $ * *****************************************************************************/ @@ -175,15 +175,14 @@ acpi_enter_sleep_state ( PM1_acontrol |= (type_a << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); PM1_bcontrol |= (type_b << acpi_hw_get_bit_shift (SLP_TYPE_X_MASK)); - /* the old version was disabling interrupts. let's try it without - * and see how that works - */ - /*disable();*/ + disable(); acpi_hw_register_write(ACPI_MTX_LOCK, PM1_a_CONTROL, PM1_acontrol); acpi_hw_register_write(ACPI_MTX_LOCK, PM1_b_CONTROL, PM1_bcontrol); + acpi_hw_register_write(ACPI_MTX_LOCK, PM1_CONTROL, + (1 << acpi_hw_get_bit_shift (SLP_EN_MASK))); - /*enable();*/ + enable(); return (AE_OK); } diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index b7f529ccf67c..5a56ddeba920 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Name: hwtimer.c - ACPI Power Management Timer Interface - * $Revision: 4 $ + * $Revision: 5 $ * *****************************************************************************/ @@ -133,7 +133,7 @@ acpi_get_timer_duration ( /* * Compute Tick Delta: * ------------------- - * Handle timer rollovers on 24- versus 32-bit timers. + * Handle (max one) timer rollovers on 24- versus 32-bit timers. */ if (start_ticks < end_ticks) { delta_ticks = end_ticks - start_ticks; @@ -141,13 +141,17 @@ acpi_get_timer_duration ( else if (start_ticks > end_ticks) { /* 24-bit Timer */ if (0 == acpi_gbl_FADT->tmr_val_ext) { - delta_ticks = (0x00FFFFFF - start_ticks) + end_ticks; + delta_ticks = (((0x00FFFFFF - start_ticks) + end_ticks) & 0x00FFFFFF); } /* 32-bit Timer */ else { delta_ticks = (0xFFFFFFFF - start_ticks) + end_ticks; } } + else { + *time_elapsed = 0; + return (AE_OK); + } /* * Compute Duration: diff --git a/drivers/acpi/include/accommon.h b/drivers/acpi/include/accommon.h index 61d54a220dcc..feeeef818907 100644 --- a/drivers/acpi/include/accommon.h +++ b/drivers/acpi/include/accommon.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 87 $ + * $Revision: 90 $ * *****************************************************************************/ @@ -27,6 +27,30 @@ #define _ACCOMMON_H +typedef +ACPI_STATUS (*ACPI_PKG_CALLBACK) ( + u8 object_type, + ACPI_OPERAND_OBJECT *source_object, + ACPI_GENERIC_STATE *state, + void *context); + + +ACPI_STATUS +acpi_cm_walk_package_tree ( + ACPI_OPERAND_OBJECT *source_object, + void *target_object, + ACPI_PKG_CALLBACK walk_callback, + void *context); + + +typedef struct acpi_pkg_info +{ + u8 *free_space; + u32 length; + u32 object_space; + u32 num_packages; +} ACPI_PKG_INFO; + #define REF_INCREMENT (u16) 0 #define REF_DECREMENT (u16) 1 #define REF_FORCE_DELETE (u16) 2 @@ -194,29 +218,30 @@ acpi_cm_build_package_object ( u32 *space_used); ACPI_STATUS -acpi_cm_build_external_object ( +acpi_cm_copy_iobject_to_eobject ( ACPI_OPERAND_OBJECT *obj, ACPI_BUFFER *ret_buffer); ACPI_STATUS -acpi_cm_build_internal_simple_object( +acpi_cm_copy_esimple_to_isimple( ACPI_OBJECT *user_obj, ACPI_OPERAND_OBJECT *obj); ACPI_STATUS -acpi_cm_build_internal_object ( +acpi_cm_copy_eobject_to_iobject ( ACPI_OBJECT *obj, ACPI_OPERAND_OBJECT *internal_obj); ACPI_STATUS -acpi_cm_copy_internal_simple_object ( +acpi_cm_copy_isimple_to_isimple ( ACPI_OPERAND_OBJECT *source_obj, ACPI_OPERAND_OBJECT *dest_obj); ACPI_STATUS -acpi_cm_build_copy_internal_package_object ( +acpi_cm_copy_ipackage_to_ipackage ( ACPI_OPERAND_OBJECT *source_obj, - ACPI_OPERAND_OBJECT *dest_obj); + ACPI_OPERAND_OBJECT *dest_obj, + ACPI_WALK_STATE *walk_state); /* @@ -526,12 +551,25 @@ acpi_cm_create_update_state ( ACPI_OPERAND_OBJECT *object, u16 action); +ACPI_GENERIC_STATE * +acpi_cm_create_pkg_state ( + void *internal_object, + void *external_object, + u16 index); + ACPI_STATUS acpi_cm_create_update_state_and_push ( ACPI_OPERAND_OBJECT *object, u16 action, ACPI_GENERIC_STATE **state_list); +ACPI_STATUS +acpi_cm_create_pkg_state_and_push ( + void *internal_object, + void *external_object, + u16 index, + ACPI_GENERIC_STATE **state_list); + ACPI_GENERIC_STATE * acpi_cm_create_control_state ( void); @@ -564,6 +602,15 @@ ACPI_STATUS acpi_cm_resolve_package_references ( ACPI_OPERAND_OBJECT *obj_desc); +#ifdef ACPI_DEBUG + +void +acpi_cm_display_init_pathname ( + ACPI_HANDLE obj_handle, + char *path); + +#endif + /* * Memory allocation functions and related macros. diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h index ea9be649d745..e45c17db84b3 100644 --- a/drivers/acpi/include/acconfig.h +++ b/drivers/acpi/include/acconfig.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 53 $ + * $Revision: 55 $ * *****************************************************************************/ @@ -53,7 +53,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20010125 +#define ACPI_CA_VERSION 0x20010208 /* Maximum objects in the various object caches */ @@ -149,10 +149,5 @@ #define RSDP_SCAN_STEP 16 -/* Maximum nesting of package objects */ - -#define MAX_PACKAGE_DEPTH 16 - - #endif /* _ACCONFIG_H */ diff --git a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h index f1fa7094ef18..d645cceb7c8c 100644 --- a/drivers/acpi/include/acdebug.h +++ b/drivers/acpi/include/acdebug.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 39 $ + * $Revision: 41 $ * *****************************************************************************/ @@ -43,6 +43,7 @@ extern u8 opt_disasm; extern u8 opt_stats; extern u8 opt_parse_jit; extern u8 opt_verbose; +extern u8 opt_ini_methods; extern NATIVE_CHAR *args[DB_MAX_ARGS]; @@ -198,6 +199,10 @@ void acpi_db_find_references ( NATIVE_CHAR *object_arg); +void +acpi_db_display_resources ( + NATIVE_CHAR *object_arg); + /* * dbdisasm - AML disassembler diff --git a/drivers/acpi/include/acgcc.h b/drivers/acpi/include/acgcc.h index 82b1e5139a99..d92af99d6aa8 100644 --- a/drivers/acpi/include/acgcc.h +++ b/drivers/acpi/include/acgcc.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acgcc.h - GCC specific defines, etc. - * $Revision: 4 $ + * $Revision: 5 $ * *****************************************************************************/ @@ -26,12 +26,11 @@ #ifndef __ACGCC_H__ #define __ACGCC_H__ -#define COMPILER_DEPENDENT_UINT64 unsigned long long - #ifdef __ia64__ #define _IA64 +#define COMPILER_DEPENDENT_UINT64 unsigned long /* Single threaded */ #define ACPI_APPLICATION @@ -95,8 +94,7 @@ #else /* DO IA32 */ - - +#define COMPILER_DEPENDENT_UINT64 unsigned long long #define ACPI_ASM_MACROS #define causeinterrupt(level) #define BREAKPOINT3 diff --git a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h index 6eb571e5fae0..94d739a07876 100644 --- a/drivers/acpi/include/acinterp.h +++ b/drivers/acpi/include/acinterp.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 91 $ + * $Revision: 92 $ * *****************************************************************************/ @@ -558,12 +558,6 @@ acpi_aml_unsigned_integer_to_string ( ACPI_INTEGER value, NATIVE_CHAR *out_string); -ACPI_STATUS -acpi_aml_build_copy_internal_package_object ( - ACPI_OPERAND_OBJECT *source_obj, - ACPI_OPERAND_OBJECT *dest_obj, - ACPI_WALK_STATE *walk_state); - /* * amregion - default Op_region handlers diff --git a/drivers/acpi/include/aclinux.h b/drivers/acpi/include/aclinux.h index 0cf0e2845519..f86c83239823 100644 --- a/drivers/acpi/include/aclinux.h +++ b/drivers/acpi/include/aclinux.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclinux.h - OS specific defines, etc. - * $Revision: 7 $ + * $Revision: 9 $ * *****************************************************************************/ @@ -26,14 +26,15 @@ #ifndef __ACLINUX_H__ #define __ACLINUX_H__ - #define ACPI_OS_NAME "Linux" +#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/ctype.h> #include <asm/system.h> #include <asm/atomic.h> +#include <asm/div64.h> /* Linux uses GCC */ @@ -42,9 +43,14 @@ #undef DEBUGGER_THREADING #define DEBUGGER_THREADING DEBUGGER_SINGLE_THREADED -/* Linux ia32 can't do int64 well */ #ifndef _IA64 +/* Linux ia32 can't do int64 well */ #define ACPI_NO_INTEGER64_SUPPORT +/* And the ia32 kernel doesn't include 64-bit divide support */ +#define ACPI_DIV64(dividend, divisor) do_div(dividend, divisor) +#else +#define ACPI_DIV64(dividend, divisor) ACPI_DIVIDE(dividend, divisor) #endif + #endif /* __ACLINUX_H__ */ diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index 2d931387ed90..d3ea8a429a23 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 100 $ + * $Revision: 104 $ * *****************************************************************************/ @@ -368,6 +368,23 @@ typedef struct acpi_update_state } ACPI_UPDATE_STATE; + +/* + * Pkg state - used to traverse nested package structures + */ +typedef struct acpi_pkg_state +{ + ACPI_STATE_COMMON + union acpi_operand_obj *source_object; + union acpi_operand_obj *dest_object; + struct acpi_walk_state *walk_state; + void *this_target_obj; + u32 num_packages; + u16 index; + +} ACPI_PKG_STATE; + + /* * Control state - one per if/else and while constructs. * Allows nesting of these constructs @@ -428,6 +445,7 @@ typedef union acpi_gen_state ACPI_UPDATE_STATE update; ACPI_SCOPE_STATE scope; ACPI_PSCOPE_STATE parse_scope; + ACPI_PKG_STATE pkg; ACPI_RESULT_VALUES results; } ACPI_GENERIC_STATE; @@ -650,7 +668,6 @@ typedef struct acpi_init_walk_info typedef struct acpi_device_walk_info { - u32 flags; u16 device_count; u16 num_STA; u16 num_INI; diff --git a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h index d6acb8444344..a8ef1e0d7fa1 100644 --- a/drivers/acpi/include/acnamesp.h +++ b/drivers/acpi/include/acnamesp.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 101 $ + * $Revision: 103 $ * *****************************************************************************/ @@ -72,7 +72,7 @@ acpi_ns_initialize_objects ( ACPI_STATUS acpi_ns_initialize_devices ( - u32 flags); + void); /* Namespace init - nsxfinit */ @@ -317,6 +317,11 @@ acpi_ns_get_node ( ACPI_NAMESPACE_NODE *in_prefix_node, ACPI_NAMESPACE_NODE **out_node); +u32 +acpi_ns_get_pathname_length ( + ACPI_NAMESPACE_NODE *node); + + /* * Object management for NTEs - nsobject */ diff --git a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h index 5c20943cba89..6939d9e7e04b 100644 --- a/drivers/acpi/include/acoutput.h +++ b/drivers/acpi/include/acoutput.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: acoutput.h -- debug output - * $Revision: 69 $ + * $Revision: 70 $ * *****************************************************************************/ @@ -96,6 +96,7 @@ #define TRACE_USER_REQUESTS 0x01000000 #define TRACE_PACKAGE 0x02000000 #define TRACE_MUTEX 0x04000000 +#define TRACE_INIT 0x08000000 #define TRACE_ALL 0x0FFFFF00 diff --git a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h index 826fc89018ad..b5bbe9619fd7 100644 --- a/drivers/acpi/include/actypes.h +++ b/drivers/acpi/include/actypes.h @@ -1,7 +1,7 @@ /****************************************************************************** * * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 163 $ + * $Revision: 165 $ * *****************************************************************************/ @@ -237,8 +237,7 @@ typedef UINT64 ACPI_INTEGER; #define ACPI_NO_EVENT_INIT 0x04 #define ACPI_NO_ACPI_ENABLE 0x08 #define ACPI_NO_DEVICE_INIT 0x10 -#define ACPI_NO_PCI_INIT 0x20 -#define ACPI_NO_OBJECT_INIT 0x40 +#define ACPI_NO_OBJECT_INIT 0x20 /* @@ -1029,22 +1028,14 @@ typedef struct _resource_tag * END: Definitions for Resource Attributes */ -/* - * Definitions for PCI Routing tables - */ -typedef struct -{ - ACPI_INTEGER address; - u32 pin; - u32 source_index; - NATIVE_CHAR source[1]; - -} PRT_ENTRY; -typedef struct _prt_tag +typedef struct pci_routing_table { u32 length; - PRT_ENTRY data; + u32 pin; + ACPI_INTEGER address; /* here for 64-bit alignment */ + u32 source_index; + NATIVE_CHAR source[4]; /* pad to 64 bits so sizeof() works in all cases */ } PCI_ROUTING_TABLE; diff --git a/drivers/acpi/interpreter/amfldio.c b/drivers/acpi/interpreter/amfldio.c index 38b08abfaf4c..f02014c7e0de 100644 --- a/drivers/acpi/interpreter/amfldio.c +++ b/drivers/acpi/interpreter/amfldio.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: amfldio - Aml Field I/O - * $Revision: 37 $ + * $Revision: 39 $ * *****************************************************************************/ @@ -416,7 +416,7 @@ acpi_aml_write_field_data_with_update_rule ( /* Check if update rule needs to be applied (not if mask is all ones) */ /* The left shift drops the bits we want to ignore. */ - if ((~mask << (sizeof(mask)*8 - bit_granularity)) != 0) { + if ((~mask << (sizeof(mask)*8 - bit_granularity)) != 0) { /* * Read the current contents of the byte/word/dword containing * the field, and merge with the new field value. diff --git a/drivers/acpi/interpreter/amstore.c b/drivers/acpi/interpreter/amstore.c index 9f350bb29d24..bb3c5c500a12 100644 --- a/drivers/acpi/interpreter/amstore.c +++ b/drivers/acpi/interpreter/amstore.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstore - AML Interpreter object store support - * $Revision: 121 $ + * $Revision: 123 $ * *****************************************************************************/ @@ -268,8 +268,7 @@ acpi_aml_store_object_to_index ( * If the source is a package, copy the source to the new dest */ if (ACPI_TYPE_PACKAGE == obj_desc->common.type) { - status = acpi_aml_build_copy_internal_package_object ( - val_desc, obj_desc, walk_state); + status = acpi_cm_copy_ipackage_to_ipackage (val_desc, obj_desc, walk_state); if (ACPI_FAILURE (status)) { acpi_cm_remove_reference (obj_desc); return (status); diff --git a/drivers/acpi/interpreter/amstorob.c b/drivers/acpi/interpreter/amstorob.c index 8118f08bd5e7..d71fe3eacf4f 100644 --- a/drivers/acpi/interpreter/amstorob.c +++ b/drivers/acpi/interpreter/amstorob.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amstorob - AML Interpreter object store support, store to object - * $Revision: 22 $ + * $Revision: 23 $ * *****************************************************************************/ @@ -66,6 +66,19 @@ acpi_aml_copy_buffer_to_buffer ( length = source_desc->buffer.length; /* + * If target is a buffer of length zero, allocate a new + * buffer of the proper length + */ + if (target_desc->buffer.length == 0) { + target_desc->buffer.pointer = acpi_cm_allocate (length); + if (!target_desc->buffer.pointer) { + return (AE_NO_MEMORY); + } + + target_desc->buffer.length = length; + } + + /* * Buffer is a static allocation, * only place what will fit in the buffer. */ @@ -141,11 +154,11 @@ acpi_aml_copy_string_to_string ( } target_desc->string.pointer = acpi_cm_allocate (length + 1); - target_desc->string.length = length; - if (!target_desc->string.pointer) { return (AE_NO_MEMORY); } + target_desc->string.length = length; + MEMCPY(target_desc->string.pointer, buffer, length); } diff --git a/drivers/acpi/interpreter/amutils.c b/drivers/acpi/interpreter/amutils.c index e3456099c00d..5edf578f783c 100644 --- a/drivers/acpi/interpreter/amutils.c +++ b/drivers/acpi/interpreter/amutils.c @@ -2,7 +2,7 @@ /****************************************************************************** * * Module Name: amutils - interpreter/scanner utilities - * $Revision: 68 $ + * $Revision: 69 $ * *****************************************************************************/ @@ -36,21 +36,6 @@ MODULE_NAME ("amutils") -typedef struct internal_search_st -{ - ACPI_OPERAND_OBJECT *dest_obj; - u32 index; - ACPI_OPERAND_OBJECT *source_obj; - -} INTERNAL_PKG_SEARCH_INFO; - - -/* Used to traverse nested packages when copying*/ -/* TBD: This must be removed! */ - -INTERNAL_PKG_SEARCH_INFO copy_level[MAX_PACKAGE_DEPTH]; - - /******************************************************************************* * * FUNCTION: Acpi_aml_enter_interpreter @@ -383,153 +368,3 @@ acpi_aml_unsigned_integer_to_string ( } -/******************************************************************************* - * - * FUNCTION: Acpi_aml_build_copy_internal_package_object - * - * PARAMETERS: *Source_obj - Pointer to the source package object - * *Dest_obj - Where the internal object is returned - * - * RETURN: Status - the status of the call - * - * DESCRIPTION: This function is called to copy an internal package object - * into another internal package object. - * - ******************************************************************************/ - -ACPI_STATUS -acpi_aml_build_copy_internal_package_object ( - ACPI_OPERAND_OBJECT *source_obj, - ACPI_OPERAND_OBJECT *dest_obj, - ACPI_WALK_STATE *walk_state) -{ - u32 current_depth = 0; - ACPI_STATUS status = AE_OK; - u32 length = 0; - u32 this_index; - u32 object_space = 0; - ACPI_OPERAND_OBJECT *this_dest_obj; - ACPI_OPERAND_OBJECT *this_source_obj; - INTERNAL_PKG_SEARCH_INFO *level_ptr; - - - /* - * Initialize the working variables - */ - - MEMSET ((void *) copy_level, 0, sizeof(copy_level)); - - copy_level[0].dest_obj = dest_obj; - copy_level[0].source_obj = source_obj; - level_ptr = ©_level[0]; - current_depth = 0; - - dest_obj->common.type = source_obj->common.type; - dest_obj->package.count = source_obj->package.count; - - - /* - * Build an array of ACPI_OBJECTS in the buffer - * and move the free space past it - */ - - dest_obj->package.elements = acpi_cm_callocate ( - (dest_obj->package.count + 1) * - sizeof (void *)); - if (!dest_obj->package.elements) { - /* Package vector allocation failure */ - - REPORT_ERROR (("Aml_build_copy_internal_package_object: Package vector allocation failure\n")); - return (AE_NO_MEMORY); - } - - dest_obj->package.next_element = dest_obj->package.elements; - - - while (1) { - this_index = level_ptr->index; - this_dest_obj = (ACPI_OPERAND_OBJECT *) level_ptr->dest_obj->package.elements[this_index]; - this_source_obj = (ACPI_OPERAND_OBJECT *) level_ptr->source_obj->package.elements[this_index]; - - if (IS_THIS_OBJECT_TYPE (this_source_obj, ACPI_TYPE_PACKAGE)) { - /* - * If this object is a package then we go one deeper - */ - if (current_depth >= MAX_PACKAGE_DEPTH-1) { - /* - * Too many nested levels of packages for us to handle - */ - return (AE_LIMIT); - } - - /* - * Build the package object - */ - this_dest_obj = acpi_cm_create_internal_object (ACPI_TYPE_PACKAGE); - level_ptr->dest_obj->package.elements[this_index] = this_dest_obj; - - - this_dest_obj->common.type = ACPI_TYPE_PACKAGE; - this_dest_obj->package.count = this_dest_obj->package.count; - - /* - * Save space for the array of objects (Package elements) - * update the buffer length counter - */ - object_space = this_dest_obj->package.count * - sizeof (ACPI_OPERAND_OBJECT); - length += object_space; - current_depth++; - level_ptr = ©_level[current_depth]; - level_ptr->dest_obj = this_dest_obj; - level_ptr->source_obj = this_source_obj; - level_ptr->index = 0; - - } /* if object is a package */ - - else { - - this_dest_obj = acpi_cm_create_internal_object ( - this_source_obj->common.type); - level_ptr->dest_obj->package.elements[this_index] = this_dest_obj; - - status = acpi_aml_store_object_to_object(this_source_obj, this_dest_obj, walk_state); - - if (ACPI_FAILURE (status)) { - /* - * Failure get out - */ - return (status); - } - - length +=object_space; - - level_ptr->index++; - while (level_ptr->index >= level_ptr->dest_obj->package.count) { - /* - * We've handled all of the objects at this level, This means - * that we have just completed a package. That package may - * have contained one or more packages itself - */ - if (current_depth == 0) { - /* - * We have handled all of the objects in the top level - * package just add the length of the package objects - * and exit - */ - return (AE_OK); - } - - /* - * Go back up a level and move the index past the just - * completed package object. - */ - current_depth--; - level_ptr = ©_level[current_depth]; - level_ptr->index++; - } - } /* else object is NOT a package */ - } /* while (1) */ -} - - diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index 6c040d22e271..155c63808252 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -2,7 +2,7 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 81 $ + * $Revision: 83 $ * ******************************************************************************/ @@ -253,8 +253,8 @@ acpi_ns_evaluate_by_handle ( node = acpi_ns_convert_handle_to_entry (handle); if (!node) { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + return (AE_BAD_PARAMETER); } @@ -316,12 +316,6 @@ acpi_ns_evaluate_by_handle ( * so we just return */ return (status); - - -unlock_and_exit: - - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); - return (status); } @@ -354,14 +348,6 @@ acpi_ns_execute_control_method ( ACPI_OPERAND_OBJECT *obj_desc; - /* Verify that there is a method associated with this object */ - - obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) method_node); - if (!obj_desc) { - return (AE_ERROR); - } - - /* * Unlock the namespace before execution. This allows namespace access * via the external Acpi* interfaces while a method is being executed. @@ -372,8 +358,16 @@ acpi_ns_execute_control_method ( acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + /* Verify that there is a method associated with this object */ + + obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) method_node); + if (!obj_desc) { + return (AE_ERROR); + } + + /* - * Excecute the method via the interpreter + * Execute the method via the interpreter */ status = acpi_aml_execute_method (method_node, params, return_obj_desc); diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index 76b535205fe0..2a1daa85cc94 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: nsinit - namespace initialization - * $Revision: 12 $ + * $Revision: 15 $ * *****************************************************************************/ @@ -89,13 +89,12 @@ acpi_ns_initialize_objects ( ACPI_STATUS acpi_ns_initialize_devices ( - u32 flags) + void) { ACPI_STATUS status; ACPI_DEVICE_WALK_INFO info; - info.flags = flags; info.device_count = 0; info.num_STA = 0; info.num_INI = 0; @@ -168,6 +167,7 @@ acpi_ns_init_one_object ( info->op_region_init++; status = acpi_ds_get_region_arguments (obj_desc); + break; @@ -180,6 +180,8 @@ acpi_ns_init_one_object ( info->field_init++; status = acpi_ds_get_field_unit_arguments (obj_desc); + + break; default: @@ -198,7 +200,7 @@ acpi_ns_init_one_object ( * * FUNCTION: Acpi_ns_init_one_device * - * PARAMETERS: The usual "I'm a namespace callback" stuff + * PARAMETERS: WALK_CALLBACK * * RETURN: ACPI_STATUS * @@ -221,6 +223,7 @@ acpi_ns_init_one_device ( ACPI_DEVICE_WALK_INFO *info = (ACPI_DEVICE_WALK_INFO *) context; + info->device_count++; acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); @@ -251,6 +254,7 @@ acpi_ns_init_one_device ( return(AE_CTRL_DEPTH); } + /* * The device is present. Run _INI. */ diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index c2fb4916378d..50c46a9dcb46 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 53 $ + * $Revision: 54 $ * ******************************************************************************/ @@ -115,6 +115,46 @@ acpi_ns_get_table_pathname ( /******************************************************************************* * + * FUNCTION: Acpi_ns_get_pathname_length + * + * PARAMETERS: Node - Namespace node + * + * RETURN: Length of path, including prefix + * + * DESCRIPTION: Get the length of the pathname string for this node + * + ******************************************************************************/ + +u32 +acpi_ns_get_pathname_length ( + ACPI_NAMESPACE_NODE *node) +{ + u32 size; + ACPI_NAMESPACE_NODE *next_node; + + /* + * Compute length of pathname as 5 * number of name segments. + * Go back up the parent tree to the root + */ + for (size = 0, next_node = node; + acpi_ns_get_parent_object (next_node); + next_node = acpi_ns_get_parent_object (next_node)) + { + size += PATH_SEGMENT_LENGTH; + } + + /* Special case for size still 0 - no parent for "special" nodes */ + + if (!size) { + size = PATH_SEGMENT_LENGTH; + } + + return (size + 1); +} + + +/******************************************************************************* + * * FUNCTION: Acpi_ns_handle_to_pathname * * PARAMETERS: Target_handle - Handle of named object whose name is @@ -138,11 +178,10 @@ acpi_ns_handle_to_pathname ( { ACPI_STATUS status = AE_OK; ACPI_NAMESPACE_NODE *node; - ACPI_NAMESPACE_NODE *next_node; u32 path_length; - u32 size; u32 user_buf_size; ACPI_NAME name; + u32 size; if (!acpi_gbl_root_node || !target_handle) { @@ -159,26 +198,12 @@ acpi_ns_handle_to_pathname ( return (AE_BAD_PARAMETER); } - /* - * Compute length of pathname as 5 * number of name segments. - * Go back up the parent tree to the root - */ - for (size = 0, next_node = node; - acpi_ns_get_parent_object (next_node); - next_node = acpi_ns_get_parent_object (next_node)) - { - size += PATH_SEGMENT_LENGTH; - } - - /* Special case for size still 0 - no parent for "special" nodes */ - - if (!size) { - size = PATH_SEGMENT_LENGTH; - } /* Set return length to the required path length */ - path_length = size + 1; + path_length = acpi_ns_get_pathname_length (node); + size = path_length - 1; + user_buf_size = *buf_size; *buf_size = path_length; diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index 742c5da6620a..b2c3dba3a3c6 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -2,7 +2,7 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 78 $ + * $Revision: 80 $ * ******************************************************************************/ @@ -117,9 +117,8 @@ acpi_evaluate_object ( * internal object */ for (i = 0; i < count; i++) { - status = - acpi_cm_build_internal_object (¶m_objects->pointer[i], - param_ptr[i]); + status = acpi_cm_copy_eobject_to_iobject (¶m_objects->pointer[i], + param_ptr[i]); if (ACPI_FAILURE (status)) { acpi_cm_delete_internal_object_list (param_ptr); @@ -236,7 +235,7 @@ acpi_evaluate_object ( /* * We have enough space for the object, build it */ - status = acpi_cm_build_external_object (return_obj, + status = acpi_cm_copy_iobject_to_eobject (return_obj, return_buffer); return_buffer->length = buffer_space_needed; } @@ -580,13 +579,13 @@ acpi_ns_get_device_callback ( acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); node = acpi_ns_convert_handle_to_entry (obj_handle); + + acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); + if (!node) { - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (AE_BAD_PARAMETER); } - acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); - /* * Run _STA to determine if device is present */ diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 86ff91be87c5..bfceeac8baf9 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -2,7 +2,7 @@ * * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length * Acpi_rs_calculate_list_length - * $Revision: 18 $ + * $Revision: 21 $ * ******************************************************************************/ @@ -27,6 +27,8 @@ #include "acpi.h" #include "acresrc.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rscalc") @@ -704,6 +706,7 @@ acpi_rs_calculate_list_length ( */ bytes_consumed = 2; structure_size = RESOURCE_LENGTH; + byte_stream_buffer_length = bytes_parsed; break; @@ -810,7 +813,10 @@ acpi_rs_calculate_pci_routing_table_length ( name_found = FALSE; for (table_index = 0; table_index < 4 && !name_found; table_index++) { - if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) { + if ((ACPI_TYPE_STRING == (*sub_object_list)->common.type) || + ((INTERNAL_TYPE_REFERENCE == (*sub_object_list)->common.type) && + ((*sub_object_list)->reference.op_code == AML_NAMEPATH_OP))) + { name_found = TRUE; } @@ -822,17 +828,22 @@ acpi_rs_calculate_pci_routing_table_length ( } } - temp_size_needed += (sizeof (PCI_ROUTING_TABLE) - 1); + temp_size_needed += (sizeof (PCI_ROUTING_TABLE) - 4); /* * Was a String type found? */ if (TRUE == name_found) { - /* - * The length String.Length field includes the - * terminating NULL - */ - temp_size_needed += (*sub_object_list)->string.length; + if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) { + /* + * The length String.Length field includes the + * terminating NULL + */ + temp_size_needed += (*sub_object_list)->string.length; + } + else { + temp_size_needed += acpi_ns_get_pathname_length ((*sub_object_list)->reference.node); + } } else { @@ -855,7 +866,7 @@ acpi_rs_calculate_pci_routing_table_length ( } - *buffer_size_needed = temp_size_needed + sizeof (PCI_ROUTING_TABLE); + *buffer_size_needed = temp_size_needed; return (AE_OK); } diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index f221a41dc290..234684edb092 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -3,7 +3,7 @@ * Module Name: rscreate - Acpi_rs_create_resource_list * Acpi_rs_create_pci_routing_table * Acpi_rs_create_byte_stream - * $Revision: 24 $ + * $Revision: 25 $ * ******************************************************************************/ @@ -28,6 +28,8 @@ #include "acpi.h" #include "acresrc.h" +#include "amlcode.h" +#include "acnamesp.h" #define _COMPONENT RESOURCE_MANAGER MODULE_NAME ("rscreate") @@ -157,6 +159,7 @@ acpi_rs_create_pci_routing_table ( u32 number_of_elements = 0; u32 index = 0; PCI_ROUTING_TABLE *user_prt = NULL; + ACPI_NAMESPACE_NODE *node; ACPI_STATUS status; @@ -203,10 +206,10 @@ acpi_rs_create_pci_routing_table ( /* * Fill in the Length field with the information we * have at this point. - * The minus one is to subtract the size of the - * u8 Source[1] member because it is added below. + * The minus four is to subtract the size of the + * u8 Source[4] member because it is added below. */ - user_prt->length = (sizeof (PCI_ROUTING_TABLE) - 1); + user_prt->length = (sizeof (PCI_ROUTING_TABLE) -4); /* * Dereference the sub-package @@ -221,11 +224,10 @@ acpi_rs_create_pci_routing_table ( sub_object_list = package_element->package.elements; /* - * Dereference the Address + * 1) First subobject: Dereference the Address */ if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->data.address = - (*sub_object_list)->integer.value; + user_prt->address = (*sub_object_list)->integer.value; } else { @@ -233,12 +235,12 @@ acpi_rs_create_pci_routing_table ( } /* - * Dereference the Pin + * 2) Second subobject: Dereference the Pin */ sub_object_list++; if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->data.pin = + user_prt->pin = (u32) (*sub_object_list)->integer.value; } @@ -247,37 +249,57 @@ acpi_rs_create_pci_routing_table ( } /* - * Dereference the Source Name + * 3) Third subobject: Dereference the Source Name */ sub_object_list++; - if (ACPI_TYPE_STRING == (*sub_object_list)->common.type) { - STRCPY (user_prt->data.source, + switch ((*sub_object_list)->common.type) + { + case INTERNAL_TYPE_REFERENCE: + if ((*sub_object_list)->reference.op_code != AML_NAMEPATH_OP) { + return (AE_BAD_DATA); + } + + node = (*sub_object_list)->reference.node; + + /* TBD: use *remaining* length of the buffer! */ + + status = acpi_ns_handle_to_pathname ((ACPI_HANDLE *) node, + output_buffer_length, user_prt->source); + + user_prt->length += STRLEN (user_prt->source) + 1; /* include null terminator */ + break; + + + case ACPI_TYPE_STRING: + + STRCPY (user_prt->source, (*sub_object_list)->string.pointer); /* * Add to the Length field the length of the string */ user_prt->length += (*sub_object_list)->string.length; - } + break; - else { + + case ACPI_TYPE_INTEGER: /* * If this is a number, then the Source Name * is NULL, since the entire buffer was zeroed * out, we can leave this alone. */ - if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - /* - * Add to the Length field the length of - * the u32 NULL - */ - user_prt->length += sizeof (u32); - } + /* + * Add to the Length field the length of + * the u32 NULL + */ + user_prt->length += sizeof (u32); + break; - else { - return (AE_BAD_DATA); - } + + default: + return (AE_BAD_DATA); + break; } /* Now align the current length */ @@ -285,12 +307,12 @@ acpi_rs_create_pci_routing_table ( user_prt->length = ROUND_UP_TO_64_bITS (user_prt->length); /* - * Dereference the Source Index + * 4) Fourth subobject: Dereference the Source Index */ sub_object_list++; if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { - user_prt->data.source_index = + user_prt->source_index = (u32) (*sub_object_list)->integer.value; } diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 03d2da6f2150..367648afef02 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -1,7 +1,7 @@ /******************************************************************************* * * Module Name: rsdump - Functions do dump out the resource structures. - * $Revision: 15 $ + * $Revision: 16 $ * ******************************************************************************/ @@ -910,24 +910,24 @@ acpi_rs_dump_irq_list ( if (acpi_dbg_level & TRACE_RESOURCES && _COMPONENT & acpi_dbg_layer) { - prt_element = (PCI_ROUTING_TABLE *)buffer; + prt_element = (PCI_ROUTING_TABLE *) buffer; while (!done) { acpi_os_printf ("\t_pCI IRQ Routing Table structure %X.\n", count++); acpi_os_printf ("\t\t_address: %X\n", - prt_element->data.address); + prt_element->address); - acpi_os_printf ("\t\t_pin: %X\n", prt_element->data.pin); + acpi_os_printf ("\t\t_pin: %X\n", prt_element->pin); - acpi_os_printf ("\t\t_source: %s\n", prt_element->data.source); + acpi_os_printf ("\t\t_source: %s\n", prt_element->source); acpi_os_printf ("\t\t_source_index: %X\n", - prt_element->data.source_index); + prt_element->source_index); buffer += prt_element->length; - prt_element = (PCI_ROUTING_TABLE *)buffer; + prt_element = (PCI_ROUTING_TABLE *) buffer; if(0 == prt_element->length) { done = TRUE; diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index de47563d0f8e..048db65a4644 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -2,7 +2,7 @@ * * Module Name: rslist - Acpi_rs_byte_stream_to_list * Acpi_list_to_byte_stream - * $Revision: 10 $ + * $Revision: 11 $ * ******************************************************************************/ @@ -302,9 +302,7 @@ acpi_rs_byte_stream_to_list ( /* * Check the reason for exiting the while loop */ - if (!(byte_stream_buffer_length == bytes_parsed) || - (TRUE != end_tag_processed)) - { + if (TRUE != end_tag_processed) { return (AE_AML_ERROR); } diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index 76d7fff15c47..fd57f3eb7273 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: tbconvrt - ACPI Table conversion utilities - * $Revision: 18 $ + * $Revision: 19 $ * *****************************************************************************/ |
