| Kernel v2.4.21-rc6-ac1 /linux-2.4.20rc2ac2-acpi-20030513.patch |
|---|
| Filename: | /linux-2.4.20rc2ac2-acpi-20030513.patch |
| Lines Added: | 2929 |
| Lines Deleted: | 0 |
| Also changed in: |
(Previous)
2.4.21-rc5-ac2
(Following) |
 2.4.21-rc6-ac1
 linux-2.4.20rc2ac2-acpi-20030513.patch
diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.21rc6/linux-2.4.20rc2ac2-acpi-20030513.patch linux.21rc6-ac1/li+
nux-2.4.20rc2ac2-acpi-20030513.patch
--- linux.21rc6/linux-2.4.20rc2ac2-acpi-20030513.patch 1970-01-01 01:00:00.000000000 +0100
+++ linux.21rc6-ac1/linux-2.4.20rc2ac2-acpi-20030513.patch 2003-05-13 02:10:13.000000000 +0100
@@ -0,0 +1,2929 @@
+diff -urN linux-2.4.20/drivers/acpi/dispatcher/dsinit.c linux-2.4.20-acpi/drivers/acpi/dispatcher/dsinit.c
+--- linux-2.4.20/drivers/acpi/dispatcher/dsinit.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/dispatcher/dsinit.c 2003-05-13 02:53:24.000000000 +0200
+@@ -222,8 +222,8 @@
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
+- "\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
+- table_desc->pointer->signature, info.object_count,
++ "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
++ table_desc->pointer->signature, table_desc->table_id, info.object_count,
+ info.device_count, info.method_count, info.op_region_count));
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+diff -urN linux-2.4.20/drivers/acpi/dispatcher/dsopcode.c linux-2.4.20-acpi/drivers/acpi/dispatcher/dsopcode.c
+--- linux-2.4.20/drivers/acpi/dispatcher/dsopcode.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/dispatcher/dsopcode.c 2003-05-13 02:53:25.000000000 +0200
+@@ -82,7 +82,7 @@
+ union acpi_parse_object *arg;
+
+
+- ACPI_FUNCTION_TRACE ("acpi_ds_execute_arguments");
++ ACPI_FUNCTION_TRACE ("ds_execute_arguments");
+
+
+ /*
+@@ -99,7 +99,7 @@
+
+ /* Create and initialize a new parser state */
+
+- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
++ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+ if (!walk_state) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+@@ -139,7 +139,7 @@
+
+ /* Create and initialize a new parser state */
+
+- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
++ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+ if (!walk_state) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+diff -urN linux-2.4.20/drivers/acpi/events/evmisc.c linux-2.4.20-acpi/drivers/acpi/events/evmisc.c
+--- linux-2.4.20/drivers/acpi/events/evmisc.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evmisc.c 2003-05-13 02:53:25.000000000 +0200
+@@ -156,10 +156,10 @@
+ case ACPI_TYPE_POWER:
+
+ if (notify_value <= ACPI_MAX_SYS_NOTIFY) {
+- handler_obj = obj_desc->common_notify.sys_handler;
++ handler_obj = obj_desc->common_notify.system_notify;
+ }
+ else {
+- handler_obj = obj_desc->common_notify.drv_handler;
++ handler_obj = obj_desc->common_notify.device_notify;
+ }
+ break;
+
+@@ -171,8 +171,8 @@
+
+ /* If there is any handler to run, schedule the dispatcher */
+
+- if ((acpi_gbl_sys_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+- (acpi_gbl_drv_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
++ if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
++ (acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) ||
+ handler_obj) {
+ notify_info = acpi_ut_create_generic_state ();
+ if (!notify_info) {
+@@ -235,17 +235,17 @@
+ if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) {
+ /* Global system notification handler */
+
+- if (acpi_gbl_sys_notify.handler) {
+- global_handler = acpi_gbl_sys_notify.handler;
+- global_context = acpi_gbl_sys_notify.context;
++ if (acpi_gbl_system_notify.handler) {
++ global_handler = acpi_gbl_system_notify.handler;
++ global_context = acpi_gbl_system_notify.context;
+ }
+ }
+ else {
+ /* Global driver notification handler */
+
+- if (acpi_gbl_drv_notify.handler) {
+- global_handler = acpi_gbl_drv_notify.handler;
+- global_context = acpi_gbl_drv_notify.context;
++ if (acpi_gbl_device_notify.handler) {
++ global_handler = acpi_gbl_device_notify.handler;
++ global_context = acpi_gbl_device_notify.context;
+ }
+ }
+
+@@ -259,8 +259,8 @@
+
+ handler_obj = notify_info->notify.handler_obj;
+ if (handler_obj) {
+- handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value,
+- handler_obj->notify_handler.context);
++ handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value,
++ handler_obj->notify.context);
+ }
+
+ /* All done with the info object */
+diff -urN linux-2.4.20/drivers/acpi/events/evregion.c linux-2.4.20-acpi/drivers/acpi/events/evregion.c
+--- linux-2.4.20/drivers/acpi/events/evregion.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evregion.c 2003-05-13 02:53:25.000000000 +0200
+@@ -161,10 +161,10 @@
+ }
+
+ /*
+- * _REG method has two arguments
+- * Arg0: Integer: Operation region space ID
++ * _REG method has two arguments
++ * Arg0: Integer: Operation region space ID
+ * Same value as region_obj->Region.space_id
+- * Arg1: Integer: connection status
++ * Arg1: Integer: connection status
+ * 1 for connecting the handler,
+ * 0 for disconnecting the handler
+ * Passed as a parameter
+@@ -180,16 +180,14 @@
+ goto cleanup;
+ }
+
+- /*
+- * Set up the parameter objects
+- */
++ /* Set up the parameter objects */
++
+ params[0]->integer.value = region_obj->region.space_id;
+ params[1]->integer.value = function;
+ params[2] = NULL;
+
+- /*
+- * Execute the method, no return value
+- */
++ /* Execute the method, no return value */
++
+ ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL));
+ status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL);
+
+@@ -245,10 +243,9 @@
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+- /*
+- * Ensure that there is a handler associated with this region
+- */
+- handler_desc = region_obj->region.addr_handler;
++ /* Ensure that there is a handler associated with this region */
++
++ handler_desc = region_obj->region.address_space;
+ if (!handler_desc) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n",
+ region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+@@ -264,24 +261,23 @@
+ /*
+ * This region has not been initialized yet, do it
+ */
+- region_setup = handler_desc->addr_handler.setup;
++ region_setup = handler_desc->address_space.setup;
+ if (!region_setup) {
+- /*
+- * Bad news, no init routine and not init'd
+- */
++ /* No initialization routine, exit with error */
++
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n",
+ region_obj, acpi_ut_get_region_name (region_obj->region.space_id)));
+- return_ACPI_STATUS (AE_UNKNOWN_STATUS);
++ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+ /*
+ * We must exit the interpreter because the region setup will potentially
+- * execute control methods
++ * execute control methods (e.g., _REG method for this region)
+ */
+ acpi_ex_exit_interpreter ();
+
+ status = region_setup (region_obj, ACPI_REGION_ACTIVATE,
+- handler_desc->addr_handler.context, ®ion_context);
++ handler_desc->address_space.context, ®ion_context);
+
+ /* Re-enter the interpreter */
+
+@@ -290,9 +286,8 @@
+ return_ACPI_STATUS (status2);
+ }
+
+- /*
+- * Init routine may fail
+- */
++ /* Check for failure of the Region Setup */
++
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n",
+ acpi_format_exception (status),
+@@ -300,40 +295,50 @@
+ return_ACPI_STATUS (status);
+ }
+
+- region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
+-
+ /*
+- * Save the returned context for use in all accesses to
+- * this particular region.
++ * Region initialization may have been completed by region_setup
+ */
+- region_obj2->extra.region_context = region_context;
++ if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
++ region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
++
++ if (region_obj2->extra.region_context) {
++ /* The handler for this region was already installed */
++
++ ACPI_MEM_FREE (region_context);
++ }
++ else {
++ /*
++ * Save the returned context for use in all accesses to
++ * this particular region
++ */
++ region_obj2->extra.region_context = region_context;
++ }
++ }
+ }
+
+- /*
+- * We have everything we need, begin the process
+- */
+- handler = handler_desc->addr_handler.handler;
++ /* We have everything we need, we can invoke the address space handler */
++
++ handler = handler_desc->address_space.handler;
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
+- ®ion_obj->region.addr_handler->addr_handler, handler,
++ ®ion_obj->region.address_space->address_space, handler,
+ ACPI_HIDWORD (address), ACPI_LODWORD (address),
+ acpi_ut_get_region_name (region_obj->region.space_id)));
+
+- if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
++ if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ /*
+- * For handlers other than the default (supplied) handlers, we must
+- * exit the interpreter because the handler *might* block -- we don't
+- * know what it will do, so we can't hold the lock on the intepreter.
++ * For handlers other than the default (supplied) handlers, we must
++ * exit the interpreter because the handler *might* block -- we don't
++ * know what it will do, so we can't hold the lock on the intepreter.
+ */
+ acpi_ex_exit_interpreter();
+ }
+
+- /*
+- * Invoke the handler.
+- */
++ /* Call the handler */
++
+ status = handler (function, address, bit_width, value,
+- handler_desc->addr_handler.context,
++ handler_desc->address_space.context,
+ region_obj2->extra.region_context);
+
+ if (ACPI_FAILURE (status)) {
+@@ -342,7 +347,7 @@
+ acpi_format_exception (status)));
+ }
+
+- if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
++ if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+ /*
+ * We just returned from a non-default handler, we must re-enter the
+ * interpreter
+@@ -393,35 +398,30 @@
+ }
+ region_context = region_obj2->extra.region_context;
+
+- /*
+- * Get the address handler from the region object
+- */
+- handler_obj = region_obj->region.addr_handler;
++ /* Get the address handler from the region object */
++
++ handler_obj = region_obj->region.address_space;
+ if (!handler_obj) {
+- /*
+- * This region has no handler, all done
+- */
++ /* This region has no handler, all done */
++
+ return_VOID;
+ }
+
++ /* Find this region in the handler's list */
+
+- /*
+- * Find this region in the handler's list
+- */
+- obj_desc = handler_obj->addr_handler.region_list;
+- last_obj_ptr = &handler_obj->addr_handler.region_list;
++ obj_desc = handler_obj->address_space.region_list;
++ last_obj_ptr = &handler_obj->address_space.region_list;
+
+ while (obj_desc) {
+- /*
+- * See if this is the one
+- */
++ /* Is this the correct Region? */
++
+ if (obj_desc == region_obj) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Removing Region %p from address handler %p\n",
+ region_obj, handler_obj));
+- /*
+- * This is it, remove it from the handler's list
+- */
++
++ /* This is it, remove it from the handler's list */
++
+ *last_obj_ptr = obj_desc->region.next;
+ obj_desc->region.next = NULL; /* Must clear field */
+
+@@ -432,9 +432,8 @@
+ }
+ }
+
+- /*
+- * Now stop region accesses by executing the _REG method
+- */
++ /* Now stop region accesses by executing the _REG method */
++
+ status = acpi_ev_execute_reg_method (region_obj, 0);
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n",
+@@ -449,16 +448,14 @@
+ }
+ }
+
+- /*
+- * Call the setup handler with the deactivate notification
+- */
+- region_setup = handler_obj->addr_handler.setup;
++ /* Call the setup handler with the deactivate notification */
++
++ region_setup = handler_obj->address_space.setup;
+ status = region_setup (region_obj, ACPI_REGION_DEACTIVATE,
+- handler_obj->addr_handler.context, ®ion_context);
++ handler_obj->address_space.context, ®ion_context);
++
++ /* Init routine may fail, Just ignore errors */
+
+- /*
+- * Init routine may fail, Just ignore errors
+- */
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n",
+ acpi_format_exception (status),
+@@ -468,31 +465,29 @@
+ region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE);
+
+ /*
+- * Remove handler reference in the region
++ * Remove handler reference in the region
+ *
+- * NOTE: this doesn't mean that the region goes away
+- * The region is just inaccessible as indicated to
+- * the _REG method
++ * NOTE: this doesn't mean that the region goes away
++ * The region is just inaccessible as indicated to
++ * the _REG method
+ *
+- * If the region is on the handler's list
+- * this better be the region's handler
++ * If the region is on the handler's list
++ * this better be the region's handler
+ */
+- region_obj->region.addr_handler = NULL;
++ region_obj->region.address_space = NULL;
++ acpi_ut_remove_reference (handler_obj);
+
+ return_VOID;
++ }
+
+- } /* found the right handler */
++ /* Walk the linked list of handlers */
+
+- /*
+- * Move through the linked list of handlers
+- */
+ last_obj_ptr = &obj_desc->region.next;
+ obj_desc = obj_desc->region.next;
+ }
+
+- /*
+- * If we get here, the region was not in the handler's region list
+- */
++ /* If we get here, the region was not in the handler's region list */
++
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Cannot remove region %p from address handler %p\n",
+ region_obj, handler_obj));
+@@ -534,16 +529,19 @@
+ 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
+- */
+- region_obj->region.next = handler_obj->addr_handler.region_list;
+- handler_obj->addr_handler.region_list = region_obj;
++ /* Link this region to the front of the handler's list */
+
+- /*
+- * Set the region's handler
+- */
+- region_obj->region.addr_handler = handler_obj;
++ region_obj->region.next = handler_obj->address_space.region_list;
++ handler_obj->address_space.region_list = region_obj;
++
++ /* Install the region's handler */
++
++ if (region_obj->region.address_space) {
++ return_ACPI_STATUS (AE_ALREADY_EXISTS);
++ }
++
++ region_obj->region.address_space = handler_obj;
++ acpi_ut_add_reference (handler_obj);
+
+ /*
+ * Tell all users that this region is usable by running the _REG
+@@ -571,14 +569,14 @@
+
+ /*******************************************************************************
+ *
+- * FUNCTION: acpi_ev_addr_handler_helper
++ * FUNCTION: acpi_ev_install_handler
+ *
+ * PARAMETERS: Handle - Node to be dumped
+ * Level - Nesting level of the handle
+ * Context - Passed into acpi_ns_walk_namespace
+ *
+ * DESCRIPTION: This routine installs an address handler into objects that are
+- * of type Region.
++ * of type Region or Device.
+ *
+ * If the Object is a Device, and the device has a handler of
+ * the same type then the search is terminated in that branch.
+@@ -589,20 +587,20 @@
+ ******************************************************************************/
+
+ acpi_status
+-acpi_ev_addr_handler_helper (
++acpi_ev_install_handler (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+ void **return_value)
+ {
+ union acpi_operand_object *handler_obj;
+- union acpi_operand_object *tmp_obj;
++ union acpi_operand_object *next_handler_obj;
+ union acpi_operand_object *obj_desc;
+ struct acpi_namespace_node *node;
+ acpi_status status;
+
+
+- ACPI_FUNCTION_NAME ("ev_addr_handler_helper");
++ ACPI_FUNCTION_NAME ("ev_install_handler");
+
+
+ handler_obj = (union acpi_operand_object *) context;
+@@ -621,8 +619,8 @@
+ }
+
+ /*
+- * We only care about regions.and objects
+- * that can have address handlers
++ * We only care about regions.and objects
++ * that are allowed to have address space handlers
+ */
+ if ((node->type != ACPI_TYPE_DEVICE) &&
+ (node->type != ACPI_TYPE_REGION) &&
+@@ -634,81 +632,70 @@
+
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (!obj_desc) {
+- /*
+- * The object DNE, we don't care about it
+- */
++ /* No object, just exit */
++
+ return (AE_OK);
+ }
+
+- /*
+- * Devices are handled different than regions
+- */
++ /* Devices are handled different than regions */
++
+ if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) {
+- /*
+- * See if this guy has any handlers
+- */
+- tmp_obj = obj_desc->device.addr_handler;
+- while (tmp_obj) {
+- /*
+- * Now let's see if it's for the same address space.
+- */
+- if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) {
+- /*
+- * It's for the same address space
+- */
++ /* Check if this Device already has a handler for this address space */
++
++ next_handler_obj = obj_desc->device.address_space;
++ while (next_handler_obj) {
++ /* Found a handler, is it for the same address space? */
++
++ if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "Found handler for region [%s] in device %p(%p) handler %p\n",
+- acpi_ut_get_region_name (handler_obj->addr_handler.space_id),
+- obj_desc, tmp_obj, handler_obj));
++ acpi_ut_get_region_name (handler_obj->address_space.space_id),
++ obj_desc, next_handler_obj, handler_obj));
+
+ /*
+- * Since the object we found it on was a device, then it
+- * means that someone has already installed a handler for
+- * the branch of the namespace from this device on. Just
+- * bail out telling the walk routine to not traverse this
+- * branch. This preserves the scoping rule for handlers.
++ * Since the object we found it on was a device, then it
++ * means that someone has already installed a handler for
++ * the branch of the namespace from this device on. Just
++ * bail out telling the walk routine to not traverse this
++ * branch. This preserves the scoping rule for handlers.
+ */
+ return (AE_CTRL_DEPTH);
+ }
+
+- /*
+- * Move through the linked list of handlers
+- */
+- tmp_obj = tmp_obj->addr_handler.next;
++ /* Walk the linked list of handlers attached to this device */
++
++ next_handler_obj = next_handler_obj->address_space.next;
+ }
+
+ /*
+- * As long as the device didn't have a handler for this
+- * space we don't care about it. We just ignore it and
+- * proceed.
++ * As long as the device didn't have a handler for this
++ * space we don't care about it. We just ignore it and
++ * proceed.
+ */
+ return (AE_OK);
+ }
+
+- /*
+- * Only here if it was a region
+- */
+- if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) {
++ /* Object is a Region */
++
++ if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
+ /*
+- * This region is for a different address space
+- * ignore it
++ * This region is for a different address space
++ * -- just ignore it
+ */
+ return (AE_OK);
+ }
+
+ /*
+- * Now we have a region and it is for the handler's address
+- * space type.
++ * Now we have a region and it is for the handler's address
++ * space type.
+ *
+- * First disconnect region for any previous handler (if any)
++ * First disconnect region for any previous handler (if any)
+ */
+ acpi_ev_detach_region (obj_desc, FALSE);
+
+- /*
+- * Then connect the region to the new handler
+- */
+- status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
++ /* Connect the region to the new handler */
+
++ status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE);
+ return (status);
+ }
+
+diff -urN linux-2.4.20/drivers/acpi/events/evrgnini.c linux-2.4.20-acpi/drivers/acpi/events/evrgnini.c
+--- linux-2.4.20/drivers/acpi/events/evrgnini.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evrgnini.c 2003-05-13 02:53:25.000000000 +0200
+@@ -165,10 +165,11 @@
+ void **region_context)
+ {
+ acpi_status status = AE_OK;
+- acpi_integer temp;
++ acpi_integer pci_value;
+ struct acpi_pci_id *pci_id = *region_context;
+ union acpi_operand_object *handler_obj;
+- struct acpi_namespace_node *node;
++ struct acpi_namespace_node *parent_node;
++ struct acpi_namespace_node *pci_root_node;
+ union acpi_operand_object *region_obj = (union acpi_operand_object *) handle;
+ struct acpi_device_id object_hID;
+
+@@ -176,7 +177,7 @@
+ ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup");
+
+
+- handler_obj = region_obj->region.addr_handler;
++ handler_obj = region_obj->region.address_space;
+ if (!handler_obj) {
+ /*
+ * No installed handler. This shouldn't happen because the dispatch
+@@ -187,45 +188,15 @@
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
++ *region_context = NULL;
+ if (function == ACPI_REGION_DEACTIVATE) {
+ if (pci_id) {
+ ACPI_MEM_FREE (pci_id);
+- *region_context = NULL;
+ }
+-
+ return_ACPI_STATUS (status);
+ }
+
+- /* Create a new context */
+-
+- pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
+- if (!pci_id) {
+- return_ACPI_STATUS (AE_NO_MEMORY);
+- }
+-
+- /*
+- * For PCI Config space access, we have to pass the segment, bus,
+- * device and function numbers. This routine must acquire those.
+- */
+-
+- /*
+- * First get device and function numbers from the _ADR object
+- * in the parent's scope.
+- */
+- node = acpi_ns_get_parent_node (region_obj->region.node);
+-
+- /* Evaluate the _ADR object */
+-
+- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp);
+-
+- /*
+- * The default is zero, and since the allocation above zeroed
+- * the data, just do nothing on failure.
+- */
+- if (ACPI_SUCCESS (status)) {
+- pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp));
+- pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp));
+- }
++ parent_node = acpi_ns_get_parent_node (region_obj->region.node);
+
+ /*
+ * Get the _SEG and _BBN values from the device upon which the handler
+@@ -236,16 +207,16 @@
+ */
+
+ /*
+- * If the addr_handler.Node is still pointing to the root, we need
++ * If the address_space.Node is still pointing to the root, we need
+ * to scan upward for a PCI Root bridge and re-associate the op_region
+ * handlers with that device.
+ */
+- if (handler_obj->addr_handler.node == acpi_gbl_root_node) {
+- /*
+- * Node is currently the parent object
+- */
+- while (node != acpi_gbl_root_node) {
+- status = acpi_ut_execute_HID (node, &object_hID);
++ if (handler_obj->address_space.node == acpi_gbl_root_node) {
++ /* Start search from the parent object */
++
++ pci_root_node = parent_node;
++ while (pci_root_node != acpi_gbl_root_node) {
++ status = acpi_ut_execute_HID (pci_root_node, &object_hID);
+ if (ACPI_SUCCESS (status)) {
+ /* Got a valid _HID, check if this is a PCI root */
+
+@@ -253,44 +224,89 @@
+ sizeof (PCI_ROOT_HID_STRING)))) {
+ /* Install a handler for this PCI root bridge */
+
+- status = acpi_install_address_space_handler ((acpi_handle) node,
++ status = acpi_install_address_space_handler ((acpi_handle) pci_root_node,
+ ACPI_ADR_SPACE_PCI_CONFIG,
+ ACPI_DEFAULT_HANDLER, NULL, NULL);
+ if (ACPI_FAILURE (status)) {
+- ACPI_REPORT_ERROR (("Could not install pci_config handler for %4.4s, %s\n",
+- node->name.ascii, acpi_format_exception (status)));
++ if (status == AE_SAME_HANDLER) {
++ /*
++ * It is OK if the handler is already installed on the root
++ * bridge. Still need to return a context object for the
++ * new PCI_Config operation region, however.
++ */
++ status = AE_OK;
++ }
++ else {
++ ACPI_REPORT_ERROR ((
++ "Could not install pci_config handler for Root Bridge %4.4s, %s\n",
++ pci_root_node->name.ascii, acpi_format_exception (status)));
++ }
+ }
+ break;
+ }
+ }
+
+- node = acpi_ns_get_parent_node (node);
++ pci_root_node = acpi_ns_get_parent_node (pci_root_node);
+ }
++
++ /* PCI root bridge not found, use namespace root node */
+ }
+ else {
+- node = handler_obj->addr_handler.node;
++ pci_root_node = handler_obj->address_space.node;
+ }
+
+ /*
+- * The PCI segment number comes from the _SEG method
++ * If this region is now initialized, we are done.
++ * (install_address_space_handler could have initialized it)
+ */
+- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp);
+- if (ACPI_SUCCESS (status)) {
+- pci_id->segment = ACPI_LOWORD (temp);
++ if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
++ return_ACPI_STATUS (AE_OK);
++ }
++
++ /* Region is still not initialized. Create a new context */
++
++ pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id));
++ if (!pci_id) {
++ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+ /*
+- * The PCI bus number comes from the _BBN method
++ * For PCI_Config space access, we need the segment, bus,
++ * device and function numbers. Acquire them here.
+ */
+- status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp);
+- if (ACPI_SUCCESS (status)) {
+- pci_id->bus = ACPI_LOWORD (temp);
+- }
+
+ /*
+- * Complete this device's pci_id
++ * Get the PCI device and function numbers from the _ADR object
++ * contained in the parent's scope.
++ */
++ status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value);
++
++ /*
++ * The default is zero, and since the allocation above zeroed
++ * the data, just do nothing on failure.
+ */
+- acpi_os_derive_pci_id (node, region_obj->region.node, &pci_id);
++ if (ACPI_SUCCESS (status)) {
++ pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value));
++ pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value));
++ }
++
++ /* The PCI segment number comes from the _SEG method */
++
++ status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value);
++ if (ACPI_SUCCESS (status)) {
++ pci_id->segment = ACPI_LOWORD (pci_value);
++ }
++
++ /* The PCI bus number comes from the _BBN method */
++
++ status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value);
++ if (ACPI_SUCCESS (status)) {
++ pci_id->bus = ACPI_LOWORD (pci_value);
++ }
++
++ /* Complete this device's pci_id */
++
++ acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id);
+
+ *region_context = pci_id;
+ return_ACPI_STATUS (AE_OK);
+@@ -451,14 +467,15 @@
+ node = acpi_ns_get_parent_node (region_obj->region.node);
+ space_id = region_obj->region.space_id;
+
+- region_obj->region.addr_handler = NULL;
++ /* Setup defaults */
++
++ region_obj->region.address_space = NULL;
+ region_obj2->extra.method_REG = NULL;
+ region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
+ region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
+
+- /*
+- * Find any "_REG" method associated with this region definition
+- */
++ /* Find any "_REG" method associated with this region definition */
++
+ status = acpi_ns_search_node (*reg_name_ptr, node,
+ ACPI_TYPE_METHOD, &method_node);
+ if (ACPI_SUCCESS (status)) {
+@@ -475,29 +492,27 @@
+ * ie: acpi_gbl_root_node->parent_entry being set to NULL
+ */
+ while (node) {
+- /*
+- * Check to see if a handler exists
+- */
++ /* Check to see if a handler exists */
++
+ handler_obj = NULL;
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (obj_desc) {
+- /*
+- * Can only be a handler if the object exists
+- */
++ /* Can only be a handler if the object exists */
++
+ switch (node->type) {
+ case ACPI_TYPE_DEVICE:
+
+- handler_obj = obj_desc->device.addr_handler;
++ handler_obj = obj_desc->device.address_space;
+ break;
+
+ case ACPI_TYPE_PROCESSOR:
+
+- handler_obj = obj_desc->processor.addr_handler;
++ handler_obj = obj_desc->processor.address_space;
+ break;
+
+ case ACPI_TYPE_THERMAL:
+
+- handler_obj = obj_desc->thermal_zone.addr_handler;
++ handler_obj = obj_desc->thermal_zone.address_space;
+ break;
+
+ default:
+@@ -508,7 +523,7 @@
+ while (handler_obj) {
+ /* Is this handler of the correct type? */
+
+- if (handler_obj->addr_handler.space_id == space_id) {
++ if (handler_obj->address_space.space_id == space_id) {
+ /* Found correct handler */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+@@ -523,7 +538,7 @@
+
+ /* Try next handler in the list */
+
+- handler_obj = handler_obj->addr_handler.next;
++ handler_obj = handler_obj->address_space.next;
+ }
+ }
+
+@@ -534,9 +549,8 @@
+ node = acpi_ns_get_parent_node (node);
+ }
+
+- /*
+- * If we get here, there is no handler for this region
+- */
++ /* If we get here, there is no handler for this region */
++
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+ "No handler for region_type %s(%X) (region_obj %p)\n",
+ acpi_ut_get_region_name (space_id), space_id, region_obj));
+diff -urN linux-2.4.20/drivers/acpi/events/evxface.c linux-2.4.20-acpi/drivers/acpi/events/evxface.c
+--- linux-2.4.20/drivers/acpi/events/evxface.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evxface.c 2003-05-13 02:53:25.000000000 +0200
+@@ -244,22 +244,22 @@
+ /* Make sure the handler is not already installed */
+
+ if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
+- acpi_gbl_sys_notify.handler) ||
++ acpi_gbl_system_notify.handler) ||
+ ((handler_type == ACPI_DEVICE_NOTIFY) &&
+- acpi_gbl_drv_notify.handler)) {
++ acpi_gbl_device_notify.handler)) {
+ status = AE_ALREADY_EXISTS;
+ goto unlock_and_exit;
+ }
+
+ if (handler_type == ACPI_SYSTEM_NOTIFY) {
+- acpi_gbl_sys_notify.node = node;
+- acpi_gbl_sys_notify.handler = handler;
+- acpi_gbl_sys_notify.context = context;
++ acpi_gbl_system_notify.node = node;
++ acpi_gbl_system_notify.handler = handler;
++ acpi_gbl_system_notify.context = context;
+ }
+ else /* ACPI_DEVICE_NOTIFY */ {
+- acpi_gbl_drv_notify.node = node;
+- acpi_gbl_drv_notify.handler = handler;
+- acpi_gbl_drv_notify.context = context;
++ acpi_gbl_device_notify.node = node;
++ acpi_gbl_device_notify.handler = handler;
++ acpi_gbl_device_notify.context = context;
+ }
+
+ /* Global notify handler installed */
+@@ -282,13 +282,12 @@
+
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (obj_desc) {
+-
+ /* Object exists - make sure there's no handler */
+
+ if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
+- obj_desc->common_notify.sys_handler) ||
++ obj_desc->common_notify.system_notify) ||
+ ((handler_type == ACPI_DEVICE_NOTIFY) &&
+- obj_desc->common_notify.drv_handler)) {
++ obj_desc->common_notify.device_notify)) {
+ status = AE_ALREADY_EXISTS;
+ goto unlock_and_exit;
+ }
+@@ -305,6 +304,11 @@
+ /* Attach new object to the Node */
+
+ status = acpi_ns_attach_object (device, obj_desc, node->type);
++
++ /* Remove local reference to the object */
++
++ acpi_ut_remove_reference (obj_desc);
++
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
+@@ -318,15 +322,15 @@
+ goto unlock_and_exit;
+ }
+
+- notify_obj->notify_handler.node = node;
+- notify_obj->notify_handler.handler = handler;
+- notify_obj->notify_handler.context = context;
++ notify_obj->notify.node = node;
++ notify_obj->notify.handler = handler;
++ notify_obj->notify.context = context;
+
+ if (handler_type == ACPI_SYSTEM_NOTIFY) {
+- obj_desc->common_notify.sys_handler = notify_obj;
++ obj_desc->common_notify.system_notify = notify_obj;
+ }
+ else /* ACPI_DEVICE_NOTIFY */ {
+- obj_desc->common_notify.drv_handler = notify_obj;
++ obj_desc->common_notify.device_notify = notify_obj;
+ }
+ }
+
+@@ -395,22 +399,22 @@
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
+
+ if (((handler_type == ACPI_SYSTEM_NOTIFY) &&
+- !acpi_gbl_sys_notify.handler) ||
++ !acpi_gbl_system_notify.handler) ||
+ ((handler_type == ACPI_DEVICE_NOTIFY) &&
+- !acpi_gbl_drv_notify.handler)) {
++ !acpi_gbl_device_notify.handler)) {
+ status = AE_NOT_EXIST;
+ goto unlock_and_exit;
+ }
+
+ if (handler_type == ACPI_SYSTEM_NOTIFY) {
+- acpi_gbl_sys_notify.node = NULL;
+- acpi_gbl_sys_notify.handler = NULL;
+- acpi_gbl_sys_notify.context = NULL;
++ acpi_gbl_system_notify.node = NULL;
++ acpi_gbl_system_notify.handler = NULL;
++ acpi_gbl_system_notify.context = NULL;
+ }
+ else {
+- acpi_gbl_drv_notify.node = NULL;
+- acpi_gbl_drv_notify.handler = NULL;
+- acpi_gbl_drv_notify.context = NULL;
++ acpi_gbl_device_notify.node = NULL;
++ acpi_gbl_device_notify.handler = NULL;
++ acpi_gbl_device_notify.context = NULL;
+ }
+ }
+
+@@ -436,14 +440,14 @@
+ /* Object exists - make sure there's an existing handler */
+
+ if (handler_type == ACPI_SYSTEM_NOTIFY) {
+- notify_obj = obj_desc->common_notify.sys_handler;
++ notify_obj = obj_desc->common_notify.system_notify;
+ }
+ else {
+- notify_obj = obj_desc->common_notify.drv_handler;
++ notify_obj = obj_desc->common_notify.device_notify;
+ }
+
+ if ((!notify_obj) ||
+- (notify_obj->notify_handler.handler != handler)) {
++ (notify_obj->notify.handler != handler)) {
+ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+@@ -451,10 +455,10 @@
+ /* Remove the handler */
+
+ if (handler_type == ACPI_SYSTEM_NOTIFY) {
+- obj_desc->common_notify.sys_handler = NULL;
++ obj_desc->common_notify.system_notify = NULL;
+ }
+ else {
+- obj_desc->common_notify.drv_handler = NULL;
++ obj_desc->common_notify.device_notify = NULL;
+ }
+
+ acpi_ut_remove_reference (notify_obj);
+diff -urN linux-2.4.20/drivers/acpi/events/evxfevnt.c linux-2.4.20-acpi/drivers/acpi/events/evxfevnt.c
+--- linux-2.4.20/drivers/acpi/events/evxfevnt.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evxfevnt.c 2003-05-13 02:53:25.000000000 +0200
+@@ -654,7 +654,11 @@
+ }
+
+ status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE);
++
++ /* Remove local reference to the object */
++
+ acpi_ut_remove_reference (obj_desc);
++
+ if (ACPI_FAILURE (status)) {
+ goto unlock_and_exit;
+ }
+diff -urN linux-2.4.20/drivers/acpi/events/evxfregn.c linux-2.4.20-acpi/drivers/acpi/events/evxfregn.c
+--- linux-2.4.20/drivers/acpi/events/evxfregn.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/events/evxfregn.c 2003-05-13 02:53:25.000000000 +0200
+@@ -154,7 +154,7 @@
+ break;
+
+ default:
+- status = AE_NOT_EXIST;
++ status = AE_BAD_PARAMETER;
+ goto unlock_and_exit;
+ }
+ }
+@@ -170,26 +170,36 @@
+ obj_desc = acpi_ns_get_attached_object (node);
+ if (obj_desc) {
+ /*
+- * The object exists.
++ * The attached device object already exists.
+ * Make sure the handler is not already installed.
+ */
++ handler_obj = obj_desc->device.address_space;
+
+- /* check the address handler the user requested */
++ /* Walk the handler list for this device */
+
+- handler_obj = obj_desc->device.addr_handler;
+ while (handler_obj) {
+- /*
+- * Found an Address handler, see if user requested this
+- * address space.
+- */
+- if(handler_obj->addr_handler.space_id == space_id) {
+- status = AE_ALREADY_EXISTS;
++ /* Same space_id indicates a handler already installed */
++
++ if(handler_obj->address_space.space_id == space_id) {
++ if (handler_obj->address_space.handler == handler) {
++ /*
++ * It is (relatively) OK to attempt to install the SAME
++ * handler twice. This can easily happen with PCI_Config space.
++ */
++ status = AE_SAME_HANDLER;
++ goto unlock_and_exit;
++ }
++ else {
++ /* A handler is already installed */
++
++ status = AE_ALREADY_EXISTS;
++ }
+ goto unlock_and_exit;
+ }
+
+ /* Walk the linked list of handlers */
+
+- handler_obj = handler_obj->addr_handler.next;
++ handler_obj = handler_obj->address_space.next;
+ }
+ }
+ else {
+@@ -218,8 +228,12 @@
+ /* Attach the new object to the Node */
+
+ status = acpi_ns_attach_object (node, obj_desc, type);
++
++ /* Remove local reference to the object */
++
++ acpi_ut_remove_reference (obj_desc);
++
+ if (ACPI_FAILURE (status)) {
+- acpi_ut_remove_reference (obj_desc);
+ goto unlock_and_exit;
+ }
+ }
+@@ -241,14 +255,25 @@
+ goto unlock_and_exit;
+ }
+
+- handler_obj->addr_handler.space_id = (u8) space_id;
+- handler_obj->addr_handler.hflags = flags;
+- handler_obj->addr_handler.next = obj_desc->device.addr_handler;
+- handler_obj->addr_handler.region_list = NULL;
+- handler_obj->addr_handler.node = node;
+- handler_obj->addr_handler.handler = handler;
+- handler_obj->addr_handler.context = context;
+- handler_obj->addr_handler.setup = setup;
++ /* Init handler obj */
++
++ handler_obj->address_space.space_id = (u8) space_id;
++ handler_obj->address_space.hflags = flags;
++ handler_obj->address_space.region_list = NULL;
++ handler_obj->address_space.node = node;
++ handler_obj->address_space.handler = handler;
++ handler_obj->address_space.context = context;
++ handler_obj->address_space.setup = setup;
++
++ /* Install at head of Device.address_space list */
++
++ handler_obj->address_space.next = obj_desc->device.address_space;
++
++ /*
++ * 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;
+
+ /*
+ * Walk the namespace finding all of the regions this
+@@ -262,18 +287,9 @@
+ * In either case, back up and search down the remainder
+ * of the branch
+ */
+- status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device,
+- ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK,
+- acpi_ev_addr_handler_helper,
+- handler_obj, NULL);
+-
+- /* Place this handler 1st on the list */
+-
+- handler_obj->common.reference_count =
+- (u16) (handler_obj->common.reference_count +
+- obj_desc->common.reference_count - 1);
+- obj_desc->device.addr_handler = handler_obj;
+-
++ status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX,
++ ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler,
++ handler_obj, NULL);
+
+ unlock_and_exit:
+ (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
+@@ -341,12 +357,12 @@
+
+ /* Find the address handler the user requested */
+
+- handler_obj = obj_desc->device.addr_handler;
+- last_obj_ptr = &obj_desc->device.addr_handler;
++ handler_obj = obj_desc->device.address_space;
++ last_obj_ptr = &obj_desc->device.address_space;
+ while (handler_obj) {
+ /* We have a handler, see if user requested this one */
+
+- if (handler_obj->addr_handler.space_id == space_id) {
++ if (handler_obj->address_space.space_id == space_id) {
+ /* Matched space_id, first dereference this in the Regions */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION,
+@@ -354,7 +370,7 @@
+ handler_obj, handler, acpi_ut_get_region_name (space_id),
+ node, obj_desc));
+
+- region_obj = handler_obj->addr_handler.region_list;
++ region_obj = handler_obj->address_space.region_list;
+
+ /* Walk the handler's region list */
+
+@@ -372,13 +388,13 @@
+ * Walk the list: Just grab the head because the
+ * detach_region removed the previous head.
+ */
+- region_obj = handler_obj->addr_handler.region_list;
++ region_obj = handler_obj->address_space.region_list;
+
+ }
+
+ /* Remove this Handler object from the list */
+
+- *last_obj_ptr = handler_obj->addr_handler.next;
++ *last_obj_ptr = handler_obj->address_space.next;
+
+ /* Now we can delete the handler object */
+
+@@ -388,8 +404,8 @@
+
+ /* Walk the linked list of handlers */
+
+- last_obj_ptr = &handler_obj->addr_handler.next;
+- handler_obj = handler_obj->addr_handler.next;
++ last_obj_ptr = &handler_obj->address_space.next;
++ handler_obj = handler_obj->address_space.next;
+ }
+
+ /* The handler does not exist */
+diff -urN linux-2.4.20/drivers/acpi/executer/exconfig.c linux-2.4.20-acpi/drivers/acpi/executer/exconfig.c
+--- linux-2.4.20/drivers/acpi/executer/exconfig.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/executer/exconfig.c 2003-05-13 02:53:25.000000000 +0200
+@@ -360,11 +360,11 @@
+ /* The table must be either an SSDT or a PSDT */
+
+ if ((!ACPI_STRNCMP (table_ptr->signature,
+- acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature,
+- acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) &&
++ acpi_gbl_table_data[ACPI_TABLE_PSDT].signature,
++ acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) &&
+ (!ACPI_STRNCMP (table_ptr->signature,
+- acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature,
+- acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) {
++ acpi_gbl_table_data[ACPI_TABLE_SSDT].signature,
++ acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Table has invalid signature [%4.4s], must be SSDT or PSDT\n",
+ table_ptr->signature));
+diff -urN linux-2.4.20/drivers/acpi/executer/exdump.c linux-2.4.20-acpi/drivers/acpi/executer/exdump.c
+--- linux-2.4.20/drivers/acpi/executer/exdump.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/executer/exdump.c 2003-05-13 02:53:25.000000000 +0200
+@@ -635,9 +635,9 @@
+
+ case ACPI_TYPE_DEVICE:
+
+- acpi_ex_out_pointer ("addr_handler", obj_desc->device.addr_handler);
+- acpi_ex_out_pointer ("sys_handler", obj_desc->device.sys_handler);
+- acpi_ex_out_pointer ("drv_handler", obj_desc->device.drv_handler);
++ acpi_ex_out_pointer ("address_space", obj_desc->device.address_space);
++ acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify);
++ acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify);
+ break;
+
+
+@@ -673,7 +673,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 ("addr_handler", obj_desc->region.addr_handler);
++ acpi_ex_out_pointer ("address_space", obj_desc->region.address_space);
+ acpi_ex_out_pointer ("Next", obj_desc->region.next);
+ break;
+
+@@ -682,8 +682,8 @@
+
+ acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level);
+ acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order);
+- acpi_ex_out_pointer ("sys_handler", obj_desc->power_resource.sys_handler);
+- acpi_ex_out_pointer ("drv_handler", obj_desc->power_resource.drv_handler);
++ acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify);
++ acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify);
+ break;
+
+
+@@ -692,17 +692,17 @@
+ acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id);
+ acpi_ex_out_integer ("Length", obj_desc->processor.length);
+ acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address);
+- acpi_ex_out_pointer ("sys_handler", obj_desc->processor.sys_handler);
+- acpi_ex_out_pointer ("drv_handler", obj_desc->processor.drv_handler);
+- acpi_ex_out_pointer ("addr_handler", obj_desc->processor.addr_handler);
++ 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);
+ break;
+
+
+ case ACPI_TYPE_THERMAL:
+
+- acpi_ex_out_pointer ("sys_handler", obj_desc->thermal_zone.sys_handler);
+- acpi_ex_out_pointer ("drv_handler", obj_desc->thermal_zone.drv_handler);
+- acpi_ex_out_pointer ("addr_handler", obj_desc->thermal_zone.addr_handler);
++ 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);
+ break;
+
+
+@@ -762,18 +762,18 @@
+
+ case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
+
+- acpi_ex_out_integer ("space_id", obj_desc->addr_handler.space_id);
+- acpi_ex_out_pointer ("Next", obj_desc->addr_handler.next);
+- acpi_ex_out_pointer ("region_list", obj_desc->addr_handler.region_list);
+- acpi_ex_out_pointer ("Node", obj_desc->addr_handler.node);
+- acpi_ex_out_pointer ("Context", obj_desc->addr_handler.context);
++ acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id);
++ acpi_ex_out_pointer ("Next", obj_desc->address_space.next);
++ acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list);
++ acpi_ex_out_pointer ("Node", obj_desc->address_space.node);
++ acpi_ex_out_pointer ("Context", obj_desc->address_space.context);
+ break;
+
+
+ case ACPI_TYPE_LOCAL_NOTIFY:
+
+- acpi_ex_out_pointer ("Node", obj_desc->notify_handler.node);
+- acpi_ex_out_pointer ("Context", obj_desc->notify_handler.context);
++ acpi_ex_out_pointer ("Node", obj_desc->notify.node);
++ acpi_ex_out_pointer ("Context", obj_desc->notify.context);
+ break;
+
+
+diff -urN linux-2.4.20/drivers/acpi/namespace/nsalloc.c linux-2.4.20-acpi/drivers/acpi/namespace/nsalloc.c
+--- linux-2.4.20/drivers/acpi/namespace/nsalloc.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/namespace/nsalloc.c 2003-05-13 02:53:25.000000000 +0200
+@@ -116,19 +116,33 @@
+ prev_node = NULL;
+ next_node = parent_node->child;
+
++ /* Find the node that is the previous peer in the parent's child list */
++
+ while (next_node != node) {
+ prev_node = next_node;
+ next_node = prev_node->peer;
+ }
+
+ if (prev_node) {
++ /* Node is not first child, unlink it */
++
+ prev_node->peer = next_node->peer;
+ if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
+ prev_node->flags |= ANOBJ_END_OF_PEER_LIST;
+ }
+ }
+ else {
+- parent_node->child = next_node->peer;
++ /* Node is first child (has no previous peer) */
++
++ if (next_node->flags & ANOBJ_END_OF_PEER_LIST) {
++ /* No peers at all */
++
++ parent_node->child = NULL;
++ }
++ else { /* Link peer list to parent */
++
++ parent_node->child = next_node->peer;
++ }
+ }
+
+
+@@ -222,7 +236,7 @@
+ struct acpi_namespace_node *node, /* New Child*/
+ acpi_object_type type)
+ {
+- u16 owner_id = TABLE_ID_DSDT;
++ u16 owner_id = 0;
+ struct acpi_namespace_node *child_node;
+ #ifdef ACPI_ALPHABETIC_NAMESPACE
+
+@@ -355,6 +369,7 @@
+ {
+ struct acpi_namespace_node *child_node;
+ struct acpi_namespace_node *next_node;
++ struct acpi_namespace_node *node;
+ u8 flags;
+
+
+@@ -399,6 +414,25 @@
+ * Detach an object if there is one, then free the child node
+ */
+ acpi_ns_detach_object (child_node);
++
++ /*
++ * Decrement the reference count(s) of all parents up to
++ * the root! (counts were incremented when the node was created)
++ */
++ node = child_node;
++ while ((node = acpi_ns_get_parent_node (node)) != NULL) {
++ node->reference_count--;
++ }
++
++ /* There should be only one reference remaining on this node */
++
++ if (child_node->reference_count != 1) {
++ ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n",
++ child_node->reference_count, child_node));
++ }
++
++ /* Now we can delete the node */
++
+ ACPI_MEM_FREE (child_node);
+
+ /* And move on to the next child in the list */
+@@ -512,7 +546,7 @@
+ *
+ ******************************************************************************/
+
+-static void
++void
+ acpi_ns_remove_reference (
+ struct acpi_namespace_node *node)
+ {
+diff -urN linux-2.4.20/drivers/acpi/namespace/nsload.c linux-2.4.20-acpi/drivers/acpi/namespace/nsload.c
+--- linux-2.4.20/drivers/acpi/namespace/nsload.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/namespace/nsload.c 2003-05-13 02:53:25.000000000 +0200
+@@ -79,7 +79,7 @@
+
+ /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */
+
+- if (!(acpi_gbl_acpi_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
++ if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) {
+ /* Just ignore this table */
+
+ return_ACPI_STATUS (AE_OK);
+@@ -182,7 +182,7 @@
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n"));
+
+- table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT];
++ table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next;
+
+ /* If table already loaded into namespace, just return */
+
+@@ -190,8 +190,6 @@
+ goto unlock_and_exit;
+ }
+
+- table_desc->table_id = TABLE_ID_DSDT;
+-
+ /* Now load the single DSDT */
+
+ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node);
+@@ -205,13 +203,13 @@
+ case ACPI_TABLE_SSDT:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n",
+- acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count));
++ acpi_gbl_table_lists[ACPI_TABLE_SSDT].count));
+
+ /*
+ * Traverse list of SSDT tables
+ */
+- table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT];
+- for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) {
++ table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next;
++ for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) {
+ /*
+ * Only attempt to load table if it is not
+ * already loaded!
+@@ -233,14 +231,14 @@
+ case ACPI_TABLE_PSDT:
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n",
+- acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count));
++ acpi_gbl_table_lists[ACPI_TABLE_PSDT].count));
+
+ /*
+ * Traverse list of PSDT tables
+ */
+- table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT];
++ table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next;
+
+- for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) {
++ for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) {
+ /* Only attempt to load table if it is not already loaded! */
+
+ if (!table_desc->loaded_into_namespace) {
+diff -urN linux-2.4.20/drivers/acpi/namespace/nsparse.c linux-2.4.20-acpi/drivers/acpi/namespace/nsparse.c
+--- linux-2.4.20/drivers/acpi/namespace/nsparse.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/namespace/nsparse.c 2003-05-13 02:53:25.000000000 +0200
+@@ -85,10 +85,9 @@
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+
+-
+ /* Create and initialize a new walk state */
+
+- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT,
++ walk_state = acpi_ds_create_walk_state (table_desc->table_id,
+ NULL, NULL, NULL);
+ if (!walk_state) {
+ acpi_ps_free_op (parse_root);
+diff -urN linux-2.4.20/drivers/acpi/namespace/nsutils.c linux-2.4.20-acpi/drivers/acpi/namespace/nsutils.c
+--- linux-2.4.20/drivers/acpi/namespace/nsutils.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/namespace/nsutils.c 2003-05-13 02:53:25.000000000 +0200
+@@ -799,38 +799,31 @@
+ acpi_ns_terminate (void)
+ {
+ union acpi_operand_object *obj_desc;
+- struct acpi_namespace_node *this_node;
+
+
+ ACPI_FUNCTION_TRACE ("ns_terminate");
+
+
+- this_node = acpi_gbl_root_node;
+-
+ /*
+- * 1) Free the entire namespace -- all objects, tables, and stacks
++ * 1) Free the entire namespace -- all nodes and objects
+ *
+- * Delete all objects linked to the root
+- * (additional table descriptors)
++ * Delete all object descriptors attached to namepsace nodes
+ */
+- acpi_ns_delete_namespace_subtree (this_node);
++ acpi_ns_delete_namespace_subtree (acpi_gbl_root_node);
+
+- /* Detach any object(s) attached to the root */
++ /* Detach any objects attached to the root */
+
+- obj_desc = acpi_ns_get_attached_object (this_node);
++ obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node);
+ if (obj_desc) {
+- acpi_ns_detach_object (this_node);
+- acpi_ut_remove_reference (obj_desc);
++ acpi_ns_detach_object (acpi_gbl_root_node);
+ }
+
+- acpi_ns_delete_children (this_node);
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n"));
+
+-
+ /*
+ * 2) Now we can delete the ACPI tables
+ */
+- acpi_tb_delete_acpi_tables ();
++ acpi_tb_delete_all_tables ();
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
+
+ return_VOID;
+diff -urN linux-2.4.20/drivers/acpi/osl.c linux-2.4.20-acpi/drivers/acpi/osl.c
+--- linux-2.4.20/drivers/acpi/osl.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/osl.c 2003-05-13 02:53:25.000000000 +0200
+@@ -997,7 +997,7 @@
+ return 0;
+
+ for (; count-- && str && *str; str++) {
+- if (isalnum(*str) || *str == ' ')
++ if (isalnum(*str) || *str == ' ' || *str == ':')
+ *p++ = *str;
+ else if (*str == '\'' || *str == '"')
+ continue;
+diff -urN linux-2.4.20/drivers/acpi/parser/pswalk.c linux-2.4.20-acpi/drivers/acpi/parser/pswalk.c
+--- linux-2.4.20/drivers/acpi/parser/pswalk.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/parser/pswalk.c 2003-05-13 02:53:25.000000000 +0200
+@@ -270,7 +270,7 @@
+ return_VOID;
+ }
+
+- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, thread);
++ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread);
+ if (!walk_state) {
+ return_VOID;
+ }
+diff -urN linux-2.4.20/drivers/acpi/parser/psxface.c linux-2.4.20-acpi/drivers/acpi/parser/psxface.c
+--- linux-2.4.20/drivers/acpi/parser/psxface.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/parser/psxface.c 2003-05-13 02:53:25.000000000 +0200
+@@ -178,7 +178,7 @@
+
+ /* Create and initialize a new walk state */
+
+- walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL);
++ walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
+ if (!walk_state) {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
+diff -urN linux-2.4.20/drivers/acpi/tables/tbconvrt.c linux-2.4.20-acpi/drivers/acpi/tables/tbconvrt.c
+--- linux-2.4.20/drivers/acpi/tables/tbconvrt.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbconvrt.c 2003-05-13 02:53:25.000000000 +0200
+@@ -460,7 +460,7 @@
+
+ /* Free the original table */
+
+- table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
++ table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next;
+ acpi_tb_delete_single_table (table_desc);
+
+ /* Install the new table */
+diff -urN linux-2.4.20/drivers/acpi/tables/tbgetall.c linux-2.4.20-acpi/drivers/acpi/tables/tbgetall.c
+--- linux-2.4.20/drivers/acpi/tables/tbgetall.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbgetall.c 2003-05-13 02:53:25.000000000 +0200
+@@ -307,7 +307,7 @@
+
+ /* Always delete the RSDP mapping, we are done with it */
+
+- acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP);
++ acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP);
+ return_ACPI_STATUS (status);
+ }
+
+diff -urN linux-2.4.20/drivers/acpi/tables/tbget.c linux-2.4.20-acpi/drivers/acpi/tables/tbget.c
+--- linux-2.4.20/drivers/acpi/tables/tbget.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbget.c 2003-05-13 02:53:25.000000000 +0200
+@@ -456,18 +456,18 @@
+ * instance is always in the list head.
+ */
+ if (instance == 1) {
+- /*
+- * Just pluck the pointer out of the global table!
+- * Will be null if no table is present
+- */
+- *table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer;
++ /* Get the first */
++
++ if (acpi_gbl_table_lists[table_type].next) {
++ *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
++ }
+ return_ACPI_STATUS (AE_OK);
+ }
+
+ /*
+ * Check for instance out of range
+ */
+- if (instance > acpi_gbl_acpi_tables[table_type].count) {
++ if (instance > acpi_gbl_table_lists[table_type].count) {
+ return_ACPI_STATUS (AE_NOT_EXIST);
+ }
+
+@@ -478,7 +478,7 @@
+ * need to walk from the 2nd table until we reach the Instance
+ * that the user is looking for and return its table pointer.
+ */
+- table_desc = acpi_gbl_acpi_tables[table_type].next;
++ table_desc = acpi_gbl_table_lists[table_type].next;
+ for (i = 2; i < instance; i++) {
+ table_desc = table_desc->next;
+ }
+diff -urN linux-2.4.20/drivers/acpi/tables/tbinstal.c linux-2.4.20-acpi/drivers/acpi/tables/tbinstal.c
+--- linux-2.4.20/drivers/acpi/tables/tbinstal.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbinstal.c 2003-05-13 02:53:25.000000000 +0200
+@@ -79,13 +79,13 @@
+ /*
+ * Search for a signature match among the known table types
+ */
+- for (i = 0; i < NUM_ACPI_TABLES; i++) {
+- if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) {
++ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
++ if (!(acpi_gbl_table_data[i].flags & search_type)) {
+ continue;
+ }
+
+- if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature,
+- acpi_gbl_acpi_table_data[i].sig_length)) {
++ if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature,
++ acpi_gbl_table_data[i].sig_length)) {
+ /* Found a signature match, return index if requested */
+
+ if (table_info) {
+@@ -94,7 +94,7 @@
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
+ "Table [%4.4s] is an ACPI table consumed by the core subsystem\n",
+- (char *) acpi_gbl_acpi_table_data[i].signature));
++ (char *) acpi_gbl_table_data[i].signature));
+
+ return_ACPI_STATUS (AE_OK);
+ }
+@@ -149,7 +149,7 @@
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n",
+- acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer));
++ acpi_gbl_table_data[table_info->type].name, table_info->pointer));
+
+ (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+ return_ACPI_STATUS (status);
+@@ -239,70 +239,58 @@
+ acpi_table_type table_type,
+ struct acpi_table_desc *table_info)
+ {
+- struct acpi_table_desc *list_head;
++ struct acpi_table_list *list_head;
+ struct acpi_table_desc *table_desc;
+
+
+ ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type);
+
++
++ /* Allocate a descriptor for this table */
++
++ table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
++ if (!table_desc) {
++ return_ACPI_STATUS (AE_NO_MEMORY);
++ }
++
+ /*
+ * Install the table into the global data structure
+ */
+- list_head = &acpi_gbl_acpi_tables[table_type];
+- table_desc = list_head;
++ list_head = &acpi_gbl_table_lists[table_type];
+
+ /*
+ * Two major types of tables: 1) Only one instance is allowed. This
+ * includes most ACPI tables such as the DSDT. 2) Multiple instances of
+ * the table are allowed. This includes SSDT and PSDTs.
+ */
+- if (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) {
++ if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) {
+ /*
+ * Only one table allowed, and a table has alread been installed
+ * at this location, so return an error.
+ */
+- if (list_head->pointer) {
++ if (list_head->next) {
+ return_ACPI_STATUS (AE_ALREADY_EXISTS);
+ }
+-
+- table_desc->count = 1;
+- table_desc->prev = NULL;
+- table_desc->next = NULL;
+ }
+- else {
+- /*
+- * Multiple tables allowed for this table type, we must link
+- * the new table in to the list of tables of this type.
+- */
+- if (list_head->pointer) {
+- table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc));
+- if (!table_desc) {
+- return_ACPI_STATUS (AE_NO_MEMORY);
+- }
+-
+- list_head->count++;
+-
+- /* Update the original previous */
+-
+- list_head->prev->next = table_desc;
+-
+- /* Update new entry */
+
+- table_desc->prev = list_head->prev;
+- table_desc->next = list_head;
+-
+- /* Update list head */
++ /*
++ * Link the new table in to the list of tables of this type.
++ * Just insert at the start of the list, order unimportant.
++ *
++ * table_desc->Prev is already NULL from calloc()
++ */
++ table_desc->next = list_head->next;
++ list_head->next = table_desc;
+
+- list_head->prev = table_desc;
+- }
+- else {
+- table_desc->count = 1;
+- }
++ if (table_desc->next) {
++ table_desc->next->prev = table_desc;
+ }
+
+- /* Common initialization of the table descriptor */
++ list_head->count++;
+
+- table_desc->type = table_info->type;
++ /* Finish initialization of the table descriptor */
++
++ table_desc->type = (u8) table_type;
+ table_desc->pointer = table_info->pointer;
+ table_desc->length = table_info->length;
+ table_desc->allocation = table_info->allocation;
+@@ -316,8 +304,8 @@
+ * Set the appropriate global pointer (if there is one) to point to the
+ * newly installed table
+ */
+- if (acpi_gbl_acpi_table_data[table_type].global_ptr) {
+- *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer;
++ if (acpi_gbl_table_data[table_type].global_ptr) {
++ *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer;
+ }
+
+ /* Return Data */
+@@ -331,7 +319,7 @@
+
+ /*******************************************************************************
+ *
+- * FUNCTION: acpi_tb_delete_acpi_tables
++ * FUNCTION: acpi_tb_delete_all_tables
+ *
+ * PARAMETERS: None.
+ *
+@@ -342,7 +330,7 @@
+ ******************************************************************************/
+
+ void
+-acpi_tb_delete_acpi_tables (void)
++acpi_tb_delete_all_tables (void)
+ {
+ acpi_table_type type;
+
+@@ -351,15 +339,15 @@
+ * Free memory allocated for ACPI tables
+ * Memory can either be mapped or allocated
+ */
+- for (type = 0; type < NUM_ACPI_TABLES; type++) {
+- acpi_tb_delete_acpi_table (type);
++ for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) {
++ acpi_tb_delete_tables_by_type (type);
+ }
+ }
+
+
+ /*******************************************************************************
+ *
+- * FUNCTION: acpi_tb_delete_acpi_table
++ * FUNCTION: acpi_tb_delete_tables_by_type
+ *
+ * PARAMETERS: Type - The table type to be deleted
+ *
+@@ -371,11 +359,15 @@
+ ******************************************************************************/
+
+ void
+-acpi_tb_delete_acpi_table (
++acpi_tb_delete_tables_by_type (
+ acpi_table_type type)
+ {
++ struct acpi_table_desc *table_desc;
++ u32 count;
++ u32 i;
+
+- ACPI_FUNCTION_TRACE_U32 ("tb_delete_acpi_table", type);
++
++ ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type);
+
+
+ if (type > ACPI_TABLE_MAX) {
+@@ -416,43 +408,10 @@
+ }
+
+ /* Free the table */
+-
+- acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]);
+-
+- (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+- return_VOID;
+-}
+-
+-
+-/*******************************************************************************
+- *
+- * FUNCTION: acpi_tb_free_acpi_tables_of_type
+- *
+- * PARAMETERS: table_info - A table info struct
+- *
+- * RETURN: None.
+- *
+- * DESCRIPTION: Free the memory associated with an internal ACPI table
+- * Table mutex should be locked.
+- *
+- ******************************************************************************/
+-
+-void
+-acpi_tb_free_acpi_tables_of_type (
+- struct acpi_table_desc *list_head)
+-{
+- struct acpi_table_desc *table_desc;
+- u32 count;
+- u32 i;
+-
+-
+- ACPI_FUNCTION_TRACE_PTR ("tb_free_acpi_tables_of_type", list_head);
+-
+-
+ /* Get the head of the list */
+
+- table_desc = list_head;
+- count = list_head->count;
++ table_desc = acpi_gbl_table_lists[type].next;
++ count = acpi_gbl_table_lists[type].count;
+
+ /*
+ * Walk the entire list, deleting both the allocated tables
+@@ -462,6 +421,7 @@
+ table_desc = acpi_tb_uninstall_table (table_desc);
+ }
+
++ (void) acpi_ut_release_mutex (ACPI_MTX_TABLES);
+ return_VOID;
+ }
+
+@@ -484,30 +444,31 @@
+ struct acpi_table_desc *table_desc)
+ {
+
+- if (!table_desc) {
++ /* Must have a valid table descriptor and pointer */
++
++ if ((!table_desc) ||
++ (!table_desc->pointer)) {
+ return;
+ }
+
+- if (table_desc->pointer) {
+- /* Valid table, determine type of memory allocation */
++ /* Valid table, determine type of memory allocation */
+
+- switch (table_desc->allocation) {
+- case ACPI_MEM_NOT_ALLOCATED:
+- break;
++ switch (table_desc->allocation) {
++ case ACPI_MEM_NOT_ALLOCATED:
++ break;
+
+- case ACPI_MEM_ALLOCATED:
++ case ACPI_MEM_ALLOCATED:
+
+- ACPI_MEM_FREE (table_desc->pointer);
+- break;
++ ACPI_MEM_FREE (table_desc->pointer);
++ break;
+
+- case ACPI_MEM_MAPPED:
++ case ACPI_MEM_MAPPED:
+
+- acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
+- break;
++ acpi_os_unmap_memory (table_desc->pointer, table_desc->length);
++ break;
+
+- default:
+- break;
+- }
++ default:
++ break;
+ }
+ }
+
+@@ -533,18 +494,23 @@
+ struct acpi_table_desc *next_desc;
+
+
+- ACPI_FUNCTION_TRACE_PTR ("acpi_tb_uninstall_table", table_desc);
++ ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc);
+
+
+ if (!table_desc) {
+ return_PTR (NULL);
+ }
+
+- /* Unlink the descriptor */
++ /* Unlink the descriptor from the doubly linked list */
+
+ if (table_desc->prev) {
+ table_desc->prev->next = table_desc->next;
+ }
++ else {
++ /* Is first on list, update list head */
++
++ acpi_gbl_table_lists[table_desc->type].next = table_desc->next;
++ }
+
+ if (table_desc->next) {
+ table_desc->next->prev = table_desc->prev;
+@@ -554,23 +520,12 @@
+
+ acpi_tb_delete_single_table (table_desc);
+
+- /* Free the table descriptor (Don't delete the list head, tho) */
+-
+- if ((table_desc->prev) == (table_desc->next)) {
+- next_desc = NULL;
++ /* Free the table descriptor */
+
+- /* Clear the list head */
++ next_desc = table_desc->next;
++ ACPI_MEM_FREE (table_desc);
+
+- table_desc->pointer = NULL;
+- table_desc->length = 0;
+- table_desc->count = 0;
+- }
+- else {
+- /* Free the table descriptor */
+-
+- next_desc = table_desc->next;
+- ACPI_MEM_FREE (table_desc);
+- }
++ /* Return pointer to the next descriptor */
+
+ return_PTR (next_desc);
+ }
+diff -urN linux-2.4.20/drivers/acpi/tables/tbutils.c linux-2.4.20-acpi/drivers/acpi/tables/tbutils.c
+--- linux-2.4.20/drivers/acpi/tables/tbutils.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbutils.c 2003-05-13 02:53:25.000000000 +0200
+@@ -66,26 +66,25 @@
+ acpi_status
+ acpi_tb_handle_to_object (
+ u16 table_id,
+- struct acpi_table_desc **table_desc)
++ struct acpi_table_desc **return_table_desc)
+ {
+ u32 i;
+- struct acpi_table_desc *list_head;
++ struct acpi_table_desc *table_desc;
+
+
+ ACPI_FUNCTION_NAME ("tb_handle_to_object");
+
+
+ for (i = 0; i < ACPI_TABLE_MAX; i++) {
+- list_head = &acpi_gbl_acpi_tables[i];
+- do {
+- if (list_head->table_id == table_id) {
+- *table_desc = list_head;
++ table_desc = acpi_gbl_table_lists[i].next;
++ while (table_desc) {
++ if (table_desc->table_id == table_id) {
++ *return_table_desc = table_desc;
+ return (AE_OK);
+ }
+
+- list_head = list_head->next;
+-
+- } while (list_head != &acpi_gbl_acpi_tables[i]);
++ table_desc = table_desc->next;
++ }
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id));
+diff -urN linux-2.4.20/drivers/acpi/tables/tbxface.c linux-2.4.20-acpi/drivers/acpi/tables/tbxface.c
+--- linux-2.4.20/drivers/acpi/tables/tbxface.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/tables/tbxface.c 2003-05-13 02:53:25.000000000 +0200
+@@ -235,7 +235,7 @@
+ acpi_unload_table (
+ acpi_table_type table_type)
+ {
+- struct acpi_table_desc *list_head;
++ struct acpi_table_desc *table_desc;
+
+
+ ACPI_FUNCTION_TRACE ("acpi_unload_table");
+@@ -250,22 +250,22 @@
+
+ /* Find all tables of the requested type */
+
+- list_head = &acpi_gbl_acpi_tables[table_type];
+- do {
++ table_desc = acpi_gbl_table_lists[table_type].next;
++ while (table_desc); {
+ /*
+ * Delete all namespace entries owned by this table. Note that these
+ * entries can appear anywhere in the namespace by virtue of the AML
+ * "Scope" operator. Thus, we need to track ownership by an ID, not
+ * simply a position within the hierarchy
+ */
+- acpi_ns_delete_namespace_by_owner (list_head->table_id);
++ acpi_ns_delete_namespace_by_owner (table_desc->table_id);
+
+- /* Delete (or unmap) the actual table */
+-
+- acpi_tb_delete_acpi_table (table_type);
++ table_desc = table_desc->next;
++ }
+
+- } while (list_head != &acpi_gbl_acpi_tables[table_type]);
++ /* Delete (or unmap) all tables of this type */
+
++ acpi_tb_delete_tables_by_type (table_type);
+ return_ACPI_STATUS (AE_OK);
+ }
+
+@@ -313,7 +313,7 @@
+ /* Check the table type and instance */
+
+ if ((table_type > ACPI_TABLE_MAX) ||
+- (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
++ (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
+ instance > 1)) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+@@ -394,7 +394,7 @@
+ /* Check the table type and instance */
+
+ if ((table_type > ACPI_TABLE_MAX) ||
+- (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
++ (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) &&
+ instance > 1)) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+diff -urN linux-2.4.20/drivers/acpi/utilities/utdelete.c linux-2.4.20-acpi/drivers/acpi/utilities/utdelete.c
+--- linux-2.4.20/drivers/acpi/utilities/utdelete.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/utilities/utdelete.c 2003-05-13 02:53:25.000000000 +0200
+@@ -71,6 +71,7 @@
+ void *obj_pointer = NULL;
+ union acpi_operand_object *handler_desc;
+ union acpi_operand_object *second_desc;
++ union acpi_operand_object *next_desc;
+
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object);
+@@ -136,6 +137,15 @@
+ if (object->device.gpe_block) {
+ (void) acpi_ev_delete_gpe_block (object->device.gpe_block);
+ }
++
++ /* Walk the handler list for this device */
++
++ handler_desc = object->device.address_space;
++ while (handler_desc) {
++ next_desc = handler_desc->address_space.next;
++ acpi_ut_remove_reference (handler_desc);
++ handler_desc = next_desc;
++ }
+ break;
+
+
+@@ -183,10 +193,13 @@
+ * default handlers -- and therefore, we created the context object
+ * locally, it was not created by an external caller.
+ */
+- handler_desc = object->region.addr_handler;
+- if ((handler_desc) &&
+- (handler_desc->addr_handler.hflags == ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
+- obj_pointer = second_desc->extra.region_context;
++ handler_desc = object->region.address_space;
++ if (handler_desc) {
++ if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
++ obj_pointer = second_desc->extra.region_context;
++ }
++
++ acpi_ut_remove_reference (handler_desc);
+ }
+
+ /* Now we can free the Extra object */
+@@ -211,7 +224,6 @@
+ break;
+ }
+
+-
+ /* Free any allocated memory (pointer within the object) found above */
+
+ if (obj_pointer) {
+@@ -299,7 +311,7 @@
+ new_count = count;
+
+ /*
+- * Reference count action (increment, decrement, or force delete)
++ * Perform the reference count action (increment, decrement, or force delete)
+ */
+ switch (action) {
+
+@@ -402,8 +414,6 @@
+ {
+ acpi_status status;
+ u32 i;
+- union acpi_operand_object *next;
+- union acpi_operand_object *new;
+ union acpi_generic_state *state_list = NULL;
+ union acpi_generic_state *state;
+
+@@ -417,9 +427,8 @@
+ return_ACPI_STATUS (AE_OK);
+ }
+
+- /*
+- * Make sure that this isn't a namespace handle
+- */
++ /* Make sure that this isn't a namespace handle */
++
+ if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object));
+ return_ACPI_STATUS (AE_OK);
+@@ -439,28 +448,8 @@
+ switch (ACPI_GET_OBJECT_TYPE (object)) {
+ case ACPI_TYPE_DEVICE:
+
+- status = acpi_ut_create_update_state_and_push (object->device.addr_handler,
+- action, &state_list);
+- if (ACPI_FAILURE (status)) {
+- goto error_exit;
+- }
+-
+- acpi_ut_update_ref_count (object->device.sys_handler, action);
+- acpi_ut_update_ref_count (object->device.drv_handler, action);
+- break;
+-
+-
+- case ACPI_TYPE_LOCAL_ADDRESS_HANDLER:
+-
+- /* Must walk list of address handlers */
+-
+- next = object->addr_handler.next;
+- while (next) {
+- new = next->addr_handler.next;
+- acpi_ut_update_ref_count (next, action);
+-
+- next = new;
+- }
++ acpi_ut_update_ref_count (object->device.system_notify, action);
++ acpi_ut_update_ref_count (object->device.device_notify, action);
+ break;
+
+
+@@ -590,16 +579,14 @@
+ ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object);
+
+
+- /*
+- * Ensure that we have a valid object
+- */
++ /* Ensure that we have a valid object */
++
+ if (!acpi_ut_valid_internal_object (object)) {
+ return_VOID;
+ }
+
+- /*
+- * We have a valid ACPI internal object, now increment the reference count
+- */
++ /* Increment the reference count */
++
+ (void) acpi_ut_update_object_reference (object, REF_INCREMENT);
+ return_VOID;
+ }
+@@ -624,6 +611,7 @@
+
+ ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object);
+
++
+ /*
+ * Allow a NULL pointer to be passed in, just ignore it. This saves
+ * each caller from having to check. Also, ignore NS nodes.
+@@ -634,9 +622,8 @@
+ return_VOID;
+ }
+
+- /*
+- * Ensure that we have a valid object
+- */
++ /* Ensure that we have a valid object */
++
+ if (!acpi_ut_valid_internal_object (object)) {
+ return_VOID;
+ }
+diff -urN linux-2.4.20/drivers/acpi/utilities/utglobal.c linux-2.4.20-acpi/drivers/acpi/utilities/utglobal.c
+--- linux-2.4.20/drivers/acpi/utilities/utglobal.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/utilities/utglobal.c 2003-05-13 02:53:25.000000000 +0200
+@@ -299,10 +299,10 @@
+ ******************************************************************************/
+
+
+-struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
++struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
+
+
+-struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] =
++struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] =
+ {
+ /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Co+
ntains valid AML? */
+
+@@ -535,12 +535,10 @@
+
+
+ #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+-
+ /*
+ * Strings and procedures used for debug only
+ */
+
+-
+ /*****************************************************************************
+ *
+ * FUNCTION: acpi_ut_get_mutex_name
+@@ -558,7 +556,7 @@
+ u32 mutex_id)
+ {
+
+- if (mutex_id > MAX_MTX)
++ if (mutex_id > MAX_MUTEX)
+ {
+ return ("Invalid Mutex ID");
+ }
+@@ -566,7 +564,6 @@
+ return (acpi_gbl_mutex_names[mutex_id]);
+ }
+
+-
+ #endif
+
+
+@@ -630,9 +627,12 @@
+ owner_id = acpi_gbl_next_table_owner_id;
+ acpi_gbl_next_table_owner_id++;
+
++ /* Check for wraparound */
++
+ if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID)
+ {
+ acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID;
++ ACPI_REPORT_WARNING (("Table owner ID wraparound\n"));
+ }
+ break;
+
+@@ -644,6 +644,8 @@
+
+ if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID)
+ {
++ /* Check for wraparound */
++
+ acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID;
+ }
+ break;
+@@ -710,23 +712,19 @@
+
+ /* ACPI table structure */
+
+- for (i = 0; i < NUM_ACPI_TABLES; i++)
++ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++)
+ {
+- acpi_gbl_acpi_tables[i].prev = &acpi_gbl_acpi_tables[i];
+- acpi_gbl_acpi_tables[i].next = &acpi_gbl_acpi_tables[i];
+- acpi_gbl_acpi_tables[i].pointer = NULL;
+- acpi_gbl_acpi_tables[i].length = 0;
+- acpi_gbl_acpi_tables[i].allocation = ACPI_MEM_NOT_ALLOCATED;
+- acpi_gbl_acpi_tables[i].count = 0;
++ acpi_gbl_table_lists[i].next = NULL;
++ acpi_gbl_table_lists[i].count = 0;
+ }
+
+ /* Mutex locked flags */
+
+- for (i = 0; i < NUM_MTX; i++)
++ for (i = 0; i < NUM_MUTEX; i++)
+ {
+- acpi_gbl_acpi_mutex_info[i].mutex = NULL;
+- acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+- acpi_gbl_acpi_mutex_info[i].use_count = 0;
++ acpi_gbl_mutex_info[i].mutex = NULL;
++ acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
++ acpi_gbl_mutex_info[i].use_count = 0;
+ }
+
+ /* GPE support */
+@@ -737,8 +735,8 @@
+
+ /* Global notify handlers */
+
+- acpi_gbl_sys_notify.handler = NULL;
+- acpi_gbl_drv_notify.handler = NULL;
++ acpi_gbl_system_notify.handler = NULL;
++ acpi_gbl_device_notify.handler = NULL;
+ acpi_gbl_init_handler = NULL;
+
+ /* Global "typed" ACPI table pointers */
+diff -urN linux-2.4.20/drivers/acpi/utilities/utmisc.c linux-2.4.20-acpi/drivers/acpi/utilities/utmisc.c
+--- linux-2.4.20/drivers/acpi/utilities/utmisc.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/utilities/utmisc.c 2003-05-13 02:53:25.000000000 +0200
+@@ -549,7 +549,7 @@
+ /*
+ * Create each of the predefined mutex objects
+ */
+- for (i = 0; i < NUM_MTX; i++) {
++ for (i = 0; i < NUM_MUTEX; i++) {
+ status = acpi_ut_create_mutex (i);
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+@@ -588,7 +588,7 @@
+ /*
+ * Delete each predefined mutex object
+ */
+- for (i = 0; i < NUM_MTX; i++) {
++ for (i = 0; i < NUM_MUTEX; i++) {
+ (void) acpi_ut_delete_mutex (i);
+ }
+
+@@ -619,15 +619,15 @@
+ ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id);
+
+
+- if (mutex_id > MAX_MTX) {
++ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+- if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) {
++ if (!acpi_gbl_mutex_info[mutex_id].mutex) {
+ status = acpi_os_create_semaphore (1, 1,
+- &acpi_gbl_acpi_mutex_info[mutex_id].mutex);
+- acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+- acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0;
++ &acpi_gbl_mutex_info[mutex_id].mutex);
++ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
++ acpi_gbl_mutex_info[mutex_id].use_count = 0;
+ }
+
+ return_ACPI_STATUS (status);
+@@ -656,14 +656,14 @@
+ ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id);
+
+
+- if (mutex_id > MAX_MTX) {
++ if (mutex_id > MAX_MUTEX) {
+ return_ACPI_STATUS (AE_BAD_PARAMETER);
+ }
+
+- status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex);
++ status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex);
+
+- acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL;
+- acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
++ acpi_gbl_mutex_info[mutex_id].mutex = NULL;
++ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+ return_ACPI_STATUS (status);
+ }
+@@ -693,7 +693,7 @@
+ ACPI_FUNCTION_NAME ("ut_acquire_mutex");
+
+
+- if (mutex_id > MAX_MTX) {
++ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+@@ -705,8 +705,8 @@
+ * the mutex ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+- for (i = mutex_id; i < MAX_MTX; i++) {
+- if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
++ for (i = mutex_id; i < MAX_MUTEX; i++) {
++ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Mutex [%s] already acquired by this thread [%X]\n",
+@@ -728,14 +728,14 @@
+ "Thread %X attempting to acquire Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+- status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex,
++ status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex,
+ 1, ACPI_WAIT_FOREVER);
+ if (ACPI_SUCCESS (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n",
+ this_thread_id, acpi_ut_get_mutex_name (mutex_id)));
+
+- acpi_gbl_acpi_mutex_info[mutex_id].use_count++;
+- acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id;
++ acpi_gbl_mutex_info[mutex_id].use_count++;
++ acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id;
+ }
+ else {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n",
+@@ -776,14 +776,14 @@
+ "Thread %X releasing Mutex [%s]\n", this_thread_id,
+ acpi_ut_get_mutex_name (mutex_id)));
+
+- if (mutex_id > MAX_MTX) {
++ if (mutex_id > MAX_MUTEX) {
+ return (AE_BAD_PARAMETER);
+ }
+
+ /*
+ * Mutex must be acquired in order to release it!
+ */
+- if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
++ if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Mutex [%s] is not acquired, cannot release\n",
+ acpi_ut_get_mutex_name (mutex_id)));
+@@ -797,8 +797,8 @@
+ * ordering rule. This indicates a coding error somewhere in
+ * the ACPI subsystem code.
+ */
+- for (i = mutex_id; i < MAX_MTX; i++) {
+- if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) {
++ for (i = mutex_id; i < MAX_MUTEX; i++) {
++ if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) {
+ if (i == mutex_id) {
+ continue;
+ }
+@@ -813,9 +813,9 @@
+
+ /* Mark unlocked FIRST */
+
+- acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
++ acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED;
+
+- status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1);
++ status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1);
+
+ if (ACPI_FAILURE (status)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n",
+diff -urN linux-2.4.20/drivers/acpi/utilities/utxface.c linux-2.4.20-acpi/drivers/acpi/utilities/utxface.c
+--- linux-2.4.20/drivers/acpi/utilities/utxface.c 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/drivers/acpi/utilities/utxface.c 2003-05-13 02:53:25.000000000 +0200
+@@ -145,22 +145,8 @@
+
+
+ /*
+- * Install the default op_region handlers. These are installed unless
+- * other handlers have already been installed via the
+- * install_address_space_handler interface
+- */
+- if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
+- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+-
+- status = acpi_ev_init_address_spaces ();
+- if (ACPI_FAILURE (status)) {
+- return_ACPI_STATUS (status);
+- }
+- }
+-
+- /*
+ * We must initialize the hardware before we can enable ACPI.
+- * FADT values are validated here.
++ * The values from the FADT are validated here.
+ */
+ if (!(flags & ACPI_NO_HARDWARE_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n"));
+@@ -172,7 +158,7 @@
+ }
+
+ /*
+- * Enable ACPI on this platform
++ * Enable ACPI mode
+ */
+ if (!(flags & ACPI_NO_ACPI_ENABLE)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n"));
+@@ -187,8 +173,9 @@
+ }
+
+ /*
+- * Note:
+- * We must have the hardware AND events initialized before we can execute
++ * Initialize ACPI Event handling
++ *
++ * NOTE: We must have the hardware AND events initialized before we can execute
+ * ANY control methods SAFELY. Any control method can require ACPI hardware
+ * support, so the hardware MUST be initialized before execution!
+ */
+@@ -201,7 +188,7 @@
+ }
+ }
+
+- /* Install SCI handler, Global Lock handler, GPE handlers */
++ /* Install the SCI handler, Global Lock handler, and GPE handlers */
+
+ if (!(flags & ACPI_NO_HANDLER_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n"));
+@@ -237,14 +224,20 @@
+
+ ACPI_FUNCTION_TRACE ("acpi_initialize_objects");
+
++
+ /*
+- * Initialize all device objects in the namespace
+- * This runs the _STA and _INI methods.
++ * Install the default op_region handlers. These are installed unless
++ * other handlers have already been installed via the
++ * install_address_space_handler interface.
++ *
++ * NOTE: This will cause _REG methods to be run. Any objects accessed
++ * by the _REG methods will be automatically initialized, even if they
++ * contain executable AML (see call to acpi_ns_initialize_objects below).
+ */
+- if (!(flags & ACPI_NO_DEVICE_INIT)) {
+- ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
++ if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) {
++ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n"));
+
+- status = acpi_ns_initialize_devices ();
++ status = acpi_ev_init_address_spaces ();
+ if (ACPI_FAILURE (status)) {
+ return_ACPI_STATUS (status);
+ }
+@@ -252,8 +245,8 @@
+
+ /*
+ * Initialize the objects that remain uninitialized. This
+- * runs the executable AML that is part of the declaration of op_regions
+- * and Fields.
++ * runs the executable AML that may be part of the declaration of these
++ * objects: operation_regions, buffer_fields, Buffers, and Packages.
+ */
+ if (!(flags & ACPI_NO_OBJECT_INIT)) {
+ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n"));
+@@ -265,6 +258,19 @@
+ }
+
+ /*
++ * Initialize all device objects in the namespace
++ * This runs the _STA and _INI methods.
++ */
++ if (!(flags & ACPI_NO_DEVICE_INIT)) {
++ ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n"));
++
++ status = acpi_ns_initialize_devices ();
++ if (ACPI_FAILURE (status)) {
++ return_ACPI_STATUS (status);
++ }
++ }
++
++ /*
+ * Empty the caches (delete the cached objects) on the assumption that
+ * the table load filled them up more than they will be at runtime --
+ * thus wasting non-paged memory.
+@@ -431,9 +437,9 @@
+
+ /* Current status of the ACPI tables, per table type */
+
+- info_ptr->num_table_types = NUM_ACPI_TABLES;
+- for (i = 0; i < NUM_ACPI_TABLES; i++) {
+- info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count;
++ info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES;
++ for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) {
++ info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+diff -urN linux-2.4.20/include/acpi/acconfig.h linux-2.4.20-acpi/include/acpi/acconfig.h
+--- linux-2.4.20/include/acpi/acconfig.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acconfig.h 2003-05-13 02:53:25.000000000 +0200
+@@ -64,7 +64,7 @@
+
+ /* Version string */
+
+-#define ACPI_CA_VERSION 0x20030424
++#define ACPI_CA_VERSION 0x20030509
+
+ /* Maximum objects in the various object caches */
+
+diff -urN linux-2.4.20/include/acpi/acevents.h linux-2.4.20-acpi/include/acpi/acevents.h
+--- linux-2.4.20/include/acpi/acevents.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acevents.h 2003-05-13 02:53:25.000000000 +0200
+@@ -165,7 +165,7 @@
+ void *value);
+
+ acpi_status
+-acpi_ev_addr_handler_helper (
++acpi_ev_install_handler (
+ acpi_handle obj_handle,
+ u32 level,
+ void *context,
+diff -urN linux-2.4.20/include/acpi/acexcep.h linux-2.4.20-acpi/include/acpi/acexcep.h
+--- linux-2.4.20/include/acpi/acexcep.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acexcep.h 2003-05-13 02:53:25.000000000 +0200
+@@ -94,8 +94,9 @@
+ #define AE_NO_GLOBAL_LOCK (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL)
+ #define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL)
+ #define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL)
++#define AE_SAME_HANDLER (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL)
+
+-#define AE_CODE_ENV_MAX 0x001C
++#define AE_CODE_ENV_MAX 0x001D
+
+ /*
+ * Programmer exceptions
+@@ -219,7 +220,8 @@
+ "AE_NO_HARDWARE_RESPONSE",
+ "AE_NO_GLOBAL_LOCK",
+ "AE_LOGICAL_ADDRESS",
+- "AE_ABORT_METHOD"
++ "AE_ABORT_METHOD",
++ "AE_SAME_HANDLER"
+ };
+
+ char const *acpi_gbl_exception_names_pgm[] =
+diff -urN linux-2.4.20/include/acpi/acglobal.h linux-2.4.20-acpi/include/acpi/acglobal.h
+--- linux-2.4.20/include/acpi/acglobal.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acglobal.h 2003-05-13 02:53:25.000000000 +0200
+@@ -117,15 +117,15 @@
+ /*
+ * ACPI Table info arrays
+ */
+-extern struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES];
+-extern struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES];
++extern struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES];
++extern struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES];
+
+ /*
+ * Predefined mutex objects. This array contains the
+ * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs.
+ * (The table maps local handles to the real OS handles)
+ */
+-ACPI_EXTERN struct acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MTX];
++ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[NUM_MUTEX];
+
+
+ /*****************************************************************************
+@@ -136,8 +136,8 @@
+
+
+ ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS];
+-ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_drv_notify;
+-ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_sys_notify;
++ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify;
++ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify;
+ ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler;
+ ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk;
+ ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore;
+@@ -202,7 +202,7 @@
+ ****************************************************************************/
+
+
+-ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list;
++ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list;
+
+ /* Control method single step flag */
+
+@@ -215,7 +215,7 @@
+ *
+ ****************************************************************************/
+
+-ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root;
++ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root;
+
+ /*****************************************************************************
+ *
+@@ -236,8 +236,8 @@
+
+ extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS];
+ ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS];
+-ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
+-ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
++ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head;
++ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS];
+ ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock;
+
+
+diff -urN linux-2.4.20/include/acpi/aclocal.h linux-2.4.20-acpi/include/acpi/aclocal.h
+--- linux-2.4.20/include/acpi/aclocal.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/aclocal.h 2003-05-13 02:53:25.000000000 +0200
+@@ -87,8 +87,8 @@
+ #define ACPI_MTX_DEBUG_CMD_COMPLETE 11
+ #define ACPI_MTX_DEBUG_CMD_READY 12
+
+-#define MAX_MTX 12
+-#define NUM_MTX MAX_MTX+1
++#define MAX_MUTEX 12
++#define NUM_MUTEX MAX_MUTEX+1
+
+
+ #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+@@ -140,12 +140,8 @@
+ typedef u16 acpi_owner_id;
+ #define ACPI_OWNER_TYPE_TABLE 0x0
+ #define ACPI_OWNER_TYPE_METHOD 0x1
+-#define ACPI_FIRST_METHOD_ID 0x0000
+-#define ACPI_FIRST_TABLE_ID 0x8000
+-
+-/* TBD: [Restructure] get rid of the need for this! */
+-
+-#define TABLE_ID_DSDT (acpi_owner_id) 0x8000
++#define ACPI_FIRST_METHOD_ID 0x0001
++#define ACPI_FIRST_TABLE_ID 0xF000
+
+
+ /* Field access granularities */
+@@ -232,13 +228,18 @@
+ u64 physical_address;
+ u32 aml_length;
+ acpi_size length;
+- u32 count;
+ acpi_owner_id table_id;
+ u8 type;
+ u8 allocation;
+ u8 loaded_into_namespace;
+ };
+
++struct acpi_table_list
++{
++ struct acpi_table_desc *next;
++ u32 count;
++};
++
+
+ struct acpi_find_context
+ {
+diff -urN linux-2.4.20/include/acpi/acnamesp.h linux-2.4.20-acpi/include/acpi/acnamesp.h
+--- linux-2.4.20/include/acpi/acnamesp.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acnamesp.h 2003-05-13 02:53:25.000000000 +0200
+@@ -201,6 +201,11 @@
+ char *name1,
+ char *name2);
+
++void
++acpi_ns_remove_reference (
++ struct acpi_namespace_node *node);
++
++
+ /*
+ * Namespace modification - nsmodify
+ */
+diff -urN linux-2.4.20/include/acpi/acobject.h linux-2.4.20-acpi/include/acpi/acobject.h
+--- linux-2.4.20/include/acpi/acobject.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acobject.h 2003-05-13 02:53:25.000000000 +0200
+@@ -112,9 +112,9 @@
+ * Common fields for objects that support ASL notifications
+ */
+ #define ACPI_COMMON_NOTIFY_INFO \
+- union acpi_operand_object *sys_handler; /* Handler for system notifies */\
+- union acpi_operand_object *drv_handler; /* Handler for driver notifies */\
+- union acpi_operand_object *addr_handler; /* Handler for Address space */
++ 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 */
+
+
+ /******************************************************************************
+@@ -214,7 +214,7 @@
+ ACPI_OBJECT_COMMON_HEADER
+
+ u8 space_id;
+- union acpi_operand_object *addr_handler; /* Handler for system notifies */
++ union acpi_operand_object *address_space; /* Handler for region access */
+ struct acpi_namespace_node *node; /* containing object */
+ union acpi_operand_object *next;
+ u32 length;
+@@ -446,8 +446,8 @@
+ struct acpi_object_buffer_field buffer_field;
+ struct acpi_object_bank_field bank_field;
+ struct acpi_object_index_field index_field;
+- struct acpi_object_notify_handler notify_handler;
+- struct acpi_object_addr_handler addr_handler;
++ struct acpi_object_notify_handler notify;
++ struct acpi_object_addr_handler address_space;
+ struct acpi_object_reference reference;
+ struct acpi_object_extra extra;
+ struct acpi_object_data data;
+diff -urN linux-2.4.20/include/acpi/acpiosxf.h linux-2.4.20-acpi/include/acpi/acpiosxf.h
+--- linux-2.4.20/include/acpi/acpiosxf.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/acpiosxf.h 2003-05-13 02:53:25.000000000 +0200
+@@ -290,12 +290,12 @@
+ u8
+ acpi_os_readable (
+ void *pointer,
+- u32 length);
++ acpi_size length);
+
+ u8
+ acpi_os_writable (
+ void *pointer,
+- u32 length);
++ acpi_size length);
+
+ u32
+ acpi_os_get_timer (
+diff -urN linux-2.4.20/include/acpi/actables.h linux-2.4.20-acpi/include/acpi/actables.h
+--- linux-2.4.20/include/acpi/actables.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/actables.h 2003-05-13 02:53:25.000000000 +0200
+@@ -157,7 +157,7 @@
+ acpi_status
+ acpi_tb_recognize_table (
+ struct acpi_table_desc *table_info,
+- u8 search_type);
++ u8 search_type);
+
+ acpi_status
+ acpi_tb_init_table_descriptor (
+@@ -170,11 +170,11 @@
+ */
+
+ void
+-acpi_tb_delete_acpi_tables (
++acpi_tb_delete_all_tables (
+ void);
+
+ void
+-acpi_tb_delete_acpi_table (
++acpi_tb_delete_tables_by_type (
+ acpi_table_type type);
+
+ void
+@@ -185,10 +185,6 @@
+ acpi_tb_uninstall_table (
+ struct acpi_table_desc *table_desc);
+
+-void
+-acpi_tb_free_acpi_tables_of_type (
+- struct acpi_table_desc *table_info);
+-
+
+ /*
+ * tbrsd - RSDP, RSDT utilities
+diff -urN linux-2.4.20/include/acpi/actypes.h linux-2.4.20-acpi/include/acpi/actypes.h
+--- linux-2.4.20/include/acpi/actypes.h 2003-05-13 02:53:06.000000000 +0200
++++ linux-2.4.20-acpi/include/acpi/actypes.h 2003-05-13 02:53:25.000000000 +0200
+@@ -407,7 +407,7 @@
+ #define ACPI_TABLE_SSDT (acpi_table_type) 5
+ #define ACPI_TABLE_XSDT (acpi_table_type) 6
+ #define ACPI_TABLE_MAX 6
+-#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1)
++#define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1)
+
+
+ /*
+@@ -747,7 +747,7 @@
+ u32 debug_level;
+ u32 debug_layer;
+ u32 num_table_types;
+- struct acpi_table_info table_info [NUM_ACPI_TABLES];
++ struct acpi_table_info table_info [NUM_ACPI_TABLE_TYPES];
+ };
+
+
|