# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1160 -> 1.1161 # include/acpi/acglobal.h 1.22 -> 1.23 # drivers/acpi/hardware/hwacpi.c 1.17 -> 1.18 # drivers/acpi/dispatcher/dswload.c 1.19 -> 1.20 # drivers/acpi/events/evrgnini.c 1.17 -> 1.18 # drivers/acpi/hardware/hwsleep.c 1.22 -> 1.23 # drivers/acpi/executer/exdump.c 1.16 -> 1.17 # drivers/acpi/events/evregion.c 1.19 -> 1.20 # drivers/acpi/utilities/utglobal.c 1.23 -> 1.24 # include/acpi/acobject.h 1.17 -> 1.18 # drivers/acpi/events/evxfregn.c 1.16 -> 1.17 # drivers/acpi/events/evgpeblk.c 1.8 -> 1.9 # include/acpi/acconfig.h 1.40 -> 1.41 # drivers/acpi/dispatcher/dsmthdat.c 1.19 -> 1.20 # drivers/acpi/resources/rsirq.c 1.13 -> 1.14 # drivers/acpi/utilities/utdelete.c 1.17 -> 1.18 # include/acpi/acevents.h 1.16 -> 1.17 # drivers/acpi/tables/tbget.c 1.18 -> 1.19 # drivers/acpi/parser/psxface.c 1.14 -> 1.15 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/12/11 len.brown@intel.com 1.1161 # [ACPI] Update Linux to ACPICA 20031203 (Bob Moore) # # Changed the initialization of Operation Regions during subsystem init to # perform two entire walks of the ACPI namespace; The first to initialize # the regions themselves, the second to execute the _REG methods. This # fixed some interdependencies across _REG methods found on some machines. # # Fixed a problem where a Store(Local0, Local1) could simply update the # object reference count, and not create a new copy of the object if the # Local1 is uninitialized. # # Implemented support for the _SST reserved method during sleep # transitions. # # Implemented support to clear the SLP_TYP and SLP_EN bits when waking up, # this is apparently required by some machines. # # When sleeping, clear the wake status only if SleepState is not S5. # # Fixed a problem in AcpiRsExtendedIrqResource() where an incorrect # pointer arithmetic advanced a string pointer too far. # # Fixed a problem in AcpiTbGetTablePtr() where a garbage pointer could be # returned if the requested table has not been loaded. # # Within the support for IRQ resources, restructured the handling of the # active and edge/level bits. # # Fixed a few problems in AcpiPsxExecute() where memory could be leaked # under certain error conditions. # # Improved error messages for the cases where the ACPI mode could not be # entered. # -------------------------------------------- # diff -Nru a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c --- a/drivers/acpi/dispatcher/dsmthdat.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/dispatcher/dsmthdat.c Thu Dec 11 23:14:25 2003 @@ -567,13 +567,13 @@ acpi_status status; struct acpi_namespace_node *node; union acpi_operand_object *current_obj_desc; + union acpi_operand_object *new_obj_desc; ACPI_FUNCTION_TRACE ("ds_store_object_to_local"); ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%d Idx=%d Obj=%p\n", opcode, index, obj_desc)); - /* Parameter validation */ if (!obj_desc) { @@ -595,6 +595,19 @@ } /* + * If the reference count on the object is more than one, we must + * take a copy of the object before we store. + */ + new_obj_desc = obj_desc; + if (obj_desc->common.reference_count > 1) { + status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state); + new_obj_desc; + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + /* * If there is an object already in this slot, we either * have to delete it, or if this is an argument and there * is an object reference stored there, we have to do @@ -637,14 +650,20 @@ (current_obj_desc->reference.opcode == AML_REF_OF_OP)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Arg (%p) is an obj_ref(Node), storing in node %p\n", - obj_desc, current_obj_desc)); + new_obj_desc, current_obj_desc)); /* * Store this object to the Node * (perform the indirect store) */ - status = acpi_ex_store_object_to_node (obj_desc, + status = acpi_ex_store_object_to_node (new_obj_desc, current_obj_desc->reference.object, walk_state); + + /* Remove local reference if we copied the object above */ + + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } return_ACPI_STATUS (status); } } @@ -657,12 +676,18 @@ } /* - * Install the obj_stack descriptor (*obj_desc) into + * Install the Obj descriptor (*new_obj_desc) into * the descriptor for the Arg or Local. - * Install the new object in the stack entry * (increments the object reference count by one) */ - status = acpi_ds_method_data_set_value (opcode, index, obj_desc, walk_state); + status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state); + + /* Remove local reference if we copied the object above */ + + if (new_obj_desc != obj_desc) { + acpi_ut_remove_reference (new_obj_desc); + } + return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c --- a/drivers/acpi/dispatcher/dswload.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/dispatcher/dswload.c Thu Dec 11 23:14:25 2003 @@ -167,7 +167,7 @@ object_type = walk_state->op_info->object_type; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, - "State=%p Op=%p [%s] ", walk_state, op, acpi_ut_get_type_name (object_type))); + "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type))); switch (walk_state->opcode) { case AML_SCOPE_OP: @@ -260,10 +260,12 @@ if ((walk_state->opcode != AML_SCOPE_OP) && (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) { flags |= ACPI_NS_ERROR_IF_FOUND; - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Cannot already exist\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", + acpi_ut_get_type_name (object_type))); } else { - ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Both Find or Create allowed\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n", + acpi_ut_get_type_name (object_type))); } /* diff -Nru a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c --- a/drivers/acpi/events/evgpeblk.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/events/evgpeblk.c Thu Dec 11 23:14:25 2003 @@ -477,7 +477,7 @@ * * RETURN: Status * - * DESCRIPTION: Install new GPE block with mutex support + * DESCRIPTION: Remove a GPE block * ******************************************************************************/ diff -Nru a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c --- a/drivers/acpi/events/evregion.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/events/evregion.c Thu Dec 11 23:14:25 2003 @@ -136,7 +136,7 @@ * ******************************************************************************/ -static acpi_status +acpi_status acpi_ev_execute_reg_method ( union acpi_operand_object *region_obj, u32 function) @@ -202,7 +202,7 @@ * * FUNCTION: acpi_ev_address_space_dispatch * - * PARAMETERS: region_obj - internal region object + * PARAMETERS: region_obj - Internal region object * space_id - ID of the address space (0-255) * Function - Read or Write operation * Address - Where in the space to read or write @@ -243,9 +243,11 @@ /* Ensure that there is a handler associated with this region */ - handler_desc = region_obj->region.address_space; + handler_desc = region_obj->region.handler; if (!handler_desc) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n", + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "No handler for Region [%4.4s] (%p) [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); return_ACPI_STATUS (AE_NOT_EXIST); @@ -320,7 +322,7 @@ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", - ®ion_obj->region.address_space->address_space, handler, + ®ion_obj->region.handler->address_space, handler, ACPI_FORMAT_UINT64 (address), acpi_ut_get_region_name (region_obj->region.space_id))); @@ -359,6 +361,7 @@ return_ACPI_STATUS (status); } + /******************************************************************************* * * FUNCTION: acpi_ev_detach_region @@ -398,7 +401,7 @@ /* Get the address handler from the region object */ - handler_obj = region_obj->region.address_space; + handler_obj = region_obj->region.handler; if (!handler_obj) { /* This region has no handler, all done */ @@ -472,7 +475,7 @@ * If the region is on the handler's list * this better be the region's handler */ - region_obj->region.address_space = NULL; + region_obj->region.handler = NULL; acpi_ut_remove_reference (handler_obj); return_VOID; @@ -515,17 +518,15 @@ union acpi_operand_object *region_obj, u8 acpi_ns_is_locked) { - acpi_status status; - acpi_status status2; - ACPI_FUNCTION_TRACE ("ev_attach_region"); ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, - "Adding Region %p to address handler %p [%s]\n", - region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - + "Adding Region [%4.4s] %p to address handler %p [%s]\n", + acpi_ut_get_node_name (region_obj->region.node), + region_obj, handler_obj, + acpi_ut_get_region_name (region_obj->region.space_id))); /* Link this region to the front of the handler's list */ @@ -534,34 +535,14 @@ /* Install the region's handler */ - if (region_obj->region.address_space) { + if (region_obj->region.handler) { return_ACPI_STATUS (AE_ALREADY_EXISTS); } - region_obj->region.address_space = handler_obj; + region_obj->region.handler = handler_obj; acpi_ut_add_reference (handler_obj); - /* - * Tell all users that this region is usable by running the _REG - * method - */ - if (acpi_ns_is_locked) { - status2 = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status2)) { - return_ACPI_STATUS (status2); - } - } - - status = acpi_ev_execute_reg_method (region_obj, 1); - - if (acpi_ns_is_locked) { - status2 = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); - if (ACPI_FAILURE (status2)) { - return_ACPI_STATUS (status2); - } - } - - return_ACPI_STATUS (status); + return_ACPI_STATUS (AE_OK); } @@ -569,9 +550,7 @@ * * FUNCTION: acpi_ev_install_handler * - * PARAMETERS: Handle - Node to be dumped - * Level - Nesting level of the handle - * Context - Passed into acpi_ns_walk_namespace + * PARAMETERS: walk_namespace callback * * DESCRIPTION: This routine installs an address handler into objects that are * of type Region or Device. @@ -640,7 +619,7 @@ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) { /* Check if this Device already has a handler for this address space */ - next_handler_obj = obj_desc->device.address_space; + next_handler_obj = obj_desc->device.handler; while (next_handler_obj) { /* Found a handler, is it for the same address space? */ @@ -697,4 +676,77 @@ return (status); } +/******************************************************************************* + * + * FUNCTION: acpi_ev_reg_run + * + * PARAMETERS: walk_namespace callback + * + * DESCRIPTION: Run _REg method for region objects of the requested space_iD + * + ******************************************************************************/ + +acpi_status +acpi_ev_reg_run ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value) +{ + union acpi_operand_object *handler_obj; + union acpi_operand_object *obj_desc; + struct acpi_namespace_node *node; + acpi_status status; + + + ACPI_FUNCTION_NAME ("ev_reg_run"); + + + handler_obj = (union acpi_operand_object *) context; + + /* Parameter validation */ + + if (!handler_obj) { + return (AE_OK); + } + + /* Convert and validate the device handle */ + + node = acpi_ns_map_handle_to_node (obj_handle); + if (!node) { + return (AE_BAD_PARAMETER); + } + + /* + * We only care about regions.and objects + * that are allowed to have address space handlers + */ + if ((node->type != ACPI_TYPE_REGION) && + (node != acpi_gbl_root_node)) { + return (AE_OK); + } + + /* Check for an existing internal object */ + + obj_desc = acpi_ns_get_attached_object (node); + if (!obj_desc) { + /* No object, just exit */ + + return (AE_OK); + } + + + /* Object is a Region */ + + if (obj_desc->region.space_id != handler_obj->address_space.space_id) { + /* + * This region is for a different address space + * -- just ignore it + */ + return (AE_OK); + } + + status = acpi_ev_execute_reg_method (obj_desc, 1); + return (status); +} diff -Nru a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c --- a/drivers/acpi/events/evrgnini.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/events/evrgnini.c Thu Dec 11 23:14:25 2003 @@ -177,7 +177,7 @@ ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); - handler_obj = region_obj->region.address_space; + handler_obj = region_obj->region.handler; if (!handler_obj) { /* * No installed handler. This shouldn't happen because the dispatch @@ -469,7 +469,7 @@ /* Setup defaults */ - region_obj->region.address_space = NULL; + region_obj->region.handler = NULL; region_obj2->extra.method_REG = NULL; region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE); region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED; @@ -502,17 +502,17 @@ switch (node->type) { case ACPI_TYPE_DEVICE: - handler_obj = obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; break; case ACPI_TYPE_PROCESSOR: - handler_obj = obj_desc->processor.address_space; + handler_obj = obj_desc->processor.handler; break; case ACPI_TYPE_THERMAL: - handler_obj = obj_desc->thermal_zone.address_space; + handler_obj = obj_desc->thermal_zone.handler; break; default: @@ -532,6 +532,26 @@ status = acpi_ev_attach_region (handler_obj, region_obj, acpi_ns_locked); + + /* + * Tell all users that this region is usable by running the _REG + * method + */ + if (acpi_ns_locked) { + status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + + status = acpi_ev_execute_reg_method (region_obj, 1); + + if (acpi_ns_locked) { + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } return_ACPI_STATUS (AE_OK); } diff -Nru a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c --- a/drivers/acpi/events/evxfregn.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/events/evxfregn.c Thu Dec 11 23:14:25 2003 @@ -173,7 +173,7 @@ * The attached device object already exists. * Make sure the handler is not already installed. */ - handler_obj = obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; /* Walk the handler list for this device */ @@ -268,13 +268,13 @@ /* Install at head of Device.address_space list */ - handler_obj->address_space.next = obj_desc->device.address_space; + handler_obj->address_space.next = obj_desc->device.handler; /* * The Device object is the first reference on the handler_obj. * Each region that uses the handler adds a reference. */ - obj_desc->device.address_space = handler_obj; + obj_desc->device.handler = handler_obj; /* * Walk the namespace finding all of the regions this @@ -292,6 +292,17 @@ ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, handler_obj, NULL); + /* + * Now we can run the _REG methods for all Regions for this + * space ID. This is a separate walk in order to handle any + * interdependencies between regions and _REG methods. (i.e. handlers + * must be installed for all regions of this Space ID before we + * can run any _REG methods. + */ + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run, + handler_obj, NULL); + unlock_and_exit: (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); return_ACPI_STATUS (status); @@ -358,8 +369,8 @@ /* Find the address handler the user requested */ - handler_obj = obj_desc->device.address_space; - last_obj_ptr = &obj_desc->device.address_space; + handler_obj = obj_desc->device.handler; + last_obj_ptr = &obj_desc->device.handler; while (handler_obj) { /* We have a handler, see if user requested this one */ diff -Nru a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c --- a/drivers/acpi/executer/exdump.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/executer/exdump.c Thu Dec 11 23:14:25 2003 @@ -631,7 +631,7 @@ case ACPI_TYPE_DEVICE: - acpi_ex_out_pointer ("address_space", obj_desc->device.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->device.handler); acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify); break; @@ -669,7 +669,7 @@ acpi_ex_out_integer ("Flags", obj_desc->region.flags); acpi_ex_out_address ("Address", obj_desc->region.address); acpi_ex_out_integer ("Length", obj_desc->region.length); - acpi_ex_out_pointer ("address_space", obj_desc->region.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->region.handler); acpi_ex_out_pointer ("Next", obj_desc->region.next); break; @@ -690,7 +690,7 @@ acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); - acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->processor.handler); break; @@ -698,7 +698,7 @@ acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); - acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space); + acpi_ex_out_pointer ("Handler", obj_desc->thermal_zone.handler); break; diff -Nru a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c --- a/drivers/acpi/hardware/hwacpi.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/hardware/hwacpi.c Thu Dec 11 23:14:25 2003 @@ -119,7 +119,7 @@ * system does not support mode transition. */ if (!acpi_gbl_FADT->smi_cmd) { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No SMI_CMD in FADT, mode transition failed.\n")); + ACPI_REPORT_ERROR (("No SMI_CMD in FADT, mode transition failed.\n")); return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } @@ -131,7 +131,7 @@ * transitions are not supported. */ if (!acpi_gbl_FADT->acpi_enable && !acpi_gbl_FADT->acpi_disable) { - ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "No mode transition supported in this system.\n")); + ACPI_REPORT_ERROR (("No ACPI mode transition supported in this system (enable/disable both zero)\n")); return_ACPI_STATUS (AE_OK); } @@ -162,6 +162,7 @@ } if (ACPI_FAILURE (status)) { + ACPI_REPORT_ERROR (("Could not write mode change, %s\n", acpi_format_exception (status))); return_ACPI_STATUS (status); } @@ -171,18 +172,16 @@ */ retry = 3000; while (retry) { - status = AE_NO_HARDWARE_RESPONSE; - if (acpi_hw_get_mode() == mode) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Mode %X successfully enabled\n", mode)); - status = AE_OK; - break; + return_ACPI_STATUS (AE_OK); } acpi_os_stall(1000); retry--; } - return_ACPI_STATUS (status); + ACPI_REPORT_ERROR (("Hardware never changed modes\n")); + return_ACPI_STATUS (AE_NO_HARDWARE_RESPONSE); } diff -Nru a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c --- a/drivers/acpi/hardware/hwsleep.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/hardware/hwsleep.c Thu Dec 11 23:14:25 2003 @@ -181,6 +181,13 @@ return_ACPI_STATUS (status); } + /* Set the system indicators to show the desired sleep state. */ + + status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + return_ACPI_STATUS (AE_OK); } @@ -220,27 +227,28 @@ return_ACPI_STATUS (AE_AML_OPERAND_VALUE); } - sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); - /* Clear wake status */ + if (sleep_state != ACPI_STATE_S5) { + /* Clear wake status */ - status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - status = acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } + status = acpi_hw_clear_acpi_status (ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } - /* Disable BM arbitration */ + /* Disable BM arbitration */ - status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 1, ACPI_MTX_DO_NOT_LOCK); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } } status = acpi_hw_disable_non_wakeup_gpes(); @@ -297,11 +305,13 @@ return_ACPI_STATUS (status); } - /* - * Wait a second, then try again. This is to get S4/5 to work on all machines. - */ if (sleep_state > ACPI_STATE_S3) { /* + * We wanted to sleep > S3, but it didn't happen (by virtue of the fact that + * we are still executing!) + * + * Wait ten seconds, then try again. This is to get S4/S5 to work on all machines. + * * We wait so long to allow chipsets that poll this reg very slowly to * still read the right value. Ideally, this entire block would go * away entirely. @@ -354,6 +364,7 @@ ACPI_FUNCTION_TRACE ("acpi_enter_sleep_state_s4bios"); + acpi_set_register (ACPI_BITREG_WAKE_STATUS, 1, ACPI_MTX_DO_NOT_LOCK); acpi_hw_clear_acpi_status(ACPI_MTX_DO_NOT_LOCK); @@ -389,15 +400,38 @@ acpi_status acpi_leave_sleep_state ( - u8 sleep_state) + u8 sleep_state) { - struct acpi_object_list arg_list; - union acpi_object arg; - acpi_status status; + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status; + struct acpi_bit_register_info *sleep_type_reg_info; + struct acpi_bit_register_info *sleep_enable_reg_info; + u32 pm1x_control; ACPI_FUNCTION_TRACE ("acpi_leave_sleep_state"); + /* Some machines require SLP_TYPE and SLP_EN to be cleared */ + + sleep_type_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_TYPE_A); + sleep_enable_reg_info = acpi_hw_get_bit_register_info (ACPI_BITREG_SLEEP_ENABLE); + + /* Get current value of PM1A control */ + + status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1_CONTROL, &pm1x_control); + if (ACPI_SUCCESS (status)) { + /* Clear SLP_TYP and SLP_EN */ + + pm1x_control &= ~(sleep_type_reg_info->access_bit_mask | + sleep_enable_reg_info->access_bit_mask); + + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1A_CONTROL, pm1x_control); + acpi_hw_register_write (ACPI_MTX_DO_NOT_LOCK, + ACPI_REGISTER_PM1B_CONTROL, pm1x_control); + } /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ @@ -407,12 +441,17 @@ arg_list.count = 1; arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = sleep_state; /* Ignore any errors from these methods */ + arg.integer.value = 0; + status = acpi_evaluate_object (NULL, "\\_SI._SST", &arg_list, NULL); + if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { + ACPI_REPORT_ERROR (("Method _SST failed, %s\n", acpi_format_exception (status))); + } + + arg.integer.value = sleep_state; status = acpi_evaluate_object (NULL, "\\_BFS", &arg_list, NULL); if (ACPI_FAILURE (status) && status != AE_NOT_FOUND) { ACPI_REPORT_ERROR (("Method _BFS failed, %s\n", acpi_format_exception (status))); @@ -430,8 +469,8 @@ return_ACPI_STATUS (status); } - /* Disable BM arbitration */ - status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); + /* Enable BM arbitration */ + status = acpi_set_register (ACPI_BITREG_ARB_DISABLE, 0, ACPI_MTX_LOCK); return_ACPI_STATUS (status); } diff -Nru a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c --- a/drivers/acpi/parser/psxface.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/parser/psxface.c Thu Dec 11 23:14:25 2003 @@ -127,7 +127,8 @@ op = acpi_ps_create_scope_op (); if (!op) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup1; } /* @@ -142,20 +143,24 @@ walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id, NULL, NULL, NULL); if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup2; } status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, NULL, NULL, 1); if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (walk_state); - return_ACPI_STATUS (status); + goto cleanup3; } /* Parse the AML */ status = acpi_ps_parse_aml (walk_state); acpi_ps_delete_parse_tree (op); + if (ACPI_FAILURE (status)) { + goto cleanup1; /* Walk state is already deleted */ + + } /* * 2) Execute the method. Performs second pass parse simultaneously @@ -168,7 +173,8 @@ op = acpi_ps_create_scope_op (); if (!op) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup1; } /* Init new op with the method name and pointer back to the NS node */ @@ -180,22 +186,30 @@ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { - return_ACPI_STATUS (AE_NO_MEMORY); + status = AE_NO_MEMORY; + goto cleanup2; } status = acpi_ds_init_aml_walk (walk_state, op, method_node, obj_desc->method.aml_start, obj_desc->method.aml_length, params, return_obj_desc, 3); if (ACPI_FAILURE (status)) { - acpi_ds_delete_walk_state (walk_state); - return_ACPI_STATUS (status); + goto cleanup3; } /* * The walk of the parse tree is where we actually execute the method */ status = acpi_ps_parse_aml (walk_state); + goto cleanup2; /* Walk state already deleted */ + + +cleanup3: + acpi_ds_delete_walk_state (walk_state); + +cleanup2: acpi_ps_delete_parse_tree (op); +cleanup1: if (params) { /* Take away the extra reference that we gave the parameters above */ @@ -204,6 +218,10 @@ (void) acpi_ut_update_object_reference (params[i], REF_DECREMENT); } + } + + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); } /* diff -Nru a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c --- a/drivers/acpi/resources/rsirq.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/resources/rsirq.c Thu Dec 11 23:14:25 2003 @@ -132,26 +132,28 @@ temp8 = *buffer; /* - * Check for HE, LL or HL + * Check for HE, LL interrupts */ - if (temp8 & 0x01) { + switch (temp8 & 0x09) { + case 0x01: /* HE */ output_struct->data.irq.edge_level = ACPI_EDGE_SENSITIVE; output_struct->data.irq.active_high_low = ACPI_ACTIVE_HIGH; - } - else { - if (temp8 & 0x8) { - output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; - output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; - } - else { - /* - * Only _LL and _HE polarity/trigger interrupts - * are allowed (ACPI spec v1.0b ection 6.4.2.1), - * so an error will occur if we reach this point - */ - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid interrupt polarity/trigger in resource list\n")); - return_ACPI_STATUS (AE_BAD_DATA); - } + break; + + case 0x08: /* LL */ + output_struct->data.irq.edge_level = ACPI_LEVEL_SENSITIVE; + output_struct->data.irq.active_high_low = ACPI_ACTIVE_LOW; + break; + + default: + /* + * Only _LL and _HE polarity/trigger interrupts + * are allowed (ACPI spec, section "IRQ Format") + * so 0x00 and 0x09 are illegal. + */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Invalid interrupt polarity/trigger in resource list, %X\n", temp8)); + return_ACPI_STATUS (AE_BAD_DATA); } /* @@ -419,7 +421,7 @@ * Point the String pointer to the end of this structure. */ output_struct->data.extended_irq.resource_source.string_ptr = - (char *)(output_struct + struct_size); + (char *)((char *) output_struct + struct_size); temp_ptr = (u8 *) output_struct->data.extended_irq.resource_source.string_ptr; diff -Nru a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c --- a/drivers/acpi/tables/tbget.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/tables/tbget.c Thu Dec 11 23:14:25 2003 @@ -455,6 +455,7 @@ if (instance == 1) { /* Get the first */ + *table_ptr_loc = NULL; if (acpi_gbl_table_lists[table_type].next) { *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer; } diff -Nru a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c --- a/drivers/acpi/utilities/utdelete.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/utilities/utdelete.c Thu Dec 11 23:14:25 2003 @@ -140,7 +140,7 @@ /* Walk the handler list for this device */ - handler_desc = object->device.address_space; + handler_desc = object->device.handler; while (handler_desc) { next_desc = handler_desc->address_space.next; acpi_ut_remove_reference (handler_desc); @@ -193,7 +193,7 @@ * default handlers -- and therefore, we created the context object * locally, it was not created by an external caller. */ - handler_desc = object->region.address_space; + handler_desc = object->region.handler; if (handler_desc) { if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { obj_pointer = second_desc->extra.region_context; diff -Nru a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c --- a/drivers/acpi/utilities/utglobal.c Thu Dec 11 23:14:25 2003 +++ b/drivers/acpi/utilities/utglobal.c Thu Dec 11 23:14:25 2003 @@ -562,12 +562,12 @@ if (node->descriptor != ACPI_DESC_TYPE_NAMED) { - return ("INVALID NODE"); + return ("****"); } if (!acpi_ut_valid_acpi_name (* (u32 *) node->name.ascii)) { - return ("INVALID NODE NAME"); + return ("----"); } return (node->name.ascii); diff -Nru a/include/acpi/acconfig.h b/include/acpi/acconfig.h --- a/include/acpi/acconfig.h Thu Dec 11 23:14:25 2003 +++ b/include/acpi/acconfig.h Thu Dec 11 23:14:25 2003 @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20031029 +#define ACPI_CA_VERSION 0x20031203 /* Maximum objects in the various object caches */ diff -Nru a/include/acpi/acevents.h b/include/acpi/acevents.h --- a/include/acpi/acevents.h Thu Dec 11 23:14:25 2003 +++ b/include/acpi/acevents.h Thu Dec 11 23:14:25 2003 @@ -182,6 +182,17 @@ union acpi_operand_object *region_obj, u8 acpi_ns_is_locked); +acpi_status +acpi_ev_execute_reg_method ( + union acpi_operand_object *region_obj, + u32 function); + +acpi_status +acpi_ev_reg_run ( + acpi_handle obj_handle, + u32 level, + void *context, + void **return_value); /* * Evregini - Region initialization and setup diff -Nru a/include/acpi/acglobal.h b/include/acpi/acglobal.h --- a/include/acpi/acglobal.h Thu Dec 11 23:14:25 2003 +++ b/include/acpi/acglobal.h Thu Dec 11 23:14:25 2003 @@ -106,6 +106,9 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; ACPI_EXTERN u8 acpi_gbl_integer_nybble_width; + +/* Keep local copies of these FADT-based registers */ + ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; diff -Nru a/include/acpi/acobject.h b/include/acpi/acobject.h --- a/include/acpi/acobject.h Thu Dec 11 23:14:25 2003 +++ b/include/acpi/acobject.h Thu Dec 11 23:14:25 2003 @@ -114,7 +114,7 @@ #define ACPI_COMMON_NOTIFY_INFO \ union acpi_operand_object *system_notify; /* Handler for system notifies */\ union acpi_operand_object *device_notify; /* Handler for driver notifies */\ - union acpi_operand_object *address_space; /* Handler for Address space */ + union acpi_operand_object *handler; /* Handler for Address space */ /****************************************************************************** @@ -214,7 +214,7 @@ ACPI_OBJECT_COMMON_HEADER u8 space_id; - union acpi_operand_object *address_space; /* Handler for region access */ + union acpi_operand_object *handler; /* Handler for region access */ struct acpi_namespace_node *node; /* containing object */ union acpi_operand_object *next; u32 length;